diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:59:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:59:20 -0500 |
commit | 1c2e02750b992703a8a18634e08b04353face243 (patch) | |
tree | 5dc2d10bad329eeb73b9e219e237662a8383f971 | |
parent | 8b4b6707ee32f929846d947d18b1b9bf42e988aa (diff) | |
parent | a3c44854a59f7e983c867060aa906bbf5befb1ef (diff) |
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
...
202 files changed, 4939 insertions, 2755 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 36b511c7cade..1def6049784c 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -513,6 +513,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
513 | 513 | ||
514 | This module supports multiple cards and autoprobe. | 514 | This module supports multiple cards and autoprobe. |
515 | 515 | ||
516 | The power-management is supported. | ||
517 | |||
516 | Module snd-ens1371 | 518 | Module snd-ens1371 |
517 | ------------------ | 519 | ------------------ |
518 | 520 | ||
@@ -526,6 +528,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
526 | 528 | ||
527 | This module supports multiple cards and autoprobe. | 529 | This module supports multiple cards and autoprobe. |
528 | 530 | ||
531 | The power-management is supported. | ||
532 | |||
529 | Module snd-es968 | 533 | Module snd-es968 |
530 | ---------------- | 534 | ---------------- |
531 | 535 | ||
@@ -671,6 +675,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
671 | 675 | ||
672 | model - force the model name | 676 | model - force the model name |
673 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) | 677 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) |
678 | single_cmd - Use single immediate commands to communicate with | ||
679 | codecs (for debugging only) | ||
674 | 680 | ||
675 | This module supports one card and autoprobe. | 681 | This module supports one card and autoprobe. |
676 | 682 | ||
@@ -694,13 +700,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
694 | asus 3-jack | 700 | asus 3-jack |
695 | uniwill 3-jack | 701 | uniwill 3-jack |
696 | F1734 2-jack | 702 | F1734 2-jack |
703 | lg LG laptop (m1 express dual) | ||
697 | test for testing/debugging purpose, almost all controls can be | 704 | test for testing/debugging purpose, almost all controls can be |
698 | adjusted. Appearing only when compiled with | 705 | adjusted. Appearing only when compiled with |
699 | $CONFIG_SND_DEBUG=y | 706 | $CONFIG_SND_DEBUG=y |
707 | auto auto-config reading BIOS (default) | ||
700 | 708 | ||
701 | ALC260 | 709 | ALC260 |
702 | hp HP machines | 710 | hp HP machines |
703 | fujitsu Fujitsu S7020 | 711 | fujitsu Fujitsu S7020 |
712 | acer Acer TravelMate | ||
713 | basic fixed pin assignment (old default model) | ||
714 | auto auto-config reading BIOS (default) | ||
715 | |||
716 | ALC262 | ||
717 | fujitsu Fujitsu Laptop | ||
718 | basic fixed pin assignment w/o SPDIF | ||
719 | auto auto-config reading BIOS (default) | ||
720 | |||
721 | ALC882/883/885 | ||
722 | 3stack-dig 3-jack with SPDIF I/O | ||
723 | 6stck-dig 6-jack digital with SPDIF I/O | ||
724 | auto auto-config reading BIOS (default) | ||
725 | |||
726 | ALC861 | ||
727 | 3stack 3-jack | ||
728 | 3stack-dig 3-jack with SPDIF I/O | ||
729 | 6stack-dig 6-jack with SPDIF I/O | ||
730 | auto auto-config reading BIOS (default) | ||
704 | 731 | ||
705 | CMI9880 | 732 | CMI9880 |
706 | minimal 3-jack in back | 733 | minimal 3-jack in back |
@@ -710,6 +737,28 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
710 | allout 5-jack in back, 2-jack in front, SPDIF out | 737 | allout 5-jack in back, 2-jack in front, SPDIF out |
711 | auto auto-config reading BIOS (default) | 738 | auto auto-config reading BIOS (default) |
712 | 739 | ||
740 | AD1981 | ||
741 | basic 3-jack (default) | ||
742 | hp HP nx6320 | ||
743 | |||
744 | AD1986A | ||
745 | 6stack 6-jack, separate surrounds (default) | ||
746 | 3stack 3-stack, shared surrounds | ||
747 | laptop 2-channel only (FSC V2060, Samsung M50) | ||
748 | laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) | ||
749 | |||
750 | AD1988 | ||
751 | 6stack 6-jack | ||
752 | 6stack-dig ditto with SPDIF | ||
753 | 3stack 3-jack | ||
754 | 3stack-dig ditto with SPDIF | ||
755 | laptop 3-jack with hp-jack automute | ||
756 | laptop-dig ditto with SPDIF | ||
757 | auto auto-confgi reading BIOS (default) | ||
758 | |||
759 | STAC7661(?) | ||
760 | vaio Setup for VAIO FE550G/SZ110 | ||
761 | |||
713 | If the default configuration doesn't work and one of the above | 762 | If the default configuration doesn't work and one of the above |
714 | matches with your device, report it together with the PCI | 763 | matches with your device, report it together with the PCI |
715 | subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel | 764 | 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. | |||
723 | (Usually SD_LPLIB register is more accurate than the | 772 | (Usually SD_LPLIB register is more accurate than the |
724 | position buffer.) | 773 | position buffer.) |
725 | 774 | ||
775 | NB: If you get many "azx_get_response timeout" messages at | ||
776 | loading, it's likely a problem of interrupts (e.g. ACPI irq | ||
777 | routing). Try to boot with options like "pci=noacpi". Also, you | ||
778 | can try "single_cmd=1" module option. This will switch the | ||
779 | communication method between HDA controller and codecs to the | ||
780 | single immediate commands instead of CORB/RIRB. Basically, the | ||
781 | single command mode is provided only for BIOS, and you won't get | ||
782 | unsolicited events, too. But, at least, this works independently | ||
783 | from the irq. Remember this is a last resort, and should be | ||
784 | avoided as much as possible... | ||
785 | |||
726 | The power-management is supported. | 786 | The power-management is supported. |
727 | 787 | ||
728 | Module snd-hdsp | 788 | Module snd-hdsp |
@@ -802,6 +862,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
802 | ------------------ | 862 | ------------------ |
803 | 863 | ||
804 | Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. | 864 | Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards. |
865 | * MidiMan M Audio Revolution 5.1 | ||
805 | * MidiMan M Audio Revolution 7.1 | 866 | * MidiMan M Audio Revolution 7.1 |
806 | * AMP Ltd AUDIO2000 | 867 | * AMP Ltd AUDIO2000 |
807 | * TerraTec Aureon 5.1 Sky | 868 | * TerraTec Aureon 5.1 Sky |
@@ -810,6 +871,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
810 | * TerraTec Phase 22 | 871 | * TerraTec Phase 22 |
811 | * TerraTec Phase 28 | 872 | * TerraTec Phase 28 |
812 | * AudioTrak Prodigy 7.1 | 873 | * AudioTrak Prodigy 7.1 |
874 | * AudioTrak Prodigy 7.1LT | ||
813 | * AudioTrak Prodigy 192 | 875 | * AudioTrak Prodigy 192 |
814 | * Pontis MS300 | 876 | * Pontis MS300 |
815 | * Albatron K8X800 Pro II | 877 | * Albatron K8X800 Pro II |
@@ -820,9 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
820 | * Shuttle SN25P | 882 | * Shuttle SN25P |
821 | 883 | ||
822 | model - Use the given board model, one of the following: | 884 | model - Use the given board model, one of the following: |
823 | revo71, amp2000, prodigy71, prodigy192, aureon51, | 885 | revo51, revo71, amp2000, prodigy71, prodigy71lt, |
824 | aureon71, universe, k8x800, phase22, phase28, ms300, | 886 | prodigy192, aureon51, aureon71, universe, |
825 | av710 | 887 | k8x800, phase22, phase28, ms300, av710 |
826 | 888 | ||
827 | This module supports multiple cards and autoprobe. | 889 | This module supports multiple cards and autoprobe. |
828 | 890 | ||
@@ -1353,6 +1415,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1353 | 1415 | ||
1354 | vid - Vendor ID for the device (optional) | 1416 | vid - Vendor ID for the device (optional) |
1355 | pid - Product ID for the device (optional) | 1417 | pid - Product ID for the device (optional) |
1418 | device_setup - Device specific magic number (optional) | ||
1419 | - Influence depends on the device | ||
1420 | - Default: 0x0000 | ||
1356 | 1421 | ||
1357 | This module supports multiple devices, autoprobe and hotplugging. | 1422 | This module supports multiple devices, autoprobe and hotplugging. |
1358 | 1423 | ||
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt new file mode 100644 index 000000000000..4692c8e77dc1 --- /dev/null +++ b/Documentation/sound/alsa/Audiophile-Usb.txt | |||
@@ -0,0 +1,333 @@ | |||
1 | Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2 | ||
2 | ======================================================== | ||
3 | |||
4 | Thibault Le Meur <Thibault.LeMeur@supelec.fr> | ||
5 | |||
6 | This document is a guide to using the M-Audio Audiophile USB (tm) device with | ||
7 | ALSA and JACK. | ||
8 | |||
9 | 1 - Audiophile USB Specs and correct usage | ||
10 | ========================================== | ||
11 | This part is a reminder of important facts about the functions and limitations | ||
12 | of the device. | ||
13 | |||
14 | The device has 4 audio interfaces, and 2 MIDI ports: | ||
15 | * Analog Stereo Input (Ai) | ||
16 | - This port supports 2 pairs of line-level audio inputs (1/4" TS and RCA) | ||
17 | - When the 1/4" TS (jack) connectors are connected, the RCA connectors | ||
18 | are disabled | ||
19 | * Analog Stereo Output (Ao) | ||
20 | * Digital Stereo Input (Di) | ||
21 | * Digital Stereo Output (Do) | ||
22 | * Midi In (Mi) | ||
23 | * Midi Out (Mo) | ||
24 | |||
25 | The internal DAC/ADC has the following caracteristics: | ||
26 | * sample depth of 16 or 24 bits | ||
27 | * sample rate from 8kHz to 96kHz | ||
28 | * Two ports can't use different sample depths at the same time.Moreover, the | ||
29 | Audiophile USB documentation gives the following Warning: "Please exit any | ||
30 | audio application running before switching between bit depths" | ||
31 | |||
32 | Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be | ||
33 | activated at the same time depending on the audio mode selected: | ||
34 | * 16-bit/48kHz ==> 4 channels in/ 4 channels out | ||
35 | - Ai+Ao+Di+Do | ||
36 | * 24-bit/48kHz ==> 4 channels in/2 channels out, | ||
37 | or 2 channels in/4 channels out | ||
38 | - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do | ||
39 | * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only) | ||
40 | - Ai or Ao or Di or Do | ||
41 | |||
42 | Important facts about the Digital interface: | ||
43 | -------------------------------------------- | ||
44 | * The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough, | ||
45 | though I haven't tested it under linux | ||
46 | - Note that in this setup only the Do interface can be enabled | ||
47 | * Apart from recording an audio digital stream, enabling the Di port is a way | ||
48 | to synchronize the device to an external sample clock | ||
49 | - As a consequence, the Di port must be enable only if an active Digital | ||
50 | source is connected | ||
51 | - Enabling Di when no digital source is connected can result in a | ||
52 | synchronization error (for instance sound played at an odd sample rate) | ||
53 | |||
54 | |||
55 | 2 - Audiophile USB support in ALSA | ||
56 | ================================== | ||
57 | |||
58 | 2.1 - MIDI ports | ||
59 | ---------------- | ||
60 | The Audiophile USB MIDI ports will be automatically supported once the | ||
61 | following modules have been loaded: | ||
62 | * snd-usb-audio | ||
63 | * snd-seq | ||
64 | * snd-seq-midi | ||
65 | |||
66 | No additionnal setting is required. | ||
67 | |||
68 | 2.2 - Audio ports | ||
69 | ----------------- | ||
70 | |||
71 | Audio functions of the Audiophile USB device are handled by the snd-usb-audio | ||
72 | module. This module can work in a default mode (without any device-specific | ||
73 | parameter), or in an advanced mode with the device-specific parameter called | ||
74 | "device_setup". | ||
75 | |||
76 | 2.2.1 - Default Alsa driver mode | ||
77 | |||
78 | The default behaviour of the snd-usb-audio driver is to parse the device | ||
79 | capabilities at startup and enable all functions inside the device (including | ||
80 | all ports at any sample rates and any sample depths supported). This approach | ||
81 | has the advantage to let the driver easily switch from sample rates/depths | ||
82 | automatically according to the need of the application claiming the device. | ||
83 | |||
84 | In this case the Audiophile ports are mapped to alsa pcm devices in the | ||
85 | following way (I suppose the device's index is 1): | ||
86 | * hw:1,0 is Ao in playback and Di in capture | ||
87 | * hw:1,1 is Do in playback and Ai in capture | ||
88 | * hw:1,2 is Do in AC3/DTS passthrough mode | ||
89 | |||
90 | You must note as well that the device uses Big Endian byte encoding so that | ||
91 | supported audio format are S16_BE for 16-bit depth modes and S24_3BE for | ||
92 | 24-bits depth mode. One exception is the hw:1,2 port which is Little Endian | ||
93 | compliant and thus uses S16_LE. | ||
94 | |||
95 | Examples: | ||
96 | * playing a S24_3BE encoded raw file to the Ao port | ||
97 | % aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw | ||
98 | * recording a S24_3BE encoded raw file from the Ai port | ||
99 | % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw | ||
100 | * playing a S16_BE encoded raw file to the Do port | ||
101 | % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw | ||
102 | |||
103 | If you're happy with the default Alsa driver setup and don't experience any | ||
104 | issue with this mode, then you can skip the following chapter. | ||
105 | |||
106 | 2.2.2 - Advanced module setup | ||
107 | |||
108 | Due to the hardware constraints described above, the device initialization made | ||
109 | by the Alsa driver in default mode may result in a corrupted state of the | ||
110 | device. For instance, a particularly annoying issue is that the sound captured | ||
111 | from the Ai port sounds distorted (as if boosted with an excessive high volume | ||
112 | gain). | ||
113 | |||
114 | For people having this problem, the snd-usb-audio module has a new module | ||
115 | parameter called "device_setup". | ||
116 | |||
117 | 2.2.2.1 - Initializing the working mode of the Audiohile USB | ||
118 | |||
119 | As far as the Audiohile USB device is concerned, this value let the user | ||
120 | specify: | ||
121 | * the sample depth | ||
122 | * the sample rate | ||
123 | * whether the Di port is used or not | ||
124 | |||
125 | Here is a list of supported device_setup values for this device: | ||
126 | * device_setup=0x00 (or omitted) | ||
127 | - Alsa driver default mode | ||
128 | - maintains backward compatibility with setups that do not use this | ||
129 | parameter by not introducing any change | ||
130 | - results sometimes in corrupted sound as decribed earlier | ||
131 | * device_setup=0x01 | ||
132 | - 16bits 48kHz mode with Di disabled | ||
133 | - Ai,Ao,Do can be used at the same time | ||
134 | - hw:1,0 is not available in capture mode | ||
135 | - hw:1,2 is not available | ||
136 | * device_setup=0x11 | ||
137 | - 16bits 48kHz mode with Di enabled | ||
138 | - Ai,Ao,Di,Do can be used at the same time | ||
139 | - hw:1,0 is available in capture mode | ||
140 | - hw:1,2 is not available | ||
141 | * device_setup=0x09 | ||
142 | - 24bits 48kHz mode with Di disabled | ||
143 | - Ai,Ao,Do can be used at the same time | ||
144 | - hw:1,0 is not available in capture mode | ||
145 | - hw:1,2 is not available | ||
146 | * device_setup=0x19 | ||
147 | - 24bits 48kHz mode with Di enabled | ||
148 | - 3 ports from {Ai,Ao,Di,Do} can be used at the same time | ||
149 | - hw:1,0 is available in capture mode and an active digital source must be | ||
150 | connected to Di | ||
151 | - hw:1,2 is not available | ||
152 | * device_setup=0x0D or 0x10 | ||
153 | - 24bits 96kHz mode | ||
154 | - Di is enabled by default for this mode but does not need to be connected | ||
155 | to an active source | ||
156 | - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time | ||
157 | - hw:1,0 is available in captured mode | ||
158 | - hw:1,2 is not available | ||
159 | * device_setup=0x03 | ||
160 | - 16bits 48kHz mode with only the Do port enabled | ||
161 | - AC3 with DTS passthru (not tested) | ||
162 | - Caution with this setup the Do port is mapped to the pcm device hw:1,0 | ||
163 | |||
164 | 2.2.2.2 - Setting and switching configurations with the device_setup parameter | ||
165 | |||
166 | The parameter can be given: | ||
167 | * By manually probing the device (as root): | ||
168 | # modprobe -r snd-usb-audio | ||
169 | # modprobe snd-usb-audio index=1 device_setup=0x09 | ||
170 | * Or while configuring the modules options in your modules configuration file | ||
171 | - For Fedora distributions, edit the /etc/modprobe.conf file: | ||
172 | alias snd-card-1 snd-usb-audio | ||
173 | options snd-usb-audio index=1 device_setup=0x09 | ||
174 | |||
175 | IMPORTANT NOTE WHEN SWITCHING CONFIGURATION: | ||
176 | ------------------------------------------- | ||
177 | * You may need to _first_ intialize the module with the correct device_setup | ||
178 | parameter and _only_after_ turn on the Audiophile USB device | ||
179 | * This is especially true when switching the sample depth: | ||
180 | - first trun off the device | ||
181 | - de-register the snd-usb-audio module | ||
182 | - change the device_setup parameter (by either manually reprobing the module | ||
183 | or changing modprobe.conf) | ||
184 | - turn on the device | ||
185 | |||
186 | 2.2.2.3 - Audiophile USB's device_setup structure | ||
187 | |||
188 | If you want to understand the device_setup magic numbers for the Audiophile | ||
189 | USB, you need some very basic understanding of binary computation. However, | ||
190 | this is not required to use the parameter and you may skip thi section. | ||
191 | |||
192 | The device_setup is one byte long and its structure is the following: | ||
193 | |||
194 | +---+---+---+---+---+---+---+---+ | ||
195 | | b7| b6| b5| b4| b3| b2| b1| b0| | ||
196 | +---+---+---+---+---+---+---+---+ | ||
197 | | 0 | 0 | 0 | Di|24B|96K|DTS|SET| | ||
198 | +---+---+---+---+---+---+---+---+ | ||
199 | |||
200 | Where: | ||
201 | * b0 is the "SET" bit | ||
202 | - it MUST be set if device_setup is initialized | ||
203 | * b1 is the "DTS" bit | ||
204 | - it is set only for Digital output with DTS/AC3 | ||
205 | - this setup is not tested | ||
206 | * b2 is the Rate selection flag | ||
207 | - When set to "1" the rate range is 48.1-96kHz | ||
208 | - Otherwise the sample rate range is 8-48kHz | ||
209 | * b3 is the bit depth selection flag | ||
210 | - When set to "1" samples are 24bits long | ||
211 | - Otherwise they are 16bits long | ||
212 | - Note that b2 implies b3 as the 96kHz mode is only supported for 24 bits | ||
213 | samples | ||
214 | * b4 is the Digital input flag | ||
215 | - When set to "1" the device assumes that an active digital source is | ||
216 | connected | ||
217 | - You shouldn't enable Di if no source is seen on the port (this leads to | ||
218 | synchronization issues) | ||
219 | - b4 is implied by b2 (since only one port is enabled at a time no synch | ||
220 | error can occur) | ||
221 | * b5 to b7 are reserved for future uses, and must be set to "0" | ||
222 | - might become Ao, Do, Ai, for b7, b6, b4 respectively | ||
223 | |||
224 | Caution: | ||
225 | * there is no check on the value you will give to device_setup | ||
226 | - for instance choosing 0x05 (16bits 96kHz) will fail back to 0x09 since | ||
227 | b2 implies b3. But _there_will_be_no_warning_ in /var/log/messages | ||
228 | * Hardware constraints due to the USB bus limitation aren't checked | ||
229 | - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll | ||
230 | only be able to use one at the same time | ||
231 | |||
232 | 2.2.3 - USB implementation details for this device | ||
233 | |||
234 | You may safely skip this section if you're not interrested in driver | ||
235 | development. | ||
236 | |||
237 | This section describes some internals aspect of the device and summarize the | ||
238 | data I got by usb-snooping the windows and linux drivers. | ||
239 | |||
240 | The M-Audio Audiophile USB has 7 USB Interfaces: | ||
241 | a "USB interface": | ||
242 | * USB Interface nb.0 | ||
243 | * USB Interface nb.1 | ||
244 | - Audio Control function | ||
245 | * USB Interface nb.2 | ||
246 | - Analog Output | ||
247 | * USB Interface nb.3 | ||
248 | - Digital Output | ||
249 | * USB Interface nb.4 | ||
250 | - Analog Input | ||
251 | * USB Interface nb.5 | ||
252 | - Digital Input | ||
253 | * USB Interface nb.6 | ||
254 | - MIDI interface compliant with the MIDIMAN quirk | ||
255 | |||
256 | Each interface has 5 altsettings (AltSet 1,2,3,4,5) except: | ||
257 | * Interface 3 (Digital Out) has an extra Alset nb.6 | ||
258 | * Interface 5 (Digital In) does not have Alset nb.3 and 5 | ||
259 | |||
260 | Here is a short description of the AltSettings capabilities: | ||
261 | * AltSettings 1 corresponds to | ||
262 | - 24-bit depth, 48.1-96kHz sample mode | ||
263 | - Adaptive playback (Ao and Do), Synch capture (Ai), or Asynch capture (Di) | ||
264 | * AltSettings 2 corresponds to | ||
265 | - 24-bit depth, 8-48kHz sample mode | ||
266 | - Asynch capture and playback (Ao,Ai,Do,Di) | ||
267 | * AltSettings 3 corresponds to | ||
268 | - 24-bit depth, 8-48kHz sample mode | ||
269 | - Synch capture (Ai) and Adaptive playback (Ao,Do) | ||
270 | * AltSettings 4 corresponds to | ||
271 | - 16-bit depth, 8-48kHz sample mode | ||
272 | - Asynch capture and playback (Ao,Ai,Do,Di) | ||
273 | * AltSettings 5 corresponds to | ||
274 | - 16-bit depth, 8-48kHz sample mode | ||
275 | - Synch capture (Ai) and Adaptive playback (Ao,Do) | ||
276 | * AltSettings 6 corresponds to | ||
277 | - 16-bit depth, 8-48kHz sample mode | ||
278 | - Synch playback (Do), audio format type III IEC1937_AC-3 | ||
279 | |||
280 | In order to ensure a correct intialization of the device, the driver | ||
281 | _must_know_ how the device will be used: | ||
282 | * if DTS is choosen, only Interface 2 with AltSet nb.6 must be | ||
283 | registered | ||
284 | * if 96KHz only AltSets nb.1 of each interface must be selected | ||
285 | * if samples are using 24bits/48KHz then AltSet 2 must me used if | ||
286 | Digital input is connected, and only AltSet nb.3 if Digital input | ||
287 | is not connected | ||
288 | * if samples are using 16bits/48KHz then AltSet 4 must me used if | ||
289 | Digital input is connected, and only AltSet nb.5 if Digital input | ||
290 | is not connected | ||
291 | |||
292 | When device_setup is given as a parameter to the snd-usb-audio module, the | ||
293 | parse_audio_enpoint function uses a quirk called | ||
294 | "audiophile_skip_setting_quirk" in order to prevent AltSettings not | ||
295 | corresponding to device_setup from being registered in the driver. | ||
296 | |||
297 | 3 - Audiophile USB and Jack support | ||
298 | =================================== | ||
299 | |||
300 | This section deals with support of the Audiophile USB device in Jack. | ||
301 | The main issue regarding this support is that the device is Big Endian | ||
302 | compliant. | ||
303 | |||
304 | 3.1 - Using the plug alsa plugin | ||
305 | -------------------------------- | ||
306 | |||
307 | Jack doesn't directly support big endian devices. Thus, one way to have support | ||
308 | for this device with Alsa is to use the Alsa "plug" converter. | ||
309 | |||
310 | For instance here is one way to run Jack with 2 playback channels on Ao and 2 | ||
311 | capture channels from Ai: | ||
312 | % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 | ||
313 | |||
314 | |||
315 | However you may see the following warning message: | ||
316 | "You appear to be using the ALSA software "plug" layer, probably a result of | ||
317 | using the "default" ALSA device. This is less efficient than it could be. | ||
318 | Consider using a hardware device instead rather than using the plug layer." | ||
319 | |||
320 | |||
321 | 3.2 - Patching alsa to use direct pcm device | ||
322 | ------------------------------------------- | ||
323 | A patch for Jack by Andreas Steinmetz adds support for Big Endian devices. | ||
324 | However it has not been included in the CVS tree. | ||
325 | |||
326 | You can find it at the following URL: | ||
327 | http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687& | ||
328 | atid=425939 | ||
329 | |||
330 | After having applied the patch you can run jackd with the following command | ||
331 | line: | ||
332 | % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 | ||
333 | |||
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl index 4251085d38d3..6dc9d9f622ca 100644 --- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl | |||
@@ -1834,7 +1834,7 @@ | |||
1834 | mychip_set_sample_format(chip, runtime->format); | 1834 | mychip_set_sample_format(chip, runtime->format); |
1835 | mychip_set_sample_rate(chip, runtime->rate); | 1835 | mychip_set_sample_rate(chip, runtime->rate); |
1836 | mychip_set_channels(chip, runtime->channels); | 1836 | mychip_set_channels(chip, runtime->channels); |
1837 | mychip_set_dma_setup(chip, runtime->dma_area, | 1837 | mychip_set_dma_setup(chip, runtime->dma_addr, |
1838 | chip->buffer_size, | 1838 | chip->buffer_size, |
1839 | chip->period_size); | 1839 | chip->period_size); |
1840 | return 0; | 1840 | return 0; |
@@ -3388,7 +3388,7 @@ struct _snd_pcm_runtime { | |||
3388 | .name = "PCM Playback Switch", | 3388 | .name = "PCM Playback Switch", |
3389 | .index = 0, | 3389 | .index = 0, |
3390 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 3390 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
3391 | .private_values = 0xffff, | 3391 | .private_value = 0xffff, |
3392 | .info = my_control_info, | 3392 | .info = my_control_info, |
3393 | .get = my_control_get, | 3393 | .get = my_control_get, |
3394 | .put = my_control_put | 3394 | .put = my_control_put |
@@ -3449,7 +3449,7 @@ struct _snd_pcm_runtime { | |||
3449 | </para> | 3449 | </para> |
3450 | 3450 | ||
3451 | <para> | 3451 | <para> |
3452 | The <structfield>private_values</structfield> field contains | 3452 | The <structfield>private_value</structfield> field contains |
3453 | an arbitrary long integer value for this record. When using | 3453 | an arbitrary long integer value for this record. When using |
3454 | generic <structfield>info</structfield>, | 3454 | generic <structfield>info</structfield>, |
3455 | <structfield>get</structfield> and | 3455 | <structfield>get</structfield> and |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index d5bda60209ec..98356f810007 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -157,14 +157,14 @@ static struct platform_device smc91x_device = { | |||
157 | .resource = smc91x_resources, | 157 | .resource = smc91x_resources, |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv) | 160 | static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv) |
161 | { | 161 | { |
162 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 162 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
163 | MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; | 163 | MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF; |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv) | 167 | static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv) |
168 | { | 168 | { |
169 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 169 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
170 | MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; | 170 | MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF; |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index bffef1decc8b..3170b8f72c68 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -63,7 +63,7 @@ struct cx88_audio_dev { | |||
63 | /* audio controls */ | 63 | /* audio controls */ |
64 | int irq; | 64 | int irq; |
65 | 65 | ||
66 | snd_card_t *card; | 66 | struct snd_card *card; |
67 | 67 | ||
68 | spinlock_t reg_lock; | 68 | spinlock_t reg_lock; |
69 | 69 | ||
@@ -82,7 +82,7 @@ struct cx88_audio_dev { | |||
82 | struct cx88_buffer *buf; | 82 | struct cx88_buffer *buf; |
83 | 83 | ||
84 | long opened; | 84 | long opened; |
85 | snd_pcm_substream_t *substream; | 85 | struct snd_pcm_substream *substream; |
86 | 86 | ||
87 | }; | 87 | }; |
88 | typedef struct cx88_audio_dev snd_cx88_card_t; | 88 | typedef struct cx88_audio_dev snd_cx88_card_t; |
@@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t; | |||
96 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 96 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
97 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 97 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
98 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; | 98 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; |
99 | static snd_card_t *snd_cx88_cards[SNDRV_CARDS]; | 99 | static struct snd_card *snd_cx88_cards[SNDRV_CARDS]; |
100 | 100 | ||
101 | module_param_array(enable, bool, NULL, 0444); | 101 | module_param_array(enable, bool, NULL, 0444); |
102 | MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); | 102 | MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); |
@@ -320,7 +320,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip) | |||
320 | /* | 320 | /* |
321 | * Digital hardware definition | 321 | * Digital hardware definition |
322 | */ | 322 | */ |
323 | static snd_pcm_hardware_t snd_cx88_digital_hw = { | 323 | static struct snd_pcm_hardware snd_cx88_digital_hw = { |
324 | .info = SNDRV_PCM_INFO_MMAP | | 324 | .info = SNDRV_PCM_INFO_MMAP | |
325 | SNDRV_PCM_INFO_INTERLEAVED | | 325 | SNDRV_PCM_INFO_INTERLEAVED | |
326 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 326 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -342,16 +342,16 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = { | |||
342 | /* | 342 | /* |
343 | * audio pcm capture runtime free | 343 | * audio pcm capture runtime free |
344 | */ | 344 | */ |
345 | static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime) | 345 | static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime) |
346 | { | 346 | { |
347 | } | 347 | } |
348 | /* | 348 | /* |
349 | * audio pcm capture open callback | 349 | * audio pcm capture open callback |
350 | */ | 350 | */ |
351 | static int snd_cx88_pcm_open(snd_pcm_substream_t *substream) | 351 | static int snd_cx88_pcm_open(struct snd_pcm_substream *substream) |
352 | { | 352 | { |
353 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 353 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); |
354 | snd_pcm_runtime_t *runtime = substream->runtime; | 354 | struct snd_pcm_runtime *runtime = substream->runtime; |
355 | int err; | 355 | int err; |
356 | 356 | ||
357 | if (test_and_set_bit(0, &chip->opened)) | 357 | if (test_and_set_bit(0, &chip->opened)) |
@@ -380,7 +380,7 @@ _error: | |||
380 | /* | 380 | /* |
381 | * audio close callback | 381 | * audio close callback |
382 | */ | 382 | */ |
383 | static int snd_cx88_close(snd_pcm_substream_t *substream) | 383 | static int snd_cx88_close(struct snd_pcm_substream *substream) |
384 | { | 384 | { |
385 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 385 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); |
386 | 386 | ||
@@ -393,8 +393,8 @@ static int snd_cx88_close(snd_pcm_substream_t *substream) | |||
393 | /* | 393 | /* |
394 | * hw_params callback | 394 | * hw_params callback |
395 | */ | 395 | */ |
396 | static int snd_cx88_hw_params(snd_pcm_substream_t * substream, | 396 | static int snd_cx88_hw_params(struct snd_pcm_substream * substream, |
397 | snd_pcm_hw_params_t * hw_params) | 397 | struct snd_pcm_hw_params * hw_params) |
398 | { | 398 | { |
399 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 399 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); |
400 | struct cx88_buffer *buf; | 400 | struct cx88_buffer *buf; |
@@ -453,7 +453,7 @@ static int snd_cx88_hw_params(snd_pcm_substream_t * substream, | |||
453 | /* | 453 | /* |
454 | * hw free callback | 454 | * hw free callback |
455 | */ | 455 | */ |
456 | static int snd_cx88_hw_free(snd_pcm_substream_t * substream) | 456 | static int snd_cx88_hw_free(struct snd_pcm_substream * substream) |
457 | { | 457 | { |
458 | 458 | ||
459 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 459 | 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) | |||
469 | /* | 469 | /* |
470 | * prepare callback | 470 | * prepare callback |
471 | */ | 471 | */ |
472 | static int snd_cx88_prepare(snd_pcm_substream_t *substream) | 472 | static int snd_cx88_prepare(struct snd_pcm_substream *substream) |
473 | { | 473 | { |
474 | return 0; | 474 | return 0; |
475 | } | 475 | } |
@@ -478,7 +478,7 @@ static int snd_cx88_prepare(snd_pcm_substream_t *substream) | |||
478 | /* | 478 | /* |
479 | * trigger callback | 479 | * trigger callback |
480 | */ | 480 | */ |
481 | static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd) | 481 | static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd) |
482 | { | 482 | { |
483 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 483 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); |
484 | int err; | 484 | int err; |
@@ -505,10 +505,10 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd) | |||
505 | /* | 505 | /* |
506 | * pointer callback | 506 | * pointer callback |
507 | */ | 507 | */ |
508 | static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream) | 508 | static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) |
509 | { | 509 | { |
510 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); | 510 | snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); |
511 | snd_pcm_runtime_t *runtime = substream->runtime; | 511 | struct snd_pcm_runtime *runtime = substream->runtime; |
512 | 512 | ||
513 | if (chip->read_count) { | 513 | if (chip->read_count) { |
514 | chip->read_count -= snd_pcm_lib_period_bytes(substream); | 514 | 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) | |||
525 | /* | 525 | /* |
526 | * operators | 526 | * operators |
527 | */ | 527 | */ |
528 | static snd_pcm_ops_t snd_cx88_pcm_ops = { | 528 | static struct snd_pcm_ops snd_cx88_pcm_ops = { |
529 | .open = snd_cx88_pcm_open, | 529 | .open = snd_cx88_pcm_open, |
530 | .close = snd_cx88_close, | 530 | .close = snd_cx88_close, |
531 | .ioctl = snd_pcm_lib_ioctl, | 531 | .ioctl = snd_pcm_lib_ioctl, |
@@ -542,7 +542,7 @@ static snd_pcm_ops_t snd_cx88_pcm_ops = { | |||
542 | static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) | 542 | static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) |
543 | { | 543 | { |
544 | int err; | 544 | int err; |
545 | snd_pcm_t *pcm; | 545 | struct snd_pcm *pcm; |
546 | 546 | ||
547 | err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); | 547 | err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); |
548 | if (err < 0) | 548 | if (err < 0) |
@@ -557,7 +557,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) | |||
557 | /**************************************************************************** | 557 | /**************************************************************************** |
558 | CONTROL INTERFACE | 558 | CONTROL INTERFACE |
559 | ****************************************************************************/ | 559 | ****************************************************************************/ |
560 | static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info) | 560 | static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol, |
561 | struct snd_ctl_elem_info *info) | ||
561 | { | 562 | { |
562 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 563 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
563 | info->count = 1; | 564 | info->count = 1; |
@@ -568,7 +569,8 @@ static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i | |||
568 | } | 569 | } |
569 | 570 | ||
570 | /* OK - TODO: test it */ | 571 | /* OK - TODO: test it */ |
571 | static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) | 572 | static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol, |
573 | struct snd_ctl_elem_value *value) | ||
572 | { | 574 | { |
573 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | 575 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); |
574 | struct cx88_core *core=chip->core; | 576 | 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 | |||
579 | } | 581 | } |
580 | 582 | ||
581 | /* OK - TODO: test it */ | 583 | /* OK - TODO: test it */ |
582 | static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) | 584 | static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol, |
585 | struct snd_ctl_elem_value *value) | ||
583 | { | 586 | { |
584 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | 587 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); |
585 | struct cx88_core *core=chip->core; | 588 | 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 | |||
595 | return v != old_control; | 598 | return v != old_control; |
596 | } | 599 | } |
597 | 600 | ||
598 | static snd_kcontrol_new_t snd_cx88_capture_volume = { | 601 | static struct snd_kcontrol_new snd_cx88_capture_volume = { |
599 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 602 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
600 | .name = "Capture Volume", | 603 | .name = "Capture Volume", |
601 | .info = snd_cx88_capture_volume_info, | 604 | .info = snd_cx88_capture_volume_info, |
@@ -641,7 +644,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip) | |||
641 | /* | 644 | /* |
642 | * Component Destructor | 645 | * Component Destructor |
643 | */ | 646 | */ |
644 | static void snd_cx88_dev_free(snd_card_t * card) | 647 | static void snd_cx88_dev_free(struct snd_card * card) |
645 | { | 648 | { |
646 | snd_cx88_card_t *chip = card->private_data; | 649 | snd_cx88_card_t *chip = card->private_data; |
647 | 650 | ||
@@ -654,8 +657,9 @@ static void snd_cx88_dev_free(snd_card_t * card) | |||
654 | */ | 657 | */ |
655 | 658 | ||
656 | static int devno; | 659 | static int devno; |
657 | static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, | 660 | static int __devinit snd_cx88_create(struct snd_card *card, |
658 | snd_cx88_card_t **rchip) | 661 | struct pci_dev *pci, |
662 | snd_cx88_card_t **rchip) | ||
659 | { | 663 | { |
660 | snd_cx88_card_t *chip; | 664 | snd_cx88_card_t *chip; |
661 | struct cx88_core *core; | 665 | struct cx88_core *core; |
@@ -726,7 +730,7 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, | |||
726 | static int __devinit cx88_audio_initdev(struct pci_dev *pci, | 730 | static int __devinit cx88_audio_initdev(struct pci_dev *pci, |
727 | const struct pci_device_id *pci_id) | 731 | const struct pci_device_id *pci_id) |
728 | { | 732 | { |
729 | snd_card_t *card; | 733 | struct snd_card *card; |
730 | snd_cx88_card_t *chip; | 734 | snd_cx88_card_t *chip; |
731 | int err; | 735 | int err; |
732 | 736 | ||
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 64e2c108df34..aca84d2f9825 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -71,7 +71,7 @@ MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s)."); | |||
71 | */ | 71 | */ |
72 | 72 | ||
73 | typedef struct snd_card_saa7134 { | 73 | typedef struct snd_card_saa7134 { |
74 | snd_card_t *card; | 74 | struct snd_card *card; |
75 | spinlock_t mixer_lock; | 75 | spinlock_t mixer_lock; |
76 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | 76 | int mixer_volume[MIXER_ADDR_LAST+1][2]; |
77 | int capture_source[MIXER_ADDR_LAST+1][2]; | 77 | int capture_source[MIXER_ADDR_LAST+1][2]; |
@@ -95,10 +95,10 @@ typedef struct snd_card_saa7134_pcm { | |||
95 | 95 | ||
96 | spinlock_t lock; | 96 | spinlock_t lock; |
97 | 97 | ||
98 | snd_pcm_substream_t *substream; | 98 | struct snd_pcm_substream *substream; |
99 | } snd_card_saa7134_pcm_t; | 99 | } snd_card_saa7134_pcm_t; |
100 | 100 | ||
101 | static snd_card_t *snd_saa7134_cards[SNDRV_CARDS]; | 101 | static struct snd_card *snd_saa7134_cards[SNDRV_CARDS]; |
102 | 102 | ||
103 | 103 | ||
104 | /* | 104 | /* |
@@ -251,10 +251,10 @@ out: | |||
251 | * | 251 | * |
252 | */ | 252 | */ |
253 | 253 | ||
254 | static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, | 254 | static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream, |
255 | int cmd) | 255 | int cmd) |
256 | { | 256 | { |
257 | snd_pcm_runtime_t *runtime = substream->runtime; | 257 | struct snd_pcm_runtime *runtime = substream->runtime; |
258 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; | 258 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
259 | struct saa7134_dev *dev=pcm->dev; | 259 | struct saa7134_dev *dev=pcm->dev; |
260 | int err = 0; | 260 | int err = 0; |
@@ -332,9 +332,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev) | |||
332 | * | 332 | * |
333 | */ | 333 | */ |
334 | 334 | ||
335 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | 335 | static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream) |
336 | { | 336 | { |
337 | snd_pcm_runtime_t *runtime = substream->runtime; | 337 | struct snd_pcm_runtime *runtime = substream->runtime; |
338 | int bswap, sign; | 338 | int bswap, sign; |
339 | u32 fmt, control; | 339 | u32 fmt, control; |
340 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 340 | 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) | |||
421 | * | 421 | * |
422 | */ | 422 | */ |
423 | 423 | ||
424 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) | 424 | static snd_pcm_uframes_t |
425 | snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream) | ||
425 | { | 426 | { |
426 | snd_pcm_runtime_t *runtime = substream->runtime; | 427 | struct snd_pcm_runtime *runtime = substream->runtime; |
427 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; | 428 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
428 | struct saa7134_dev *dev=pcm->dev; | 429 | struct saa7134_dev *dev=pcm->dev; |
429 | 430 | ||
@@ -441,7 +442,7 @@ static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * | |||
441 | * ALSA hardware capabilities definition | 442 | * ALSA hardware capabilities definition |
442 | */ | 443 | */ |
443 | 444 | ||
444 | static snd_pcm_hardware_t snd_card_saa7134_capture = | 445 | static struct snd_pcm_hardware snd_card_saa7134_capture = |
445 | { | 446 | { |
446 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 447 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
447 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 448 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -464,7 +465,7 @@ static snd_pcm_hardware_t snd_card_saa7134_capture = | |||
464 | .periods_max = 1024, | 465 | .periods_max = 1024, |
465 | }; | 466 | }; |
466 | 467 | ||
467 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | 468 | static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime) |
468 | { | 469 | { |
469 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; | 470 | snd_card_saa7134_pcm_t *pcm = runtime->private_data; |
470 | 471 | ||
@@ -481,8 +482,8 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | |||
481 | * | 482 | * |
482 | */ | 483 | */ |
483 | 484 | ||
484 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | 485 | static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream, |
485 | snd_pcm_hw_params_t * hw_params) | 486 | struct snd_pcm_hw_params * hw_params) |
486 | { | 487 | { |
487 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 488 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
488 | struct saa7134_dev *dev; | 489 | struct saa7134_dev *dev; |
@@ -561,7 +562,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | |||
561 | * | 562 | * |
562 | */ | 563 | */ |
563 | 564 | ||
564 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) | 565 | static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream) |
565 | { | 566 | { |
566 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 567 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
567 | struct saa7134_dev *dev; | 568 | struct saa7134_dev *dev; |
@@ -587,7 +588,7 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) | |||
587 | * | 588 | * |
588 | */ | 589 | */ |
589 | 590 | ||
590 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | 591 | static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream) |
591 | { | 592 | { |
592 | return 0; | 593 | return 0; |
593 | } | 594 | } |
@@ -602,9 +603,9 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | |||
602 | * | 603 | * |
603 | */ | 604 | */ |
604 | 605 | ||
605 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | 606 | static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) |
606 | { | 607 | { |
607 | snd_pcm_runtime_t *runtime = substream->runtime; | 608 | struct snd_pcm_runtime *runtime = substream->runtime; |
608 | snd_card_saa7134_pcm_t *pcm; | 609 | snd_card_saa7134_pcm_t *pcm; |
609 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 610 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
610 | struct saa7134_dev *dev = saa7134->dev; | 611 | struct saa7134_dev *dev = saa7134->dev; |
@@ -640,7 +641,7 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | |||
640 | * ALSA capture callbacks definition | 641 | * ALSA capture callbacks definition |
641 | */ | 642 | */ |
642 | 643 | ||
643 | static snd_pcm_ops_t snd_card_saa7134_capture_ops = { | 644 | static struct snd_pcm_ops snd_card_saa7134_capture_ops = { |
644 | .open = snd_card_saa7134_capture_open, | 645 | .open = snd_card_saa7134_capture_open, |
645 | .close = snd_card_saa7134_capture_close, | 646 | .close = snd_card_saa7134_capture_close, |
646 | .ioctl = snd_pcm_lib_ioctl, | 647 | .ioctl = snd_pcm_lib_ioctl, |
@@ -661,7 +662,7 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = { | |||
661 | 662 | ||
662 | static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) | 663 | static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) |
663 | { | 664 | { |
664 | snd_pcm_t *pcm; | 665 | struct snd_pcm *pcm; |
665 | int err; | 666 | int err; |
666 | 667 | ||
667 | if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0) | 668 | 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) | |||
679 | .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \ | 680 | .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \ |
680 | .private_value = addr } | 681 | .private_value = addr } |
681 | 682 | ||
682 | static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) | 683 | static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol, |
684 | struct snd_ctl_elem_info * uinfo) | ||
683 | { | 685 | { |
684 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 686 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
685 | uinfo->count = 2; | 687 | uinfo->count = 2; |
@@ -688,7 +690,8 @@ static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_ | |||
688 | return 0; | 690 | return 0; |
689 | } | 691 | } |
690 | 692 | ||
691 | static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 693 | static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol, |
694 | struct snd_ctl_elem_value * ucontrol) | ||
692 | { | 695 | { |
693 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 696 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
694 | int addr = kcontrol->private_value; | 697 | int addr = kcontrol->private_value; |
@@ -698,7 +701,8 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
698 | return 0; | 701 | return 0; |
699 | } | 702 | } |
700 | 703 | ||
701 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 704 | static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol, |
705 | struct snd_ctl_elem_value * ucontrol) | ||
702 | { | 706 | { |
703 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 707 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
704 | int change, addr = kcontrol->private_value; | 708 | int change, addr = kcontrol->private_value; |
@@ -729,7 +733,8 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
729 | .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \ | 733 | .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \ |
730 | .private_value = addr } | 734 | .private_value = addr } |
731 | 735 | ||
732 | static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) | 736 | static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol, |
737 | struct snd_ctl_elem_info * uinfo) | ||
733 | { | 738 | { |
734 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 739 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
735 | uinfo->count = 2; | 740 | uinfo->count = 2; |
@@ -738,7 +743,8 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_ | |||
738 | return 0; | 743 | return 0; |
739 | } | 744 | } |
740 | 745 | ||
741 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 746 | static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol, |
747 | struct snd_ctl_elem_value * ucontrol) | ||
742 | { | 748 | { |
743 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 749 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
744 | int addr = kcontrol->private_value; | 750 | int addr = kcontrol->private_value; |
@@ -751,7 +757,8 @@ static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
751 | return 0; | 757 | return 0; |
752 | } | 758 | } |
753 | 759 | ||
754 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | 760 | static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol, |
761 | struct snd_ctl_elem_value * ucontrol) | ||
755 | { | 762 | { |
756 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | 763 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); |
757 | int change, addr = kcontrol->private_value; | 764 | int change, addr = kcontrol->private_value; |
@@ -828,7 +835,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_ | |||
828 | return change; | 835 | return change; |
829 | } | 836 | } |
830 | 837 | ||
831 | static snd_kcontrol_new_t snd_saa7134_controls[] = { | 838 | static struct snd_kcontrol_new snd_saa7134_controls[] = { |
832 | SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), | 839 | SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), |
833 | SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), | 840 | SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), |
834 | SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), | 841 | SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), |
@@ -847,7 +854,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), | |||
847 | 854 | ||
848 | static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | 855 | static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) |
849 | { | 856 | { |
850 | snd_card_t *card = chip->card; | 857 | struct snd_card *card = chip->card; |
851 | unsigned int idx; | 858 | unsigned int idx; |
852 | int err; | 859 | int err; |
853 | 860 | ||
@@ -861,7 +868,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | |||
861 | return 0; | 868 | return 0; |
862 | } | 869 | } |
863 | 870 | ||
864 | static void snd_saa7134_free(snd_card_t * card) | 871 | static void snd_saa7134_free(struct snd_card * card) |
865 | { | 872 | { |
866 | snd_card_saa7134_t *chip = card->private_data; | 873 | snd_card_saa7134_t *chip = card->private_data; |
867 | 874 | ||
@@ -888,7 +895,7 @@ static void snd_saa7134_free(snd_card_t * card) | |||
888 | static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) | 895 | static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum) |
889 | { | 896 | { |
890 | 897 | ||
891 | snd_card_t *card; | 898 | struct snd_card *card; |
892 | snd_card_saa7134_t *chip; | 899 | snd_card_saa7134_t *chip; |
893 | int err; | 900 | int err; |
894 | 901 | ||
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 17ba34f30760..ce1c2e0b065e 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -397,7 +397,7 @@ struct saa7134_dmasound { | |||
397 | unsigned int read_offset; | 397 | unsigned int read_offset; |
398 | unsigned int read_count; | 398 | unsigned int read_count; |
399 | void * priv_data; | 399 | void * priv_data; |
400 | snd_pcm_substream_t *substream; | 400 | struct snd_pcm_substream *substream; |
401 | }; | 401 | }; |
402 | 402 | ||
403 | /* IR input */ | 403 | /* IR input */ |
diff --git a/include/asm-arm/arch-pxa/audio.h b/include/asm-arm/arch-pxa/audio.h index 60976f830e3f..17eccd720136 100644 --- a/include/asm-arm/arch-pxa/audio.h +++ b/include/asm-arm/arch-pxa/audio.h | |||
@@ -6,8 +6,8 @@ | |||
6 | #include <sound/pcm.h> | 6 | #include <sound/pcm.h> |
7 | 7 | ||
8 | typedef struct { | 8 | typedef struct { |
9 | int (*startup)(snd_pcm_substream_t *, void *); | 9 | int (*startup)(struct snd_pcm_substream *, void *); |
10 | void (*shutdown)(snd_pcm_substream_t *, void *); | 10 | void (*shutdown)(struct snd_pcm_substream *, void *); |
11 | void (*suspend)(void *); | 11 | void (*suspend)(void *); |
12 | void (*resume)(void *); | 12 | void (*resume)(void *); |
13 | void *priv; | 13 | void *priv; |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 2d80cc761a15..a8731062a74c 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -20,6 +20,7 @@ enum dma_data_direction { | |||
20 | #define DMA_31BIT_MASK 0x000000007fffffffULL | 20 | #define DMA_31BIT_MASK 0x000000007fffffffULL |
21 | #define DMA_30BIT_MASK 0x000000003fffffffULL | 21 | #define DMA_30BIT_MASK 0x000000003fffffffULL |
22 | #define DMA_29BIT_MASK 0x000000001fffffffULL | 22 | #define DMA_29BIT_MASK 0x000000001fffffffULL |
23 | #define DMA_28BIT_MASK 0x000000000fffffffULL | ||
23 | 24 | ||
24 | #include <asm/dma-mapping.h> | 25 | #include <asm/dma-mapping.h> |
25 | 26 | ||
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index b0b3ea7b365e..b45a73712748 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h | |||
@@ -433,6 +433,12 @@ struct snd_ac97_bus { | |||
433 | struct snd_info_entry *proc; | 433 | struct snd_info_entry *proc; |
434 | }; | 434 | }; |
435 | 435 | ||
436 | /* static resolution table */ | ||
437 | struct snd_ac97_res_table { | ||
438 | unsigned short reg; /* register */ | ||
439 | unsigned short bits; /* resolution bitmask */ | ||
440 | }; | ||
441 | |||
436 | struct snd_ac97_template { | 442 | struct snd_ac97_template { |
437 | void *private_data; | 443 | void *private_data; |
438 | void (*private_free) (struct snd_ac97 *ac97); | 444 | void (*private_free) (struct snd_ac97 *ac97); |
@@ -440,8 +446,7 @@ struct snd_ac97_template { | |||
440 | unsigned short num; /* number of codec: 0 = primary, 1 = secondary */ | 446 | unsigned short num; /* number of codec: 0 = primary, 1 = secondary */ |
441 | unsigned short addr; /* physical address of codec [0-3] */ | 447 | unsigned short addr; /* physical address of codec [0-3] */ |
442 | unsigned int scaps; /* driver capabilities */ | 448 | unsigned int scaps; /* driver capabilities */ |
443 | unsigned int limited_regs; /* allow limited registers only */ | 449 | const struct snd_ac97_res_table *res_table; /* static resolution */ |
444 | DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */ | ||
445 | }; | 450 | }; |
446 | 451 | ||
447 | struct snd_ac97 { | 452 | struct snd_ac97 { |
@@ -456,20 +461,20 @@ struct snd_ac97 { | |||
456 | struct snd_info_entry *proc_regs; | 461 | struct snd_info_entry *proc_regs; |
457 | unsigned short subsystem_vendor; | 462 | unsigned short subsystem_vendor; |
458 | unsigned short subsystem_device; | 463 | unsigned short subsystem_device; |
459 | struct semaphore reg_mutex; | 464 | struct mutex reg_mutex; |
460 | struct semaphore page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */ | 465 | struct mutex page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */ |
461 | unsigned short num; /* number of codec: 0 = primary, 1 = secondary */ | 466 | unsigned short num; /* number of codec: 0 = primary, 1 = secondary */ |
462 | unsigned short addr; /* physical address of codec [0-3] */ | 467 | unsigned short addr; /* physical address of codec [0-3] */ |
463 | unsigned int id; /* identification of codec */ | 468 | unsigned int id; /* identification of codec */ |
464 | unsigned short caps; /* capabilities (register 0) */ | 469 | unsigned short caps; /* capabilities (register 0) */ |
465 | unsigned short ext_id; /* extended feature identification (register 28) */ | 470 | unsigned short ext_id; /* extended feature identification (register 28) */ |
466 | unsigned short ext_mid; /* extended modem ID (register 3C) */ | 471 | unsigned short ext_mid; /* extended modem ID (register 3C) */ |
472 | const struct snd_ac97_res_table *res_table; /* static resolution */ | ||
467 | unsigned int scaps; /* driver capabilities */ | 473 | unsigned int scaps; /* driver capabilities */ |
468 | unsigned int flags; /* specific code */ | 474 | unsigned int flags; /* specific code */ |
469 | unsigned int rates[6]; /* see AC97_RATES_* defines */ | 475 | unsigned int rates[6]; /* see AC97_RATES_* defines */ |
470 | unsigned int spdif_status; | 476 | unsigned int spdif_status; |
471 | unsigned short regs[0x80]; /* register cache */ | 477 | unsigned short regs[0x80]; /* register cache */ |
472 | unsigned int limited_regs; /* allow limited registers only */ | ||
473 | DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */ | 478 | DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */ |
474 | union { /* vendor specific code */ | 479 | union { /* vendor specific code */ |
475 | struct { | 480 | struct { |
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h index 1a2759f3a292..57af1fe7b309 100644 --- a/include/sound/ad1848.h +++ b/include/sound/ad1848.h | |||
@@ -154,7 +154,7 @@ struct snd_ad1848 { | |||
154 | #endif | 154 | #endif |
155 | 155 | ||
156 | spinlock_t reg_lock; | 156 | spinlock_t reg_lock; |
157 | struct semaphore open_mutex; | 157 | struct mutex open_mutex; |
158 | }; | 158 | }; |
159 | 159 | ||
160 | /* exported functions */ | 160 | /* exported functions */ |
diff --git a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h index edf04070ce7c..fb30faab43a8 100644 --- a/include/sound/ak4531_codec.h +++ b/include/sound/ak4531_codec.h | |||
@@ -71,7 +71,7 @@ struct snd_ak4531 { | |||
71 | void (*private_free) (struct snd_ak4531 *ak4531); | 71 | void (*private_free) (struct snd_ak4531 *ak4531); |
72 | /* --- */ | 72 | /* --- */ |
73 | unsigned char regs[0x20]; | 73 | unsigned char regs[0x20]; |
74 | struct semaphore reg_mutex; | 74 | struct mutex reg_mutex; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, | 77 | int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, |
diff --git a/include/sound/core.h b/include/sound/core.h index 3093e3ddcf36..144bdc2f217f 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/sched.h> /* wake_up() */ | 25 | #include <linux/sched.h> /* wake_up() */ |
26 | #include <asm/semaphore.h> /* struct semaphore */ | 26 | #include <linux/mutex.h> /* struct mutex */ |
27 | #include <linux/rwsem.h> /* struct rw_semaphore */ | 27 | #include <linux/rwsem.h> /* struct rw_semaphore */ |
28 | #include <linux/workqueue.h> /* struct workqueue_struct */ | 28 | #include <linux/workqueue.h> /* struct workqueue_struct */ |
29 | #include <linux/pm.h> /* pm_message_t */ | 29 | #include <linux/pm.h> /* pm_message_t */ |
@@ -137,7 +137,7 @@ struct snd_card { | |||
137 | 137 | ||
138 | #ifdef CONFIG_PM | 138 | #ifdef CONFIG_PM |
139 | unsigned int power_state; /* power state */ | 139 | unsigned int power_state; /* power state */ |
140 | struct semaphore power_lock; /* power lock */ | 140 | struct mutex power_lock; /* power lock */ |
141 | wait_queue_head_t power_sleep; | 141 | wait_queue_head_t power_sleep; |
142 | #endif | 142 | #endif |
143 | 143 | ||
@@ -150,12 +150,12 @@ struct snd_card { | |||
150 | #ifdef CONFIG_PM | 150 | #ifdef CONFIG_PM |
151 | static inline void snd_power_lock(struct snd_card *card) | 151 | static inline void snd_power_lock(struct snd_card *card) |
152 | { | 152 | { |
153 | down(&card->power_lock); | 153 | mutex_lock(&card->power_lock); |
154 | } | 154 | } |
155 | 155 | ||
156 | static inline void snd_power_unlock(struct snd_card *card) | 156 | static inline void snd_power_unlock(struct snd_card *card) |
157 | { | 157 | { |
158 | up(&card->power_lock); | 158 | mutex_unlock(&card->power_lock); |
159 | } | 159 | } |
160 | 160 | ||
161 | static inline unsigned int snd_power_get_state(struct snd_card *card) | 161 | static inline unsigned int snd_power_get_state(struct snd_card *card) |
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h index ac6a5d882088..60b5b92a1319 100644 --- a/include/sound/cs4231.h +++ b/include/sound/cs4231.h | |||
@@ -248,8 +248,8 @@ struct snd_cs4231 { | |||
248 | unsigned int c_dma_size; | 248 | unsigned int c_dma_size; |
249 | 249 | ||
250 | spinlock_t reg_lock; | 250 | spinlock_t reg_lock; |
251 | struct semaphore mce_mutex; | 251 | struct mutex mce_mutex; |
252 | struct semaphore open_mutex; | 252 | struct mutex open_mutex; |
253 | 253 | ||
254 | int (*rate_constraint) (struct snd_pcm_runtime *runtime); | 254 | int (*rate_constraint) (struct snd_pcm_runtime *runtime); |
255 | void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr); | 255 | void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr); |
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h index 199b5098ff7e..80b2979c0cba 100644 --- a/include/sound/cs46xx.h +++ b/include/sound/cs46xx.h | |||
@@ -1711,7 +1711,7 @@ struct snd_cs46xx { | |||
1711 | int current_gpio; | 1711 | int current_gpio; |
1712 | #endif | 1712 | #endif |
1713 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1713 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1714 | struct semaphore spos_mutex; | 1714 | struct mutex spos_mutex; |
1715 | 1715 | ||
1716 | struct dsp_spos_instance * dsp_spos_instance; | 1716 | struct dsp_spos_instance * dsp_spos_instance; |
1717 | 1717 | ||
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index 951e40d720d9..186e00ad9e79 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <sound/pcm-indirect.h> | 33 | #include <sound/pcm-indirect.h> |
34 | #include <sound/timer.h> | 34 | #include <sound/timer.h> |
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/mutex.h> | ||
36 | #include <asm/io.h> | 37 | #include <asm/io.h> |
37 | 38 | ||
38 | /* ------------------- DEFINES -------------------- */ | 39 | /* ------------------- DEFINES -------------------- */ |
@@ -1022,7 +1023,7 @@ struct snd_emu10k1_fx8010 { | |||
1022 | int gpr_size; /* size of allocated GPR controls */ | 1023 | int gpr_size; /* size of allocated GPR controls */ |
1023 | int gpr_count; /* count of used kcontrols */ | 1024 | int gpr_count; /* count of used kcontrols */ |
1024 | struct list_head gpr_ctl; /* GPR controls */ | 1025 | struct list_head gpr_ctl; /* GPR controls */ |
1025 | struct semaphore lock; | 1026 | struct mutex lock; |
1026 | struct snd_emu10k1_fx8010_pcm pcm[8]; | 1027 | struct snd_emu10k1_fx8010_pcm pcm[8]; |
1027 | spinlock_t irq_lock; | 1028 | spinlock_t irq_lock; |
1028 | struct snd_emu10k1_fx8010_irq *irq_handlers; | 1029 | struct snd_emu10k1_fx8010_irq *irq_handlers; |
@@ -1122,7 +1123,6 @@ struct snd_emu10k1 { | |||
1122 | spinlock_t reg_lock; | 1123 | spinlock_t reg_lock; |
1123 | spinlock_t emu_lock; | 1124 | spinlock_t emu_lock; |
1124 | spinlock_t voice_lock; | 1125 | spinlock_t voice_lock; |
1125 | struct semaphore ptb_lock; | ||
1126 | 1126 | ||
1127 | struct snd_emu10k1_voice voices[NUM_G]; | 1127 | struct snd_emu10k1_voice voices[NUM_G]; |
1128 | struct snd_emu10k1_voice p16v_voices[4]; | 1128 | struct snd_emu10k1_voice p16v_voices[4]; |
diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h index b2d6b2acc7c7..d8cb51b86c20 100644 --- a/include/sound/emux_synth.h +++ b/include/sound/emux_synth.h | |||
@@ -113,7 +113,7 @@ struct snd_emux { | |||
113 | struct snd_emux_voice *voices; /* Voices (EMU 'channel') */ | 113 | struct snd_emux_voice *voices; /* Voices (EMU 'channel') */ |
114 | int use_time; /* allocation counter */ | 114 | int use_time; /* allocation counter */ |
115 | spinlock_t voice_lock; /* Lock for voice access */ | 115 | spinlock_t voice_lock; /* Lock for voice access */ |
116 | struct semaphore register_mutex; | 116 | struct mutex register_mutex; |
117 | int client; /* For the sequencer client */ | 117 | int client; /* For the sequencer client */ |
118 | int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */ | 118 | int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */ |
119 | struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS]; | 119 | struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS]; |
diff --git a/include/sound/gus.h b/include/sound/gus.h index 63da50fae773..68a664ab97f3 100644 --- a/include/sound/gus.h +++ b/include/sound/gus.h | |||
@@ -209,7 +209,7 @@ struct snd_gf1_mem { | |||
209 | struct snd_gf1_bank_info banks_16[4]; | 209 | struct snd_gf1_bank_info banks_16[4]; |
210 | struct snd_gf1_mem_block *first; | 210 | struct snd_gf1_mem_block *first; |
211 | struct snd_gf1_mem_block *last; | 211 | struct snd_gf1_mem_block *last; |
212 | struct semaphore memory_mutex; | 212 | struct mutex memory_mutex; |
213 | }; | 213 | }; |
214 | 214 | ||
215 | struct snd_gf1_dma_block { | 215 | struct snd_gf1_dma_block { |
@@ -467,8 +467,8 @@ struct snd_gus_card { | |||
467 | spinlock_t dma_lock; | 467 | spinlock_t dma_lock; |
468 | spinlock_t pcm_volume_level_lock; | 468 | spinlock_t pcm_volume_level_lock; |
469 | spinlock_t uart_cmd_lock; | 469 | spinlock_t uart_cmd_lock; |
470 | struct semaphore dma_mutex; | 470 | struct mutex dma_mutex; |
471 | struct semaphore register_mutex; | 471 | struct mutex register_mutex; |
472 | }; | 472 | }; |
473 | 473 | ||
474 | /* I/O functions for GF1/InterWave chip - gus_io.c */ | 474 | /* I/O functions for GF1/InterWave chip - gus_io.c */ |
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h index c679e5b31111..94c387b5d724 100644 --- a/include/sound/hwdep.h +++ b/include/sound/hwdep.h | |||
@@ -60,7 +60,7 @@ struct snd_hwdep { | |||
60 | void *private_data; | 60 | void *private_data; |
61 | void (*private_free) (struct snd_hwdep *hwdep); | 61 | void (*private_free) (struct snd_hwdep *hwdep); |
62 | 62 | ||
63 | struct semaphore open_mutex; | 63 | struct mutex open_mutex; |
64 | int used; | 64 | int used; |
65 | unsigned int dsp_loaded; | 65 | unsigned int dsp_loaded; |
66 | unsigned int exclusive: 1; | 66 | unsigned int exclusive: 1; |
diff --git a/include/sound/i2c.h b/include/sound/i2c.h index 81eb23ed761f..d125ff8c85e8 100644 --- a/include/sound/i2c.h +++ b/include/sound/i2c.h | |||
@@ -55,7 +55,7 @@ struct snd_i2c_bus { | |||
55 | struct snd_card *card; /* card which I2C belongs to */ | 55 | struct snd_card *card; /* card which I2C belongs to */ |
56 | char name[32]; /* some useful label */ | 56 | char name[32]; /* some useful label */ |
57 | 57 | ||
58 | struct semaphore lock_mutex; | 58 | struct mutex lock_mutex; |
59 | 59 | ||
60 | struct snd_i2c_bus *master; /* master bus when SCK/SCL is shared */ | 60 | struct snd_i2c_bus *master; /* master bus when SCK/SCL is shared */ |
61 | struct list_head buses; /* master: slave buses sharing SCK/SCL, slave: link list */ | 61 | 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); | |||
84 | static inline void snd_i2c_lock(struct snd_i2c_bus *bus) | 84 | static inline void snd_i2c_lock(struct snd_i2c_bus *bus) |
85 | { | 85 | { |
86 | if (bus->master) | 86 | if (bus->master) |
87 | down(&bus->master->lock_mutex); | 87 | mutex_lock(&bus->master->lock_mutex); |
88 | else | 88 | else |
89 | down(&bus->lock_mutex); | 89 | mutex_lock(&bus->lock_mutex); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline void snd_i2c_unlock(struct snd_i2c_bus *bus) | 92 | static inline void snd_i2c_unlock(struct snd_i2c_bus *bus) |
93 | { | 93 | { |
94 | if (bus->master) | 94 | if (bus->master) |
95 | up(&bus->master->lock_mutex); | 95 | mutex_unlock(&bus->master->lock_mutex); |
96 | else | 96 | else |
97 | up(&bus->lock_mutex); | 97 | mutex_unlock(&bus->lock_mutex); |
98 | } | 98 | } |
99 | 99 | ||
100 | int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count); | 100 | int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count); |
diff --git a/include/sound/info.h b/include/sound/info.h index 8ea5c7497c03..f23d8381c216 100644 --- a/include/sound/info.h +++ b/include/sound/info.h | |||
@@ -84,7 +84,7 @@ struct snd_info_entry { | |||
84 | void *private_data; | 84 | void *private_data; |
85 | void (*private_free)(struct snd_info_entry *entry); | 85 | void (*private_free)(struct snd_info_entry *entry); |
86 | struct proc_dir_entry *p; | 86 | struct proc_dir_entry *p; |
87 | struct semaphore access; | 87 | struct mutex access; |
88 | }; | 88 | }; |
89 | 89 | ||
90 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) | 90 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) |
diff --git a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h index ca5b4822b62c..197b9e3d612b 100644 --- a/include/sound/mixer_oss.h +++ b/include/sound/mixer_oss.h | |||
@@ -61,7 +61,7 @@ struct snd_mixer_oss { | |||
61 | unsigned int active_index); | 61 | unsigned int active_index); |
62 | void *private_data_recsrc; | 62 | void *private_data_recsrc; |
63 | void (*private_free_recsrc)(struct snd_mixer_oss *mixer); | 63 | void (*private_free_recsrc)(struct snd_mixer_oss *mixer); |
64 | struct semaphore reg_mutex; | 64 | struct mutex reg_mutex; |
65 | struct snd_info_entry *proc_entry; | 65 | struct snd_info_entry *proc_entry; |
66 | int oss_dev_alloc; | 66 | int oss_dev_alloc; |
67 | /* --- */ | 67 | /* --- */ |
diff --git a/include/sound/opl3.h b/include/sound/opl3.h index 83392641cb47..444907166f97 100644 --- a/include/sound/opl3.h +++ b/include/sound/opl3.h | |||
@@ -53,6 +53,7 @@ | |||
53 | 53 | ||
54 | #include "driver.h" | 54 | #include "driver.h" |
55 | #include <linux/time.h> | 55 | #include <linux/time.h> |
56 | #include <linux/mutex.h> | ||
56 | #include "core.h" | 57 | #include "core.h" |
57 | #include "hwdep.h" | 58 | #include "hwdep.h" |
58 | #include "timer.h" | 59 | #include "timer.h" |
@@ -312,7 +313,7 @@ struct snd_opl3 { | |||
312 | int sys_timer_status; /* system timer run status */ | 313 | int sys_timer_status; /* system timer run status */ |
313 | spinlock_t sys_timer_lock; /* Lock for system timer access */ | 314 | spinlock_t sys_timer_lock; /* Lock for system timer access */ |
314 | #endif | 315 | #endif |
315 | struct semaphore access_mutex; /* locking */ | 316 | struct mutex access_mutex; /* locking */ |
316 | }; | 317 | }; |
317 | 318 | ||
318 | /* opl3.c */ | 319 | /* opl3.c */ |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 314268a11048..15b885660bf0 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -420,7 +420,7 @@ struct snd_pcm { | |||
420 | char id[64]; | 420 | char id[64]; |
421 | char name[80]; | 421 | char name[80]; |
422 | struct snd_pcm_str streams[2]; | 422 | struct snd_pcm_str streams[2]; |
423 | struct semaphore open_mutex; | 423 | struct mutex open_mutex; |
424 | wait_queue_head_t open_wait; | 424 | wait_queue_head_t open_wait; |
425 | void *private_data; | 425 | void *private_data; |
426 | void (*private_free) (struct snd_pcm *pcm); | 426 | void (*private_free) (struct snd_pcm *pcm); |
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h index fddaddde47b4..bff0778e1969 100644 --- a/include/sound/pcm_oss.h +++ b/include/sound/pcm_oss.h | |||
@@ -56,8 +56,10 @@ struct snd_pcm_oss_runtime { | |||
56 | size_t mmap_bytes; | 56 | size_t mmap_bytes; |
57 | char *buffer; /* vmallocated period */ | 57 | char *buffer; /* vmallocated period */ |
58 | size_t buffer_used; /* used length from period buffer */ | 58 | size_t buffer_used; /* used length from period buffer */ |
59 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
59 | struct snd_pcm_plugin *plugin_first; | 60 | struct snd_pcm_plugin *plugin_first; |
60 | struct snd_pcm_plugin *plugin_last; | 61 | struct snd_pcm_plugin *plugin_last; |
62 | #endif | ||
61 | unsigned int prev_hw_ptr_interrupt; | 63 | unsigned int prev_hw_ptr_interrupt; |
62 | }; | 64 | }; |
63 | 65 | ||
@@ -73,7 +75,7 @@ struct snd_pcm_oss_substream { | |||
73 | 75 | ||
74 | struct snd_pcm_oss_stream { | 76 | struct snd_pcm_oss_stream { |
75 | struct snd_pcm_oss_setup *setup_list; /* setup list */ | 77 | struct snd_pcm_oss_setup *setup_list; /* setup list */ |
76 | struct semaphore setup_mutex; | 78 | struct mutex setup_mutex; |
77 | struct snd_info_entry *proc_entry; | 79 | struct snd_info_entry *proc_entry; |
78 | }; | 80 | }; |
79 | 81 | ||
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index d19bddfbf995..584e73dd4793 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <asm/semaphore.h> | 29 | #include <linux/mutex.h> |
30 | 30 | ||
31 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 31 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) |
32 | #include "seq_device.h" | 32 | #include "seq_device.h" |
@@ -130,7 +130,7 @@ struct snd_rawmidi { | |||
130 | void *private_data; | 130 | void *private_data; |
131 | void (*private_free) (struct snd_rawmidi *rmidi); | 131 | void (*private_free) (struct snd_rawmidi *rmidi); |
132 | 132 | ||
133 | struct semaphore open_mutex; | 133 | struct mutex open_mutex; |
134 | wait_queue_head_t open_wait; | 134 | wait_queue_head_t open_wait; |
135 | 135 | ||
136 | struct snd_info_entry *dev; | 136 | struct snd_info_entry *dev; |
diff --git a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h index 3b44d4b370f5..caf6fe21514d 100644 --- a/include/sound/sb16_csp.h +++ b/include/sound/sb16_csp.h | |||
@@ -158,7 +158,7 @@ struct snd_sb_csp { | |||
158 | struct snd_kcontrol *qsound_switch; | 158 | struct snd_kcontrol *qsound_switch; |
159 | struct snd_kcontrol *qsound_space; | 159 | struct snd_kcontrol *qsound_space; |
160 | 160 | ||
161 | struct semaphore access_mutex; /* locking */ | 161 | struct mutex access_mutex; /* locking */ |
162 | }; | 162 | }; |
163 | 163 | ||
164 | int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep); | 164 | int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep); |
diff --git a/include/sound/seq_instr.h b/include/sound/seq_instr.h index db764f09efb7..f2db03bfd74e 100644 --- a/include/sound/seq_instr.h +++ b/include/sound/seq_instr.h | |||
@@ -64,7 +64,7 @@ struct snd_seq_kinstr_list { | |||
64 | 64 | ||
65 | spinlock_t lock; | 65 | spinlock_t lock; |
66 | spinlock_t ops_lock; | 66 | spinlock_t ops_lock; |
67 | struct semaphore ops_mutex; | 67 | struct mutex ops_mutex; |
68 | unsigned long ops_flags; | 68 | unsigned long ops_flags; |
69 | }; | 69 | }; |
70 | 70 | ||
diff --git a/include/sound/soundfont.h b/include/sound/soundfont.h index 61a010c65d02..f95d99ba7f74 100644 --- a/include/sound/soundfont.h +++ b/include/sound/soundfont.h | |||
@@ -93,7 +93,7 @@ struct snd_sf_list { | |||
93 | int sample_locked; /* locked time for sample */ | 93 | int sample_locked; /* locked time for sample */ |
94 | struct snd_sf_callback callback; /* callback functions */ | 94 | struct snd_sf_callback callback; /* callback functions */ |
95 | int presets_locked; | 95 | int presets_locked; |
96 | struct semaphore presets_mutex; | 96 | struct mutex presets_mutex; |
97 | spinlock_t lock; | 97 | spinlock_t lock; |
98 | struct snd_util_memhdr *memhdr; | 98 | struct snd_util_memhdr *memhdr; |
99 | }; | 99 | }; |
diff --git a/include/sound/util_mem.h b/include/sound/util_mem.h index 69944bbb5445..a1fb706b59a6 100644 --- a/include/sound/util_mem.h +++ b/include/sound/util_mem.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef __SOUND_UTIL_MEM_H | 1 | #ifndef __SOUND_UTIL_MEM_H |
2 | #define __SOUND_UTIL_MEM_H | 2 | #define __SOUND_UTIL_MEM_H |
3 | |||
4 | #include <linux/mutex.h> | ||
3 | /* | 5 | /* |
4 | * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> | 6 | * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> |
5 | * | 7 | * |
@@ -40,7 +42,7 @@ struct snd_util_memhdr { | |||
40 | int nblocks; /* # of allocated blocks */ | 42 | int nblocks; /* # of allocated blocks */ |
41 | unsigned int used; /* used memory size */ | 43 | unsigned int used; /* used memory size */ |
42 | int block_extra_size; /* extra data size of chunk */ | 44 | int block_extra_size; /* extra data size of chunk */ |
43 | struct semaphore block_mutex; /* lock */ | 45 | struct mutex block_mutex; /* lock */ |
44 | }; | 46 | }; |
45 | 47 | ||
46 | /* | 48 | /* |
diff --git a/include/sound/version.h b/include/sound/version.h index 919da0dd001c..4f0e65808cf1 100644 --- a/include/sound/version.h +++ b/include/sound/version.h | |||
@@ -1,3 +1,3 @@ | |||
1 | /* include/version.h. Generated by configure. */ | 1 | /* include/version.h. Generated by configure. */ |
2 | #define CONFIG_SND_VERSION "1.0.11rc2" | 2 | #define CONFIG_SND_VERSION "1.0.11rc4" |
3 | #define CONFIG_SND_DATE " (Wed Jan 04 08:57:20 2006 UTC)" | 3 | #define CONFIG_SND_DATE " (Wed Mar 22 10:27:24 2006 UTC)" |
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h index 5fd6f3305e0d..9821a6194caa 100644 --- a/include/sound/vx_core.h +++ b/include/sound/vx_core.h | |||
@@ -206,7 +206,7 @@ struct vx_core { | |||
206 | int audio_monitor[4]; /* playback hw-monitor level */ | 206 | int audio_monitor[4]; /* playback hw-monitor level */ |
207 | unsigned char audio_monitor_active[4]; /* playback hw-monitor mute/unmute */ | 207 | unsigned char audio_monitor_active[4]; /* playback hw-monitor mute/unmute */ |
208 | 208 | ||
209 | struct semaphore mixer_mutex; | 209 | struct mutex mixer_mutex; |
210 | 210 | ||
211 | const struct firmware *firmware[4]; /* loaded firmware data */ | 211 | const struct firmware *firmware[4]; /* loaded firmware data */ |
212 | }; | 212 | }; |
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h index d567bfdbf513..d41cda97e952 100644 --- a/include/sound/ymfpci.h +++ b/include/sound/ymfpci.h | |||
@@ -269,9 +269,10 @@ struct snd_ymfpci_pcm { | |||
269 | enum snd_ymfpci_pcm_type type; | 269 | enum snd_ymfpci_pcm_type type; |
270 | struct snd_pcm_substream *substream; | 270 | struct snd_pcm_substream *substream; |
271 | struct snd_ymfpci_voice *voices[2]; /* playback only */ | 271 | struct snd_ymfpci_voice *voices[2]; /* playback only */ |
272 | unsigned int running: 1; | 272 | unsigned int running: 1, |
273 | unsigned int output_front: 1; | 273 | output_front: 1, |
274 | unsigned int output_rear: 1; | 274 | output_rear: 1, |
275 | swap_rear: 1; | ||
275 | unsigned int update_pcm_vol; | 276 | unsigned int update_pcm_vol; |
276 | u32 period_size; /* cached from runtime->period_size */ | 277 | u32 period_size; /* cached from runtime->period_size */ |
277 | u32 buffer_size; /* cached from runtime->buffer_size */ | 278 | u32 buffer_size; /* cached from runtime->buffer_size */ |
@@ -344,6 +345,7 @@ struct snd_ymfpci { | |||
344 | struct snd_kcontrol *spdif_pcm_ctl; | 345 | struct snd_kcontrol *spdif_pcm_ctl; |
345 | int mode_dup4ch; | 346 | int mode_dup4ch; |
346 | int rear_opened; | 347 | int rear_opened; |
348 | int rear_swap; | ||
347 | int spdif_opened; | 349 | int spdif_opened; |
348 | struct { | 350 | struct { |
349 | u16 left; | 351 | u16 left; |
@@ -376,7 +378,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | |||
376 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 378 | int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); |
377 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 379 | int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); |
378 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); | 380 | int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); |
379 | int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch); | 381 | int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap); |
380 | int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); | 382 | int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); |
381 | 383 | ||
382 | #endif /* __SOUND_YMFPCI_H */ | 384 | #endif /* __SOUND_YMFPCI_H */ |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 149feb410654..5f22d70fefc0 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -73,7 +73,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned | |||
73 | if (ac97->num >= 4) | 73 | if (ac97->num >= 4) |
74 | return; | 74 | return; |
75 | 75 | ||
76 | down(&aaci->ac97_sem); | 76 | mutex_lock(&aaci->ac97_sem); |
77 | 77 | ||
78 | aaci_ac97_select_codec(aaci, ac97); | 78 | aaci_ac97_select_codec(aaci, ac97); |
79 | 79 | ||
@@ -91,7 +91,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned | |||
91 | v = readl(aaci->base + AACI_SLFR); | 91 | v = readl(aaci->base + AACI_SLFR); |
92 | } while (v & (SLFR_1TXB|SLFR_2TXB)); | 92 | } while (v & (SLFR_1TXB|SLFR_2TXB)); |
93 | 93 | ||
94 | up(&aaci->ac97_sem); | 94 | mutex_unlock(&aaci->ac97_sem); |
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /* |
@@ -105,7 +105,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
105 | if (ac97->num >= 4) | 105 | if (ac97->num >= 4) |
106 | return ~0; | 106 | return ~0; |
107 | 107 | ||
108 | down(&aaci->ac97_sem); | 108 | mutex_lock(&aaci->ac97_sem); |
109 | 109 | ||
110 | aaci_ac97_select_codec(aaci, ac97); | 110 | aaci_ac97_select_codec(aaci, ac97); |
111 | 111 | ||
@@ -145,7 +145,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
145 | v = ~0; | 145 | v = ~0; |
146 | } | 146 | } |
147 | 147 | ||
148 | up(&aaci->ac97_sem); | 148 | mutex_unlock(&aaci->ac97_sem); |
149 | return v; | 149 | return v; |
150 | } | 150 | } |
151 | 151 | ||
@@ -783,7 +783,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev) | |||
783 | card->shortname, dev->res.start, dev->irq[0]); | 783 | card->shortname, dev->res.start, dev->irq[0]); |
784 | 784 | ||
785 | aaci = card->private_data; | 785 | aaci = card->private_data; |
786 | init_MUTEX(&aaci->ac97_sem); | 786 | mutex_init(&aaci->ac97_sem); |
787 | spin_lock_init(&aaci->lock); | 787 | spin_lock_init(&aaci->lock); |
788 | aaci->card = card; | 788 | aaci->card = card; |
789 | aaci->dev = dev; | 789 | aaci->dev = dev; |
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h index 83f73c2505c6..06295190606c 100644 --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h | |||
@@ -227,7 +227,7 @@ struct aaci { | |||
227 | unsigned int fifosize; | 227 | unsigned int fifosize; |
228 | 228 | ||
229 | /* AC'97 */ | 229 | /* AC'97 */ |
230 | struct semaphore ac97_sem; | 230 | struct mutex ac97_sem; |
231 | ac97_bus_t *ac97_bus; | 231 | ac97_bus_t *ac97_bus; |
232 | 232 | ||
233 | u32 maincr; | 233 | u32 maincr; |
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 3acbc6023d19..599aff8290e8 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <sound/initval.h> | 25 | #include <sound/initval.h> |
26 | 26 | ||
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | #include <asm/semaphore.h> | 28 | #include <linux/mutex.h> |
29 | #include <asm/hardware.h> | 29 | #include <asm/hardware.h> |
30 | #include <asm/arch/pxa-regs.h> | 30 | #include <asm/arch/pxa-regs.h> |
31 | #include <asm/arch/audio.h> | 31 | #include <asm/arch/audio.h> |
@@ -33,7 +33,7 @@ | |||
33 | #include "pxa2xx-pcm.h" | 33 | #include "pxa2xx-pcm.h" |
34 | 34 | ||
35 | 35 | ||
36 | static DECLARE_MUTEX(car_mutex); | 36 | static DEFINE_MUTEX(car_mutex); |
37 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | 37 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); |
38 | static volatile long gsr_bits; | 38 | static volatile long gsr_bits; |
39 | 39 | ||
@@ -52,7 +52,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg | |||
52 | unsigned short val = -1; | 52 | unsigned short val = -1; |
53 | volatile u32 *reg_addr; | 53 | volatile u32 *reg_addr; |
54 | 54 | ||
55 | down(&car_mutex); | 55 | mutex_lock(&car_mutex); |
56 | 56 | ||
57 | /* set up primary or secondary codec space */ | 57 | /* set up primary or secondary codec space */ |
58 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | 58 | 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 | |||
79 | /* but we've just started another cycle... */ | 79 | /* but we've just started another cycle... */ |
80 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); | 80 | wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); |
81 | 81 | ||
82 | out: up(&car_mutex); | 82 | out: mutex_unlock(&car_mutex); |
83 | return val; | 83 | return val; |
84 | } | 84 | } |
85 | 85 | ||
@@ -87,7 +87,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne | |||
87 | { | 87 | { |
88 | volatile u32 *reg_addr; | 88 | volatile u32 *reg_addr; |
89 | 89 | ||
90 | down(&car_mutex); | 90 | mutex_lock(&car_mutex); |
91 | 91 | ||
92 | /* set up primary or secondary codec space */ | 92 | /* set up primary or secondary codec space */ |
93 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | 93 | 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 | |||
101 | printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", | 101 | printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", |
102 | __FUNCTION__, reg, GSR | gsr_bits); | 102 | __FUNCTION__, reg, GSR | gsr_bits); |
103 | 103 | ||
104 | up(&car_mutex); | 104 | mutex_unlock(&car_mutex); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) | 107 | static void pxa2xx_ac97_reset(struct snd_ac97 *ac97) |
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index f79755f77a81..9dd121bb5638 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig | |||
@@ -73,6 +73,15 @@ config SND_PCM_OSS | |||
73 | To compile this driver as a module, choose M here: the module | 73 | To compile this driver as a module, choose M here: the module |
74 | will be called snd-pcm-oss. | 74 | will be called snd-pcm-oss. |
75 | 75 | ||
76 | config SND_PCM_OSS_PLUGINS | ||
77 | bool "OSS PCM (digital audio) API - Include plugin system" | ||
78 | depends on SND_PCM_OSS | ||
79 | default y | ||
80 | help | ||
81 | If you disable this option, the ALSA's OSS PCM API will not | ||
82 | support conversion of channels, formats and rates. It will | ||
83 | behave like most of new OSS/Free drivers in 2.4/2.6 kernels. | ||
84 | |||
76 | config SND_SEQUENCER_OSS | 85 | config SND_SEQUENCER_OSS |
77 | bool "OSS Sequencer API" | 86 | bool "OSS Sequencer API" |
78 | depends on SND && SND_SEQUENCER | 87 | depends on SND && SND_SEQUENCER |
@@ -130,6 +139,15 @@ config SND_SUPPORT_OLD_API | |||
130 | Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 | 139 | Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 |
131 | or older). | 140 | or older). |
132 | 141 | ||
142 | config SND_VERBOSE_PROCFS | ||
143 | bool "Verbose procfs contents" | ||
144 | depends on SND | ||
145 | default y | ||
146 | help | ||
147 | Say Y here to include code for verbose procfs contents (provides | ||
148 | usefull information to developers when a problem occurs). On the | ||
149 | other side, it makes the ALSA subsystem larger. | ||
150 | |||
133 | config SND_VERBOSE_PRINTK | 151 | config SND_VERBOSE_PRINTK |
134 | bool "Verbose printk" | 152 | bool "Verbose printk" |
135 | depends on SND | 153 | depends on SND |
diff --git a/sound/core/control.c b/sound/core/control.c index 0c29679a8576..574745314e70 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
309 | { | 309 | { |
310 | struct snd_ctl_elem_id id; | 310 | struct snd_ctl_elem_id id; |
311 | unsigned int idx; | 311 | unsigned int idx; |
312 | int err = -EINVAL; | ||
312 | 313 | ||
313 | snd_assert(card != NULL, return -EINVAL); | ||
314 | if (! kcontrol) | 314 | if (! kcontrol) |
315 | return -EINVAL; | 315 | return err; |
316 | snd_assert(kcontrol->info != NULL, return -EINVAL); | 316 | snd_assert(card != NULL, goto error); |
317 | snd_assert(kcontrol->info != NULL, goto error); | ||
317 | id = kcontrol->id; | 318 | id = kcontrol->id; |
318 | down_write(&card->controls_rwsem); | 319 | down_write(&card->controls_rwsem); |
319 | if (snd_ctl_find_id(card, &id)) { | 320 | if (snd_ctl_find_id(card, &id)) { |
320 | up_write(&card->controls_rwsem); | 321 | up_write(&card->controls_rwsem); |
321 | snd_ctl_free_one(kcontrol); | ||
322 | snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", | 322 | snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", |
323 | id.iface, | 323 | id.iface, |
324 | id.device, | 324 | id.device, |
325 | id.subdevice, | 325 | id.subdevice, |
326 | id.name, | 326 | id.name, |
327 | id.index); | 327 | id.index); |
328 | return -EBUSY; | 328 | err = -EBUSY; |
329 | goto error; | ||
329 | } | 330 | } |
330 | if (snd_ctl_find_hole(card, kcontrol->count) < 0) { | 331 | if (snd_ctl_find_hole(card, kcontrol->count) < 0) { |
331 | up_write(&card->controls_rwsem); | 332 | up_write(&card->controls_rwsem); |
332 | snd_ctl_free_one(kcontrol); | 333 | err = -ENOMEM; |
333 | return -ENOMEM; | 334 | goto error; |
334 | } | 335 | } |
335 | list_add_tail(&kcontrol->list, &card->controls); | 336 | list_add_tail(&kcontrol->list, &card->controls); |
336 | card->controls_count += kcontrol->count; | 337 | card->controls_count += kcontrol->count; |
@@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
340 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | 341 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) |
341 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | 342 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); |
342 | return 0; | 343 | return 0; |
344 | |||
345 | error: | ||
346 | snd_ctl_free_one(kcontrol); | ||
347 | return err; | ||
343 | } | 348 | } |
344 | 349 | ||
345 | /** | 350 | /** |
@@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, | |||
658 | 663 | ||
659 | if (copy_from_user(&info, _info, sizeof(info))) | 664 | if (copy_from_user(&info, _info, sizeof(info))) |
660 | return -EFAULT; | 665 | return -EFAULT; |
661 | result = snd_ctl_elem_info(ctl, &info); | 666 | snd_power_lock(ctl->card); |
667 | result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); | ||
668 | if (result >= 0) | ||
669 | result = snd_ctl_elem_info(ctl, &info); | ||
670 | snd_power_unlock(ctl->card); | ||
662 | if (result >= 0) | 671 | if (result >= 0) |
663 | if (copy_to_user(_info, &info, sizeof(info))) | 672 | if (copy_to_user(_info, &info, sizeof(info))) |
664 | return -EFAULT; | 673 | return -EFAULT; |
@@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card, | |||
708 | kfree(control); | 717 | kfree(control); |
709 | return -EFAULT; | 718 | return -EFAULT; |
710 | } | 719 | } |
711 | result = snd_ctl_elem_read(card, control); | 720 | snd_power_lock(card); |
721 | result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); | ||
722 | if (result >= 0) | ||
723 | result = snd_ctl_elem_read(card, control); | ||
724 | snd_power_unlock(card); | ||
712 | if (result >= 0) | 725 | if (result >= 0) |
713 | if (copy_to_user(_control, control, sizeof(*control))) | 726 | if (copy_to_user(_control, control, sizeof(*control))) |
714 | result = -EFAULT; | 727 | result = -EFAULT; |
@@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, | |||
758 | struct snd_ctl_elem_value __user *_control) | 771 | struct snd_ctl_elem_value __user *_control) |
759 | { | 772 | { |
760 | struct snd_ctl_elem_value *control; | 773 | struct snd_ctl_elem_value *control; |
774 | struct snd_card *card; | ||
761 | int result; | 775 | int result; |
762 | 776 | ||
763 | control = kmalloc(sizeof(*control), GFP_KERNEL); | 777 | control = kmalloc(sizeof(*control), GFP_KERNEL); |
@@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, | |||
767 | kfree(control); | 781 | kfree(control); |
768 | return -EFAULT; | 782 | return -EFAULT; |
769 | } | 783 | } |
770 | result = snd_ctl_elem_write(file->card, file, control); | 784 | card = file->card; |
785 | snd_power_lock(card); | ||
786 | result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); | ||
787 | if (result >= 0) | ||
788 | result = snd_ctl_elem_write(card, file, control); | ||
789 | snd_power_unlock(card); | ||
771 | if (result >= 0) | 790 | if (result >= 0) |
772 | if (copy_to_user(_control, control, sizeof(*control))) | 791 | if (copy_to_user(_control, control, sizeof(*control))) |
773 | result = -EFAULT; | 792 | result = -EFAULT; |
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index a529b62972b4..84fef5084e17 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c | |||
@@ -107,7 +107,13 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, | |||
107 | */ | 107 | */ |
108 | if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) | 108 | if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) |
109 | goto error; | 109 | goto error; |
110 | err = snd_ctl_elem_info(ctl, data); | 110 | |
111 | snd_power_lock(ctl->card); | ||
112 | err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); | ||
113 | if (err >= 0) | ||
114 | err = snd_ctl_elem_info(ctl, data); | ||
115 | snd_power_unlock(ctl->card); | ||
116 | |||
111 | if (err < 0) | 117 | if (err < 0) |
112 | goto error; | 118 | goto error; |
113 | /* restore info to 32bit */ | 119 | /* restore info to 32bit */ |
@@ -286,9 +292,14 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card, | |||
286 | 292 | ||
287 | if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) | 293 | if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) |
288 | goto error; | 294 | goto error; |
289 | if ((err = snd_ctl_elem_read(card, data)) < 0) | 295 | |
290 | goto error; | 296 | snd_power_lock(card); |
291 | err = copy_ctl_value_to_user(data32, data, type, count); | 297 | err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); |
298 | if (err >= 0) | ||
299 | err = snd_ctl_elem_read(card, data); | ||
300 | snd_power_unlock(card); | ||
301 | if (err >= 0) | ||
302 | err = copy_ctl_value_to_user(data32, data, type, count); | ||
292 | error: | 303 | error: |
293 | kfree(data); | 304 | kfree(data); |
294 | return err; | 305 | return err; |
@@ -298,17 +309,23 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, | |||
298 | struct snd_ctl_elem_value32 __user *data32) | 309 | struct snd_ctl_elem_value32 __user *data32) |
299 | { | 310 | { |
300 | struct snd_ctl_elem_value *data; | 311 | struct snd_ctl_elem_value *data; |
312 | struct snd_card *card = file->card; | ||
301 | int err, type, count; | 313 | int err, type, count; |
302 | 314 | ||
303 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 315 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
304 | if (data == NULL) | 316 | if (data == NULL) |
305 | return -ENOMEM; | 317 | return -ENOMEM; |
306 | 318 | ||
307 | if ((err = copy_ctl_value_from_user(file->card, data, data32, &type, &count)) < 0) | 319 | if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) |
308 | goto error; | ||
309 | if ((err = snd_ctl_elem_write(file->card, file, data)) < 0) | ||
310 | goto error; | 320 | goto error; |
311 | err = copy_ctl_value_to_user(data32, data, type, count); | 321 | |
322 | snd_power_lock(card); | ||
323 | err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); | ||
324 | if (err >= 0) | ||
325 | err = snd_ctl_elem_write(card, file, data); | ||
326 | snd_power_unlock(card); | ||
327 | if (err >= 0) | ||
328 | err = copy_ctl_value_to_user(data32, data, type, count); | ||
312 | error: | 329 | error: |
313 | kfree(data); | 330 | kfree(data); |
314 | return err; | 331 | return err; |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 618c43be0bc3..2524e66eccdd 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include <sound/control.h> | 30 | #include <sound/control.h> |
30 | #include <sound/minors.h> | 31 | #include <sound/minors.h> |
@@ -36,7 +37,7 @@ MODULE_DESCRIPTION("Hardware dependent layer"); | |||
36 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
37 | 38 | ||
38 | static LIST_HEAD(snd_hwdep_devices); | 39 | static LIST_HEAD(snd_hwdep_devices); |
39 | static DECLARE_MUTEX(register_mutex); | 40 | static DEFINE_MUTEX(register_mutex); |
40 | 41 | ||
41 | static int snd_hwdep_free(struct snd_hwdep *hwdep); | 42 | static int snd_hwdep_free(struct snd_hwdep *hwdep); |
42 | static int snd_hwdep_dev_free(struct snd_device *device); | 43 | 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) | |||
111 | 112 | ||
112 | init_waitqueue_entry(&wait, current); | 113 | init_waitqueue_entry(&wait, current); |
113 | add_wait_queue(&hw->open_wait, &wait); | 114 | add_wait_queue(&hw->open_wait, &wait); |
114 | down(&hw->open_mutex); | 115 | mutex_lock(&hw->open_mutex); |
115 | while (1) { | 116 | while (1) { |
116 | if (hw->exclusive && hw->used > 0) { | 117 | if (hw->exclusive && hw->used > 0) { |
117 | err = -EBUSY; | 118 | err = -EBUSY; |
@@ -128,9 +129,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) | |||
128 | } else | 129 | } else |
129 | break; | 130 | break; |
130 | set_current_state(TASK_INTERRUPTIBLE); | 131 | set_current_state(TASK_INTERRUPTIBLE); |
131 | up(&hw->open_mutex); | 132 | mutex_unlock(&hw->open_mutex); |
132 | schedule(); | 133 | schedule(); |
133 | down(&hw->open_mutex); | 134 | mutex_lock(&hw->open_mutex); |
134 | if (signal_pending(current)) { | 135 | if (signal_pending(current)) { |
135 | err = -ERESTARTSYS; | 136 | err = -ERESTARTSYS; |
136 | break; | 137 | break; |
@@ -147,7 +148,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) | |||
147 | hw->ops.release(hw, file); | 148 | hw->ops.release(hw, file); |
148 | } | 149 | } |
149 | } | 150 | } |
150 | up(&hw->open_mutex); | 151 | mutex_unlock(&hw->open_mutex); |
151 | if (err < 0) | 152 | if (err < 0) |
152 | module_put(hw->card->module); | 153 | module_put(hw->card->module); |
153 | return err; | 154 | return err; |
@@ -157,7 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) | |||
157 | { | 158 | { |
158 | int err = -ENXIO; | 159 | int err = -ENXIO; |
159 | struct snd_hwdep *hw = file->private_data; | 160 | struct snd_hwdep *hw = file->private_data; |
160 | down(&hw->open_mutex); | 161 | mutex_lock(&hw->open_mutex); |
161 | if (hw->ops.release) { | 162 | if (hw->ops.release) { |
162 | err = hw->ops.release(hw, file); | 163 | err = hw->ops.release(hw, file); |
163 | wake_up(&hw->open_wait); | 164 | wake_up(&hw->open_wait); |
@@ -165,7 +166,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) | |||
165 | if (hw->used > 0) | 166 | if (hw->used > 0) |
166 | hw->used--; | 167 | hw->used--; |
167 | snd_card_file_remove(hw->card, file); | 168 | snd_card_file_remove(hw->card, file); |
168 | up(&hw->open_mutex); | 169 | mutex_unlock(&hw->open_mutex); |
169 | module_put(hw->card->module); | 170 | module_put(hw->card->module); |
170 | return err; | 171 | return err; |
171 | } | 172 | } |
@@ -272,7 +273,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
272 | 273 | ||
273 | if (get_user(device, (int __user *)arg)) | 274 | if (get_user(device, (int __user *)arg)) |
274 | return -EFAULT; | 275 | return -EFAULT; |
275 | down(®ister_mutex); | 276 | mutex_lock(®ister_mutex); |
276 | device = device < 0 ? 0 : device + 1; | 277 | device = device < 0 ? 0 : device + 1; |
277 | while (device < SNDRV_MINOR_HWDEPS) { | 278 | while (device < SNDRV_MINOR_HWDEPS) { |
278 | if (snd_hwdep_search(card, device)) | 279 | if (snd_hwdep_search(card, device)) |
@@ -281,7 +282,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
281 | } | 282 | } |
282 | if (device >= SNDRV_MINOR_HWDEPS) | 283 | if (device >= SNDRV_MINOR_HWDEPS) |
283 | device = -1; | 284 | device = -1; |
284 | up(®ister_mutex); | 285 | mutex_unlock(®ister_mutex); |
285 | if (put_user(device, (int __user *)arg)) | 286 | if (put_user(device, (int __user *)arg)) |
286 | return -EFAULT; | 287 | return -EFAULT; |
287 | return 0; | 288 | return 0; |
@@ -294,13 +295,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
294 | 295 | ||
295 | if (get_user(device, &info->device)) | 296 | if (get_user(device, &info->device)) |
296 | return -EFAULT; | 297 | return -EFAULT; |
297 | down(®ister_mutex); | 298 | mutex_lock(®ister_mutex); |
298 | hwdep = snd_hwdep_search(card, device); | 299 | hwdep = snd_hwdep_search(card, device); |
299 | if (hwdep) | 300 | if (hwdep) |
300 | err = snd_hwdep_info(hwdep, info); | 301 | err = snd_hwdep_info(hwdep, info); |
301 | else | 302 | else |
302 | err = -ENXIO; | 303 | err = -ENXIO; |
303 | up(®ister_mutex); | 304 | mutex_unlock(®ister_mutex); |
304 | return err; | 305 | return err; |
305 | } | 306 | } |
306 | } | 307 | } |
@@ -375,7 +376,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, | |||
375 | return err; | 376 | return err; |
376 | } | 377 | } |
377 | init_waitqueue_head(&hwdep->open_wait); | 378 | init_waitqueue_head(&hwdep->open_wait); |
378 | init_MUTEX(&hwdep->open_mutex); | 379 | mutex_init(&hwdep->open_mutex); |
379 | *rhwdep = hwdep; | 380 | *rhwdep = hwdep; |
380 | return 0; | 381 | return 0; |
381 | } | 382 | } |
@@ -401,9 +402,9 @@ static int snd_hwdep_dev_register(struct snd_device *device) | |||
401 | int err; | 402 | int err; |
402 | char name[32]; | 403 | char name[32]; |
403 | 404 | ||
404 | down(®ister_mutex); | 405 | mutex_lock(®ister_mutex); |
405 | if (snd_hwdep_search(hwdep->card, hwdep->device)) { | 406 | if (snd_hwdep_search(hwdep->card, hwdep->device)) { |
406 | up(®ister_mutex); | 407 | mutex_unlock(®ister_mutex); |
407 | return -EBUSY; | 408 | return -EBUSY; |
408 | } | 409 | } |
409 | list_add_tail(&hwdep->list, &snd_hwdep_devices); | 410 | list_add_tail(&hwdep->list, &snd_hwdep_devices); |
@@ -414,7 +415,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) | |||
414 | snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", | 415 | snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", |
415 | hwdep->card->number, hwdep->device); | 416 | hwdep->card->number, hwdep->device); |
416 | list_del(&hwdep->list); | 417 | list_del(&hwdep->list); |
417 | up(®ister_mutex); | 418 | mutex_unlock(®ister_mutex); |
418 | return err; | 419 | return err; |
419 | } | 420 | } |
420 | #ifdef CONFIG_SND_OSSEMUL | 421 | #ifdef CONFIG_SND_OSSEMUL |
@@ -434,7 +435,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) | |||
434 | } | 435 | } |
435 | } | 436 | } |
436 | #endif | 437 | #endif |
437 | up(®ister_mutex); | 438 | mutex_unlock(®ister_mutex); |
438 | return 0; | 439 | return 0; |
439 | } | 440 | } |
440 | 441 | ||
@@ -443,9 +444,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) | |||
443 | struct snd_hwdep *hwdep = device->device_data; | 444 | struct snd_hwdep *hwdep = device->device_data; |
444 | 445 | ||
445 | snd_assert(hwdep != NULL, return -ENXIO); | 446 | snd_assert(hwdep != NULL, return -ENXIO); |
446 | down(®ister_mutex); | 447 | mutex_lock(®ister_mutex); |
447 | if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { | 448 | if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { |
448 | up(®ister_mutex); | 449 | mutex_unlock(®ister_mutex); |
449 | return -EINVAL; | 450 | return -EINVAL; |
450 | } | 451 | } |
451 | #ifdef CONFIG_SND_OSSEMUL | 452 | #ifdef CONFIG_SND_OSSEMUL |
@@ -454,7 +455,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) | |||
454 | #endif | 455 | #endif |
455 | snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); | 456 | snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); |
456 | list_del(&hwdep->list); | 457 | list_del(&hwdep->list); |
457 | up(®ister_mutex); | 458 | mutex_unlock(®ister_mutex); |
458 | return snd_hwdep_free(hwdep); | 459 | return snd_hwdep_free(hwdep); |
459 | } | 460 | } |
460 | 461 | ||
@@ -469,13 +470,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry, | |||
469 | struct list_head *p; | 470 | struct list_head *p; |
470 | struct snd_hwdep *hwdep; | 471 | struct snd_hwdep *hwdep; |
471 | 472 | ||
472 | down(®ister_mutex); | 473 | mutex_lock(®ister_mutex); |
473 | list_for_each(p, &snd_hwdep_devices) { | 474 | list_for_each(p, &snd_hwdep_devices) { |
474 | hwdep = list_entry(p, struct snd_hwdep, list); | 475 | hwdep = list_entry(p, struct snd_hwdep, list); |
475 | snd_iprintf(buffer, "%02i-%02i: %s\n", | 476 | snd_iprintf(buffer, "%02i-%02i: %s\n", |
476 | hwdep->card->number, hwdep->device, hwdep->name); | 477 | hwdep->card->number, hwdep->device, hwdep->name); |
477 | } | 478 | } |
478 | up(®ister_mutex); | 479 | mutex_unlock(®ister_mutex); |
479 | } | 480 | } |
480 | 481 | ||
481 | static struct snd_info_entry *snd_hwdep_proc_entry; | 482 | static struct snd_info_entry *snd_hwdep_proc_entry; |
diff --git a/sound/core/info.c b/sound/core/info.c index af123e3bdb24..2582b74d3199 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <sound/version.h> | 31 | #include <sound/version.h> |
32 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
33 | #include <linux/devfs_fs_kernel.h> | 33 | #include <linux/devfs_fs_kernel.h> |
34 | #include <linux/mutex.h> | ||
34 | #include <stdarg.h> | 35 | #include <stdarg.h> |
35 | 36 | ||
36 | /* | 37 | /* |
@@ -68,7 +69,7 @@ int snd_info_check_reserved_words(const char *str) | |||
68 | return 1; | 69 | return 1; |
69 | } | 70 | } |
70 | 71 | ||
71 | static DECLARE_MUTEX(info_mutex); | 72 | static DEFINE_MUTEX(info_mutex); |
72 | 73 | ||
73 | struct snd_info_private_data { | 74 | struct snd_info_private_data { |
74 | struct snd_info_buffer *rbuffer; | 75 | struct snd_info_buffer *rbuffer; |
@@ -265,11 +266,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
265 | struct proc_dir_entry *p; | 266 | struct proc_dir_entry *p; |
266 | int mode, err; | 267 | int mode, err; |
267 | 268 | ||
268 | down(&info_mutex); | 269 | mutex_lock(&info_mutex); |
269 | p = PDE(inode); | 270 | p = PDE(inode); |
270 | entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; | 271 | entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; |
271 | if (entry == NULL || entry->disconnected) { | 272 | if (entry == NULL || entry->disconnected) { |
272 | up(&info_mutex); | 273 | mutex_unlock(&info_mutex); |
273 | return -ENODEV; | 274 | return -ENODEV; |
274 | } | 275 | } |
275 | if (!try_module_get(entry->module)) { | 276 | if (!try_module_get(entry->module)) { |
@@ -361,13 +362,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
361 | break; | 362 | break; |
362 | } | 363 | } |
363 | file->private_data = data; | 364 | file->private_data = data; |
364 | up(&info_mutex); | 365 | mutex_unlock(&info_mutex); |
365 | if (entry->content == SNDRV_INFO_CONTENT_TEXT && | 366 | if (entry->content == SNDRV_INFO_CONTENT_TEXT && |
366 | (mode == O_RDONLY || mode == O_RDWR)) { | 367 | (mode == O_RDONLY || mode == O_RDWR)) { |
367 | if (entry->c.text.read) { | 368 | if (entry->c.text.read) { |
368 | down(&entry->access); | 369 | mutex_lock(&entry->access); |
369 | entry->c.text.read(entry, data->rbuffer); | 370 | entry->c.text.read(entry, data->rbuffer); |
370 | up(&entry->access); | 371 | mutex_unlock(&entry->access); |
371 | } | 372 | } |
372 | } | 373 | } |
373 | return 0; | 374 | return 0; |
@@ -375,7 +376,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) | |||
375 | __error: | 376 | __error: |
376 | module_put(entry->module); | 377 | module_put(entry->module); |
377 | __error1: | 378 | __error1: |
378 | up(&info_mutex); | 379 | mutex_unlock(&info_mutex); |
379 | return err; | 380 | return err; |
380 | } | 381 | } |
381 | 382 | ||
@@ -747,7 +748,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name) | |||
747 | } | 748 | } |
748 | entry->mode = S_IFREG | S_IRUGO; | 749 | entry->mode = S_IFREG | S_IRUGO; |
749 | entry->content = SNDRV_INFO_CONTENT_TEXT; | 750 | entry->content = SNDRV_INFO_CONTENT_TEXT; |
750 | init_MUTEX(&entry->access); | 751 | mutex_init(&entry->access); |
751 | return entry; | 752 | return entry; |
752 | } | 753 | } |
753 | 754 | ||
@@ -896,10 +897,10 @@ int snd_info_register(struct snd_info_entry * entry) | |||
896 | 897 | ||
897 | snd_assert(entry != NULL, return -ENXIO); | 898 | snd_assert(entry != NULL, return -ENXIO); |
898 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; | 899 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
899 | down(&info_mutex); | 900 | mutex_lock(&info_mutex); |
900 | p = snd_create_proc_entry(entry->name, entry->mode, root); | 901 | p = snd_create_proc_entry(entry->name, entry->mode, root); |
901 | if (!p) { | 902 | if (!p) { |
902 | up(&info_mutex); | 903 | mutex_unlock(&info_mutex); |
903 | return -ENOMEM; | 904 | return -ENOMEM; |
904 | } | 905 | } |
905 | p->owner = entry->module; | 906 | p->owner = entry->module; |
@@ -908,7 +909,7 @@ int snd_info_register(struct snd_info_entry * entry) | |||
908 | p->size = entry->size; | 909 | p->size = entry->size; |
909 | p->data = entry; | 910 | p->data = entry; |
910 | entry->p = p; | 911 | entry->p = p; |
911 | up(&info_mutex); | 912 | mutex_unlock(&info_mutex); |
912 | return 0; | 913 | return 0; |
913 | } | 914 | } |
914 | 915 | ||
@@ -929,9 +930,9 @@ int snd_info_unregister(struct snd_info_entry * entry) | |||
929 | snd_assert(entry->p != NULL, return -ENXIO); | 930 | snd_assert(entry->p != NULL, return -ENXIO); |
930 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; | 931 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
931 | snd_assert(root, return -ENXIO); | 932 | snd_assert(root, return -ENXIO); |
932 | down(&info_mutex); | 933 | mutex_lock(&info_mutex); |
933 | snd_remove_proc_entry(root, entry->p); | 934 | snd_remove_proc_entry(root, entry->p); |
934 | up(&info_mutex); | 935 | mutex_unlock(&info_mutex); |
935 | snd_info_free_entry(entry); | 936 | snd_info_free_entry(entry); |
936 | return 0; | 937 | return 0; |
937 | } | 938 | } |
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index 820f4772e44a..f9ce854b3d11 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <sound/info.h> | 28 | #include <sound/info.h> |
29 | #include <sound/version.h> | 29 | #include <sound/version.h> |
30 | #include <linux/utsname.h> | 30 | #include <linux/utsname.h> |
31 | #include <linux/mutex.h> | ||
31 | 32 | ||
32 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) | 33 | #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) |
33 | 34 | ||
@@ -35,7 +36,7 @@ | |||
35 | * OSS compatible part | 36 | * OSS compatible part |
36 | */ | 37 | */ |
37 | 38 | ||
38 | static DECLARE_MUTEX(strings); | 39 | static DEFINE_MUTEX(strings); |
39 | static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; | 40 | static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; |
40 | static struct snd_info_entry *snd_sndstat_proc_entry; | 41 | static struct snd_info_entry *snd_sndstat_proc_entry; |
41 | 42 | ||
@@ -45,7 +46,7 @@ int snd_oss_info_register(int dev, int num, char *string) | |||
45 | 46 | ||
46 | snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); | 47 | snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); |
47 | snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); | 48 | snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); |
48 | down(&strings); | 49 | mutex_lock(&strings); |
49 | if (string == NULL) { | 50 | if (string == NULL) { |
50 | if ((x = snd_sndstat_strings[num][dev]) != NULL) { | 51 | if ((x = snd_sndstat_strings[num][dev]) != NULL) { |
51 | kfree(x); | 52 | kfree(x); |
@@ -54,12 +55,12 @@ int snd_oss_info_register(int dev, int num, char *string) | |||
54 | } else { | 55 | } else { |
55 | x = kstrdup(string, GFP_KERNEL); | 56 | x = kstrdup(string, GFP_KERNEL); |
56 | if (x == NULL) { | 57 | if (x == NULL) { |
57 | up(&strings); | 58 | mutex_unlock(&strings); |
58 | return -ENOMEM; | 59 | return -ENOMEM; |
59 | } | 60 | } |
60 | } | 61 | } |
61 | snd_sndstat_strings[num][dev] = x; | 62 | snd_sndstat_strings[num][dev] = x; |
62 | up(&strings); | 63 | mutex_unlock(&strings); |
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
65 | 66 | ||
@@ -71,7 +72,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d | |||
71 | char *str; | 72 | char *str; |
72 | 73 | ||
73 | snd_iprintf(buf, "\n%s:", id); | 74 | snd_iprintf(buf, "\n%s:", id); |
74 | down(&strings); | 75 | mutex_lock(&strings); |
75 | for (idx = 0; idx < SNDRV_CARDS; idx++) { | 76 | for (idx = 0; idx < SNDRV_CARDS; idx++) { |
76 | str = snd_sndstat_strings[idx][dev]; | 77 | str = snd_sndstat_strings[idx][dev]; |
77 | if (str) { | 78 | if (str) { |
@@ -82,7 +83,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d | |||
82 | snd_iprintf(buf, "%i: %s\n", idx, str); | 83 | snd_iprintf(buf, "%i: %s\n", idx, str); |
83 | } | 84 | } |
84 | } | 85 | } |
85 | up(&strings); | 86 | mutex_unlock(&strings); |
86 | if (ok < 0) | 87 | if (ok < 0) |
87 | snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); | 88 | snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); |
88 | return ok; | 89 | return ok; |
diff --git a/sound/core/init.c b/sound/core/init.c index 75816688607c..ad68761abba1 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -145,7 +145,7 @@ struct snd_card *snd_card_new(int idx, const char *xid, | |||
145 | init_waitqueue_head(&card->shutdown_sleep); | 145 | init_waitqueue_head(&card->shutdown_sleep); |
146 | INIT_WORK(&card->free_workq, snd_card_free_thread, card); | 146 | INIT_WORK(&card->free_workq, snd_card_free_thread, card); |
147 | #ifdef CONFIG_PM | 147 | #ifdef CONFIG_PM |
148 | init_MUTEX(&card->power_lock); | 148 | mutex_init(&card->power_lock); |
149 | init_waitqueue_head(&card->power_sleep); | 149 | init_waitqueue_head(&card->power_sleep); |
150 | #endif | 150 | #endif |
151 | /* the control interface cannot be accessed from the user space until */ | 151 | /* 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, | |||
169 | return NULL; | 169 | return NULL; |
170 | } | 170 | } |
171 | 171 | ||
172 | static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) | ||
173 | { | ||
174 | return -ENODEV; | ||
175 | } | ||
176 | |||
177 | static ssize_t snd_disconnect_read(struct file *file, char __user *buf, | ||
178 | size_t count, loff_t *offset) | ||
179 | { | ||
180 | return -ENODEV; | ||
181 | } | ||
182 | |||
183 | static ssize_t snd_disconnect_write(struct file *file, const char __user *buf, | ||
184 | size_t count, loff_t *offset) | ||
185 | { | ||
186 | return -ENODEV; | ||
187 | } | ||
188 | |||
172 | static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) | 189 | static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) |
173 | { | 190 | { |
174 | return POLLERR | POLLNVAL; | 191 | return POLLERR | POLLNVAL; |
175 | } | 192 | } |
176 | 193 | ||
194 | static long snd_disconnect_ioctl(struct file *file, | ||
195 | unsigned int cmd, unsigned long arg) | ||
196 | { | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | |||
200 | static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma) | ||
201 | { | ||
202 | return -ENODEV; | ||
203 | } | ||
204 | |||
205 | static int snd_disconnect_fasync(int fd, struct file *file, int on) | ||
206 | { | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
177 | /** | 210 | /** |
178 | * snd_card_disconnect - disconnect all APIs from the file-operations (user space) | 211 | * snd_card_disconnect - disconnect all APIs from the file-operations (user space) |
179 | * @card: soundcard structure | 212 | * @card: soundcard structure |
@@ -224,7 +257,16 @@ int snd_card_disconnect(struct snd_card *card) | |||
224 | memset(f_ops, 0, sizeof(*f_ops)); | 257 | memset(f_ops, 0, sizeof(*f_ops)); |
225 | f_ops->owner = file->f_op->owner; | 258 | f_ops->owner = file->f_op->owner; |
226 | f_ops->release = file->f_op->release; | 259 | f_ops->release = file->f_op->release; |
260 | f_ops->llseek = snd_disconnect_llseek; | ||
261 | f_ops->read = snd_disconnect_read; | ||
262 | f_ops->write = snd_disconnect_write; | ||
227 | f_ops->poll = snd_disconnect_poll; | 263 | f_ops->poll = snd_disconnect_poll; |
264 | f_ops->unlocked_ioctl = snd_disconnect_ioctl; | ||
265 | #ifdef CONFIG_COMPAT | ||
266 | f_ops->compat_ioctl = snd_disconnect_ioctl; | ||
267 | #endif | ||
268 | f_ops->mmap = snd_disconnect_mmap; | ||
269 | f_ops->fasync = snd_disconnect_fasync; | ||
228 | 270 | ||
229 | s_f_ops->next = card->s_f_ops; | 271 | s_f_ops->next = card->s_f_ops; |
230 | card->s_f_ops = s_f_ops; | 272 | card->s_f_ops = s_f_ops; |
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 19b3dcbb09c2..3fc6f97075ed 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/moduleparam.h> | 33 | #include <linux/moduleparam.h> |
34 | #include <asm/semaphore.h> | 34 | #include <linux/mutex.h> |
35 | #include <sound/memalloc.h> | 35 | #include <sound/memalloc.h> |
36 | #ifdef CONFIG_SBUS | 36 | #ifdef CONFIG_SBUS |
37 | #include <asm/sbus.h> | 37 | #include <asm/sbus.h> |
@@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab); | |||
54 | /* | 54 | /* |
55 | */ | 55 | */ |
56 | 56 | ||
57 | static DECLARE_MUTEX(list_mutex); | 57 | static DEFINE_MUTEX(list_mutex); |
58 | static LIST_HEAD(mem_list_head); | 58 | static LIST_HEAD(mem_list_head); |
59 | 59 | ||
60 | /* buffer preservation list */ | 60 | /* buffer preservation list */ |
@@ -83,7 +83,7 @@ struct snd_mem_list { | |||
83 | * Hacks | 83 | * Hacks |
84 | */ | 84 | */ |
85 | 85 | ||
86 | #if defined(__i386__) || defined(__ppc__) || defined(__x86_64__) | 86 | #if defined(__i386__) |
87 | /* | 87 | /* |
88 | * A hack to allocate large buffers via dma_alloc_coherent() | 88 | * A hack to allocate large buffers via dma_alloc_coherent() |
89 | * | 89 | * |
@@ -141,10 +141,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, | |||
141 | 141 | ||
142 | #endif /* arch */ | 142 | #endif /* arch */ |
143 | 143 | ||
144 | #if ! defined(__arm__) | ||
145 | #define NEED_RESERVE_PAGES | ||
146 | #endif | ||
147 | |||
148 | /* | 144 | /* |
149 | * | 145 | * |
150 | * Generic memory allocators | 146 | * Generic memory allocators |
@@ -163,20 +159,6 @@ static inline void dec_snd_pages(int order) | |||
163 | snd_allocated_pages -= 1 << order; | 159 | snd_allocated_pages -= 1 << order; |
164 | } | 160 | } |
165 | 161 | ||
166 | static void mark_pages(struct page *page, int order) | ||
167 | { | ||
168 | struct page *last_page = page + (1 << order); | ||
169 | while (page < last_page) | ||
170 | SetPageReserved(page++); | ||
171 | } | ||
172 | |||
173 | static void unmark_pages(struct page *page, int order) | ||
174 | { | ||
175 | struct page *last_page = page + (1 << order); | ||
176 | while (page < last_page) | ||
177 | ClearPageReserved(page++); | ||
178 | } | ||
179 | |||
180 | /** | 162 | /** |
181 | * snd_malloc_pages - allocate pages with the given size | 163 | * snd_malloc_pages - allocate pages with the given size |
182 | * @size: the size to allocate in bytes | 164 | * @size: the size to allocate in bytes |
@@ -195,10 +177,8 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) | |||
195 | snd_assert(gfp_flags != 0, return NULL); | 177 | snd_assert(gfp_flags != 0, return NULL); |
196 | gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ | 178 | gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ |
197 | pg = get_order(size); | 179 | pg = get_order(size); |
198 | if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) { | 180 | if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) |
199 | mark_pages(virt_to_page(res), pg); | ||
200 | inc_snd_pages(pg); | 181 | inc_snd_pages(pg); |
201 | } | ||
202 | return res; | 182 | return res; |
203 | } | 183 | } |
204 | 184 | ||
@@ -217,7 +197,6 @@ void snd_free_pages(void *ptr, size_t size) | |||
217 | return; | 197 | return; |
218 | pg = get_order(size); | 198 | pg = get_order(size); |
219 | dec_snd_pages(pg); | 199 | dec_snd_pages(pg); |
220 | unmark_pages(virt_to_page(ptr), pg); | ||
221 | free_pages((unsigned long) ptr, pg); | 200 | free_pages((unsigned long) ptr, pg); |
222 | } | 201 | } |
223 | 202 | ||
@@ -242,12 +221,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d | |||
242 | | __GFP_NORETRY /* don't trigger OOM-killer */ | 221 | | __GFP_NORETRY /* don't trigger OOM-killer */ |
243 | | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ | 222 | | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ |
244 | res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); | 223 | res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); |
245 | if (res != NULL) { | 224 | if (res != NULL) |
246 | #ifdef NEED_RESERVE_PAGES | ||
247 | mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */ | ||
248 | #endif | ||
249 | inc_snd_pages(pg); | 225 | inc_snd_pages(pg); |
250 | } | ||
251 | 226 | ||
252 | return res; | 227 | return res; |
253 | } | 228 | } |
@@ -262,9 +237,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, | |||
262 | return; | 237 | return; |
263 | pg = get_order(size); | 238 | pg = get_order(size); |
264 | dec_snd_pages(pg); | 239 | dec_snd_pages(pg); |
265 | #ifdef NEED_RESERVE_PAGES | ||
266 | unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */ | ||
267 | #endif | ||
268 | dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); | 240 | dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); |
269 | } | 241 | } |
270 | 242 | ||
@@ -440,7 +412,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) | |||
440 | 412 | ||
441 | snd_assert(dmab, return 0); | 413 | snd_assert(dmab, return 0); |
442 | 414 | ||
443 | down(&list_mutex); | 415 | mutex_lock(&list_mutex); |
444 | list_for_each(p, &mem_list_head) { | 416 | list_for_each(p, &mem_list_head) { |
445 | mem = list_entry(p, struct snd_mem_list, list); | 417 | mem = list_entry(p, struct snd_mem_list, list); |
446 | if (mem->id == id && | 418 | if (mem->id == id && |
@@ -452,11 +424,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) | |||
452 | if (dmab->dev.dev == NULL) | 424 | if (dmab->dev.dev == NULL) |
453 | dmab->dev.dev = dev; | 425 | dmab->dev.dev = dev; |
454 | kfree(mem); | 426 | kfree(mem); |
455 | up(&list_mutex); | 427 | mutex_unlock(&list_mutex); |
456 | return dmab->bytes; | 428 | return dmab->bytes; |
457 | } | 429 | } |
458 | } | 430 | } |
459 | up(&list_mutex); | 431 | mutex_unlock(&list_mutex); |
460 | return 0; | 432 | return 0; |
461 | } | 433 | } |
462 | 434 | ||
@@ -477,11 +449,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) | |||
477 | mem = kmalloc(sizeof(*mem), GFP_KERNEL); | 449 | mem = kmalloc(sizeof(*mem), GFP_KERNEL); |
478 | if (! mem) | 450 | if (! mem) |
479 | return -ENOMEM; | 451 | return -ENOMEM; |
480 | down(&list_mutex); | 452 | mutex_lock(&list_mutex); |
481 | mem->buffer = *dmab; | 453 | mem->buffer = *dmab; |
482 | mem->id = id; | 454 | mem->id = id; |
483 | list_add_tail(&mem->list, &mem_list_head); | 455 | list_add_tail(&mem->list, &mem_list_head); |
484 | up(&list_mutex); | 456 | mutex_unlock(&list_mutex); |
485 | return 0; | 457 | return 0; |
486 | } | 458 | } |
487 | 459 | ||
@@ -493,7 +465,7 @@ static void free_all_reserved_pages(void) | |||
493 | struct list_head *p; | 465 | struct list_head *p; |
494 | struct snd_mem_list *mem; | 466 | struct snd_mem_list *mem; |
495 | 467 | ||
496 | down(&list_mutex); | 468 | mutex_lock(&list_mutex); |
497 | while (! list_empty(&mem_list_head)) { | 469 | while (! list_empty(&mem_list_head)) { |
498 | p = mem_list_head.next; | 470 | p = mem_list_head.next; |
499 | mem = list_entry(p, struct snd_mem_list, list); | 471 | mem = list_entry(p, struct snd_mem_list, list); |
@@ -501,7 +473,7 @@ static void free_all_reserved_pages(void) | |||
501 | snd_dma_free_pages(&mem->buffer); | 473 | snd_dma_free_pages(&mem->buffer); |
502 | kfree(mem); | 474 | kfree(mem); |
503 | } | 475 | } |
504 | up(&list_mutex); | 476 | mutex_unlock(&list_mutex); |
505 | } | 477 | } |
506 | 478 | ||
507 | 479 | ||
@@ -522,7 +494,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, | |||
522 | int devno; | 494 | int devno; |
523 | static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; | 495 | static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; |
524 | 496 | ||
525 | down(&list_mutex); | 497 | mutex_lock(&list_mutex); |
526 | len += snprintf(page + len, count - len, | 498 | len += snprintf(page + len, count - len, |
527 | "pages : %li bytes (%li pages per %likB)\n", | 499 | "pages : %li bytes (%li pages per %likB)\n", |
528 | pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); | 500 | pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); |
@@ -537,7 +509,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, | |||
537 | " addr = 0x%lx, size = %d bytes\n", | 509 | " addr = 0x%lx, size = %d bytes\n", |
538 | (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); | 510 | (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); |
539 | } | 511 | } |
540 | up(&list_mutex); | 512 | mutex_unlock(&list_mutex); |
541 | return len; | 513 | return len; |
542 | } | 514 | } |
543 | 515 | ||
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c index d6a04c2d5a75..6658facc5cda 100644 --- a/sound/core/oss/copy.c +++ b/sound/core/oss/copy.c | |||
@@ -20,6 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | |||
24 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
25 | |||
23 | #include <linux/time.h> | 26 | #include <linux/time.h> |
24 | #include <sound/core.h> | 27 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
@@ -85,3 +88,5 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug, | |||
85 | *r_plugin = plugin; | 88 | *r_plugin = plugin; |
86 | return 0; | 89 | return 0; |
87 | } | 90 | } |
91 | |||
92 | #endif | ||
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index 322702e05f3e..b6e7ce30e5a3 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c | |||
@@ -20,6 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | |||
24 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
25 | |||
23 | #include <linux/time.h> | 26 | #include <linux/time.h> |
24 | #include <sound/core.h> | 27 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
@@ -132,3 +135,5 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug, | |||
132 | *r_plugin = plugin; | 135 | *r_plugin = plugin; |
133 | return 0; | 136 | return 0; |
134 | } | 137 | } |
138 | |||
139 | #endif | ||
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index 8cbfa415ce40..5b1bcdc64779 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c | |||
@@ -21,6 +21,9 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <sound/driver.h> | 23 | #include <sound/driver.h> |
24 | |||
25 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
26 | |||
24 | #include <linux/time.h> | 27 | #include <linux/time.h> |
25 | #include <sound/core.h> | 28 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
@@ -103,7 +106,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, | |||
103 | return frames; | 106 | return frames; |
104 | } | 107 | } |
105 | 108 | ||
106 | int conv_index(int src_format, int dst_format) | 109 | static int conv_index(int src_format, int dst_format) |
107 | { | 110 | { |
108 | int src_endian, dst_endian, sign, src_width, dst_width; | 111 | int src_endian, dst_endian, sign, src_width, dst_width; |
109 | 112 | ||
@@ -156,3 +159,5 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, | |||
156 | *r_plugin = plugin; | 159 | *r_plugin = plugin; |
157 | return 0; | 160 | return 0; |
158 | } | 161 | } |
162 | |||
163 | #endif | ||
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index f08e65a2bffe..9c68bc3f97aa 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, | |||
1095 | struct snd_mixer_oss *mixer = entry->private_data; | 1095 | struct snd_mixer_oss *mixer = entry->private_data; |
1096 | int i; | 1096 | int i; |
1097 | 1097 | ||
1098 | down(&mixer->reg_mutex); | 1098 | mutex_lock(&mixer->reg_mutex); |
1099 | for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) { | 1099 | for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) { |
1100 | struct slot *p; | 1100 | struct slot *p; |
1101 | 1101 | ||
@@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, | |||
1110 | else | 1110 | else |
1111 | snd_iprintf(buffer, "\"\" 0\n"); | 1111 | snd_iprintf(buffer, "\"\" 0\n"); |
1112 | } | 1112 | } |
1113 | up(&mixer->reg_mutex); | 1113 | mutex_unlock(&mixer->reg_mutex); |
1114 | } | 1114 | } |
1115 | 1115 | ||
1116 | static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, | 1116 | 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, | |||
1134 | cptr = snd_info_get_str(str, cptr, sizeof(str)); | 1134 | cptr = snd_info_get_str(str, cptr, sizeof(str)); |
1135 | if (! *str) { | 1135 | if (! *str) { |
1136 | /* remove the entry */ | 1136 | /* remove the entry */ |
1137 | down(&mixer->reg_mutex); | 1137 | mutex_lock(&mixer->reg_mutex); |
1138 | mixer_slot_clear(&mixer->slots[ch]); | 1138 | mixer_slot_clear(&mixer->slots[ch]); |
1139 | up(&mixer->reg_mutex); | 1139 | mutex_unlock(&mixer->reg_mutex); |
1140 | continue; | 1140 | continue; |
1141 | } | 1141 | } |
1142 | snd_info_get_str(idxstr, cptr, sizeof(idxstr)); | 1142 | snd_info_get_str(idxstr, cptr, sizeof(idxstr)); |
@@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, | |||
1145 | snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx); | 1145 | snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx); |
1146 | continue; | 1146 | continue; |
1147 | } | 1147 | } |
1148 | down(&mixer->reg_mutex); | 1148 | mutex_lock(&mixer->reg_mutex); |
1149 | slot = (struct slot *)mixer->slots[ch].private_data; | 1149 | slot = (struct slot *)mixer->slots[ch].private_data; |
1150 | if (slot && slot->assigned && | 1150 | if (slot && slot->assigned && |
1151 | slot->assigned->index == idx && ! strcmp(slot->assigned->name, str)) | 1151 | 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, | |||
1168 | kfree(tbl); | 1168 | kfree(tbl); |
1169 | } | 1169 | } |
1170 | __unlock: | 1170 | __unlock: |
1171 | up(&mixer->reg_mutex); | 1171 | mutex_unlock(&mixer->reg_mutex); |
1172 | } | 1172 | } |
1173 | } | 1173 | } |
1174 | 1174 | ||
@@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) | |||
1288 | mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); | 1288 | mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); |
1289 | if (mixer == NULL) | 1289 | if (mixer == NULL) |
1290 | return -ENOMEM; | 1290 | return -ENOMEM; |
1291 | init_MUTEX(&mixer->reg_mutex); | 1291 | mutex_init(&mixer->reg_mutex); |
1292 | sprintf(name, "mixer%i%i", card->number, 0); | 1292 | sprintf(name, "mixer%i%i", card->number, 0); |
1293 | if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, | 1293 | if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, |
1294 | card, 0, | 1294 | card, 0, |
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c index 14f5578ec7a7..2eb18807e6d0 100644 --- a/sound/core/oss/mulaw.c +++ b/sound/core/oss/mulaw.c | |||
@@ -22,6 +22,9 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | |||
26 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
27 | |||
25 | #include <linux/time.h> | 28 | #include <linux/time.h> |
26 | #include <sound/core.h> | 29 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
@@ -262,6 +265,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin, | |||
262 | return frames; | 265 | return frames; |
263 | } | 266 | } |
264 | 267 | ||
268 | static int getput_index(int format) | ||
269 | { | ||
270 | int sign, width, endian; | ||
271 | sign = !snd_pcm_format_signed(format); | ||
272 | width = snd_pcm_format_width(format) / 8 - 1; | ||
273 | if (width < 0 || width > 3) { | ||
274 | snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); | ||
275 | width = 0; | ||
276 | } | ||
277 | #ifdef SNDRV_LITTLE_ENDIAN | ||
278 | endian = snd_pcm_format_big_endian(format); | ||
279 | #else | ||
280 | endian = snd_pcm_format_little_endian(format); | ||
281 | #endif | ||
282 | if (endian < 0) | ||
283 | endian = 0; | ||
284 | return width * 4 + endian * 2 + sign; | ||
285 | } | ||
286 | |||
265 | int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, | 287 | int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, |
266 | struct snd_pcm_plugin_format *src_format, | 288 | struct snd_pcm_plugin_format *src_format, |
267 | struct snd_pcm_plugin_format *dst_format, | 289 | struct snd_pcm_plugin_format *dst_format, |
@@ -306,3 +328,5 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, | |||
306 | *r_plugin = plugin; | 328 | *r_plugin = plugin; |
307 | return 0; | 329 | return 0; |
308 | } | 330 | } |
331 | |||
332 | #endif | ||
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 7fd072392c7e..f8302b703a30 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -78,6 +78,7 @@ static inline void snd_leave_user(mm_segment_t fs) | |||
78 | set_fs(fs); | 78 | set_fs(fs); |
79 | } | 79 | } |
80 | 80 | ||
81 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
81 | static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) | 82 | static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) |
82 | { | 83 | { |
83 | struct snd_pcm_runtime *runtime = substream->runtime; | 84 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -122,6 +123,7 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin) | |||
122 | } | 123 | } |
123 | return 0; | 124 | return 0; |
124 | } | 125 | } |
126 | #endif /* CONFIG_SND_PCM_OSS_PLUGINS */ | ||
125 | 127 | ||
126 | static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) | 128 | static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) |
127 | { | 129 | { |
@@ -412,6 +414,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
412 | oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * | 414 | oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * |
413 | params_channels(params) / 8; | 415 | params_channels(params) / 8; |
414 | 416 | ||
417 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
415 | snd_pcm_oss_plugin_clear(substream); | 418 | snd_pcm_oss_plugin_clear(substream); |
416 | if (!direct) { | 419 | if (!direct) { |
417 | /* add necessary plugins */ | 420 | /* add necessary plugins */ |
@@ -441,6 +444,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
441 | } | 444 | } |
442 | } | 445 | } |
443 | } | 446 | } |
447 | #endif | ||
444 | 448 | ||
445 | err = snd_pcm_oss_period_size(substream, params, sparams); | 449 | err = snd_pcm_oss_period_size(substream, params, sparams); |
446 | if (err < 0) | 450 | if (err < 0) |
@@ -498,11 +502,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) | |||
498 | runtime->oss.periods = params_periods(sparams); | 502 | runtime->oss.periods = params_periods(sparams); |
499 | oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); | 503 | oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); |
500 | snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); | 504 | snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); |
505 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
501 | if (runtime->oss.plugin_first) { | 506 | if (runtime->oss.plugin_first) { |
502 | err = snd_pcm_plug_alloc(substream, oss_period_size); | 507 | err = snd_pcm_plug_alloc(substream, oss_period_size); |
503 | if (err < 0) | 508 | if (err < 0) |
504 | goto failure; | 509 | goto failure; |
505 | } | 510 | } |
511 | #endif | ||
506 | oss_period_size *= oss_frame_size; | 512 | oss_period_size *= oss_frame_size; |
507 | 513 | ||
508 | oss_buffer_size = oss_period_size * runtime->oss.periods; | 514 | 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 | |||
784 | { | 790 | { |
785 | struct snd_pcm_runtime *runtime = substream->runtime; | 791 | struct snd_pcm_runtime *runtime = substream->runtime; |
786 | snd_pcm_sframes_t frames, frames1; | 792 | snd_pcm_sframes_t frames, frames1; |
793 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
787 | if (runtime->oss.plugin_first) { | 794 | if (runtime->oss.plugin_first) { |
788 | struct snd_pcm_plugin_channel *channels; | 795 | struct snd_pcm_plugin_channel *channels; |
789 | size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; | 796 | 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 | |||
800 | if (frames1 <= 0) | 807 | if (frames1 <= 0) |
801 | return frames1; | 808 | return frames1; |
802 | bytes = frames1 * oss_frame_bytes; | 809 | bytes = frames1 * oss_frame_bytes; |
803 | } else { | 810 | } else |
811 | #endif | ||
812 | { | ||
804 | frames = bytes_to_frames(runtime, bytes); | 813 | frames = bytes_to_frames(runtime, bytes); |
805 | frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); | 814 | frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); |
806 | if (frames1 <= 0) | 815 | if (frames1 <= 0) |
@@ -871,6 +880,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, | |||
871 | { | 880 | { |
872 | struct snd_pcm_runtime *runtime = substream->runtime; | 881 | struct snd_pcm_runtime *runtime = substream->runtime; |
873 | snd_pcm_sframes_t frames, frames1; | 882 | snd_pcm_sframes_t frames, frames1; |
883 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
874 | char __user *final_dst = (char __user *)buf; | 884 | char __user *final_dst = (char __user *)buf; |
875 | if (runtime->oss.plugin_first) { | 885 | if (runtime->oss.plugin_first) { |
876 | struct snd_pcm_plugin_channel *channels; | 886 | struct snd_pcm_plugin_channel *channels; |
@@ -887,7 +897,9 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, | |||
887 | bytes = frames1 * oss_frame_bytes; | 897 | bytes = frames1 * oss_frame_bytes; |
888 | if (!in_kernel && copy_to_user(final_dst, buf, bytes)) | 898 | if (!in_kernel && copy_to_user(final_dst, buf, bytes)) |
889 | return -EFAULT; | 899 | return -EFAULT; |
890 | } else { | 900 | } else |
901 | #endif | ||
902 | { | ||
891 | frames = bytes_to_frames(runtime, bytes); | 903 | frames = bytes_to_frames(runtime, bytes); |
892 | frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); | 904 | frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); |
893 | if (frames1 <= 0) | 905 | if (frames1 <= 0) |
@@ -1631,10 +1643,10 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, | |||
1631 | const char *ptr, *ptrl; | 1643 | const char *ptr, *ptrl; |
1632 | struct snd_pcm_oss_setup *setup; | 1644 | struct snd_pcm_oss_setup *setup; |
1633 | 1645 | ||
1634 | down(&pcm->streams[stream].oss.setup_mutex); | 1646 | mutex_lock(&pcm->streams[stream].oss.setup_mutex); |
1635 | for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { | 1647 | for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { |
1636 | if (!strcmp(setup->task_name, task_name)) { | 1648 | if (!strcmp(setup->task_name, task_name)) { |
1637 | up(&pcm->streams[stream].oss.setup_mutex); | 1649 | mutex_unlock(&pcm->streams[stream].oss.setup_mutex); |
1638 | return setup; | 1650 | return setup; |
1639 | } | 1651 | } |
1640 | } | 1652 | } |
@@ -1650,12 +1662,12 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, | |||
1650 | } | 1662 | } |
1651 | for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { | 1663 | for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { |
1652 | if (!strcmp(setup->task_name, ptrl)) { | 1664 | if (!strcmp(setup->task_name, ptrl)) { |
1653 | up(&pcm->streams[stream].oss.setup_mutex); | 1665 | mutex_unlock(&pcm->streams[stream].oss.setup_mutex); |
1654 | return setup; | 1666 | return setup; |
1655 | } | 1667 | } |
1656 | } | 1668 | } |
1657 | __not_found: | 1669 | __not_found: |
1658 | up(&pcm->streams[stream].oss.setup_mutex); | 1670 | mutex_unlock(&pcm->streams[stream].oss.setup_mutex); |
1659 | return NULL; | 1671 | return NULL; |
1660 | } | 1672 | } |
1661 | 1673 | ||
@@ -1692,7 +1704,9 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) | |||
1692 | struct snd_pcm_runtime *runtime; | 1704 | struct snd_pcm_runtime *runtime; |
1693 | runtime = substream->runtime; | 1705 | runtime = substream->runtime; |
1694 | vfree(runtime->oss.buffer); | 1706 | vfree(runtime->oss.buffer); |
1707 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
1695 | snd_pcm_oss_plugin_clear(substream); | 1708 | snd_pcm_oss_plugin_clear(substream); |
1709 | #endif | ||
1696 | substream->oss.file = NULL; | 1710 | substream->oss.file = NULL; |
1697 | substream->oss.oss = 0; | 1711 | substream->oss.oss = 0; |
1698 | } | 1712 | } |
@@ -1881,7 +1895,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1881 | 1895 | ||
1882 | init_waitqueue_entry(&wait, current); | 1896 | init_waitqueue_entry(&wait, current); |
1883 | add_wait_queue(&pcm->open_wait, &wait); | 1897 | add_wait_queue(&pcm->open_wait, &wait); |
1884 | down(&pcm->open_mutex); | 1898 | mutex_lock(&pcm->open_mutex); |
1885 | while (1) { | 1899 | while (1) { |
1886 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, | 1900 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, |
1887 | iminor(inode), psetup, csetup); | 1901 | iminor(inode), psetup, csetup); |
@@ -1895,16 +1909,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1895 | } else | 1909 | } else |
1896 | break; | 1910 | break; |
1897 | set_current_state(TASK_INTERRUPTIBLE); | 1911 | set_current_state(TASK_INTERRUPTIBLE); |
1898 | up(&pcm->open_mutex); | 1912 | mutex_unlock(&pcm->open_mutex); |
1899 | schedule(); | 1913 | schedule(); |
1900 | down(&pcm->open_mutex); | 1914 | mutex_lock(&pcm->open_mutex); |
1901 | if (signal_pending(current)) { | 1915 | if (signal_pending(current)) { |
1902 | err = -ERESTARTSYS; | 1916 | err = -ERESTARTSYS; |
1903 | break; | 1917 | break; |
1904 | } | 1918 | } |
1905 | } | 1919 | } |
1906 | remove_wait_queue(&pcm->open_wait, &wait); | 1920 | remove_wait_queue(&pcm->open_wait, &wait); |
1907 | up(&pcm->open_mutex); | 1921 | mutex_unlock(&pcm->open_mutex); |
1908 | if (err < 0) | 1922 | if (err < 0) |
1909 | goto __error; | 1923 | goto __error; |
1910 | return err; | 1924 | return err; |
@@ -1930,9 +1944,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) | |||
1930 | snd_assert(substream != NULL, return -ENXIO); | 1944 | snd_assert(substream != NULL, return -ENXIO); |
1931 | pcm = substream->pcm; | 1945 | pcm = substream->pcm; |
1932 | snd_pcm_oss_sync(pcm_oss_file); | 1946 | snd_pcm_oss_sync(pcm_oss_file); |
1933 | down(&pcm->open_mutex); | 1947 | mutex_lock(&pcm->open_mutex); |
1934 | snd_pcm_oss_release_file(pcm_oss_file); | 1948 | snd_pcm_oss_release_file(pcm_oss_file); |
1935 | up(&pcm->open_mutex); | 1949 | mutex_unlock(&pcm->open_mutex); |
1936 | wake_up(&pcm->open_wait); | 1950 | wake_up(&pcm->open_wait); |
1937 | module_put(pcm->card->module); | 1951 | module_put(pcm->card->module); |
1938 | snd_card_file_remove(pcm->card, file); | 1952 | 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) | |||
2246 | if ((err = snd_pcm_oss_change_params(substream)) < 0) | 2260 | if ((err = snd_pcm_oss_change_params(substream)) < 0) |
2247 | return err; | 2261 | return err; |
2248 | } | 2262 | } |
2263 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
2249 | if (runtime->oss.plugin_first != NULL) | 2264 | if (runtime->oss.plugin_first != NULL) |
2250 | return -EIO; | 2265 | return -EIO; |
2266 | #endif | ||
2251 | 2267 | ||
2252 | if (area->vm_pgoff != 0) | 2268 | if (area->vm_pgoff != 0) |
2253 | return -EINVAL; | 2269 | return -EINVAL; |
@@ -2277,7 +2293,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, | |||
2277 | { | 2293 | { |
2278 | struct snd_pcm_str *pstr = entry->private_data; | 2294 | struct snd_pcm_str *pstr = entry->private_data; |
2279 | struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; | 2295 | struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; |
2280 | down(&pstr->oss.setup_mutex); | 2296 | mutex_lock(&pstr->oss.setup_mutex); |
2281 | while (setup) { | 2297 | while (setup) { |
2282 | snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", | 2298 | snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", |
2283 | setup->task_name, | 2299 | setup->task_name, |
@@ -2291,7 +2307,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, | |||
2291 | setup->nosilence ? " no-silence" : ""); | 2307 | setup->nosilence ? " no-silence" : ""); |
2292 | setup = setup->next; | 2308 | setup = setup->next; |
2293 | } | 2309 | } |
2294 | up(&pstr->oss.setup_mutex); | 2310 | mutex_unlock(&pstr->oss.setup_mutex); |
2295 | } | 2311 | } |
2296 | 2312 | ||
2297 | static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) | 2313 | 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, | |||
2321 | struct snd_pcm_oss_setup *setup, *setup1, template; | 2337 | struct snd_pcm_oss_setup *setup, *setup1, template; |
2322 | 2338 | ||
2323 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 2339 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
2324 | down(&pstr->oss.setup_mutex); | 2340 | mutex_lock(&pstr->oss.setup_mutex); |
2325 | memset(&template, 0, sizeof(template)); | 2341 | memset(&template, 0, sizeof(template)); |
2326 | ptr = snd_info_get_str(task_name, line, sizeof(task_name)); | 2342 | ptr = snd_info_get_str(task_name, line, sizeof(task_name)); |
2327 | if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { | 2343 | if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { |
2328 | snd_pcm_oss_proc_free_setup_list(pstr); | 2344 | snd_pcm_oss_proc_free_setup_list(pstr); |
2329 | up(&pstr->oss.setup_mutex); | 2345 | mutex_unlock(&pstr->oss.setup_mutex); |
2330 | continue; | 2346 | continue; |
2331 | } | 2347 | } |
2332 | for (setup = pstr->oss.setup_list; setup; setup = setup->next) { | 2348 | 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, | |||
2378 | } | 2394 | } |
2379 | if (setup) | 2395 | if (setup) |
2380 | *setup = template; | 2396 | *setup = template; |
2381 | up(&pstr->oss.setup_mutex); | 2397 | mutex_unlock(&pstr->oss.setup_mutex); |
2382 | } | 2398 | } |
2383 | } | 2399 | } |
2384 | 2400 | ||
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 7e8676880dde..0e67dd280a5d 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #include <sound/driver.h> | 27 | #include <sound/driver.h> |
28 | |||
29 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
30 | |||
28 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
29 | #include <linux/time.h> | 32 | #include <linux/time.h> |
30 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
@@ -36,26 +39,6 @@ | |||
36 | #define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first) | 39 | #define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first) |
37 | #define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last) | 40 | #define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last) |
38 | 41 | ||
39 | static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin, | ||
40 | unsigned long *dst_vmask, | ||
41 | unsigned long **src_vmask) | ||
42 | { | ||
43 | unsigned long *vmask = plugin->src_vmask; | ||
44 | bitmap_copy(vmask, dst_vmask, plugin->src_format.channels); | ||
45 | *src_vmask = vmask; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin, | ||
50 | unsigned long *src_vmask, | ||
51 | unsigned long **dst_vmask) | ||
52 | { | ||
53 | unsigned long *vmask = plugin->dst_vmask; | ||
54 | bitmap_copy(vmask, src_vmask, plugin->dst_format.channels); | ||
55 | *dst_vmask = vmask; | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | /* | 42 | /* |
60 | * because some cards might have rates "very close", we ignore | 43 | * because some cards might have rates "very close", we ignore |
61 | * all "resampling" requests within +-5% | 44 | * all "resampling" requests within +-5% |
@@ -193,19 +176,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, | |||
193 | snd_pcm_plugin_free(plugin); | 176 | snd_pcm_plugin_free(plugin); |
194 | return -ENOMEM; | 177 | return -ENOMEM; |
195 | } | 178 | } |
196 | plugin->src_vmask = bitmap_alloc(src_format->channels); | ||
197 | if (plugin->src_vmask == NULL) { | ||
198 | snd_pcm_plugin_free(plugin); | ||
199 | return -ENOMEM; | ||
200 | } | ||
201 | plugin->dst_vmask = bitmap_alloc(dst_format->channels); | ||
202 | if (plugin->dst_vmask == NULL) { | ||
203 | snd_pcm_plugin_free(plugin); | ||
204 | return -ENOMEM; | ||
205 | } | ||
206 | plugin->client_channels = snd_pcm_plugin_client_channels; | 179 | plugin->client_channels = snd_pcm_plugin_client_channels; |
207 | plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask; | ||
208 | plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask; | ||
209 | *ret = plugin; | 180 | *ret = plugin; |
210 | return 0; | 181 | return 0; |
211 | } | 182 | } |
@@ -218,8 +189,6 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin) | |||
218 | plugin->private_free(plugin); | 189 | plugin->private_free(plugin); |
219 | kfree(plugin->buf_channels); | 190 | kfree(plugin->buf_channels); |
220 | vfree(plugin->buf); | 191 | vfree(plugin->buf); |
221 | kfree(plugin->src_vmask); | ||
222 | kfree(plugin->dst_vmask); | ||
223 | kfree(plugin); | 192 | kfree(plugin); |
224 | return 0; | 193 | return 0; |
225 | } | 194 | } |
@@ -429,24 +398,14 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, | |||
429 | dstformat.channels); | 398 | dstformat.channels); |
430 | 399 | ||
431 | /* Format change (linearization) */ | 400 | /* Format change (linearization) */ |
432 | if ((srcformat.format != dstformat.format || | 401 | if (! rate_match(srcformat.rate, dstformat.rate) && |
433 | !rate_match(srcformat.rate, dstformat.rate) || | 402 | ! snd_pcm_format_linear(srcformat.format)) { |
434 | srcformat.channels != dstformat.channels) && | 403 | if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW) |
435 | !snd_pcm_format_linear(srcformat.format)) { | ||
436 | if (snd_pcm_format_linear(dstformat.format)) | ||
437 | tmpformat.format = dstformat.format; | ||
438 | else | ||
439 | tmpformat.format = SNDRV_PCM_FORMAT_S16; | ||
440 | switch (srcformat.format) { | ||
441 | case SNDRV_PCM_FORMAT_MU_LAW: | ||
442 | err = snd_pcm_plugin_build_mulaw(plug, | ||
443 | &srcformat, &tmpformat, | ||
444 | &plugin); | ||
445 | break; | ||
446 | default: | ||
447 | return -EINVAL; | 404 | return -EINVAL; |
448 | } | 405 | tmpformat.format = SNDRV_PCM_FORMAT_S16; |
449 | pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err); | 406 | err = snd_pcm_plugin_build_mulaw(plug, |
407 | &srcformat, &tmpformat, | ||
408 | &plugin); | ||
450 | if (err < 0) | 409 | if (err < 0) |
451 | return err; | 410 | return err; |
452 | err = snd_pcm_plugin_append(plugin); | 411 | err = snd_pcm_plugin_append(plugin); |
@@ -460,35 +419,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, | |||
460 | 419 | ||
461 | /* channels reduction */ | 420 | /* channels reduction */ |
462 | if (srcformat.channels > dstformat.channels) { | 421 | if (srcformat.channels > dstformat.channels) { |
463 | int sv = srcformat.channels; | ||
464 | int dv = dstformat.channels; | ||
465 | int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); | ||
466 | if (ttable == NULL) | ||
467 | return -ENOMEM; | ||
468 | #if 1 | ||
469 | if (sv == 2 && dv == 1) { | ||
470 | ttable[0] = HALF; | ||
471 | ttable[1] = HALF; | ||
472 | } else | ||
473 | #endif | ||
474 | { | ||
475 | int v; | ||
476 | for (v = 0; v < dv; ++v) | ||
477 | ttable[v * sv + v] = FULL; | ||
478 | } | ||
479 | tmpformat.channels = dstformat.channels; | 422 | tmpformat.channels = dstformat.channels; |
480 | if (rate_match(srcformat.rate, dstformat.rate) && | 423 | err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); |
481 | snd_pcm_format_linear(dstformat.format)) | ||
482 | tmpformat.format = dstformat.format; | ||
483 | err = snd_pcm_plugin_build_route(plug, | ||
484 | &srcformat, &tmpformat, | ||
485 | ttable, &plugin); | ||
486 | kfree(ttable); | ||
487 | pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); | 424 | pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); |
488 | if (err < 0) { | 425 | if (err < 0) |
489 | snd_pcm_plugin_free(plugin); | ||
490 | return err; | 426 | return err; |
491 | } | ||
492 | err = snd_pcm_plugin_append(plugin); | 427 | err = snd_pcm_plugin_append(plugin); |
493 | if (err < 0) { | 428 | if (err < 0) { |
494 | snd_pcm_plugin_free(plugin); | 429 | snd_pcm_plugin_free(plugin); |
@@ -500,18 +435,29 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, | |||
500 | 435 | ||
501 | /* rate resampling */ | 436 | /* rate resampling */ |
502 | if (!rate_match(srcformat.rate, dstformat.rate)) { | 437 | if (!rate_match(srcformat.rate, dstformat.rate)) { |
438 | if (srcformat.format != SNDRV_PCM_FORMAT_S16) { | ||
439 | /* convert to S16 for resampling */ | ||
440 | tmpformat.format = SNDRV_PCM_FORMAT_S16; | ||
441 | err = snd_pcm_plugin_build_linear(plug, | ||
442 | &srcformat, &tmpformat, | ||
443 | &plugin); | ||
444 | if (err < 0) | ||
445 | return err; | ||
446 | err = snd_pcm_plugin_append(plugin); | ||
447 | if (err < 0) { | ||
448 | snd_pcm_plugin_free(plugin); | ||
449 | return err; | ||
450 | } | ||
451 | srcformat = tmpformat; | ||
452 | src_access = dst_access; | ||
453 | } | ||
503 | tmpformat.rate = dstformat.rate; | 454 | tmpformat.rate = dstformat.rate; |
504 | if (srcformat.channels == dstformat.channels && | ||
505 | snd_pcm_format_linear(dstformat.format)) | ||
506 | tmpformat.format = dstformat.format; | ||
507 | err = snd_pcm_plugin_build_rate(plug, | 455 | err = snd_pcm_plugin_build_rate(plug, |
508 | &srcformat, &tmpformat, | 456 | &srcformat, &tmpformat, |
509 | &plugin); | 457 | &plugin); |
510 | pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err); | 458 | pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err); |
511 | if (err < 0) { | 459 | if (err < 0) |
512 | snd_pcm_plugin_free(plugin); | ||
513 | return err; | 460 | return err; |
514 | } | ||
515 | err = snd_pcm_plugin_append(plugin); | 461 | err = snd_pcm_plugin_append(plugin); |
516 | if (err < 0) { | 462 | if (err < 0) { |
517 | snd_pcm_plugin_free(plugin); | 463 | snd_pcm_plugin_free(plugin); |
@@ -521,56 +467,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, | |||
521 | src_access = dst_access; | 467 | src_access = dst_access; |
522 | } | 468 | } |
523 | 469 | ||
524 | /* channels extension */ | ||
525 | if (srcformat.channels < dstformat.channels) { | ||
526 | int sv = srcformat.channels; | ||
527 | int dv = dstformat.channels; | ||
528 | int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); | ||
529 | if (ttable == NULL) | ||
530 | return -ENOMEM; | ||
531 | #if 0 | ||
532 | { | ||
533 | int v; | ||
534 | for (v = 0; v < sv; ++v) | ||
535 | ttable[v * sv + v] = FULL; | ||
536 | } | ||
537 | #else | ||
538 | { | ||
539 | /* Playback is spreaded on all channels */ | ||
540 | int vd, vs; | ||
541 | for (vd = 0, vs = 0; vd < dv; ++vd) { | ||
542 | ttable[vd * sv + vs] = FULL; | ||
543 | vs++; | ||
544 | if (vs == sv) | ||
545 | vs = 0; | ||
546 | } | ||
547 | } | ||
548 | #endif | ||
549 | tmpformat.channels = dstformat.channels; | ||
550 | if (snd_pcm_format_linear(dstformat.format)) | ||
551 | tmpformat.format = dstformat.format; | ||
552 | err = snd_pcm_plugin_build_route(plug, | ||
553 | &srcformat, &tmpformat, | ||
554 | ttable, &plugin); | ||
555 | kfree(ttable); | ||
556 | pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); | ||
557 | if (err < 0) { | ||
558 | snd_pcm_plugin_free(plugin); | ||
559 | return err; | ||
560 | } | ||
561 | err = snd_pcm_plugin_append(plugin); | ||
562 | if (err < 0) { | ||
563 | snd_pcm_plugin_free(plugin); | ||
564 | return err; | ||
565 | } | ||
566 | srcformat = tmpformat; | ||
567 | src_access = dst_access; | ||
568 | } | ||
569 | |||
570 | /* format change */ | 470 | /* format change */ |
571 | if (srcformat.format != dstformat.format) { | 471 | if (srcformat.format != dstformat.format) { |
572 | tmpformat.format = dstformat.format; | 472 | tmpformat.format = dstformat.format; |
573 | if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { | 473 | if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW || |
474 | tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { | ||
574 | err = snd_pcm_plugin_build_mulaw(plug, | 475 | err = snd_pcm_plugin_build_mulaw(plug, |
575 | &srcformat, &tmpformat, | 476 | &srcformat, &tmpformat, |
576 | &plugin); | 477 | &plugin); |
@@ -595,6 +496,22 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, | |||
595 | src_access = dst_access; | 496 | src_access = dst_access; |
596 | } | 497 | } |
597 | 498 | ||
499 | /* channels extension */ | ||
500 | if (srcformat.channels < dstformat.channels) { | ||
501 | tmpformat.channels = dstformat.channels; | ||
502 | err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); | ||
503 | pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | err = snd_pcm_plugin_append(plugin); | ||
507 | if (err < 0) { | ||
508 | snd_pcm_plugin_free(plugin); | ||
509 | return err; | ||
510 | } | ||
511 | srcformat = tmpformat; | ||
512 | src_access = dst_access; | ||
513 | } | ||
514 | |||
598 | /* de-interleave */ | 515 | /* de-interleave */ |
599 | if (src_access != dst_access) { | 516 | if (src_access != dst_access) { |
600 | err = snd_pcm_plugin_build_copy(plug, | 517 | 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 | |||
650 | return count; | 567 | return count; |
651 | } | 568 | } |
652 | 569 | ||
653 | static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug, | ||
654 | unsigned long *client_vmask) | ||
655 | { | ||
656 | struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); | ||
657 | if (plugin == NULL) { | ||
658 | return 0; | ||
659 | } else { | ||
660 | int schannels = plugin->dst_format.channels; | ||
661 | DECLARE_BITMAP(bs, schannels); | ||
662 | unsigned long *srcmask; | ||
663 | unsigned long *dstmask = bs; | ||
664 | int err; | ||
665 | bitmap_fill(dstmask, schannels); | ||
666 | |||
667 | while (1) { | ||
668 | err = plugin->src_channels_mask(plugin, dstmask, &srcmask); | ||
669 | if (err < 0) | ||
670 | return err; | ||
671 | dstmask = srcmask; | ||
672 | if (plugin->prev == NULL) | ||
673 | break; | ||
674 | plugin = plugin->prev; | ||
675 | } | ||
676 | bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels); | ||
677 | return 0; | ||
678 | } | ||
679 | } | ||
680 | |||
681 | static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug, | ||
682 | struct snd_pcm_plugin_channel *src_channels) | ||
683 | { | ||
684 | struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug); | ||
685 | unsigned int nchannels = plugin->src_format.channels; | ||
686 | DECLARE_BITMAP(bs, nchannels); | ||
687 | unsigned long *srcmask = bs; | ||
688 | int err; | ||
689 | unsigned int channel; | ||
690 | for (channel = 0; channel < nchannels; channel++) { | ||
691 | if (src_channels[channel].enabled) | ||
692 | set_bit(channel, srcmask); | ||
693 | else | ||
694 | clear_bit(channel, srcmask); | ||
695 | } | ||
696 | err = snd_pcm_plug_playback_channels_mask(plug, srcmask); | ||
697 | if (err < 0) | ||
698 | return err; | ||
699 | for (channel = 0; channel < nchannels; channel++) { | ||
700 | if (!test_bit(channel, srcmask)) | ||
701 | src_channels[channel].enabled = 0; | ||
702 | } | ||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug, | ||
707 | struct snd_pcm_plugin_channel *src_channels, | ||
708 | struct snd_pcm_plugin_channel *client_channels) | ||
709 | { | ||
710 | struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); | ||
711 | unsigned int nchannels = plugin->dst_format.channels; | ||
712 | DECLARE_BITMAP(bs, nchannels); | ||
713 | unsigned long *dstmask = bs; | ||
714 | unsigned long *srcmask; | ||
715 | int err; | ||
716 | unsigned int channel; | ||
717 | for (channel = 0; channel < nchannels; channel++) { | ||
718 | if (client_channels[channel].enabled) | ||
719 | set_bit(channel, dstmask); | ||
720 | else | ||
721 | clear_bit(channel, dstmask); | ||
722 | } | ||
723 | while (plugin) { | ||
724 | err = plugin->src_channels_mask(plugin, dstmask, &srcmask); | ||
725 | if (err < 0) | ||
726 | return err; | ||
727 | dstmask = srcmask; | ||
728 | plugin = plugin->prev; | ||
729 | } | ||
730 | plugin = snd_pcm_plug_first(plug); | ||
731 | nchannels = plugin->src_format.channels; | ||
732 | for (channel = 0; channel < nchannels; channel++) { | ||
733 | if (!test_bit(channel, dstmask)) | ||
734 | src_channels[channel].enabled = 0; | ||
735 | } | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | 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) | 570 | 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) |
740 | { | 571 | { |
741 | struct snd_pcm_plugin *plugin, *next; | 572 | 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 | |||
743 | int err; | 574 | int err; |
744 | snd_pcm_sframes_t frames = size; | 575 | snd_pcm_sframes_t frames = size; |
745 | 576 | ||
746 | if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0) | ||
747 | return err; | ||
748 | |||
749 | plugin = snd_pcm_plug_first(plug); | 577 | plugin = snd_pcm_plug_first(plug); |
750 | while (plugin && frames > 0) { | 578 | while (plugin && frames > 0) { |
751 | if ((next = plugin->next) != NULL) { | 579 | if ((next = plugin->next) != NULL) { |
@@ -790,10 +618,6 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str | |||
790 | return err; | 618 | return err; |
791 | } | 619 | } |
792 | frames = err; | 620 | frames = err; |
793 | if (!plugin->prev) { | ||
794 | if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0) | ||
795 | return err; | ||
796 | } | ||
797 | } else { | 621 | } else { |
798 | dst_channels = dst_channels_final; | 622 | dst_channels = dst_channels_final; |
799 | } | 623 | } |
@@ -916,3 +740,5 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of | |||
916 | } | 740 | } |
917 | return 0; | 741 | return 0; |
918 | } | 742 | } |
743 | |||
744 | #endif | ||
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h index 29198da615cd..3be91b3d5377 100644 --- a/sound/core/oss/pcm_plugin.h +++ b/sound/core/oss/pcm_plugin.h | |||
@@ -22,12 +22,7 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/bitmap.h> | 25 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS |
26 | |||
27 | static inline unsigned long *bitmap_alloc(unsigned int nbits) | ||
28 | { | ||
29 | return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL); | ||
30 | } | ||
31 | 26 | ||
32 | #define snd_pcm_plug_stream(plug) ((plug)->stream) | 27 | #define snd_pcm_plug_stream(plug) ((plug)->stream) |
33 | 28 | ||
@@ -69,12 +64,6 @@ struct snd_pcm_plugin { | |||
69 | snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, | 64 | snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, |
70 | snd_pcm_uframes_t frames, | 65 | snd_pcm_uframes_t frames, |
71 | struct snd_pcm_plugin_channel **channels); | 66 | struct snd_pcm_plugin_channel **channels); |
72 | int (*src_channels_mask)(struct snd_pcm_plugin *plugin, | ||
73 | unsigned long *dst_vmask, | ||
74 | unsigned long **src_vmask); | ||
75 | int (*dst_channels_mask)(struct snd_pcm_plugin *plugin, | ||
76 | unsigned long *src_vmask, | ||
77 | unsigned long **dst_vmask); | ||
78 | snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin, | 67 | snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin, |
79 | const struct snd_pcm_plugin_channel *src_channels, | 68 | const struct snd_pcm_plugin_channel *src_channels, |
80 | struct snd_pcm_plugin_channel *dst_channels, | 69 | struct snd_pcm_plugin_channel *dst_channels, |
@@ -90,8 +79,6 @@ struct snd_pcm_plugin { | |||
90 | char *buf; | 79 | char *buf; |
91 | snd_pcm_uframes_t buf_frames; | 80 | snd_pcm_uframes_t buf_frames; |
92 | struct snd_pcm_plugin_channel *buf_channels; | 81 | struct snd_pcm_plugin_channel *buf_channels; |
93 | unsigned long *src_vmask; | ||
94 | unsigned long *dst_vmask; | ||
95 | char extra_data[0]; | 82 | char extra_data[0]; |
96 | }; | 83 | }; |
97 | 84 | ||
@@ -128,7 +115,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle, | |||
128 | int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle, | 115 | int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle, |
129 | struct snd_pcm_plugin_format *src_format, | 116 | struct snd_pcm_plugin_format *src_format, |
130 | struct snd_pcm_plugin_format *dst_format, | 117 | struct snd_pcm_plugin_format *dst_format, |
131 | int *ttable, | ||
132 | struct snd_pcm_plugin **r_plugin); | 118 | struct snd_pcm_plugin **r_plugin); |
133 | int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle, | 119 | int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle, |
134 | struct snd_pcm_plugin_format *src_format, | 120 | struct snd_pcm_plugin_format *src_format, |
@@ -181,15 +167,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, | |||
181 | void **bufs, snd_pcm_uframes_t frames, | 167 | void **bufs, snd_pcm_uframes_t frames, |
182 | int in_kernel); | 168 | int in_kernel); |
183 | 169 | ||
184 | #define ROUTE_PLUGIN_RESOLUTION 16 | 170 | #else |
185 | 171 | ||
186 | int getput_index(int format); | 172 | 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; } |
187 | int copy_index(int format); | 173 | 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; } |
188 | int conv_index(int src_format, int dst_format); | 174 | static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; } |
189 | 175 | ||
190 | void zero_channel(struct snd_pcm_plugin *plugin, | 176 | #endif |
191 | const struct snd_pcm_plugin_channel *dst_channel, | ||
192 | size_t samples); | ||
193 | 177 | ||
194 | #ifdef PLUGIN_DEBUG | 178 | #ifdef PLUGIN_DEBUG |
195 | #define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) | 179 | #define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) |
diff --git a/sound/core/oss/plugin_ops.h b/sound/core/oss/plugin_ops.h index 0607e9566084..1f5bde4631f1 100644 --- a/sound/core/oss/plugin_ops.h +++ b/sound/core/oss/plugin_ops.h | |||
@@ -362,172 +362,6 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_ | |||
362 | } | 362 | } |
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | #if 0 | ||
366 | #ifdef GET32_LABELS | ||
367 | /* src_wid src_endswap unsigned */ | ||
368 | static void *get32_labels[4 * 2 * 2] = { | ||
369 | &&get32_xxx1_1000, /* 8h -> 32h */ | ||
370 | &&get32_xxx1_9000, /* 8h ^> 32h */ | ||
371 | &&get32_xxx1_1000, /* 8s -> 32h */ | ||
372 | &&get32_xxx1_9000, /* 8s ^> 32h */ | ||
373 | &&get32_xx12_1200, /* 16h -> 32h */ | ||
374 | &&get32_xx12_9200, /* 16h ^> 32h */ | ||
375 | &&get32_xx12_2100, /* 16s -> 32h */ | ||
376 | &&get32_xx12_A100, /* 16s ^> 32h */ | ||
377 | &&get32_x123_1230, /* 24h -> 32h */ | ||
378 | &&get32_x123_9230, /* 24h ^> 32h */ | ||
379 | &&get32_123x_3210, /* 24s -> 32h */ | ||
380 | &&get32_123x_B210, /* 24s ^> 32h */ | ||
381 | &&get32_1234_1234, /* 32h -> 32h */ | ||
382 | &&get32_1234_9234, /* 32h ^> 32h */ | ||
383 | &&get32_1234_4321, /* 32s -> 32h */ | ||
384 | &&get32_1234_C321, /* 32s ^> 32h */ | ||
385 | }; | ||
386 | #endif | ||
387 | |||
388 | #ifdef GET32_END | ||
389 | while (0) { | ||
390 | get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END; | ||
391 | get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END; | ||
392 | get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END; | ||
393 | get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END; | ||
394 | get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END; | ||
395 | get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END; | ||
396 | get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END; | ||
397 | get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END; | ||
398 | get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END; | ||
399 | get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END; | ||
400 | get32_1234_1234: sample = as_u32(src); goto GET32_END; | ||
401 | get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END; | ||
402 | get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END; | ||
403 | get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END; | ||
404 | } | ||
405 | #endif | ||
406 | #endif | ||
407 | |||
408 | #ifdef PUT_U32_LABELS | ||
409 | /* dst_wid dst_endswap unsigned */ | ||
410 | static void *put_u32_labels[4 * 2 * 2] = { | ||
411 | &&put_u32_1234_xxx9, /* u32h -> s8h */ | ||
412 | &&put_u32_1234_xxx1, /* u32h -> u8h */ | ||
413 | &&put_u32_1234_xxx9, /* u32h -> s8s */ | ||
414 | &&put_u32_1234_xxx1, /* u32h -> u8s */ | ||
415 | &&put_u32_1234_xx92, /* u32h -> s16h */ | ||
416 | &&put_u32_1234_xx12, /* u32h -> u16h */ | ||
417 | &&put_u32_1234_xx29, /* u32h -> s16s */ | ||
418 | &&put_u32_1234_xx21, /* u32h -> u16s */ | ||
419 | &&put_u32_1234_x923, /* u32h -> s24h */ | ||
420 | &&put_u32_1234_x123, /* u32h -> u24h */ | ||
421 | &&put_u32_1234_329x, /* u32h -> s24s */ | ||
422 | &&put_u32_1234_321x, /* u32h -> u24s */ | ||
423 | &&put_u32_1234_9234, /* u32h -> s32h */ | ||
424 | &&put_u32_1234_1234, /* u32h -> u32h */ | ||
425 | &&put_u32_1234_4329, /* u32h -> s32s */ | ||
426 | &&put_u32_1234_4321, /* u32h -> u32s */ | ||
427 | }; | ||
428 | #endif | ||
429 | |||
430 | #ifdef PUT_U32_END | ||
431 | while (0) { | ||
432 | put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END; | ||
433 | put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END; | ||
434 | put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END; | ||
435 | put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END; | ||
436 | put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END; | ||
437 | put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END; | ||
438 | put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END; | ||
439 | put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END; | ||
440 | put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END; | ||
441 | put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END; | ||
442 | put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END; | ||
443 | put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END; | ||
444 | put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END; | ||
445 | put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END; | ||
446 | } | ||
447 | #endif | ||
448 | |||
449 | #ifdef GET_U_LABELS | ||
450 | /* width endswap unsigned*/ | ||
451 | static void *get_u_labels[4 * 2 * 2] = { | ||
452 | &&get_u_s8, /* s8 -> u8 */ | ||
453 | &&get_u_u8, /* u8 -> u8 */ | ||
454 | &&get_u_s8, /* s8 -> u8 */ | ||
455 | &&get_u_u8, /* u8 -> u8 */ | ||
456 | &&get_u_s16h, /* s16h -> u16h */ | ||
457 | &&get_u_u16h, /* u16h -> u16h */ | ||
458 | &&get_u_s16s, /* s16s -> u16h */ | ||
459 | &&get_u_u16s, /* u16s -> u16h */ | ||
460 | &&get_u_s24h, /* s24h -> u32h */ | ||
461 | &&get_u_u24h, /* u24h -> u32h */ | ||
462 | &&get_u_s24s, /* s24s -> u32h */ | ||
463 | &&get_u_u24s, /* u24s -> u32h */ | ||
464 | &&get_u_s32h, /* s32h -> u32h */ | ||
465 | &&get_u_u32h, /* u32h -> u32h */ | ||
466 | &&get_u_s32s, /* s32s -> u32h */ | ||
467 | &&get_u_u32s, /* u32s -> u32h */ | ||
468 | }; | ||
469 | #endif | ||
470 | |||
471 | #ifdef GET_U_END | ||
472 | while (0) { | ||
473 | get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END; | ||
474 | get_u_u8: sample = as_u8(src); goto GET_U_END; | ||
475 | get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END; | ||
476 | get_u_u16h: sample = as_u16(src); goto GET_U_END; | ||
477 | get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END; | ||
478 | get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END; | ||
479 | get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END; | ||
480 | get_u_u24h: sample = as_u32(src); goto GET_U_END; | ||
481 | get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END; | ||
482 | get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END; | ||
483 | get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END; | ||
484 | get_u_u32h: sample = as_u32(src); goto GET_U_END; | ||
485 | get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END; | ||
486 | get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END; | ||
487 | } | ||
488 | #endif | ||
489 | |||
490 | #if 0 | ||
491 | #ifdef PUT_LABELS | ||
492 | /* width endswap unsigned */ | ||
493 | static void *put_labels[4 * 2 * 2] = { | ||
494 | &&put_s8, /* s8 -> s8 */ | ||
495 | &&put_u8, /* u8 -> s8 */ | ||
496 | &&put_s8, /* s8 -> s8 */ | ||
497 | &&put_u8, /* u8 -> s8 */ | ||
498 | &&put_s16h, /* s16h -> s16h */ | ||
499 | &&put_u16h, /* u16h -> s16h */ | ||
500 | &&put_s16s, /* s16s -> s16h */ | ||
501 | &&put_u16s, /* u16s -> s16h */ | ||
502 | &&put_s24h, /* s24h -> s32h */ | ||
503 | &&put_u24h, /* u24h -> s32h */ | ||
504 | &&put_s24s, /* s24s -> s32h */ | ||
505 | &&put_u24s, /* u24s -> s32h */ | ||
506 | &&put_s32h, /* s32h -> s32h */ | ||
507 | &&put_u32h, /* u32h -> s32h */ | ||
508 | &&put_s32s, /* s32s -> s32h */ | ||
509 | &&put_u32s, /* u32s -> s32h */ | ||
510 | }; | ||
511 | #endif | ||
512 | |||
513 | #ifdef PUT_END | ||
514 | put_s8: as_s8(dst) = sample; goto PUT_END; | ||
515 | put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END; | ||
516 | put_s16h: as_s16(dst) = sample; goto PUT_END; | ||
517 | put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END; | ||
518 | put_s16s: as_s16(dst) = swab16(sample); goto PUT_END; | ||
519 | put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END; | ||
520 | put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END; | ||
521 | put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END; | ||
522 | put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END; | ||
523 | put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END; | ||
524 | put_s32h: as_s32(dst) = sample; goto PUT_END; | ||
525 | put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END; | ||
526 | put_s32s: as_s32(dst) = swab32(sample); goto PUT_END; | ||
527 | put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END; | ||
528 | #endif | ||
529 | #endif | ||
530 | |||
531 | #undef as_u8 | 365 | #undef as_u8 |
532 | #undef as_u16 | 366 | #undef as_u16 |
533 | #undef as_u32 | 367 | #undef as_u32 |
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 4854cef6fb4f..18d8a0f4e816 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c | |||
@@ -20,6 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | |||
24 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
25 | |||
23 | #include <linux/time.h> | 26 | #include <linux/time.h> |
24 | #include <sound/core.h> | 27 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
@@ -47,7 +50,6 @@ struct rate_priv { | |||
47 | unsigned int pitch; | 50 | unsigned int pitch; |
48 | unsigned int pos; | 51 | unsigned int pos; |
49 | rate_f func; | 52 | rate_f func; |
50 | int get, put; | ||
51 | snd_pcm_sframes_t old_src_frames, old_dst_frames; | 53 | snd_pcm_sframes_t old_src_frames, old_dst_frames; |
52 | struct rate_channel channels[0]; | 54 | struct rate_channel channels[0]; |
53 | }; | 55 | }; |
@@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
71 | unsigned int pos = 0; | 73 | unsigned int pos = 0; |
72 | signed int val; | 74 | signed int val; |
73 | signed short S1, S2; | 75 | signed short S1, S2; |
74 | char *src, *dst; | 76 | signed short *src, *dst; |
75 | unsigned int channel; | 77 | unsigned int channel; |
76 | int src_step, dst_step; | 78 | int src_step, dst_step; |
77 | int src_frames1, dst_frames1; | 79 | int src_frames1, dst_frames1; |
78 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; | 80 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; |
79 | struct rate_channel *rchannels = data->channels; | 81 | struct rate_channel *rchannels = data->channels; |
80 | |||
81 | #define GET_S16_LABELS | ||
82 | #define PUT_S16_LABELS | ||
83 | #include "plugin_ops.h" | ||
84 | #undef GET_S16_LABELS | ||
85 | #undef PUT_S16_LABELS | ||
86 | void *get = get_s16_labels[data->get]; | ||
87 | void *put = put_s16_labels[data->put]; | ||
88 | signed short sample = 0; | ||
89 | 82 | ||
90 | for (channel = 0; channel < plugin->src_format.channels; channel++) { | 83 | for (channel = 0; channel < plugin->src_format.channels; channel++) { |
91 | pos = data->pos; | 84 | pos = data->pos; |
@@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
98 | continue; | 91 | continue; |
99 | } | 92 | } |
100 | dst_channels[channel].enabled = 1; | 93 | dst_channels[channel].enabled = 1; |
101 | src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; | 94 | src = (signed short *)src_channels[channel].area.addr + |
102 | dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; | 95 | src_channels[channel].area.first / 8 / 2; |
103 | src_step = src_channels[channel].area.step / 8; | 96 | dst = (signed short *)dst_channels[channel].area.addr + |
104 | dst_step = dst_channels[channel].area.step / 8; | 97 | dst_channels[channel].area.first / 8 / 2; |
98 | src_step = src_channels[channel].area.step / 8 / 2; | ||
99 | dst_step = dst_channels[channel].area.step / 8 / 2; | ||
105 | src_frames1 = src_frames; | 100 | src_frames1 = src_frames; |
106 | dst_frames1 = dst_frames; | 101 | dst_frames1 = dst_frames; |
107 | while (dst_frames1-- > 0) { | 102 | while (dst_frames1-- > 0) { |
@@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
109 | pos &= R_MASK; | 104 | pos &= R_MASK; |
110 | S1 = S2; | 105 | S1 = S2; |
111 | if (src_frames1-- > 0) { | 106 | if (src_frames1-- > 0) { |
112 | goto *get; | 107 | S2 = *src; |
113 | #define GET_S16_END after_get | ||
114 | #include "plugin_ops.h" | ||
115 | #undef GET_S16_END | ||
116 | after_get: | ||
117 | S2 = sample; | ||
118 | src += src_step; | 108 | src += src_step; |
119 | } | 109 | } |
120 | } | 110 | } |
@@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, | |||
123 | val = -32768; | 113 | val = -32768; |
124 | else if (val > 32767) | 114 | else if (val > 32767) |
125 | val = 32767; | 115 | val = 32767; |
126 | sample = val; | 116 | *dst = val; |
127 | goto *put; | ||
128 | #define PUT_S16_END after_put | ||
129 | #include "plugin_ops.h" | ||
130 | #undef PUT_S16_END | ||
131 | after_put: | ||
132 | dst += dst_step; | 117 | dst += dst_step; |
133 | pos += data->pitch; | 118 | pos += data->pitch; |
134 | } | 119 | } |
@@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
147 | unsigned int pos = 0; | 132 | unsigned int pos = 0; |
148 | signed int val; | 133 | signed int val; |
149 | signed short S1, S2; | 134 | signed short S1, S2; |
150 | char *src, *dst; | 135 | signed short *src, *dst; |
151 | unsigned int channel; | 136 | unsigned int channel; |
152 | int src_step, dst_step; | 137 | int src_step, dst_step; |
153 | int src_frames1, dst_frames1; | 138 | int src_frames1, dst_frames1; |
154 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; | 139 | struct rate_priv *data = (struct rate_priv *)plugin->extra_data; |
155 | struct rate_channel *rchannels = data->channels; | 140 | struct rate_channel *rchannels = data->channels; |
156 | |||
157 | #define GET_S16_LABELS | ||
158 | #define PUT_S16_LABELS | ||
159 | #include "plugin_ops.h" | ||
160 | #undef GET_S16_LABELS | ||
161 | #undef PUT_S16_LABELS | ||
162 | void *get = get_s16_labels[data->get]; | ||
163 | void *put = put_s16_labels[data->put]; | ||
164 | signed short sample = 0; | ||
165 | 141 | ||
166 | for (channel = 0; channel < plugin->src_format.channels; ++channel) { | 142 | for (channel = 0; channel < plugin->src_format.channels; ++channel) { |
167 | pos = data->pos; | 143 | pos = data->pos; |
@@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
174 | continue; | 150 | continue; |
175 | } | 151 | } |
176 | dst_channels[channel].enabled = 1; | 152 | dst_channels[channel].enabled = 1; |
177 | src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; | 153 | src = (signed short *)src_channels[channel].area.addr + |
178 | dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; | 154 | src_channels[channel].area.first / 8 / 2; |
179 | src_step = src_channels[channel].area.step / 8; | 155 | dst = (signed short *)dst_channels[channel].area.addr + |
180 | dst_step = dst_channels[channel].area.step / 8; | 156 | dst_channels[channel].area.first / 8 / 2; |
157 | src_step = src_channels[channel].area.step / 8 / 2; | ||
158 | dst_step = dst_channels[channel].area.step / 8 / 2; | ||
181 | src_frames1 = src_frames; | 159 | src_frames1 = src_frames; |
182 | dst_frames1 = dst_frames; | 160 | dst_frames1 = dst_frames; |
183 | while (dst_frames1 > 0) { | 161 | while (dst_frames1 > 0) { |
184 | S1 = S2; | 162 | S1 = S2; |
185 | if (src_frames1-- > 0) { | 163 | if (src_frames1-- > 0) { |
186 | goto *get; | 164 | S1 = *src; |
187 | #define GET_S16_END after_get | ||
188 | #include "plugin_ops.h" | ||
189 | #undef GET_S16_END | ||
190 | after_get: | ||
191 | S2 = sample; | ||
192 | src += src_step; | 165 | src += src_step; |
193 | } | 166 | } |
194 | if (pos & ~R_MASK) { | 167 | if (pos & ~R_MASK) { |
@@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, | |||
198 | val = -32768; | 171 | val = -32768; |
199 | else if (val > 32767) | 172 | else if (val > 32767) |
200 | val = 32767; | 173 | val = 32767; |
201 | sample = val; | 174 | *dst = val; |
202 | goto *put; | ||
203 | #define PUT_S16_END after_put | ||
204 | #include "plugin_ops.h" | ||
205 | #undef PUT_S16_END | ||
206 | after_put: | ||
207 | dst += dst_step; | 175 | dst += dst_step; |
208 | dst_frames1--; | 176 | dst_frames1--; |
209 | } | 177 | } |
@@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
343 | 311 | ||
344 | snd_assert(src_format->channels == dst_format->channels, return -ENXIO); | 312 | snd_assert(src_format->channels == dst_format->channels, return -ENXIO); |
345 | snd_assert(src_format->channels > 0, return -ENXIO); | 313 | snd_assert(src_format->channels > 0, return -ENXIO); |
346 | snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO); | 314 | snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); |
347 | snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO); | 315 | snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); |
348 | snd_assert(src_format->rate != dst_format->rate, return -ENXIO); | 316 | snd_assert(src_format->rate != dst_format->rate, return -ENXIO); |
349 | 317 | ||
350 | err = snd_pcm_plugin_build(plug, "rate conversion", | 318 | err = snd_pcm_plugin_build(plug, "rate conversion", |
@@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
355 | if (err < 0) | 323 | if (err < 0) |
356 | return err; | 324 | return err; |
357 | data = (struct rate_priv *)plugin->extra_data; | 325 | data = (struct rate_priv *)plugin->extra_data; |
358 | data->get = getput_index(src_format->format); | ||
359 | snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); | ||
360 | data->put = getput_index(dst_format->format); | ||
361 | snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL); | ||
362 | |||
363 | if (src_format->rate < dst_format->rate) { | 326 | if (src_format->rate < dst_format->rate) { |
364 | data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; | 327 | data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; |
365 | data->func = resample_expand; | 328 | data->func = resample_expand; |
@@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, | |||
377 | *r_plugin = plugin; | 340 | *r_plugin = plugin; |
378 | return 0; | 341 | return 0; |
379 | } | 342 | } |
343 | |||
344 | #endif | ||
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index 726c5caa3fdb..46917dc0196b 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Attenuated route Plug-In | 2 | * Route Plug-In |
3 | * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> | 3 | * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> |
4 | * | 4 | * |
5 | * | 5 | * |
@@ -20,502 +20,93 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
23 | |||
24 | #ifdef CONFIG_SND_PCM_OSS_PLUGINS | ||
25 | |||
23 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
24 | #include <linux/time.h> | 27 | #include <linux/time.h> |
25 | #include <sound/core.h> | 28 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
27 | #include "pcm_plugin.h" | 30 | #include "pcm_plugin.h" |
28 | 31 | ||
29 | /* The best possible hack to support missing optimization in gcc 2.7.2.3 */ | 32 | static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts, |
30 | #if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0 | 33 | snd_pcm_uframes_t frames, int format) |
31 | #define div(a) a /= ROUTE_PLUGIN_RESOLUTION | ||
32 | #elif ROUTE_PLUGIN_RESOLUTION == 16 | ||
33 | #define div(a) a >>= 4 | ||
34 | #else | ||
35 | #error "Add some code here" | ||
36 | #endif | ||
37 | |||
38 | struct ttable_dst; | ||
39 | |||
40 | typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin, | ||
41 | const struct snd_pcm_plugin_channel *src_channels, | ||
42 | struct snd_pcm_plugin_channel *dst_channel, | ||
43 | struct ttable_dst *ttable, snd_pcm_uframes_t frames); | ||
44 | |||
45 | struct ttable_src { | ||
46 | int channel; | ||
47 | int as_int; | ||
48 | }; | ||
49 | |||
50 | struct ttable_dst { | ||
51 | int att; /* Attenuated */ | ||
52 | unsigned int nsrcs; | ||
53 | struct ttable_src *srcs; | ||
54 | route_channel_f func; | ||
55 | }; | ||
56 | |||
57 | struct route_priv { | ||
58 | enum {R_UINT32=0, R_UINT64=1} sum_type; | ||
59 | int get, put; | ||
60 | int conv; | ||
61 | int src_sample_size; | ||
62 | struct ttable_dst ttable[0]; | ||
63 | }; | ||
64 | |||
65 | union sum { | ||
66 | u_int32_t as_uint32; | ||
67 | u_int64_t as_uint64; | ||
68 | }; | ||
69 | |||
70 | |||
71 | static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin, | ||
72 | const struct snd_pcm_plugin_channel *src_channels, | ||
73 | struct snd_pcm_plugin_channel *dst_channel, | ||
74 | struct ttable_dst *ttable, | ||
75 | snd_pcm_uframes_t frames) | ||
76 | { | ||
77 | if (dst_channel->wanted) | ||
78 | snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format); | ||
79 | dst_channel->enabled = 0; | ||
80 | } | ||
81 | |||
82 | static void route_to_channel_from_one(struct snd_pcm_plugin *plugin, | ||
83 | const struct snd_pcm_plugin_channel *src_channels, | ||
84 | struct snd_pcm_plugin_channel *dst_channel, | ||
85 | struct ttable_dst *ttable, | ||
86 | snd_pcm_uframes_t frames) | ||
87 | { | 34 | { |
88 | #define CONV_LABELS | 35 | int dst = 0; |
89 | #include "plugin_ops.h" | 36 | for (; dst < ndsts; ++dst) { |
90 | #undef CONV_LABELS | 37 | if (dvp->wanted) |
91 | struct route_priv *data = (struct route_priv *)plugin->extra_data; | 38 | snd_pcm_area_silence(&dvp->area, 0, frames, format); |
92 | void *conv; | 39 | dvp->enabled = 0; |
93 | const struct snd_pcm_plugin_channel *src_channel = NULL; | 40 | dvp++; |
94 | unsigned int srcidx; | ||
95 | char *src, *dst; | ||
96 | int src_step, dst_step; | ||
97 | for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) { | ||
98 | src_channel = &src_channels[ttable->srcs[srcidx].channel]; | ||
99 | if (src_channel->area.addr != NULL) | ||
100 | break; | ||
101 | } | ||
102 | if (srcidx == ttable->nsrcs) { | ||
103 | route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | dst_channel->enabled = 1; | ||
108 | conv = conv_labels[data->conv]; | ||
109 | src = src_channel->area.addr + src_channel->area.first / 8; | ||
110 | src_step = src_channel->area.step / 8; | ||
111 | dst = dst_channel->area.addr + dst_channel->area.first / 8; | ||
112 | dst_step = dst_channel->area.step / 8; | ||
113 | while (frames-- > 0) { | ||
114 | goto *conv; | ||
115 | #define CONV_END after | ||
116 | #include "plugin_ops.h" | ||
117 | #undef CONV_END | ||
118 | after: | ||
119 | src += src_step; | ||
120 | dst += dst_step; | ||
121 | } | 41 | } |
122 | } | 42 | } |
123 | 43 | ||
124 | static void route_to_channel(struct snd_pcm_plugin *plugin, | 44 | static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel, |
125 | const struct snd_pcm_plugin_channel *src_channels, | ||
126 | struct snd_pcm_plugin_channel *dst_channel, | 45 | struct snd_pcm_plugin_channel *dst_channel, |
127 | struct ttable_dst *ttable, snd_pcm_uframes_t frames) | 46 | snd_pcm_uframes_t frames, int format) |
128 | { | 47 | { |
129 | #define GET_U_LABELS | ||
130 | #define PUT_U32_LABELS | ||
131 | #include "plugin_ops.h" | ||
132 | #undef GET_U_LABELS | ||
133 | #undef PUT_U32_LABELS | ||
134 | static void *zero_labels[2] = { &&zero_int32, &&zero_int64 }; | ||
135 | /* sum_type att */ | ||
136 | static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att, | ||
137 | &&add_int64_noatt, &&add_int64_att, | ||
138 | }; | ||
139 | /* sum_type att shift */ | ||
140 | static void *norm_labels[2 * 2 * 4] = { NULL, | ||
141 | &&norm_int32_8_noatt, | ||
142 | &&norm_int32_16_noatt, | ||
143 | &&norm_int32_24_noatt, | ||
144 | NULL, | ||
145 | &&norm_int32_8_att, | ||
146 | &&norm_int32_16_att, | ||
147 | &&norm_int32_24_att, | ||
148 | &&norm_int64_0_noatt, | ||
149 | &&norm_int64_8_noatt, | ||
150 | &&norm_int64_16_noatt, | ||
151 | &&norm_int64_24_noatt, | ||
152 | &&norm_int64_0_att, | ||
153 | &&norm_int64_8_att, | ||
154 | &&norm_int64_16_att, | ||
155 | &&norm_int64_24_att, | ||
156 | }; | ||
157 | struct route_priv *data = (struct route_priv *)plugin->extra_data; | ||
158 | void *zero, *get, *add, *norm, *put_u32; | ||
159 | int nsrcs = ttable->nsrcs; | ||
160 | char *dst; | ||
161 | int dst_step; | ||
162 | char *srcs[nsrcs]; | ||
163 | int src_steps[nsrcs]; | ||
164 | struct ttable_src src_tt[nsrcs]; | ||
165 | u_int32_t sample = 0; | ||
166 | int srcidx, srcidx1 = 0; | ||
167 | for (srcidx = 0; srcidx < nsrcs; ++srcidx) { | ||
168 | const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel]; | ||
169 | if (!src_channel->enabled) | ||
170 | continue; | ||
171 | srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8; | ||
172 | src_steps[srcidx1] = src_channel->area.step / 8; | ||
173 | src_tt[srcidx1] = ttable->srcs[srcidx]; | ||
174 | srcidx1++; | ||
175 | } | ||
176 | nsrcs = srcidx1; | ||
177 | if (nsrcs == 0) { | ||
178 | route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); | ||
179 | return; | ||
180 | } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) { | ||
181 | route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames); | ||
182 | return; | ||
183 | } | ||
184 | |||
185 | dst_channel->enabled = 1; | 48 | dst_channel->enabled = 1; |
186 | zero = zero_labels[data->sum_type]; | 49 | snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format); |
187 | get = get_u_labels[data->get]; | ||
188 | add = add_labels[data->sum_type * 2 + ttable->att]; | ||
189 | norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size]; | ||
190 | put_u32 = put_u32_labels[data->put]; | ||
191 | dst = dst_channel->area.addr + dst_channel->area.first / 8; | ||
192 | dst_step = dst_channel->area.step / 8; | ||
193 | |||
194 | while (frames-- > 0) { | ||
195 | struct ttable_src *ttp = src_tt; | ||
196 | union sum sum; | ||
197 | |||
198 | /* Zero sum */ | ||
199 | goto *zero; | ||
200 | zero_int32: | ||
201 | sum.as_uint32 = 0; | ||
202 | goto zero_end; | ||
203 | zero_int64: | ||
204 | sum.as_uint64 = 0; | ||
205 | goto zero_end; | ||
206 | zero_end: | ||
207 | for (srcidx = 0; srcidx < nsrcs; ++srcidx) { | ||
208 | char *src = srcs[srcidx]; | ||
209 | |||
210 | /* Get sample */ | ||
211 | goto *get; | ||
212 | #define GET_U_END after_get | ||
213 | #include "plugin_ops.h" | ||
214 | #undef GET_U_END | ||
215 | after_get: | ||
216 | |||
217 | /* Sum */ | ||
218 | goto *add; | ||
219 | add_int32_att: | ||
220 | sum.as_uint32 += sample * ttp->as_int; | ||
221 | goto after_sum; | ||
222 | add_int32_noatt: | ||
223 | if (ttp->as_int) | ||
224 | sum.as_uint32 += sample; | ||
225 | goto after_sum; | ||
226 | add_int64_att: | ||
227 | sum.as_uint64 += (u_int64_t) sample * ttp->as_int; | ||
228 | goto after_sum; | ||
229 | add_int64_noatt: | ||
230 | if (ttp->as_int) | ||
231 | sum.as_uint64 += sample; | ||
232 | goto after_sum; | ||
233 | after_sum: | ||
234 | srcs[srcidx] += src_steps[srcidx]; | ||
235 | ttp++; | ||
236 | } | ||
237 | |||
238 | /* Normalization */ | ||
239 | goto *norm; | ||
240 | norm_int32_8_att: | ||
241 | sum.as_uint64 = sum.as_uint32; | ||
242 | norm_int64_8_att: | ||
243 | sum.as_uint64 <<= 8; | ||
244 | norm_int64_0_att: | ||
245 | div(sum.as_uint64); | ||
246 | goto norm_int; | ||
247 | |||
248 | norm_int32_16_att: | ||
249 | sum.as_uint64 = sum.as_uint32; | ||
250 | norm_int64_16_att: | ||
251 | sum.as_uint64 <<= 16; | ||
252 | div(sum.as_uint64); | ||
253 | goto norm_int; | ||
254 | |||
255 | norm_int32_24_att: | ||
256 | sum.as_uint64 = sum.as_uint32; | ||
257 | norm_int64_24_att: | ||
258 | sum.as_uint64 <<= 24; | ||
259 | div(sum.as_uint64); | ||
260 | goto norm_int; | ||
261 | |||
262 | norm_int32_8_noatt: | ||
263 | sum.as_uint64 = sum.as_uint32; | ||
264 | norm_int64_8_noatt: | ||
265 | sum.as_uint64 <<= 8; | ||
266 | goto norm_int; | ||
267 | |||
268 | norm_int32_16_noatt: | ||
269 | sum.as_uint64 = sum.as_uint32; | ||
270 | norm_int64_16_noatt: | ||
271 | sum.as_uint64 <<= 16; | ||
272 | goto norm_int; | ||
273 | |||
274 | norm_int32_24_noatt: | ||
275 | sum.as_uint64 = sum.as_uint32; | ||
276 | norm_int64_24_noatt: | ||
277 | sum.as_uint64 <<= 24; | ||
278 | goto norm_int; | ||
279 | |||
280 | norm_int64_0_noatt: | ||
281 | norm_int: | ||
282 | if (sum.as_uint64 > (u_int32_t)0xffffffff) | ||
283 | sample = (u_int32_t)0xffffffff; | ||
284 | else | ||
285 | sample = sum.as_uint64; | ||
286 | goto after_norm; | ||
287 | |||
288 | after_norm: | ||
289 | |||
290 | /* Put sample */ | ||
291 | goto *put_u32; | ||
292 | #define PUT_U32_END after_put_u32 | ||
293 | #include "plugin_ops.h" | ||
294 | #undef PUT_U32_END | ||
295 | after_put_u32: | ||
296 | |||
297 | dst += dst_step; | ||
298 | } | ||
299 | } | ||
300 | |||
301 | static int route_src_channels_mask(struct snd_pcm_plugin *plugin, | ||
302 | unsigned long *dst_vmask, | ||
303 | unsigned long **src_vmask) | ||
304 | { | ||
305 | struct route_priv *data = (struct route_priv *)plugin->extra_data; | ||
306 | int schannels = plugin->src_format.channels; | ||
307 | int dchannels = plugin->dst_format.channels; | ||
308 | unsigned long *vmask = plugin->src_vmask; | ||
309 | int channel; | ||
310 | struct ttable_dst *dp = data->ttable; | ||
311 | bitmap_zero(vmask, schannels); | ||
312 | for (channel = 0; channel < dchannels; channel++, dp++) { | ||
313 | unsigned int src; | ||
314 | struct ttable_src *sp; | ||
315 | if (!test_bit(channel, dst_vmask)) | ||
316 | continue; | ||
317 | sp = dp->srcs; | ||
318 | for (src = 0; src < dp->nsrcs; src++, sp++) | ||
319 | set_bit(sp->channel, vmask); | ||
320 | } | ||
321 | *src_vmask = vmask; | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int route_dst_channels_mask(struct snd_pcm_plugin *plugin, | ||
326 | unsigned long *src_vmask, | ||
327 | unsigned long **dst_vmask) | ||
328 | { | ||
329 | struct route_priv *data = (struct route_priv *)plugin->extra_data; | ||
330 | int dchannels = plugin->dst_format.channels; | ||
331 | unsigned long *vmask = plugin->dst_vmask; | ||
332 | int channel; | ||
333 | struct ttable_dst *dp = data->ttable; | ||
334 | bitmap_zero(vmask, dchannels); | ||
335 | for (channel = 0; channel < dchannels; channel++, dp++) { | ||
336 | unsigned int src; | ||
337 | struct ttable_src *sp; | ||
338 | sp = dp->srcs; | ||
339 | for (src = 0; src < dp->nsrcs; src++, sp++) { | ||
340 | if (test_bit(sp->channel, src_vmask)) { | ||
341 | set_bit(channel, vmask); | ||
342 | break; | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | *dst_vmask = vmask; | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void route_free(struct snd_pcm_plugin *plugin) | ||
351 | { | ||
352 | struct route_priv *data = (struct route_priv *)plugin->extra_data; | ||
353 | unsigned int dst_channel; | ||
354 | for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { | ||
355 | kfree(data->ttable[dst_channel].srcs); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | static int route_load_ttable(struct snd_pcm_plugin *plugin, | ||
360 | const int *src_ttable) | ||
361 | { | ||
362 | struct route_priv *data; | ||
363 | unsigned int src_channel, dst_channel; | ||
364 | const int *sptr; | ||
365 | struct ttable_dst *dptr; | ||
366 | if (src_ttable == NULL) | ||
367 | return 0; | ||
368 | data = (struct route_priv *)plugin->extra_data; | ||
369 | dptr = data->ttable; | ||
370 | sptr = src_ttable; | ||
371 | plugin->private_free = route_free; | ||
372 | for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { | ||
373 | int t = 0; | ||
374 | int att = 0; | ||
375 | int nsrcs = 0; | ||
376 | struct ttable_src srcs[plugin->src_format.channels]; | ||
377 | for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) { | ||
378 | snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO); | ||
379 | if (*sptr != 0) { | ||
380 | srcs[nsrcs].channel = src_channel; | ||
381 | srcs[nsrcs].as_int = *sptr; | ||
382 | if (*sptr != FULL) | ||
383 | att = 1; | ||
384 | t += *sptr; | ||
385 | nsrcs++; | ||
386 | } | ||
387 | sptr++; | ||
388 | } | ||
389 | dptr->att = att; | ||
390 | dptr->nsrcs = nsrcs; | ||
391 | if (nsrcs == 0) | ||
392 | dptr->func = route_to_channel_from_zero; | ||
393 | else if (nsrcs == 1 && !att) | ||
394 | dptr->func = route_to_channel_from_one; | ||
395 | else | ||
396 | dptr->func = route_to_channel; | ||
397 | if (nsrcs > 0) { | ||
398 | int srcidx; | ||
399 | dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL); | ||
400 | for(srcidx = 0; srcidx < nsrcs; srcidx++) | ||
401 | dptr->srcs[srcidx] = srcs[srcidx]; | ||
402 | } else | ||
403 | dptr->srcs = NULL; | ||
404 | dptr++; | ||
405 | } | ||
406 | return 0; | ||
407 | } | 50 | } |
408 | 51 | ||
409 | static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, | 52 | static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, |
410 | const struct snd_pcm_plugin_channel *src_channels, | 53 | const struct snd_pcm_plugin_channel *src_channels, |
411 | struct snd_pcm_plugin_channel *dst_channels, | 54 | struct snd_pcm_plugin_channel *dst_channels, |
412 | snd_pcm_uframes_t frames) | 55 | snd_pcm_uframes_t frames) |
413 | { | 56 | { |
414 | struct route_priv *data; | 57 | int nsrcs, ndsts, dst; |
415 | int src_nchannels, dst_nchannels; | ||
416 | int dst_channel; | ||
417 | struct ttable_dst *ttp; | ||
418 | struct snd_pcm_plugin_channel *dvp; | 58 | struct snd_pcm_plugin_channel *dvp; |
59 | int format; | ||
419 | 60 | ||
420 | snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); | 61 | snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); |
421 | if (frames == 0) | 62 | if (frames == 0) |
422 | return 0; | 63 | return 0; |
423 | data = (struct route_priv *)plugin->extra_data; | ||
424 | 64 | ||
425 | src_nchannels = plugin->src_format.channels; | 65 | nsrcs = plugin->src_format.channels; |
426 | dst_nchannels = plugin->dst_format.channels; | 66 | ndsts = plugin->dst_format.channels; |
427 | 67 | ||
428 | #ifdef CONFIG_SND_DEBUG | 68 | format = plugin->dst_format.format; |
429 | { | 69 | dvp = dst_channels; |
430 | int src_channel; | 70 | if (nsrcs <= 1) { |
431 | for (src_channel = 0; src_channel < src_nchannels; ++src_channel) { | 71 | /* expand to all channels */ |
432 | snd_assert(src_channels[src_channel].area.first % 8 == 0 || | 72 | for (dst = 0; dst < ndsts; ++dst) { |
433 | src_channels[src_channel].area.step % 8 == 0, | 73 | copy_area(src_channels, dvp, frames, format); |
434 | return -ENXIO); | 74 | dvp++; |
435 | } | ||
436 | for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { | ||
437 | snd_assert(dst_channels[dst_channel].area.first % 8 == 0 || | ||
438 | dst_channels[dst_channel].area.step % 8 == 0, | ||
439 | return -ENXIO); | ||
440 | } | 75 | } |
76 | return frames; | ||
441 | } | 77 | } |
442 | #endif | ||
443 | 78 | ||
444 | ttp = data->ttable; | 79 | for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) { |
445 | dvp = dst_channels; | 80 | copy_area(src_channels, dvp, frames, format); |
446 | for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { | ||
447 | ttp->func(plugin, src_channels, dvp, ttp, frames); | ||
448 | dvp++; | 81 | dvp++; |
449 | ttp++; | 82 | src_channels++; |
450 | } | 83 | } |
84 | if (dst < ndsts) | ||
85 | zero_areas(dvp, ndsts - dst, frames, format); | ||
451 | return frames; | 86 | return frames; |
452 | } | 87 | } |
453 | 88 | ||
454 | int getput_index(int format) | ||
455 | { | ||
456 | int sign, width, endian; | ||
457 | sign = !snd_pcm_format_signed(format); | ||
458 | width = snd_pcm_format_width(format) / 8 - 1; | ||
459 | if (width < 0 || width > 3) { | ||
460 | snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); | ||
461 | width = 0; | ||
462 | } | ||
463 | #ifdef SNDRV_LITTLE_ENDIAN | ||
464 | endian = snd_pcm_format_big_endian(format); | ||
465 | #else | ||
466 | endian = snd_pcm_format_little_endian(format); | ||
467 | #endif | ||
468 | if (endian < 0) | ||
469 | endian = 0; | ||
470 | return width * 4 + endian * 2 + sign; | ||
471 | } | ||
472 | |||
473 | int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, | 89 | int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, |
474 | struct snd_pcm_plugin_format *src_format, | 90 | struct snd_pcm_plugin_format *src_format, |
475 | struct snd_pcm_plugin_format *dst_format, | 91 | struct snd_pcm_plugin_format *dst_format, |
476 | int *ttable, | ||
477 | struct snd_pcm_plugin **r_plugin) | 92 | struct snd_pcm_plugin **r_plugin) |
478 | { | 93 | { |
479 | struct route_priv *data; | ||
480 | struct snd_pcm_plugin *plugin; | 94 | struct snd_pcm_plugin *plugin; |
481 | int err; | 95 | int err; |
482 | 96 | ||
483 | snd_assert(r_plugin != NULL, return -ENXIO); | 97 | snd_assert(r_plugin != NULL, return -ENXIO); |
484 | *r_plugin = NULL; | 98 | *r_plugin = NULL; |
485 | snd_assert(src_format->rate == dst_format->rate, return -ENXIO); | 99 | snd_assert(src_format->rate == dst_format->rate, return -ENXIO); |
486 | snd_assert(snd_pcm_format_linear(src_format->format) != 0 && | 100 | snd_assert(src_format->format == dst_format->format, return -ENXIO); |
487 | snd_pcm_format_linear(dst_format->format) != 0, | ||
488 | return -ENXIO); | ||
489 | 101 | ||
490 | err = snd_pcm_plugin_build(plug, "attenuated route conversion", | 102 | err = snd_pcm_plugin_build(plug, "route conversion", |
491 | src_format, dst_format, | 103 | src_format, dst_format, 0, &plugin); |
492 | sizeof(struct route_priv) + | ||
493 | sizeof(data->ttable[0]) * dst_format->channels, | ||
494 | &plugin); | ||
495 | if (err < 0) | 104 | if (err < 0) |
496 | return err; | 105 | return err; |
497 | 106 | ||
498 | data = (struct route_priv *)plugin->extra_data; | ||
499 | |||
500 | data->get = getput_index(src_format->format); | ||
501 | snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); | ||
502 | data->put = getput_index(dst_format->format); | ||
503 | snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); | ||
504 | data->conv = conv_index(src_format->format, dst_format->format); | ||
505 | |||
506 | if (snd_pcm_format_width(src_format->format) == 32) | ||
507 | data->sum_type = R_UINT64; | ||
508 | else | ||
509 | data->sum_type = R_UINT32; | ||
510 | data->src_sample_size = snd_pcm_format_width(src_format->format) / 8; | ||
511 | |||
512 | if ((err = route_load_ttable(plugin, ttable)) < 0) { | ||
513 | snd_pcm_plugin_free(plugin); | ||
514 | return err; | ||
515 | } | ||
516 | plugin->transfer = route_transfer; | 107 | plugin->transfer = route_transfer; |
517 | plugin->src_channels_mask = route_src_channels_mask; | ||
518 | plugin->dst_channels_mask = route_dst_channels_mask; | ||
519 | *r_plugin = plugin; | 108 | *r_plugin = plugin; |
520 | return 0; | 109 | return 0; |
521 | } | 110 | } |
111 | |||
112 | #endif | ||
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 28ca61eb0b0d..3da6a38c2d0f 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/mutex.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | #include <sound/minors.h> | 28 | #include <sound/minors.h> |
28 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
@@ -35,7 +36,7 @@ MODULE_LICENSE("GPL"); | |||
35 | 36 | ||
36 | static LIST_HEAD(snd_pcm_devices); | 37 | static LIST_HEAD(snd_pcm_devices); |
37 | static LIST_HEAD(snd_pcm_notify_list); | 38 | static LIST_HEAD(snd_pcm_notify_list); |
38 | static DECLARE_MUTEX(register_mutex); | 39 | static DEFINE_MUTEX(register_mutex); |
39 | 40 | ||
40 | static int snd_pcm_free(struct snd_pcm *pcm); | 41 | static int snd_pcm_free(struct snd_pcm *pcm); |
41 | static int snd_pcm_dev_free(struct snd_device *device); | 42 | static int snd_pcm_dev_free(struct snd_device *device); |
@@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
67 | 68 | ||
68 | if (get_user(device, (int __user *)arg)) | 69 | if (get_user(device, (int __user *)arg)) |
69 | return -EFAULT; | 70 | return -EFAULT; |
70 | down(®ister_mutex); | 71 | mutex_lock(®ister_mutex); |
71 | device = device < 0 ? 0 : device + 1; | 72 | device = device < 0 ? 0 : device + 1; |
72 | while (device < SNDRV_PCM_DEVICES) { | 73 | while (device < SNDRV_PCM_DEVICES) { |
73 | if (snd_pcm_search(card, device)) | 74 | if (snd_pcm_search(card, device)) |
@@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
76 | } | 77 | } |
77 | if (device == SNDRV_PCM_DEVICES) | 78 | if (device == SNDRV_PCM_DEVICES) |
78 | device = -1; | 79 | device = -1; |
79 | up(®ister_mutex); | 80 | mutex_unlock(®ister_mutex); |
80 | if (put_user(device, (int __user *)arg)) | 81 | if (put_user(device, (int __user *)arg)) |
81 | return -EFAULT; | 82 | return -EFAULT; |
82 | return 0; | 83 | return 0; |
@@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
100 | return -EINVAL; | 101 | return -EINVAL; |
101 | if (get_user(subdevice, &info->subdevice)) | 102 | if (get_user(subdevice, &info->subdevice)) |
102 | return -EFAULT; | 103 | return -EFAULT; |
103 | down(®ister_mutex); | 104 | mutex_lock(®ister_mutex); |
104 | pcm = snd_pcm_search(card, device); | 105 | pcm = snd_pcm_search(card, device); |
105 | if (pcm == NULL) { | 106 | if (pcm == NULL) { |
106 | err = -ENXIO; | 107 | err = -ENXIO; |
@@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
125 | } | 126 | } |
126 | err = snd_pcm_info_user(substream, info); | 127 | err = snd_pcm_info_user(substream, info); |
127 | _error: | 128 | _error: |
128 | up(®ister_mutex); | 129 | mutex_unlock(®ister_mutex); |
129 | return err; | 130 | return err; |
130 | } | 131 | } |
131 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: | 132 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: |
@@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
140 | } | 141 | } |
141 | return -ENOIOCTLCMD; | 142 | return -ENOIOCTLCMD; |
142 | } | 143 | } |
144 | |||
145 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS) | ||
146 | |||
143 | #define STATE(v) [SNDRV_PCM_STATE_##v] = #v | 147 | #define STATE(v) [SNDRV_PCM_STATE_##v] = #v |
144 | #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v | 148 | #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v |
145 | #define READY(v) [SNDRV_PCM_READY_##v] = #v | 149 | #define READY(v) [SNDRV_PCM_READY_##v] = #v |
@@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format) | |||
197 | return snd_pcm_format_names[format]; | 201 | return snd_pcm_format_names[format]; |
198 | } | 202 | } |
199 | 203 | ||
200 | #ifdef CONFIG_PROC_FS | ||
201 | static char *snd_pcm_stream_names[] = { | 204 | static char *snd_pcm_stream_names[] = { |
202 | STREAM(PLAYBACK), | 205 | STREAM(PLAYBACK), |
203 | STREAM(CAPTURE), | 206 | STREAM(CAPTURE), |
@@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state) | |||
260 | 263 | ||
261 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 264 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) |
262 | #include <linux/soundcard.h> | 265 | #include <linux/soundcard.h> |
266 | |||
263 | static const char *snd_pcm_oss_format_name(int format) | 267 | static const char *snd_pcm_oss_format_name(int format) |
264 | { | 268 | { |
265 | switch (format) { | 269 | switch (format) { |
@@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
622 | struct snd_pcm_substream *substream, *prev; | 626 | struct snd_pcm_substream *substream, *prev; |
623 | 627 | ||
624 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 628 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) |
625 | init_MUTEX(&pstr->oss.setup_mutex); | 629 | mutex_init(&pstr->oss.setup_mutex); |
626 | #endif | 630 | #endif |
627 | pstr->stream = stream; | 631 | pstr->stream = stream; |
628 | pstr->pcm = pcm; | 632 | pstr->pcm = pcm; |
@@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, | |||
716 | snd_pcm_free(pcm); | 720 | snd_pcm_free(pcm); |
717 | return err; | 721 | return err; |
718 | } | 722 | } |
719 | init_MUTEX(&pcm->open_mutex); | 723 | mutex_init(&pcm->open_mutex); |
720 | init_waitqueue_head(&pcm->open_wait); | 724 | init_waitqueue_head(&pcm->open_wait); |
721 | if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { | 725 | if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { |
722 | snd_pcm_free(pcm); | 726 | snd_pcm_free(pcm); |
@@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
902 | struct snd_pcm *pcm = device->device_data; | 906 | struct snd_pcm *pcm = device->device_data; |
903 | 907 | ||
904 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); | 908 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); |
905 | down(®ister_mutex); | 909 | mutex_lock(®ister_mutex); |
906 | if (snd_pcm_search(pcm->card, pcm->device)) { | 910 | if (snd_pcm_search(pcm->card, pcm->device)) { |
907 | up(®ister_mutex); | 911 | mutex_unlock(®ister_mutex); |
908 | return -EBUSY; | 912 | return -EBUSY; |
909 | } | 913 | } |
910 | list_add_tail(&pcm->list, &snd_pcm_devices); | 914 | list_add_tail(&pcm->list, &snd_pcm_devices); |
@@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
928 | pcm, str)) < 0) | 932 | pcm, str)) < 0) |
929 | { | 933 | { |
930 | list_del(&pcm->list); | 934 | list_del(&pcm->list); |
931 | up(®ister_mutex); | 935 | mutex_unlock(®ister_mutex); |
932 | return err; | 936 | return err; |
933 | } | 937 | } |
934 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 938 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
@@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
939 | notify = list_entry(list, struct snd_pcm_notify, list); | 943 | notify = list_entry(list, struct snd_pcm_notify, list); |
940 | notify->n_register(pcm); | 944 | notify->n_register(pcm); |
941 | } | 945 | } |
942 | up(®ister_mutex); | 946 | mutex_unlock(®ister_mutex); |
943 | return 0; | 947 | return 0; |
944 | } | 948 | } |
945 | 949 | ||
@@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
950 | struct snd_pcm_substream *substream; | 954 | struct snd_pcm_substream *substream; |
951 | int cidx; | 955 | int cidx; |
952 | 956 | ||
953 | down(®ister_mutex); | 957 | mutex_lock(®ister_mutex); |
954 | list_del_init(&pcm->list); | 958 | list_del_init(&pcm->list); |
955 | for (cidx = 0; cidx < 2; cidx++) | 959 | for (cidx = 0; cidx < 2; cidx++) |
956 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 960 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
@@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
961 | notify = list_entry(list, struct snd_pcm_notify, list); | 965 | notify = list_entry(list, struct snd_pcm_notify, list); |
962 | notify->n_disconnect(pcm); | 966 | notify->n_disconnect(pcm); |
963 | } | 967 | } |
964 | up(®ister_mutex); | 968 | mutex_unlock(®ister_mutex); |
965 | return 0; | 969 | return 0; |
966 | } | 970 | } |
967 | 971 | ||
@@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) | |||
973 | struct snd_pcm *pcm = device->device_data; | 977 | struct snd_pcm *pcm = device->device_data; |
974 | 978 | ||
975 | snd_assert(pcm != NULL, return -ENXIO); | 979 | snd_assert(pcm != NULL, return -ENXIO); |
976 | down(®ister_mutex); | 980 | mutex_lock(®ister_mutex); |
977 | list_del(&pcm->list); | 981 | list_del(&pcm->list); |
978 | for (cidx = 0; cidx < 2; cidx++) { | 982 | for (cidx = 0; cidx < 2; cidx++) { |
979 | devtype = -1; | 983 | devtype = -1; |
@@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) | |||
994 | notify = list_entry(list, struct snd_pcm_notify, list); | 998 | notify = list_entry(list, struct snd_pcm_notify, list); |
995 | notify->n_unregister(pcm); | 999 | notify->n_unregister(pcm); |
996 | } | 1000 | } |
997 | up(®ister_mutex); | 1001 | mutex_unlock(®ister_mutex); |
998 | return snd_pcm_free(pcm); | 1002 | return snd_pcm_free(pcm); |
999 | } | 1003 | } |
1000 | 1004 | ||
@@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1003 | struct list_head *p; | 1007 | struct list_head *p; |
1004 | 1008 | ||
1005 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); | 1009 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); |
1006 | down(®ister_mutex); | 1010 | mutex_lock(®ister_mutex); |
1007 | if (nfree) { | 1011 | if (nfree) { |
1008 | list_del(¬ify->list); | 1012 | list_del(¬ify->list); |
1009 | list_for_each(p, &snd_pcm_devices) | 1013 | list_for_each(p, &snd_pcm_devices) |
@@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1014 | list_for_each(p, &snd_pcm_devices) | 1018 | list_for_each(p, &snd_pcm_devices) |
1015 | notify->n_register(list_entry(p, struct snd_pcm, list)); | 1019 | notify->n_register(list_entry(p, struct snd_pcm, list)); |
1016 | } | 1020 | } |
1017 | up(®ister_mutex); | 1021 | mutex_unlock(®ister_mutex); |
1018 | return 0; | 1022 | return 0; |
1019 | } | 1023 | } |
1020 | 1024 | ||
@@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, | |||
1029 | struct list_head *p; | 1033 | struct list_head *p; |
1030 | struct snd_pcm *pcm; | 1034 | struct snd_pcm *pcm; |
1031 | 1035 | ||
1032 | down(®ister_mutex); | 1036 | mutex_lock(®ister_mutex); |
1033 | list_for_each(p, &snd_pcm_devices) { | 1037 | list_for_each(p, &snd_pcm_devices) { |
1034 | pcm = list_entry(p, struct snd_pcm, list); | 1038 | pcm = list_entry(p, struct snd_pcm, list); |
1035 | snd_iprintf(buffer, "%02i-%02i: %s : %s", | 1039 | snd_iprintf(buffer, "%02i-%02i: %s : %s", |
@@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, | |||
1042 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); | 1046 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); |
1043 | snd_iprintf(buffer, "\n"); | 1047 | snd_iprintf(buffer, "\n"); |
1044 | } | 1048 | } |
1045 | up(®ister_mutex); | 1049 | mutex_unlock(®ister_mutex); |
1046 | } | 1050 | } |
1047 | 1051 | ||
1048 | static struct snd_info_entry *snd_pcm_proc_entry = NULL; | 1052 | static struct snd_info_entry *snd_pcm_proc_entry = NULL; |
@@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream); | |||
1101 | EXPORT_SYMBOL(snd_pcm_notify); | 1105 | EXPORT_SYMBOL(snd_pcm_notify); |
1102 | EXPORT_SYMBOL(snd_pcm_open_substream); | 1106 | EXPORT_SYMBOL(snd_pcm_open_substream); |
1103 | EXPORT_SYMBOL(snd_pcm_release_substream); | 1107 | EXPORT_SYMBOL(snd_pcm_release_substream); |
1104 | EXPORT_SYMBOL(snd_pcm_format_name); | ||
1105 | /* pcm_native.c */ | 1108 | /* pcm_native.c */ |
1106 | EXPORT_SYMBOL(snd_pcm_link_rwlock); | 1109 | EXPORT_SYMBOL(snd_pcm_link_rwlock); |
1107 | #ifdef CONFIG_PM | 1110 | #ifdef CONFIG_PM |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f3d5de7b55ac..01f150f0990e 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -2112,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | |||
2112 | } | 2112 | } |
2113 | init_waitqueue_entry(&wait, current); | 2113 | init_waitqueue_entry(&wait, current); |
2114 | add_wait_queue(&pcm->open_wait, &wait); | 2114 | add_wait_queue(&pcm->open_wait, &wait); |
2115 | down(&pcm->open_mutex); | 2115 | mutex_lock(&pcm->open_mutex); |
2116 | while (1) { | 2116 | while (1) { |
2117 | err = snd_pcm_open_file(file, pcm, stream, &pcm_file); | 2117 | err = snd_pcm_open_file(file, pcm, stream, &pcm_file); |
2118 | if (err >= 0) | 2118 | if (err >= 0) |
@@ -2125,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | |||
2125 | } else | 2125 | } else |
2126 | break; | 2126 | break; |
2127 | set_current_state(TASK_INTERRUPTIBLE); | 2127 | set_current_state(TASK_INTERRUPTIBLE); |
2128 | up(&pcm->open_mutex); | 2128 | mutex_unlock(&pcm->open_mutex); |
2129 | schedule(); | 2129 | schedule(); |
2130 | down(&pcm->open_mutex); | 2130 | mutex_lock(&pcm->open_mutex); |
2131 | if (signal_pending(current)) { | 2131 | if (signal_pending(current)) { |
2132 | err = -ERESTARTSYS; | 2132 | err = -ERESTARTSYS; |
2133 | break; | 2133 | break; |
2134 | } | 2134 | } |
2135 | } | 2135 | } |
2136 | remove_wait_queue(&pcm->open_wait, &wait); | 2136 | remove_wait_queue(&pcm->open_wait, &wait); |
2137 | up(&pcm->open_mutex); | 2137 | mutex_unlock(&pcm->open_mutex); |
2138 | if (err < 0) | 2138 | if (err < 0) |
2139 | goto __error; | 2139 | goto __error; |
2140 | return err; | 2140 | return err; |
@@ -2160,9 +2160,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file) | |||
2160 | pcm = substream->pcm; | 2160 | pcm = substream->pcm; |
2161 | snd_pcm_drop(substream); | 2161 | snd_pcm_drop(substream); |
2162 | fasync_helper(-1, file, 0, &substream->runtime->fasync); | 2162 | fasync_helper(-1, file, 0, &substream->runtime->fasync); |
2163 | down(&pcm->open_mutex); | 2163 | mutex_lock(&pcm->open_mutex); |
2164 | snd_pcm_release_file(pcm_file); | 2164 | snd_pcm_release_file(pcm_file); |
2165 | up(&pcm->open_mutex); | 2165 | mutex_unlock(&pcm->open_mutex); |
2166 | wake_up(&pcm->open_wait); | 2166 | wake_up(&pcm->open_wait); |
2167 | module_put(pcm->card->module); | 2167 | module_put(pcm->card->module); |
2168 | snd_card_file_remove(pcm->card, file); | 2168 | snd_card_file_remove(pcm->card, file); |
@@ -2539,6 +2539,14 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, | |||
2539 | return snd_pcm_drain(substream); | 2539 | return snd_pcm_drain(substream); |
2540 | case SNDRV_PCM_IOCTL_DROP: | 2540 | case SNDRV_PCM_IOCTL_DROP: |
2541 | return snd_pcm_drop(substream); | 2541 | return snd_pcm_drop(substream); |
2542 | case SNDRV_PCM_IOCTL_PAUSE: | ||
2543 | { | ||
2544 | int res; | ||
2545 | snd_pcm_stream_lock_irq(substream); | ||
2546 | res = snd_pcm_pause(substream, (int)(unsigned long)arg); | ||
2547 | snd_pcm_stream_unlock_irq(substream); | ||
2548 | return res; | ||
2549 | } | ||
2542 | } | 2550 | } |
2543 | snd_printd("unknown ioctl = 0x%x\n", cmd); | 2551 | snd_printd("unknown ioctl = 0x%x\n", cmd); |
2544 | return -ENOTTY; | 2552 | return -ENOTTY; |
@@ -2619,14 +2627,6 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, | |||
2619 | __put_user(result, _frames); | 2627 | __put_user(result, _frames); |
2620 | return result < 0 ? result : 0; | 2628 | return result < 0 ? result : 0; |
2621 | } | 2629 | } |
2622 | case SNDRV_PCM_IOCTL_PAUSE: | ||
2623 | { | ||
2624 | int res; | ||
2625 | snd_pcm_stream_lock_irq(substream); | ||
2626 | res = snd_pcm_pause(substream, (int)(unsigned long)arg); | ||
2627 | snd_pcm_stream_unlock_irq(substream); | ||
2628 | return res; | ||
2629 | } | ||
2630 | } | 2630 | } |
2631 | return snd_pcm_common_ioctl1(substream, cmd, arg); | 2631 | return snd_pcm_common_ioctl1(substream, cmd, arg); |
2632 | } | 2632 | } |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index d4d124e21924..6b7a36774298 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/time.h> | 29 | #include <linux/time.h> |
30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
31 | #include <linux/mutex.h> | ||
31 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
33 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
@@ -57,7 +58,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device); | |||
57 | static int snd_rawmidi_dev_unregister(struct snd_device *device); | 58 | static int snd_rawmidi_dev_unregister(struct snd_device *device); |
58 | 59 | ||
59 | static LIST_HEAD(snd_rawmidi_devices); | 60 | static LIST_HEAD(snd_rawmidi_devices); |
60 | static DECLARE_MUTEX(register_mutex); | 61 | static DEFINE_MUTEX(register_mutex); |
61 | 62 | ||
62 | static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) | 63 | static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) |
63 | { | 64 | { |
@@ -237,9 +238,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, | |||
237 | 238 | ||
238 | if (rfile) | 239 | if (rfile) |
239 | rfile->input = rfile->output = NULL; | 240 | rfile->input = rfile->output = NULL; |
240 | down(®ister_mutex); | 241 | mutex_lock(®ister_mutex); |
241 | rmidi = snd_rawmidi_search(card, device); | 242 | rmidi = snd_rawmidi_search(card, device); |
242 | up(®ister_mutex); | 243 | mutex_unlock(®ister_mutex); |
243 | if (rmidi == NULL) { | 244 | if (rmidi == NULL) { |
244 | err = -ENODEV; | 245 | err = -ENODEV; |
245 | goto __error1; | 246 | goto __error1; |
@@ -249,7 +250,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, | |||
249 | goto __error1; | 250 | goto __error1; |
250 | } | 251 | } |
251 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) | 252 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) |
252 | down(&rmidi->open_mutex); | 253 | mutex_lock(&rmidi->open_mutex); |
253 | if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { | 254 | if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { |
254 | if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { | 255 | if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { |
255 | err = -ENXIO; | 256 | err = -ENXIO; |
@@ -359,7 +360,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, | |||
359 | soutput = NULL; | 360 | soutput = NULL; |
360 | } | 361 | } |
361 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) | 362 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) |
362 | up(&rmidi->open_mutex); | 363 | mutex_unlock(&rmidi->open_mutex); |
363 | if (rfile) { | 364 | if (rfile) { |
364 | rfile->rmidi = rmidi; | 365 | rfile->rmidi = rmidi; |
365 | rfile->input = sinput; | 366 | rfile->input = sinput; |
@@ -374,7 +375,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, | |||
374 | snd_rawmidi_runtime_free(soutput); | 375 | snd_rawmidi_runtime_free(soutput); |
375 | module_put(rmidi->card->module); | 376 | module_put(rmidi->card->module); |
376 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) | 377 | if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) |
377 | up(&rmidi->open_mutex); | 378 | mutex_unlock(&rmidi->open_mutex); |
378 | __error1: | 379 | __error1: |
379 | return err; | 380 | return err; |
380 | } | 381 | } |
@@ -422,7 +423,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
422 | } | 423 | } |
423 | init_waitqueue_entry(&wait, current); | 424 | init_waitqueue_entry(&wait, current); |
424 | add_wait_queue(&rmidi->open_wait, &wait); | 425 | add_wait_queue(&rmidi->open_wait, &wait); |
425 | down(&rmidi->open_mutex); | 426 | mutex_lock(&rmidi->open_mutex); |
426 | while (1) { | 427 | while (1) { |
427 | subdevice = -1; | 428 | subdevice = -1; |
428 | down_read(&card->controls_rwsem); | 429 | down_read(&card->controls_rwsem); |
@@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
446 | } else | 447 | } else |
447 | break; | 448 | break; |
448 | set_current_state(TASK_INTERRUPTIBLE); | 449 | set_current_state(TASK_INTERRUPTIBLE); |
449 | up(&rmidi->open_mutex); | 450 | mutex_unlock(&rmidi->open_mutex); |
450 | schedule(); | 451 | schedule(); |
451 | down(&rmidi->open_mutex); | 452 | mutex_lock(&rmidi->open_mutex); |
452 | if (signal_pending(current)) { | 453 | if (signal_pending(current)) { |
453 | err = -ERESTARTSYS; | 454 | err = -ERESTARTSYS; |
454 | break; | 455 | break; |
@@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
467 | snd_card_file_remove(card, file); | 468 | snd_card_file_remove(card, file); |
468 | kfree(rawmidi_file); | 469 | kfree(rawmidi_file); |
469 | } | 470 | } |
470 | up(&rmidi->open_mutex); | 471 | mutex_unlock(&rmidi->open_mutex); |
471 | return err; | 472 | return err; |
472 | } | 473 | } |
473 | 474 | ||
@@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) | |||
480 | snd_assert(rfile != NULL, return -ENXIO); | 481 | snd_assert(rfile != NULL, return -ENXIO); |
481 | snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); | 482 | snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); |
482 | rmidi = rfile->rmidi; | 483 | rmidi = rfile->rmidi; |
483 | down(&rmidi->open_mutex); | 484 | mutex_lock(&rmidi->open_mutex); |
484 | if (rfile->input != NULL) { | 485 | if (rfile->input != NULL) { |
485 | substream = rfile->input; | 486 | substream = rfile->input; |
486 | rfile->input = NULL; | 487 | rfile->input = NULL; |
@@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) | |||
514 | } | 515 | } |
515 | rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; | 516 | rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; |
516 | } | 517 | } |
517 | up(&rmidi->open_mutex); | 518 | mutex_unlock(&rmidi->open_mutex); |
518 | module_put(rmidi->card->module); | 519 | module_put(rmidi->card->module); |
519 | return 0; | 520 | return 0; |
520 | } | 521 | } |
@@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info | |||
576 | struct snd_rawmidi_substream *substream; | 577 | struct snd_rawmidi_substream *substream; |
577 | struct list_head *list; | 578 | struct list_head *list; |
578 | 579 | ||
579 | down(®ister_mutex); | 580 | mutex_lock(®ister_mutex); |
580 | rmidi = snd_rawmidi_search(card, info->device); | 581 | rmidi = snd_rawmidi_search(card, info->device); |
581 | up(®ister_mutex); | 582 | mutex_unlock(®ister_mutex); |
582 | if (!rmidi) | 583 | if (!rmidi) |
583 | return -ENXIO; | 584 | return -ENXIO; |
584 | if (info->stream < 0 || info->stream > 1) | 585 | if (info->stream < 0 || info->stream > 1) |
@@ -818,7 +819,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
818 | 819 | ||
819 | if (get_user(device, (int __user *)argp)) | 820 | if (get_user(device, (int __user *)argp)) |
820 | return -EFAULT; | 821 | return -EFAULT; |
821 | down(®ister_mutex); | 822 | mutex_lock(®ister_mutex); |
822 | device = device < 0 ? 0 : device + 1; | 823 | device = device < 0 ? 0 : device + 1; |
823 | while (device < SNDRV_RAWMIDI_DEVICES) { | 824 | while (device < SNDRV_RAWMIDI_DEVICES) { |
824 | if (snd_rawmidi_search(card, device)) | 825 | if (snd_rawmidi_search(card, device)) |
@@ -827,7 +828,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
827 | } | 828 | } |
828 | if (device == SNDRV_RAWMIDI_DEVICES) | 829 | if (device == SNDRV_RAWMIDI_DEVICES) |
829 | device = -1; | 830 | device = -1; |
830 | up(®ister_mutex); | 831 | mutex_unlock(®ister_mutex); |
831 | if (put_user(device, (int __user *)argp)) | 832 | if (put_user(device, (int __user *)argp)) |
832 | return -EFAULT; | 833 | return -EFAULT; |
833 | return 0; | 834 | return 0; |
@@ -1314,7 +1315,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, | |||
1314 | 1315 | ||
1315 | rmidi = entry->private_data; | 1316 | rmidi = entry->private_data; |
1316 | snd_iprintf(buffer, "%s\n\n", rmidi->name); | 1317 | snd_iprintf(buffer, "%s\n\n", rmidi->name); |
1317 | down(&rmidi->open_mutex); | 1318 | mutex_lock(&rmidi->open_mutex); |
1318 | if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { | 1319 | if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { |
1319 | list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { | 1320 | list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { |
1320 | substream = list_entry(list, struct snd_rawmidi_substream, list); | 1321 | 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, | |||
1355 | } | 1356 | } |
1356 | } | 1357 | } |
1357 | } | 1358 | } |
1358 | up(&rmidi->open_mutex); | 1359 | mutex_unlock(&rmidi->open_mutex); |
1359 | } | 1360 | } |
1360 | 1361 | ||
1361 | /* | 1362 | /* |
@@ -1436,7 +1437,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, | |||
1436 | } | 1437 | } |
1437 | rmidi->card = card; | 1438 | rmidi->card = card; |
1438 | rmidi->device = device; | 1439 | rmidi->device = device; |
1439 | init_MUTEX(&rmidi->open_mutex); | 1440 | mutex_init(&rmidi->open_mutex); |
1440 | init_waitqueue_head(&rmidi->open_wait); | 1441 | init_waitqueue_head(&rmidi->open_wait); |
1441 | if (id != NULL) | 1442 | if (id != NULL) |
1442 | strlcpy(rmidi->id, id, sizeof(rmidi->id)); | 1443 | strlcpy(rmidi->id, id, sizeof(rmidi->id)); |
@@ -1507,9 +1508,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1507 | 1508 | ||
1508 | if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) | 1509 | if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) |
1509 | return -ENOMEM; | 1510 | return -ENOMEM; |
1510 | down(®ister_mutex); | 1511 | mutex_lock(®ister_mutex); |
1511 | if (snd_rawmidi_search(rmidi->card, rmidi->device)) { | 1512 | if (snd_rawmidi_search(rmidi->card, rmidi->device)) { |
1512 | up(®ister_mutex); | 1513 | mutex_unlock(®ister_mutex); |
1513 | return -EBUSY; | 1514 | return -EBUSY; |
1514 | } | 1515 | } |
1515 | list_add_tail(&rmidi->list, &snd_rawmidi_devices); | 1516 | list_add_tail(&rmidi->list, &snd_rawmidi_devices); |
@@ -1519,14 +1520,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1519 | &snd_rawmidi_f_ops, rmidi, name)) < 0) { | 1520 | &snd_rawmidi_f_ops, rmidi, name)) < 0) { |
1520 | snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); | 1521 | snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); |
1521 | list_del(&rmidi->list); | 1522 | list_del(&rmidi->list); |
1522 | up(®ister_mutex); | 1523 | mutex_unlock(®ister_mutex); |
1523 | return err; | 1524 | return err; |
1524 | } | 1525 | } |
1525 | if (rmidi->ops && rmidi->ops->dev_register && | 1526 | if (rmidi->ops && rmidi->ops->dev_register && |
1526 | (err = rmidi->ops->dev_register(rmidi)) < 0) { | 1527 | (err = rmidi->ops->dev_register(rmidi)) < 0) { |
1527 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); | 1528 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); |
1528 | list_del(&rmidi->list); | 1529 | list_del(&rmidi->list); |
1529 | up(®ister_mutex); | 1530 | mutex_unlock(®ister_mutex); |
1530 | return err; | 1531 | return err; |
1531 | } | 1532 | } |
1532 | #ifdef CONFIG_SND_OSSEMUL | 1533 | #ifdef CONFIG_SND_OSSEMUL |
@@ -1553,7 +1554,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1553 | } | 1554 | } |
1554 | } | 1555 | } |
1555 | #endif /* CONFIG_SND_OSSEMUL */ | 1556 | #endif /* CONFIG_SND_OSSEMUL */ |
1556 | up(®ister_mutex); | 1557 | mutex_unlock(®ister_mutex); |
1557 | sprintf(name, "midi%d", rmidi->device); | 1558 | sprintf(name, "midi%d", rmidi->device); |
1558 | entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); | 1559 | entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); |
1559 | if (entry) { | 1560 | if (entry) { |
@@ -1583,9 +1584,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) | |||
1583 | { | 1584 | { |
1584 | struct snd_rawmidi *rmidi = device->device_data; | 1585 | struct snd_rawmidi *rmidi = device->device_data; |
1585 | 1586 | ||
1586 | down(®ister_mutex); | 1587 | mutex_lock(®ister_mutex); |
1587 | list_del_init(&rmidi->list); | 1588 | list_del_init(&rmidi->list); |
1588 | up(®ister_mutex); | 1589 | mutex_unlock(®ister_mutex); |
1589 | return 0; | 1590 | return 0; |
1590 | } | 1591 | } |
1591 | 1592 | ||
@@ -1594,7 +1595,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) | |||
1594 | struct snd_rawmidi *rmidi = device->device_data; | 1595 | struct snd_rawmidi *rmidi = device->device_data; |
1595 | 1596 | ||
1596 | snd_assert(rmidi != NULL, return -ENXIO); | 1597 | snd_assert(rmidi != NULL, return -ENXIO); |
1597 | down(®ister_mutex); | 1598 | mutex_lock(®ister_mutex); |
1598 | list_del(&rmidi->list); | 1599 | list_del(&rmidi->list); |
1599 | if (rmidi->proc_entry) { | 1600 | if (rmidi->proc_entry) { |
1600 | snd_info_unregister(rmidi->proc_entry); | 1601 | snd_info_unregister(rmidi->proc_entry); |
@@ -1616,7 +1617,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) | |||
1616 | if (rmidi->ops && rmidi->ops->dev_unregister) | 1617 | if (rmidi->ops && rmidi->ops->dev_unregister) |
1617 | rmidi->ops->dev_unregister(rmidi); | 1618 | rmidi->ops->dev_unregister(rmidi); |
1618 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); | 1619 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); |
1619 | up(®ister_mutex); | 1620 | mutex_unlock(®ister_mutex); |
1620 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) | 1621 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) |
1621 | if (rmidi->seq_dev) { | 1622 | if (rmidi->seq_dev) { |
1622 | snd_device_free(rmidi->card, rmidi->seq_dev); | 1623 | snd_device_free(rmidi->card, rmidi->seq_dev); |
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index c98f0ba13810..b9919785180b 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
26 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
28 | #include <sound/minors.h> | 29 | #include <sound/minors.h> |
29 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
@@ -124,7 +125,7 @@ module_exit(alsa_seq_oss_exit) | |||
124 | * ALSA minor device interface | 125 | * ALSA minor device interface |
125 | */ | 126 | */ |
126 | 127 | ||
127 | static DECLARE_MUTEX(register_mutex); | 128 | static DEFINE_MUTEX(register_mutex); |
128 | 129 | ||
129 | static int | 130 | static int |
130 | odev_open(struct inode *inode, struct file *file) | 131 | odev_open(struct inode *inode, struct file *file) |
@@ -136,9 +137,9 @@ odev_open(struct inode *inode, struct file *file) | |||
136 | else | 137 | else |
137 | level = SNDRV_SEQ_OSS_MODE_SYNTH; | 138 | level = SNDRV_SEQ_OSS_MODE_SYNTH; |
138 | 139 | ||
139 | down(®ister_mutex); | 140 | mutex_lock(®ister_mutex); |
140 | rc = snd_seq_oss_open(file, level); | 141 | rc = snd_seq_oss_open(file, level); |
141 | up(®ister_mutex); | 142 | mutex_unlock(®ister_mutex); |
142 | 143 | ||
143 | return rc; | 144 | return rc; |
144 | } | 145 | } |
@@ -153,9 +154,9 @@ odev_release(struct inode *inode, struct file *file) | |||
153 | 154 | ||
154 | snd_seq_oss_drain_write(dp); | 155 | snd_seq_oss_drain_write(dp); |
155 | 156 | ||
156 | down(®ister_mutex); | 157 | mutex_lock(®ister_mutex); |
157 | snd_seq_oss_release(dp); | 158 | snd_seq_oss_release(dp); |
158 | up(®ister_mutex); | 159 | mutex_unlock(®ister_mutex); |
159 | 160 | ||
160 | return 0; | 161 | return 0; |
161 | } | 162 | } |
@@ -224,13 +225,13 @@ register_device(void) | |||
224 | { | 225 | { |
225 | int rc; | 226 | int rc; |
226 | 227 | ||
227 | down(®ister_mutex); | 228 | mutex_lock(®ister_mutex); |
228 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, | 229 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, |
229 | NULL, 0, | 230 | NULL, 0, |
230 | &seq_oss_f_ops, NULL, | 231 | &seq_oss_f_ops, NULL, |
231 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { | 232 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { |
232 | snd_printk(KERN_ERR "can't register device seq\n"); | 233 | snd_printk(KERN_ERR "can't register device seq\n"); |
233 | up(®ister_mutex); | 234 | mutex_unlock(®ister_mutex); |
234 | return rc; | 235 | return rc; |
235 | } | 236 | } |
236 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, | 237 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, |
@@ -239,24 +240,24 @@ register_device(void) | |||
239 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { | 240 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { |
240 | snd_printk(KERN_ERR "can't register device music\n"); | 241 | snd_printk(KERN_ERR "can't register device music\n"); |
241 | snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); | 242 | snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); |
242 | up(®ister_mutex); | 243 | mutex_unlock(®ister_mutex); |
243 | return rc; | 244 | return rc; |
244 | } | 245 | } |
245 | debug_printk(("device registered\n")); | 246 | debug_printk(("device registered\n")); |
246 | up(®ister_mutex); | 247 | mutex_unlock(®ister_mutex); |
247 | return 0; | 248 | return 0; |
248 | } | 249 | } |
249 | 250 | ||
250 | static void | 251 | static void |
251 | unregister_device(void) | 252 | unregister_device(void) |
252 | { | 253 | { |
253 | down(®ister_mutex); | 254 | mutex_lock(®ister_mutex); |
254 | debug_printk(("device unregistered\n")); | 255 | debug_printk(("device unregistered\n")); |
255 | if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) | 256 | if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) |
256 | snd_printk(KERN_ERR "error unregister device music\n"); | 257 | snd_printk(KERN_ERR "error unregister device music\n"); |
257 | if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) | 258 | if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) |
258 | snd_printk(KERN_ERR "error unregister device seq\n"); | 259 | snd_printk(KERN_ERR "error unregister device seq\n"); |
259 | up(®ister_mutex); | 260 | mutex_unlock(®ister_mutex); |
260 | } | 261 | } |
261 | 262 | ||
262 | /* | 263 | /* |
@@ -270,12 +271,12 @@ static struct snd_info_entry *info_entry; | |||
270 | static void | 271 | static void |
271 | info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) | 272 | info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) |
272 | { | 273 | { |
273 | down(®ister_mutex); | 274 | mutex_lock(®ister_mutex); |
274 | snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); | 275 | snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); |
275 | snd_seq_oss_system_info_read(buf); | 276 | snd_seq_oss_system_info_read(buf); |
276 | snd_seq_oss_synth_info_read(buf); | 277 | snd_seq_oss_synth_info_read(buf); |
277 | snd_seq_oss_midi_info_read(buf); | 278 | snd_seq_oss_midi_info_read(buf); |
278 | up(®ister_mutex); | 279 | mutex_unlock(®ister_mutex); |
279 | } | 280 | } |
280 | 281 | ||
281 | 282 | ||
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index fd2032eae214..bb15d9ee8842 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -67,7 +67,7 @@ | |||
67 | #define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) | 67 | #define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) |
68 | 68 | ||
69 | static DEFINE_SPINLOCK(clients_lock); | 69 | static DEFINE_SPINLOCK(clients_lock); |
70 | static DECLARE_MUTEX(register_mutex); | 70 | static DEFINE_MUTEX(register_mutex); |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * client table | 73 | * client table |
@@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) | |||
237 | client->type = NO_CLIENT; | 237 | client->type = NO_CLIENT; |
238 | snd_use_lock_init(&client->use_lock); | 238 | snd_use_lock_init(&client->use_lock); |
239 | rwlock_init(&client->ports_lock); | 239 | rwlock_init(&client->ports_lock); |
240 | init_MUTEX(&client->ports_mutex); | 240 | mutex_init(&client->ports_mutex); |
241 | INIT_LIST_HEAD(&client->ports_list_head); | 241 | INIT_LIST_HEAD(&client->ports_list_head); |
242 | 242 | ||
243 | /* find free slot in the client table */ | 243 | /* find free slot in the client table */ |
@@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client) | |||
290 | 290 | ||
291 | static void seq_free_client(struct snd_seq_client * client) | 291 | static void seq_free_client(struct snd_seq_client * client) |
292 | { | 292 | { |
293 | down(®ister_mutex); | 293 | mutex_lock(®ister_mutex); |
294 | switch (client->type) { | 294 | switch (client->type) { |
295 | case NO_CLIENT: | 295 | case NO_CLIENT: |
296 | snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", | 296 | 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) | |||
306 | snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", | 306 | snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", |
307 | client->number, client->type); | 307 | client->number, client->type); |
308 | } | 308 | } |
309 | up(®ister_mutex); | 309 | mutex_unlock(®ister_mutex); |
310 | 310 | ||
311 | snd_seq_system_client_ev_client_exit(client->number); | 311 | snd_seq_system_client_ev_client_exit(client->number); |
312 | } | 312 | } |
@@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file) | |||
322 | struct snd_seq_client *client; | 322 | struct snd_seq_client *client; |
323 | struct snd_seq_user_client *user; | 323 | struct snd_seq_user_client *user; |
324 | 324 | ||
325 | if (down_interruptible(®ister_mutex)) | 325 | if (mutex_lock_interruptible(®ister_mutex)) |
326 | return -ERESTARTSYS; | 326 | return -ERESTARTSYS; |
327 | client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); | 327 | client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); |
328 | if (client == NULL) { | 328 | if (client == NULL) { |
329 | up(®ister_mutex); | 329 | mutex_unlock(®ister_mutex); |
330 | return -ENOMEM; /* failure code */ | 330 | return -ENOMEM; /* failure code */ |
331 | } | 331 | } |
332 | 332 | ||
@@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file) | |||
346 | if (user->fifo == NULL) { | 346 | if (user->fifo == NULL) { |
347 | seq_free_client1(client); | 347 | seq_free_client1(client); |
348 | kfree(client); | 348 | kfree(client); |
349 | up(®ister_mutex); | 349 | mutex_unlock(®ister_mutex); |
350 | return -ENOMEM; | 350 | return -ENOMEM; |
351 | } | 351 | } |
352 | } | 352 | } |
353 | 353 | ||
354 | usage_alloc(&client_usage, 1); | 354 | usage_alloc(&client_usage, 1); |
355 | client->type = USER_CLIENT; | 355 | client->type = USER_CLIENT; |
356 | up(®ister_mutex); | 356 | mutex_unlock(®ister_mutex); |
357 | 357 | ||
358 | c = client->number; | 358 | c = client->number; |
359 | file->private_data = client; | 359 | file->private_data = client; |
@@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, | |||
1743 | if (queue == NULL) | 1743 | if (queue == NULL) |
1744 | return -EINVAL; | 1744 | return -EINVAL; |
1745 | 1745 | ||
1746 | if (down_interruptible(&queue->timer_mutex)) { | 1746 | if (mutex_lock_interruptible(&queue->timer_mutex)) { |
1747 | queuefree(queue); | 1747 | queuefree(queue); |
1748 | return -ERESTARTSYS; | 1748 | return -ERESTARTSYS; |
1749 | } | 1749 | } |
@@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, | |||
1756 | timer.u.alsa.id = tmr->alsa_id; | 1756 | timer.u.alsa.id = tmr->alsa_id; |
1757 | timer.u.alsa.resolution = tmr->preferred_resolution; | 1757 | timer.u.alsa.resolution = tmr->preferred_resolution; |
1758 | } | 1758 | } |
1759 | up(&queue->timer_mutex); | 1759 | mutex_unlock(&queue->timer_mutex); |
1760 | queuefree(queue); | 1760 | queuefree(queue); |
1761 | 1761 | ||
1762 | if (copy_to_user(arg, &timer, sizeof(timer))) | 1762 | 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, | |||
1785 | q = queueptr(timer.queue); | 1785 | q = queueptr(timer.queue); |
1786 | if (q == NULL) | 1786 | if (q == NULL) |
1787 | return -ENXIO; | 1787 | return -ENXIO; |
1788 | if (down_interruptible(&q->timer_mutex)) { | 1788 | if (mutex_lock_interruptible(&q->timer_mutex)) { |
1789 | queuefree(q); | 1789 | queuefree(q); |
1790 | return -ERESTARTSYS; | 1790 | return -ERESTARTSYS; |
1791 | } | 1791 | } |
@@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, | |||
1797 | tmr->preferred_resolution = timer.u.alsa.resolution; | 1797 | tmr->preferred_resolution = timer.u.alsa.resolution; |
1798 | } | 1798 | } |
1799 | result = snd_seq_queue_timer_open(timer.queue); | 1799 | result = snd_seq_queue_timer_open(timer.queue); |
1800 | up(&q->timer_mutex); | 1800 | mutex_unlock(&q->timer_mutex); |
1801 | queuefree(q); | 1801 | queuefree(q); |
1802 | } else { | 1802 | } else { |
1803 | return -EPERM; | 1803 | return -EPERM; |
@@ -1866,8 +1866,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, | |||
1866 | info.output_pool = cptr->pool->size; | 1866 | info.output_pool = cptr->pool->size; |
1867 | info.output_room = cptr->pool->room; | 1867 | info.output_room = cptr->pool->room; |
1868 | info.output_free = info.output_pool; | 1868 | info.output_free = info.output_pool; |
1869 | if (cptr->pool) | 1869 | info.output_free = snd_seq_unused_cells(cptr->pool); |
1870 | info.output_free = snd_seq_unused_cells(cptr->pool); | ||
1871 | if (cptr->type == USER_CLIENT) { | 1870 | if (cptr->type == USER_CLIENT) { |
1872 | info.input_pool = cptr->data.user.fifo_pool_size; | 1871 | info.input_pool = cptr->data.user.fifo_pool_size; |
1873 | info.input_free = info.input_pool; | 1872 | info.input_free = info.input_pool; |
@@ -2230,7 +2229,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, | |||
2230 | if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) | 2229 | if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) |
2231 | return -EINVAL; | 2230 | return -EINVAL; |
2232 | 2231 | ||
2233 | if (down_interruptible(®ister_mutex)) | 2232 | if (mutex_lock_interruptible(®ister_mutex)) |
2234 | return -ERESTARTSYS; | 2233 | return -ERESTARTSYS; |
2235 | 2234 | ||
2236 | if (card) { | 2235 | if (card) { |
@@ -2243,7 +2242,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, | |||
2243 | /* empty write queue as default */ | 2242 | /* empty write queue as default */ |
2244 | client = seq_create_client1(client_index, 0); | 2243 | client = seq_create_client1(client_index, 0); |
2245 | if (client == NULL) { | 2244 | if (client == NULL) { |
2246 | up(®ister_mutex); | 2245 | mutex_unlock(®ister_mutex); |
2247 | return -EBUSY; /* failure code */ | 2246 | return -EBUSY; /* failure code */ |
2248 | } | 2247 | } |
2249 | usage_alloc(&client_usage, 1); | 2248 | usage_alloc(&client_usage, 1); |
@@ -2256,7 +2255,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, | |||
2256 | va_end(args); | 2255 | va_end(args); |
2257 | 2256 | ||
2258 | client->type = KERNEL_CLIENT; | 2257 | client->type = KERNEL_CLIENT; |
2259 | up(®ister_mutex); | 2258 | mutex_unlock(®ister_mutex); |
2260 | 2259 | ||
2261 | /* make others aware this new client */ | 2260 | /* make others aware this new client */ |
2262 | snd_seq_system_client_ev_client_start(client->number); | 2261 | 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, | |||
2464 | { | 2463 | { |
2465 | struct list_head *l; | 2464 | struct list_head *l; |
2466 | 2465 | ||
2467 | down(&client->ports_mutex); | 2466 | mutex_lock(&client->ports_mutex); |
2468 | list_for_each(l, &client->ports_list_head) { | 2467 | list_for_each(l, &client->ports_list_head) { |
2469 | struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); | 2468 | struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); |
2470 | snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", | 2469 | 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, | |||
2476 | snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); | 2475 | snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); |
2477 | snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); | 2476 | snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); |
2478 | } | 2477 | } |
2479 | up(&client->ports_mutex); | 2478 | mutex_unlock(&client->ports_mutex); |
2480 | } | 2479 | } |
2481 | 2480 | ||
2482 | 2481 | ||
@@ -2550,16 +2549,16 @@ int __init snd_sequencer_device_init(void) | |||
2550 | { | 2549 | { |
2551 | int err; | 2550 | int err; |
2552 | 2551 | ||
2553 | if (down_interruptible(®ister_mutex)) | 2552 | if (mutex_lock_interruptible(®ister_mutex)) |
2554 | return -ERESTARTSYS; | 2553 | return -ERESTARTSYS; |
2555 | 2554 | ||
2556 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, | 2555 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, |
2557 | &snd_seq_f_ops, NULL, "seq")) < 0) { | 2556 | &snd_seq_f_ops, NULL, "seq")) < 0) { |
2558 | up(®ister_mutex); | 2557 | mutex_unlock(®ister_mutex); |
2559 | return err; | 2558 | return err; |
2560 | } | 2559 | } |
2561 | 2560 | ||
2562 | up(®ister_mutex); | 2561 | mutex_unlock(®ister_mutex); |
2563 | 2562 | ||
2564 | return 0; | 2563 | return 0; |
2565 | } | 2564 | } |
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 450091ca153d..5e04e20e239f 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h | |||
@@ -58,7 +58,7 @@ struct snd_seq_client { | |||
58 | int num_ports; /* number of ports */ | 58 | int num_ports; /* number of ports */ |
59 | struct list_head ports_list_head; | 59 | struct list_head ports_list_head; |
60 | rwlock_t ports_lock; | 60 | rwlock_t ports_lock; |
61 | struct semaphore ports_mutex; | 61 | struct mutex ports_mutex; |
62 | int convert32; /* convert 32->64bit */ | 62 | int convert32; /* convert 32->64bit */ |
63 | 63 | ||
64 | /* output pool */ | 64 | /* output pool */ |
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 9ece443fba55..d9a3e5a18d6a 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <sound/initval.h> | 45 | #include <sound/initval.h> |
46 | #include <linux/kmod.h> | 46 | #include <linux/kmod.h> |
47 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
48 | #include <linux/mutex.h> | ||
48 | 49 | ||
49 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 50 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
50 | MODULE_DESCRIPTION("ALSA sequencer device management"); | 51 | MODULE_DESCRIPTION("ALSA sequencer device management"); |
@@ -69,7 +70,7 @@ struct ops_list { | |||
69 | struct list_head dev_list; /* list of devices */ | 70 | struct list_head dev_list; /* list of devices */ |
70 | int num_devices; /* number of associated devices */ | 71 | int num_devices; /* number of associated devices */ |
71 | int num_init_devices; /* number of initialized devices */ | 72 | int num_init_devices; /* number of initialized devices */ |
72 | struct semaphore reg_mutex; | 73 | struct mutex reg_mutex; |
73 | 74 | ||
74 | struct list_head list; /* next driver */ | 75 | struct list_head list; /* next driver */ |
75 | }; | 76 | }; |
@@ -77,7 +78,7 @@ struct ops_list { | |||
77 | 78 | ||
78 | static LIST_HEAD(opslist); | 79 | static LIST_HEAD(opslist); |
79 | static int num_ops; | 80 | static int num_ops; |
80 | static DECLARE_MUTEX(ops_mutex); | 81 | static DEFINE_MUTEX(ops_mutex); |
81 | #ifdef CONFIG_PROC_FS | 82 | #ifdef CONFIG_PROC_FS |
82 | static struct snd_info_entry *info_entry = NULL; | 83 | static struct snd_info_entry *info_entry = NULL; |
83 | #endif | 84 | #endif |
@@ -108,7 +109,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, | |||
108 | { | 109 | { |
109 | struct list_head *head; | 110 | struct list_head *head; |
110 | 111 | ||
111 | down(&ops_mutex); | 112 | mutex_lock(&ops_mutex); |
112 | list_for_each(head, &opslist) { | 113 | list_for_each(head, &opslist) { |
113 | struct ops_list *ops = list_entry(head, struct ops_list, list); | 114 | struct ops_list *ops = list_entry(head, struct ops_list, list); |
114 | snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", | 115 | 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, | |||
118 | ops->driver & DRIVER_LOCKED ? ",locked" : "", | 119 | ops->driver & DRIVER_LOCKED ? ",locked" : "", |
119 | ops->num_devices); | 120 | ops->num_devices); |
120 | } | 121 | } |
121 | up(&ops_mutex); | 122 | mutex_unlock(&ops_mutex); |
122 | } | 123 | } |
123 | #endif | 124 | #endif |
124 | 125 | ||
@@ -154,20 +155,20 @@ void snd_seq_device_load_drivers(void) | |||
154 | if (! current->fs->root) | 155 | if (! current->fs->root) |
155 | return; | 156 | return; |
156 | 157 | ||
157 | down(&ops_mutex); | 158 | mutex_lock(&ops_mutex); |
158 | list_for_each(head, &opslist) { | 159 | list_for_each(head, &opslist) { |
159 | struct ops_list *ops = list_entry(head, struct ops_list, list); | 160 | struct ops_list *ops = list_entry(head, struct ops_list, list); |
160 | if (! (ops->driver & DRIVER_LOADED) && | 161 | if (! (ops->driver & DRIVER_LOADED) && |
161 | ! (ops->driver & DRIVER_REQUESTED)) { | 162 | ! (ops->driver & DRIVER_REQUESTED)) { |
162 | ops->used++; | 163 | ops->used++; |
163 | up(&ops_mutex); | 164 | mutex_unlock(&ops_mutex); |
164 | ops->driver |= DRIVER_REQUESTED; | 165 | ops->driver |= DRIVER_REQUESTED; |
165 | request_module("snd-%s", ops->id); | 166 | request_module("snd-%s", ops->id); |
166 | down(&ops_mutex); | 167 | mutex_lock(&ops_mutex); |
167 | ops->used--; | 168 | ops->used--; |
168 | } | 169 | } |
169 | } | 170 | } |
170 | up(&ops_mutex); | 171 | mutex_unlock(&ops_mutex); |
171 | #endif | 172 | #endif |
172 | } | 173 | } |
173 | 174 | ||
@@ -214,10 +215,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, | |||
214 | dev->status = SNDRV_SEQ_DEVICE_FREE; | 215 | dev->status = SNDRV_SEQ_DEVICE_FREE; |
215 | 216 | ||
216 | /* add this device to the list */ | 217 | /* add this device to the list */ |
217 | down(&ops->reg_mutex); | 218 | mutex_lock(&ops->reg_mutex); |
218 | list_add_tail(&dev->list, &ops->dev_list); | 219 | list_add_tail(&dev->list, &ops->dev_list); |
219 | ops->num_devices++; | 220 | ops->num_devices++; |
220 | up(&ops->reg_mutex); | 221 | mutex_unlock(&ops->reg_mutex); |
221 | 222 | ||
222 | unlock_driver(ops); | 223 | unlock_driver(ops); |
223 | 224 | ||
@@ -246,10 +247,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev) | |||
246 | return -ENXIO; | 247 | return -ENXIO; |
247 | 248 | ||
248 | /* remove the device from the list */ | 249 | /* remove the device from the list */ |
249 | down(&ops->reg_mutex); | 250 | mutex_lock(&ops->reg_mutex); |
250 | list_del(&dev->list); | 251 | list_del(&dev->list); |
251 | ops->num_devices--; | 252 | ops->num_devices--; |
252 | up(&ops->reg_mutex); | 253 | mutex_unlock(&ops->reg_mutex); |
253 | 254 | ||
254 | free_device(dev, ops); | 255 | free_device(dev, ops); |
255 | if (dev->private_free) | 256 | if (dev->private_free) |
@@ -344,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, | |||
344 | return -EBUSY; | 345 | return -EBUSY; |
345 | } | 346 | } |
346 | 347 | ||
347 | down(&ops->reg_mutex); | 348 | mutex_lock(&ops->reg_mutex); |
348 | /* copy driver operators */ | 349 | /* copy driver operators */ |
349 | ops->ops = *entry; | 350 | ops->ops = *entry; |
350 | ops->driver |= DRIVER_LOADED; | 351 | ops->driver |= DRIVER_LOADED; |
@@ -355,7 +356,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, | |||
355 | struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); | 356 | struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); |
356 | init_device(dev, ops); | 357 | init_device(dev, ops); |
357 | } | 358 | } |
358 | up(&ops->reg_mutex); | 359 | mutex_unlock(&ops->reg_mutex); |
359 | 360 | ||
360 | unlock_driver(ops); | 361 | unlock_driver(ops); |
361 | snd_seq_autoload_unlock(); | 362 | snd_seq_autoload_unlock(); |
@@ -378,17 +379,17 @@ static struct ops_list * create_driver(char *id) | |||
378 | 379 | ||
379 | /* set up driver entry */ | 380 | /* set up driver entry */ |
380 | strlcpy(ops->id, id, sizeof(ops->id)); | 381 | strlcpy(ops->id, id, sizeof(ops->id)); |
381 | init_MUTEX(&ops->reg_mutex); | 382 | mutex_init(&ops->reg_mutex); |
382 | ops->driver = DRIVER_EMPTY; | 383 | ops->driver = DRIVER_EMPTY; |
383 | INIT_LIST_HEAD(&ops->dev_list); | 384 | INIT_LIST_HEAD(&ops->dev_list); |
384 | /* lock this instance */ | 385 | /* lock this instance */ |
385 | ops->used = 1; | 386 | ops->used = 1; |
386 | 387 | ||
387 | /* register driver entry */ | 388 | /* register driver entry */ |
388 | down(&ops_mutex); | 389 | mutex_lock(&ops_mutex); |
389 | list_add_tail(&ops->list, &opslist); | 390 | list_add_tail(&ops->list, &opslist); |
390 | num_ops++; | 391 | num_ops++; |
391 | up(&ops_mutex); | 392 | mutex_unlock(&ops_mutex); |
392 | 393 | ||
393 | return ops; | 394 | return ops; |
394 | } | 395 | } |
@@ -414,7 +415,7 @@ int snd_seq_device_unregister_driver(char *id) | |||
414 | } | 415 | } |
415 | 416 | ||
416 | /* close and release all devices associated with this driver */ | 417 | /* close and release all devices associated with this driver */ |
417 | down(&ops->reg_mutex); | 418 | mutex_lock(&ops->reg_mutex); |
418 | ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ | 419 | ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ |
419 | list_for_each(head, &ops->dev_list) { | 420 | list_for_each(head, &ops->dev_list) { |
420 | struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); | 421 | 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) | |||
425 | if (ops->num_init_devices > 0) | 426 | if (ops->num_init_devices > 0) |
426 | snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", | 427 | snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", |
427 | ops->num_init_devices); | 428 | ops->num_init_devices); |
428 | up(&ops->reg_mutex); | 429 | mutex_unlock(&ops->reg_mutex); |
429 | 430 | ||
430 | unlock_driver(ops); | 431 | unlock_driver(ops); |
431 | 432 | ||
@@ -443,7 +444,7 @@ static void remove_drivers(void) | |||
443 | { | 444 | { |
444 | struct list_head *head; | 445 | struct list_head *head; |
445 | 446 | ||
446 | down(&ops_mutex); | 447 | mutex_lock(&ops_mutex); |
447 | head = opslist.next; | 448 | head = opslist.next; |
448 | while (head != &opslist) { | 449 | while (head != &opslist) { |
449 | struct ops_list *ops = list_entry(head, struct ops_list, list); | 450 | struct ops_list *ops = list_entry(head, struct ops_list, list); |
@@ -456,7 +457,7 @@ static void remove_drivers(void) | |||
456 | } else | 457 | } else |
457 | head = head->next; | 458 | head = head->next; |
458 | } | 459 | } |
459 | up(&ops_mutex); | 460 | mutex_unlock(&ops_mutex); |
460 | } | 461 | } |
461 | 462 | ||
462 | /* | 463 | /* |
@@ -519,16 +520,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty) | |||
519 | { | 520 | { |
520 | struct list_head *head; | 521 | struct list_head *head; |
521 | 522 | ||
522 | down(&ops_mutex); | 523 | mutex_lock(&ops_mutex); |
523 | list_for_each(head, &opslist) { | 524 | list_for_each(head, &opslist) { |
524 | struct ops_list *ops = list_entry(head, struct ops_list, list); | 525 | struct ops_list *ops = list_entry(head, struct ops_list, list); |
525 | if (strcmp(ops->id, id) == 0) { | 526 | if (strcmp(ops->id, id) == 0) { |
526 | ops->used++; | 527 | ops->used++; |
527 | up(&ops_mutex); | 528 | mutex_unlock(&ops_mutex); |
528 | return ops; | 529 | return ops; |
529 | } | 530 | } |
530 | } | 531 | } |
531 | up(&ops_mutex); | 532 | mutex_unlock(&ops_mutex); |
532 | if (create_if_empty) | 533 | if (create_if_empty) |
533 | return create_driver(id); | 534 | return create_driver(id); |
534 | return NULL; | 535 | return NULL; |
@@ -536,9 +537,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty) | |||
536 | 537 | ||
537 | static void unlock_driver(struct ops_list *ops) | 538 | static void unlock_driver(struct ops_list *ops) |
538 | { | 539 | { |
539 | down(&ops_mutex); | 540 | mutex_lock(&ops_mutex); |
540 | ops->used--; | 541 | ops->used--; |
541 | up(&ops_mutex); | 542 | mutex_unlock(&ops_mutex); |
542 | } | 543 | } |
543 | 544 | ||
544 | 545 | ||
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c index 487452063965..f30d171b6d96 100644 --- a/sound/core/seq/seq_instr.c +++ b/sound/core/seq/seq_instr.c | |||
@@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list) | |||
36 | if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { | 36 | if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { |
37 | spin_lock_irqsave(&list->ops_lock, list->ops_flags); | 37 | spin_lock_irqsave(&list->ops_lock, list->ops_flags); |
38 | } else { | 38 | } else { |
39 | down(&list->ops_mutex); | 39 | mutex_lock(&list->ops_mutex); |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
@@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list) | |||
45 | if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { | 45 | if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { |
46 | spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); | 46 | spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); |
47 | } else { | 47 | } else { |
48 | up(&list->ops_mutex); | 48 | mutex_unlock(&list->ops_mutex); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
@@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void) | |||
82 | return NULL; | 82 | return NULL; |
83 | spin_lock_init(&list->lock); | 83 | spin_lock_init(&list->lock); |
84 | spin_lock_init(&list->ops_lock); | 84 | spin_lock_init(&list->ops_lock); |
85 | init_MUTEX(&list->ops_mutex); | 85 | mutex_init(&list->ops_mutex); |
86 | list->owner = -1; | 86 | list->owner = -1; |
87 | return list; | 87 | return list; |
88 | } | 88 | } |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index ce0df86157de..9caa1372bece 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -32,7 +32,7 @@ Possible options for midisynth module: | |||
32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
35 | #include <asm/semaphore.h> | 35 | #include <linux/mutex.h> |
36 | #include <sound/core.h> | 36 | #include <sound/core.h> |
37 | #include <sound/rawmidi.h> | 37 | #include <sound/rawmidi.h> |
38 | #include <sound/seq_kernel.h> | 38 | #include <sound/seq_kernel.h> |
@@ -70,7 +70,7 @@ struct seq_midisynth_client { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct seq_midisynth_client *synths[SNDRV_CARDS]; | 72 | static struct seq_midisynth_client *synths[SNDRV_CARDS]; |
73 | static DECLARE_MUTEX(register_mutex); | 73 | static DEFINE_MUTEX(register_mutex); |
74 | 74 | ||
75 | /* handle rawmidi input event (MIDI v1.0 stream) */ | 75 | /* handle rawmidi input event (MIDI v1.0 stream) */ |
76 | static void snd_midi_input_event(struct snd_rawmidi_substream *substream) | 76 | 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) | |||
308 | if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) | 308 | if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) |
309 | ports = 256 / SNDRV_RAWMIDI_DEVICES; | 309 | ports = 256 / SNDRV_RAWMIDI_DEVICES; |
310 | 310 | ||
311 | down(®ister_mutex); | 311 | mutex_lock(®ister_mutex); |
312 | client = synths[card->number]; | 312 | client = synths[card->number]; |
313 | if (client == NULL) { | 313 | if (client == NULL) { |
314 | newclient = 1; | 314 | newclient = 1; |
315 | client = kzalloc(sizeof(*client), GFP_KERNEL); | 315 | client = kzalloc(sizeof(*client), GFP_KERNEL); |
316 | if (client == NULL) { | 316 | if (client == NULL) { |
317 | up(®ister_mutex); | 317 | mutex_unlock(®ister_mutex); |
318 | kfree(info); | 318 | kfree(info); |
319 | return -ENOMEM; | 319 | return -ENOMEM; |
320 | } | 320 | } |
@@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
324 | (const char *)info->name : "External MIDI"); | 324 | (const char *)info->name : "External MIDI"); |
325 | if (client->seq_client < 0) { | 325 | if (client->seq_client < 0) { |
326 | kfree(client); | 326 | kfree(client); |
327 | up(®ister_mutex); | 327 | mutex_unlock(®ister_mutex); |
328 | kfree(info); | 328 | kfree(info); |
329 | return -ENOMEM; | 329 | return -ENOMEM; |
330 | } | 330 | } |
@@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
397 | client->num_ports++; | 397 | client->num_ports++; |
398 | if (newclient) | 398 | if (newclient) |
399 | synths[card->number] = client; | 399 | synths[card->number] = client; |
400 | up(®ister_mutex); | 400 | mutex_unlock(®ister_mutex); |
401 | kfree(info); | 401 | kfree(info); |
402 | kfree(port); | 402 | kfree(port); |
403 | return 0; /* success */ | 403 | return 0; /* success */ |
@@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
414 | } | 414 | } |
415 | kfree(info); | 415 | kfree(info); |
416 | kfree(port); | 416 | kfree(port); |
417 | up(®ister_mutex); | 417 | mutex_unlock(®ister_mutex); |
418 | return -ENOMEM; | 418 | return -ENOMEM; |
419 | } | 419 | } |
420 | 420 | ||
@@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) | |||
427 | struct snd_card *card = dev->card; | 427 | struct snd_card *card = dev->card; |
428 | int device = dev->device, p, ports; | 428 | int device = dev->device, p, ports; |
429 | 429 | ||
430 | down(®ister_mutex); | 430 | mutex_lock(®ister_mutex); |
431 | client = synths[card->number]; | 431 | client = synths[card->number]; |
432 | if (client == NULL || client->ports[device] == NULL) { | 432 | if (client == NULL || client->ports[device] == NULL) { |
433 | up(®ister_mutex); | 433 | mutex_unlock(®ister_mutex); |
434 | return -ENODEV; | 434 | return -ENODEV; |
435 | } | 435 | } |
436 | ports = client->ports_per_device[device]; | 436 | ports = client->ports_per_device[device]; |
@@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) | |||
446 | synths[card->number] = NULL; | 446 | synths[card->number] = NULL; |
447 | kfree(client); | 447 | kfree(client); |
448 | } | 448 | } |
449 | up(®ister_mutex); | 449 | mutex_unlock(®ister_mutex); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 2b384fd7967f..41e078c938cd 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c | |||
@@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, | |||
159 | port_subs_info_init(&new_port->c_dest); | 159 | port_subs_info_init(&new_port->c_dest); |
160 | 160 | ||
161 | num = port >= 0 ? port : 0; | 161 | num = port >= 0 ? port : 0; |
162 | down(&client->ports_mutex); | 162 | mutex_lock(&client->ports_mutex); |
163 | write_lock_irqsave(&client->ports_lock, flags); | 163 | write_lock_irqsave(&client->ports_lock, flags); |
164 | list_for_each(l, &client->ports_list_head) { | 164 | list_for_each(l, &client->ports_list_head) { |
165 | struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); | 165 | 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, | |||
173 | client->num_ports++; | 173 | client->num_ports++; |
174 | new_port->addr.port = num; /* store the port number in the port */ | 174 | new_port->addr.port = num; /* store the port number in the port */ |
175 | write_unlock_irqrestore(&client->ports_lock, flags); | 175 | write_unlock_irqrestore(&client->ports_lock, flags); |
176 | up(&client->ports_mutex); | 176 | mutex_unlock(&client->ports_mutex); |
177 | sprintf(new_port->name, "port-%d", num); | 177 | sprintf(new_port->name, "port-%d", num); |
178 | 178 | ||
179 | return new_port; | 179 | return new_port; |
@@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) | |||
292 | struct list_head *l; | 292 | struct list_head *l; |
293 | struct snd_seq_client_port *found = NULL; | 293 | struct snd_seq_client_port *found = NULL; |
294 | 294 | ||
295 | down(&client->ports_mutex); | 295 | mutex_lock(&client->ports_mutex); |
296 | write_lock_irqsave(&client->ports_lock, flags); | 296 | write_lock_irqsave(&client->ports_lock, flags); |
297 | list_for_each(l, &client->ports_list_head) { | 297 | list_for_each(l, &client->ports_list_head) { |
298 | struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); | 298 | 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) | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | write_unlock_irqrestore(&client->ports_lock, flags); | 307 | write_unlock_irqrestore(&client->ports_lock, flags); |
308 | up(&client->ports_mutex); | 308 | mutex_unlock(&client->ports_mutex); |
309 | if (found) | 309 | if (found) |
310 | return port_delete(client, found); | 310 | return port_delete(client, found); |
311 | else | 311 | else |
@@ -321,7 +321,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) | |||
321 | /* move the port list to deleted_list, and | 321 | /* move the port list to deleted_list, and |
322 | * clear the port list in the client data. | 322 | * clear the port list in the client data. |
323 | */ | 323 | */ |
324 | down(&client->ports_mutex); | 324 | mutex_lock(&client->ports_mutex); |
325 | write_lock_irqsave(&client->ports_lock, flags); | 325 | write_lock_irqsave(&client->ports_lock, flags); |
326 | if (! list_empty(&client->ports_list_head)) { | 326 | if (! list_empty(&client->ports_list_head)) { |
327 | __list_add(&deleted_list, | 327 | __list_add(&deleted_list, |
@@ -341,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) | |||
341 | snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); | 341 | snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); |
342 | port_delete(client, port); | 342 | port_delete(client, port); |
343 | } | 343 | } |
344 | up(&client->ports_mutex); | 344 | mutex_unlock(&client->ports_mutex); |
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 9cf20f045542..9b87bb0c7f33 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c | |||
@@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked) | |||
119 | 119 | ||
120 | spin_lock_init(&q->owner_lock); | 120 | spin_lock_init(&q->owner_lock); |
121 | spin_lock_init(&q->check_lock); | 121 | spin_lock_init(&q->check_lock); |
122 | init_MUTEX(&q->timer_mutex); | 122 | mutex_init(&q->timer_mutex); |
123 | snd_use_lock_init(&q->use_lock); | 123 | snd_use_lock_init(&q->use_lock); |
124 | q->queue = -1; | 124 | q->queue = -1; |
125 | 125 | ||
@@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use) | |||
516 | queue = queueptr(queueid); | 516 | queue = queueptr(queueid); |
517 | if (queue == NULL) | 517 | if (queue == NULL) |
518 | return -EINVAL; | 518 | return -EINVAL; |
519 | down(&queue->timer_mutex); | 519 | mutex_lock(&queue->timer_mutex); |
520 | if (use) { | 520 | if (use) { |
521 | if (!test_and_set_bit(client, queue->clients_bitmap)) | 521 | if (!test_and_set_bit(client, queue->clients_bitmap)) |
522 | queue->clients++; | 522 | queue->clients++; |
@@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use) | |||
531 | } else { | 531 | } else { |
532 | snd_seq_timer_close(queue); | 532 | snd_seq_timer_close(queue); |
533 | } | 533 | } |
534 | up(&queue->timer_mutex); | 534 | mutex_unlock(&queue->timer_mutex); |
535 | queuefree(queue); | 535 | queuefree(queue); |
536 | return 0; | 536 | return 0; |
537 | } | 537 | } |
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 888438599387..30c8111477f6 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h | |||
@@ -54,7 +54,7 @@ struct snd_seq_queue { | |||
54 | /* clients which uses this queue (bitmap) */ | 54 | /* clients which uses this queue (bitmap) */ |
55 | DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); | 55 | DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); |
56 | unsigned int clients; /* users of this queue */ | 56 | unsigned int clients; /* users of this queue */ |
57 | struct semaphore timer_mutex; | 57 | struct mutex timer_mutex; |
58 | 58 | ||
59 | snd_use_lock_t use_lock; | 59 | snd_use_lock_t use_lock; |
60 | }; | 60 | }; |
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 14fd1a608e14..f4edec603b8f 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c | |||
@@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, | |||
167 | return; /* ignored */ | 167 | return; /* ignored */ |
168 | } | 168 | } |
169 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { | 169 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { |
170 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) | 170 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) |
171 | return; | 171 | return; |
172 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; | 172 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; |
173 | } | 173 | } |
@@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, | |||
186 | pbuf += res; | 186 | pbuf += res; |
187 | count -= res; | 187 | count -= res; |
188 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { | 188 | if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { |
189 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) | 189 | if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) |
190 | return; | 190 | return; |
191 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; | 191 | vmidi->event.type = SNDRV_SEQ_EVENT_NONE; |
192 | } | 192 | } |
diff --git a/sound/core/sound.c b/sound/core/sound.c index a8eda02bcf1c..4d28e5212611 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <sound/initval.h> | 33 | #include <sound/initval.h> |
34 | #include <linux/kmod.h> | 34 | #include <linux/kmod.h> |
35 | #include <linux/devfs_fs_kernel.h> | 35 | #include <linux/devfs_fs_kernel.h> |
36 | #include <linux/mutex.h> | ||
36 | 37 | ||
37 | #define SNDRV_OS_MINORS 256 | 38 | #define SNDRV_OS_MINORS 256 |
38 | 39 | ||
@@ -61,7 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); | |||
61 | int snd_ecards_limit; | 62 | int snd_ecards_limit; |
62 | 63 | ||
63 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; | 64 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
64 | static DECLARE_MUTEX(sound_mutex); | 65 | static DEFINE_MUTEX(sound_mutex); |
65 | 66 | ||
66 | extern struct class *sound_class; | 67 | extern struct class *sound_class; |
67 | 68 | ||
@@ -120,15 +121,15 @@ void *snd_lookup_minor_data(unsigned int minor, int type) | |||
120 | struct snd_minor *mreg; | 121 | struct snd_minor *mreg; |
121 | void *private_data; | 122 | void *private_data; |
122 | 123 | ||
123 | if (minor > ARRAY_SIZE(snd_minors)) | 124 | if (minor >= ARRAY_SIZE(snd_minors)) |
124 | return NULL; | 125 | return NULL; |
125 | down(&sound_mutex); | 126 | mutex_lock(&sound_mutex); |
126 | mreg = snd_minors[minor]; | 127 | mreg = snd_minors[minor]; |
127 | if (mreg && mreg->type == type) | 128 | if (mreg && mreg->type == type) |
128 | private_data = mreg->private_data; | 129 | private_data = mreg->private_data; |
129 | else | 130 | else |
130 | private_data = NULL; | 131 | private_data = NULL; |
131 | up(&sound_mutex); | 132 | mutex_unlock(&sound_mutex); |
132 | return private_data; | 133 | return private_data; |
133 | } | 134 | } |
134 | 135 | ||
@@ -139,7 +140,7 @@ static int snd_open(struct inode *inode, struct file *file) | |||
139 | struct file_operations *old_fops; | 140 | struct file_operations *old_fops; |
140 | int err = 0; | 141 | int err = 0; |
141 | 142 | ||
142 | if (minor > ARRAY_SIZE(snd_minors)) | 143 | if (minor >= ARRAY_SIZE(snd_minors)) |
143 | return -ENODEV; | 144 | return -ENODEV; |
144 | mptr = snd_minors[minor]; | 145 | mptr = snd_minors[minor]; |
145 | if (mptr == NULL) { | 146 | if (mptr == NULL) { |
@@ -256,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
256 | preg->f_ops = f_ops; | 257 | preg->f_ops = f_ops; |
257 | preg->private_data = private_data; | 258 | preg->private_data = private_data; |
258 | strcpy(preg->name, name); | 259 | strcpy(preg->name, name); |
259 | down(&sound_mutex); | 260 | mutex_lock(&sound_mutex); |
260 | #ifdef CONFIG_SND_DYNAMIC_MINORS | 261 | #ifdef CONFIG_SND_DYNAMIC_MINORS |
261 | minor = snd_find_free_minor(); | 262 | minor = snd_find_free_minor(); |
262 | #else | 263 | #else |
@@ -265,7 +266,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
265 | minor = -EBUSY; | 266 | minor = -EBUSY; |
266 | #endif | 267 | #endif |
267 | if (minor < 0) { | 268 | if (minor < 0) { |
268 | up(&sound_mutex); | 269 | mutex_unlock(&sound_mutex); |
269 | kfree(preg); | 270 | kfree(preg); |
270 | return minor; | 271 | return minor; |
271 | } | 272 | } |
@@ -276,7 +277,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
276 | device = card->dev; | 277 | device = card->dev; |
277 | class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); | 278 | class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); |
278 | 279 | ||
279 | up(&sound_mutex); | 280 | mutex_unlock(&sound_mutex); |
280 | return 0; | 281 | return 0; |
281 | } | 282 | } |
282 | 283 | ||
@@ -297,7 +298,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
297 | struct snd_minor *mptr; | 298 | struct snd_minor *mptr; |
298 | 299 | ||
299 | cardnum = card ? card->number : -1; | 300 | cardnum = card ? card->number : -1; |
300 | down(&sound_mutex); | 301 | mutex_lock(&sound_mutex); |
301 | for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) | 302 | for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) |
302 | if ((mptr = snd_minors[minor]) != NULL && | 303 | if ((mptr = snd_minors[minor]) != NULL && |
303 | mptr->type == type && | 304 | mptr->type == type && |
@@ -305,7 +306,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
305 | mptr->device == dev) | 306 | mptr->device == dev) |
306 | break; | 307 | break; |
307 | if (minor == ARRAY_SIZE(snd_minors)) { | 308 | if (minor == ARRAY_SIZE(snd_minors)) { |
308 | up(&sound_mutex); | 309 | mutex_unlock(&sound_mutex); |
309 | return -EINVAL; | 310 | return -EINVAL; |
310 | } | 311 | } |
311 | 312 | ||
@@ -315,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
315 | class_device_destroy(sound_class, MKDEV(major, minor)); | 316 | class_device_destroy(sound_class, MKDEV(major, minor)); |
316 | 317 | ||
317 | snd_minors[minor] = NULL; | 318 | snd_minors[minor] = NULL; |
318 | up(&sound_mutex); | 319 | mutex_unlock(&sound_mutex); |
319 | kfree(mptr); | 320 | kfree(mptr); |
320 | return 0; | 321 | return 0; |
321 | } | 322 | } |
@@ -354,7 +355,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu | |||
354 | int minor; | 355 | int minor; |
355 | struct snd_minor *mptr; | 356 | struct snd_minor *mptr; |
356 | 357 | ||
357 | down(&sound_mutex); | 358 | mutex_lock(&sound_mutex); |
358 | for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { | 359 | for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { |
359 | if (!(mptr = snd_minors[minor])) | 360 | if (!(mptr = snd_minors[minor])) |
360 | continue; | 361 | continue; |
@@ -371,7 +372,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu | |||
371 | snd_iprintf(buffer, "%3i: : %s\n", minor, | 372 | snd_iprintf(buffer, "%3i: : %s\n", minor, |
372 | snd_device_type_name(mptr->type)); | 373 | snd_device_type_name(mptr->type)); |
373 | } | 374 | } |
374 | up(&sound_mutex); | 375 | mutex_unlock(&sound_mutex); |
375 | } | 376 | } |
376 | 377 | ||
377 | int __init snd_minor_info_init(void) | 378 | int __init snd_minor_info_init(void) |
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index d0be32b517c1..4023d3b406de 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
@@ -34,26 +34,27 @@ | |||
34 | #include <sound/minors.h> | 34 | #include <sound/minors.h> |
35 | #include <sound/info.h> | 35 | #include <sound/info.h> |
36 | #include <linux/sound.h> | 36 | #include <linux/sound.h> |
37 | #include <linux/mutex.h> | ||
37 | 38 | ||
38 | #define SNDRV_OSS_MINORS 128 | 39 | #define SNDRV_OSS_MINORS 128 |
39 | 40 | ||
40 | static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; | 41 | static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; |
41 | static DECLARE_MUTEX(sound_oss_mutex); | 42 | static DEFINE_MUTEX(sound_oss_mutex); |
42 | 43 | ||
43 | void *snd_lookup_oss_minor_data(unsigned int minor, int type) | 44 | void *snd_lookup_oss_minor_data(unsigned int minor, int type) |
44 | { | 45 | { |
45 | struct snd_minor *mreg; | 46 | struct snd_minor *mreg; |
46 | void *private_data; | 47 | void *private_data; |
47 | 48 | ||
48 | if (minor > ARRAY_SIZE(snd_oss_minors)) | 49 | if (minor >= ARRAY_SIZE(snd_oss_minors)) |
49 | return NULL; | 50 | return NULL; |
50 | down(&sound_oss_mutex); | 51 | mutex_lock(&sound_oss_mutex); |
51 | mreg = snd_oss_minors[minor]; | 52 | mreg = snd_oss_minors[minor]; |
52 | if (mreg && mreg->type == type) | 53 | if (mreg && mreg->type == type) |
53 | private_data = mreg->private_data; | 54 | private_data = mreg->private_data; |
54 | else | 55 | else |
55 | private_data = NULL; | 56 | private_data = NULL; |
56 | up(&sound_oss_mutex); | 57 | mutex_unlock(&sound_oss_mutex); |
57 | return private_data; | 58 | return private_data; |
58 | } | 59 | } |
59 | 60 | ||
@@ -117,7 +118,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
117 | preg->device = dev; | 118 | preg->device = dev; |
118 | preg->f_ops = f_ops; | 119 | preg->f_ops = f_ops; |
119 | preg->private_data = private_data; | 120 | preg->private_data = private_data; |
120 | down(&sound_oss_mutex); | 121 | mutex_lock(&sound_oss_mutex); |
121 | snd_oss_minors[minor] = preg; | 122 | snd_oss_minors[minor] = preg; |
122 | minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); | 123 | minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); |
123 | switch (minor_unit) { | 124 | switch (minor_unit) { |
@@ -143,7 +144,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
143 | goto __end; | 144 | goto __end; |
144 | snd_oss_minors[track2] = preg; | 145 | snd_oss_minors[track2] = preg; |
145 | } | 146 | } |
146 | up(&sound_oss_mutex); | 147 | mutex_unlock(&sound_oss_mutex); |
147 | return 0; | 148 | return 0; |
148 | 149 | ||
149 | __end: | 150 | __end: |
@@ -152,7 +153,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
152 | if (register1 >= 0) | 153 | if (register1 >= 0) |
153 | unregister_sound_special(register1); | 154 | unregister_sound_special(register1); |
154 | snd_oss_minors[minor] = NULL; | 155 | snd_oss_minors[minor] = NULL; |
155 | up(&sound_oss_mutex); | 156 | mutex_unlock(&sound_oss_mutex); |
156 | kfree(preg); | 157 | kfree(preg); |
157 | return -EBUSY; | 158 | return -EBUSY; |
158 | } | 159 | } |
@@ -168,10 +169,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | |||
168 | return 0; | 169 | return 0; |
169 | if (minor < 0) | 170 | if (minor < 0) |
170 | return minor; | 171 | return minor; |
171 | down(&sound_oss_mutex); | 172 | mutex_lock(&sound_oss_mutex); |
172 | mptr = snd_oss_minors[minor]; | 173 | mptr = snd_oss_minors[minor]; |
173 | if (mptr == NULL) { | 174 | if (mptr == NULL) { |
174 | up(&sound_oss_mutex); | 175 | mutex_unlock(&sound_oss_mutex); |
175 | return -ENOENT; | 176 | return -ENOENT; |
176 | } | 177 | } |
177 | unregister_sound_special(minor); | 178 | unregister_sound_special(minor); |
@@ -191,7 +192,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | |||
191 | snd_oss_minors[track2] = NULL; | 192 | snd_oss_minors[track2] = NULL; |
192 | } | 193 | } |
193 | snd_oss_minors[minor] = NULL; | 194 | snd_oss_minors[minor] = NULL; |
194 | up(&sound_oss_mutex); | 195 | mutex_unlock(&sound_oss_mutex); |
195 | kfree(mptr); | 196 | kfree(mptr); |
196 | return 0; | 197 | return 0; |
197 | } | 198 | } |
@@ -229,7 +230,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, | |||
229 | int minor; | 230 | int minor; |
230 | struct snd_minor *mptr; | 231 | struct snd_minor *mptr; |
231 | 232 | ||
232 | down(&sound_oss_mutex); | 233 | mutex_lock(&sound_oss_mutex); |
233 | for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { | 234 | for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { |
234 | if (!(mptr = snd_oss_minors[minor])) | 235 | if (!(mptr = snd_oss_minors[minor])) |
235 | continue; | 236 | continue; |
@@ -241,7 +242,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, | |||
241 | snd_iprintf(buffer, "%3i: : %s\n", minor, | 242 | snd_iprintf(buffer, "%3i: : %s\n", minor, |
242 | snd_oss_device_type_name(mptr->type)); | 243 | snd_oss_device_type_name(mptr->type)); |
243 | } | 244 | } |
244 | up(&sound_oss_mutex); | 245 | mutex_unlock(&sound_oss_mutex); |
245 | } | 246 | } |
246 | 247 | ||
247 | 248 | ||
diff --git a/sound/core/timer.c b/sound/core/timer.c index 2425b971b240..cdeeb639b675 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/smp_lock.h> | 25 | #include <linux/smp_lock.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
29 | #include <linux/string.h> | 30 | #include <linux/string.h> |
30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
@@ -70,7 +71,7 @@ struct snd_timer_user { | |||
70 | struct timespec tstamp; /* trigger tstamp */ | 71 | struct timespec tstamp; /* trigger tstamp */ |
71 | wait_queue_head_t qchange_sleep; | 72 | wait_queue_head_t qchange_sleep; |
72 | struct fasync_struct *fasync; | 73 | struct fasync_struct *fasync; |
73 | struct semaphore tread_sem; | 74 | struct mutex tread_sem; |
74 | }; | 75 | }; |
75 | 76 | ||
76 | /* list of timers */ | 77 | /* list of timers */ |
@@ -82,7 +83,7 @@ static LIST_HEAD(snd_timer_slave_list); | |||
82 | /* lock for slave active lists */ | 83 | /* lock for slave active lists */ |
83 | static DEFINE_SPINLOCK(slave_active_lock); | 84 | static DEFINE_SPINLOCK(slave_active_lock); |
84 | 85 | ||
85 | static DECLARE_MUTEX(register_mutex); | 86 | static DEFINE_MUTEX(register_mutex); |
86 | 87 | ||
87 | static int snd_timer_free(struct snd_timer *timer); | 88 | static int snd_timer_free(struct snd_timer *timer); |
88 | static int snd_timer_dev_free(struct snd_device *device); | 89 | static int snd_timer_dev_free(struct snd_device *device); |
@@ -252,10 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti, | |||
252 | snd_printd("invalid slave class %i\n", tid->dev_sclass); | 253 | snd_printd("invalid slave class %i\n", tid->dev_sclass); |
253 | return -EINVAL; | 254 | return -EINVAL; |
254 | } | 255 | } |
255 | down(®ister_mutex); | 256 | mutex_lock(®ister_mutex); |
256 | timeri = snd_timer_instance_new(owner, NULL); | 257 | timeri = snd_timer_instance_new(owner, NULL); |
257 | if (!timeri) { | 258 | if (!timeri) { |
258 | up(®ister_mutex); | 259 | mutex_unlock(®ister_mutex); |
259 | return -ENOMEM; | 260 | return -ENOMEM; |
260 | } | 261 | } |
261 | timeri->slave_class = tid->dev_sclass; | 262 | timeri->slave_class = tid->dev_sclass; |
@@ -263,37 +264,37 @@ int snd_timer_open(struct snd_timer_instance **ti, | |||
263 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; | 264 | timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; |
264 | list_add_tail(&timeri->open_list, &snd_timer_slave_list); | 265 | list_add_tail(&timeri->open_list, &snd_timer_slave_list); |
265 | snd_timer_check_slave(timeri); | 266 | snd_timer_check_slave(timeri); |
266 | up(®ister_mutex); | 267 | mutex_unlock(®ister_mutex); |
267 | *ti = timeri; | 268 | *ti = timeri; |
268 | return 0; | 269 | return 0; |
269 | } | 270 | } |
270 | 271 | ||
271 | /* open a master instance */ | 272 | /* open a master instance */ |
272 | down(®ister_mutex); | 273 | mutex_lock(®ister_mutex); |
273 | timer = snd_timer_find(tid); | 274 | timer = snd_timer_find(tid); |
274 | #ifdef CONFIG_KMOD | 275 | #ifdef CONFIG_KMOD |
275 | if (timer == NULL) { | 276 | if (timer == NULL) { |
276 | up(®ister_mutex); | 277 | mutex_unlock(®ister_mutex); |
277 | snd_timer_request(tid); | 278 | snd_timer_request(tid); |
278 | down(®ister_mutex); | 279 | mutex_lock(®ister_mutex); |
279 | timer = snd_timer_find(tid); | 280 | timer = snd_timer_find(tid); |
280 | } | 281 | } |
281 | #endif | 282 | #endif |
282 | if (!timer) { | 283 | if (!timer) { |
283 | up(®ister_mutex); | 284 | mutex_unlock(®ister_mutex); |
284 | return -ENODEV; | 285 | return -ENODEV; |
285 | } | 286 | } |
286 | if (!list_empty(&timer->open_list_head)) { | 287 | if (!list_empty(&timer->open_list_head)) { |
287 | timeri = list_entry(timer->open_list_head.next, | 288 | timeri = list_entry(timer->open_list_head.next, |
288 | struct snd_timer_instance, open_list); | 289 | struct snd_timer_instance, open_list); |
289 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { | 290 | if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { |
290 | up(®ister_mutex); | 291 | mutex_unlock(®ister_mutex); |
291 | return -EBUSY; | 292 | return -EBUSY; |
292 | } | 293 | } |
293 | } | 294 | } |
294 | timeri = snd_timer_instance_new(owner, timer); | 295 | timeri = snd_timer_instance_new(owner, timer); |
295 | if (!timeri) { | 296 | if (!timeri) { |
296 | up(®ister_mutex); | 297 | mutex_unlock(®ister_mutex); |
297 | return -ENOMEM; | 298 | return -ENOMEM; |
298 | } | 299 | } |
299 | timeri->slave_class = tid->dev_sclass; | 300 | timeri->slave_class = tid->dev_sclass; |
@@ -302,7 +303,7 @@ int snd_timer_open(struct snd_timer_instance **ti, | |||
302 | timer->hw.open(timer); | 303 | timer->hw.open(timer); |
303 | list_add_tail(&timeri->open_list, &timer->open_list_head); | 304 | list_add_tail(&timeri->open_list, &timer->open_list_head); |
304 | snd_timer_check_master(timeri); | 305 | snd_timer_check_master(timeri); |
305 | up(®ister_mutex); | 306 | mutex_unlock(®ister_mutex); |
306 | *ti = timeri; | 307 | *ti = timeri; |
307 | return 0; | 308 | return 0; |
308 | } | 309 | } |
@@ -333,9 +334,9 @@ int snd_timer_close(struct snd_timer_instance *timeri) | |||
333 | spin_lock_irq(&slave_active_lock); | 334 | spin_lock_irq(&slave_active_lock); |
334 | } | 335 | } |
335 | spin_unlock_irq(&slave_active_lock); | 336 | spin_unlock_irq(&slave_active_lock); |
336 | down(®ister_mutex); | 337 | mutex_lock(®ister_mutex); |
337 | list_del(&timeri->open_list); | 338 | list_del(&timeri->open_list); |
338 | up(®ister_mutex); | 339 | mutex_unlock(®ister_mutex); |
339 | } else { | 340 | } else { |
340 | timer = timeri->timer; | 341 | timer = timeri->timer; |
341 | /* wait, until the active callback is finished */ | 342 | /* wait, until the active callback is finished */ |
@@ -346,7 +347,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) | |||
346 | spin_lock_irq(&timer->lock); | 347 | spin_lock_irq(&timer->lock); |
347 | } | 348 | } |
348 | spin_unlock_irq(&timer->lock); | 349 | spin_unlock_irq(&timer->lock); |
349 | down(®ister_mutex); | 350 | mutex_lock(®ister_mutex); |
350 | list_del(&timeri->open_list); | 351 | list_del(&timeri->open_list); |
351 | if (timer && list_empty(&timer->open_list_head) && | 352 | if (timer && list_empty(&timer->open_list_head) && |
352 | timer->hw.close) | 353 | timer->hw.close) |
@@ -362,7 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) | |||
362 | slave->timer = NULL; | 363 | slave->timer = NULL; |
363 | spin_unlock_irq(&slave_active_lock); | 364 | spin_unlock_irq(&slave_active_lock); |
364 | } | 365 | } |
365 | up(®ister_mutex); | 366 | mutex_unlock(®ister_mutex); |
366 | } | 367 | } |
367 | if (timeri->private_free) | 368 | if (timeri->private_free) |
368 | timeri->private_free(timeri); | 369 | timeri->private_free(timeri); |
@@ -835,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev) | |||
835 | !timer->hw.resolution && timer->hw.c_resolution == NULL) | 836 | !timer->hw.resolution && timer->hw.c_resolution == NULL) |
836 | return -EINVAL; | 837 | return -EINVAL; |
837 | 838 | ||
838 | down(®ister_mutex); | 839 | mutex_lock(®ister_mutex); |
839 | list_for_each(p, &snd_timer_list) { | 840 | list_for_each(p, &snd_timer_list) { |
840 | timer1 = list_entry(p, struct snd_timer, device_list); | 841 | timer1 = list_entry(p, struct snd_timer, device_list); |
841 | if (timer1->tmr_class > timer->tmr_class) | 842 | if (timer1->tmr_class > timer->tmr_class) |
@@ -857,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev) | |||
857 | if (timer1->tmr_subdevice < timer->tmr_subdevice) | 858 | if (timer1->tmr_subdevice < timer->tmr_subdevice) |
858 | continue; | 859 | continue; |
859 | /* conflicts.. */ | 860 | /* conflicts.. */ |
860 | up(®ister_mutex); | 861 | mutex_unlock(®ister_mutex); |
861 | return -EBUSY; | 862 | return -EBUSY; |
862 | } | 863 | } |
863 | list_add_tail(&timer->device_list, p); | 864 | list_add_tail(&timer->device_list, p); |
864 | up(®ister_mutex); | 865 | mutex_unlock(®ister_mutex); |
865 | return 0; | 866 | return 0; |
866 | } | 867 | } |
867 | 868 | ||
@@ -871,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer) | |||
871 | struct snd_timer_instance *ti; | 872 | struct snd_timer_instance *ti; |
872 | 873 | ||
873 | snd_assert(timer != NULL, return -ENXIO); | 874 | snd_assert(timer != NULL, return -ENXIO); |
874 | down(®ister_mutex); | 875 | mutex_lock(®ister_mutex); |
875 | if (! list_empty(&timer->open_list_head)) { | 876 | if (! list_empty(&timer->open_list_head)) { |
876 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); | 877 | snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); |
877 | list_for_each_safe(p, n, &timer->open_list_head) { | 878 | list_for_each_safe(p, n, &timer->open_list_head) { |
@@ -881,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer) | |||
881 | } | 882 | } |
882 | } | 883 | } |
883 | list_del(&timer->device_list); | 884 | list_del(&timer->device_list); |
884 | up(®ister_mutex); | 885 | mutex_unlock(®ister_mutex); |
885 | return snd_timer_free(timer); | 886 | return snd_timer_free(timer); |
886 | } | 887 | } |
887 | 888 | ||
@@ -1065,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, | |||
1065 | struct snd_timer_instance *ti; | 1066 | struct snd_timer_instance *ti; |
1066 | struct list_head *p, *q; | 1067 | struct list_head *p, *q; |
1067 | 1068 | ||
1068 | down(®ister_mutex); | 1069 | mutex_lock(®ister_mutex); |
1069 | list_for_each(p, &snd_timer_list) { | 1070 | list_for_each(p, &snd_timer_list) { |
1070 | timer = list_entry(p, struct snd_timer, device_list); | 1071 | timer = list_entry(p, struct snd_timer, device_list); |
1071 | switch (timer->tmr_class) { | 1072 | switch (timer->tmr_class) { |
@@ -1105,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, | |||
1105 | } | 1106 | } |
1106 | spin_unlock_irqrestore(&timer->lock, flags); | 1107 | spin_unlock_irqrestore(&timer->lock, flags); |
1107 | } | 1108 | } |
1108 | up(®ister_mutex); | 1109 | mutex_unlock(®ister_mutex); |
1109 | } | 1110 | } |
1110 | 1111 | ||
1111 | static struct snd_info_entry *snd_timer_proc_entry = NULL; | 1112 | 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) | |||
1269 | return -ENOMEM; | 1270 | return -ENOMEM; |
1270 | spin_lock_init(&tu->qlock); | 1271 | spin_lock_init(&tu->qlock); |
1271 | init_waitqueue_head(&tu->qchange_sleep); | 1272 | init_waitqueue_head(&tu->qchange_sleep); |
1272 | init_MUTEX(&tu->tread_sem); | 1273 | mutex_init(&tu->tread_sem); |
1273 | tu->ticks = 1; | 1274 | tu->ticks = 1; |
1274 | tu->queue_size = 128; | 1275 | tu->queue_size = 128; |
1275 | tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), | 1276 | 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) | |||
1325 | 1326 | ||
1326 | if (copy_from_user(&id, _tid, sizeof(id))) | 1327 | if (copy_from_user(&id, _tid, sizeof(id))) |
1327 | return -EFAULT; | 1328 | return -EFAULT; |
1328 | down(®ister_mutex); | 1329 | mutex_lock(®ister_mutex); |
1329 | if (id.dev_class < 0) { /* first item */ | 1330 | if (id.dev_class < 0) { /* first item */ |
1330 | if (list_empty(&snd_timer_list)) | 1331 | if (list_empty(&snd_timer_list)) |
1331 | snd_timer_user_zero_id(&id); | 1332 | snd_timer_user_zero_id(&id); |
@@ -1407,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) | |||
1407 | snd_timer_user_zero_id(&id); | 1408 | snd_timer_user_zero_id(&id); |
1408 | } | 1409 | } |
1409 | } | 1410 | } |
1410 | up(®ister_mutex); | 1411 | mutex_unlock(®ister_mutex); |
1411 | if (copy_to_user(_tid, &id, sizeof(*_tid))) | 1412 | if (copy_to_user(_tid, &id, sizeof(*_tid))) |
1412 | return -EFAULT; | 1413 | return -EFAULT; |
1413 | return 0; | 1414 | return 0; |
@@ -1432,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file, | |||
1432 | tid = ginfo->tid; | 1433 | tid = ginfo->tid; |
1433 | memset(ginfo, 0, sizeof(*ginfo)); | 1434 | memset(ginfo, 0, sizeof(*ginfo)); |
1434 | ginfo->tid = tid; | 1435 | ginfo->tid = tid; |
1435 | down(®ister_mutex); | 1436 | mutex_lock(®ister_mutex); |
1436 | t = snd_timer_find(&tid); | 1437 | t = snd_timer_find(&tid); |
1437 | if (t != NULL) { | 1438 | if (t != NULL) { |
1438 | ginfo->card = t->card ? t->card->number : -1; | 1439 | ginfo->card = t->card ? t->card->number : -1; |
@@ -1451,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file, | |||
1451 | } else { | 1452 | } else { |
1452 | err = -ENODEV; | 1453 | err = -ENODEV; |
1453 | } | 1454 | } |
1454 | up(®ister_mutex); | 1455 | mutex_unlock(®ister_mutex); |
1455 | if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) | 1456 | if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) |
1456 | err = -EFAULT; | 1457 | err = -EFAULT; |
1457 | kfree(ginfo); | 1458 | kfree(ginfo); |
@@ -1467,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file, | |||
1467 | 1468 | ||
1468 | if (copy_from_user(&gparams, _gparams, sizeof(gparams))) | 1469 | if (copy_from_user(&gparams, _gparams, sizeof(gparams))) |
1469 | return -EFAULT; | 1470 | return -EFAULT; |
1470 | down(®ister_mutex); | 1471 | mutex_lock(®ister_mutex); |
1471 | t = snd_timer_find(&gparams.tid); | 1472 | t = snd_timer_find(&gparams.tid); |
1472 | if (!t) { | 1473 | if (!t) { |
1473 | err = -ENODEV; | 1474 | err = -ENODEV; |
@@ -1483,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file, | |||
1483 | } | 1484 | } |
1484 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); | 1485 | err = t->hw.set_period(t, gparams.period_num, gparams.period_den); |
1485 | _error: | 1486 | _error: |
1486 | up(®ister_mutex); | 1487 | mutex_unlock(®ister_mutex); |
1487 | return err; | 1488 | return err; |
1488 | } | 1489 | } |
1489 | 1490 | ||
@@ -1500,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file, | |||
1500 | tid = gstatus.tid; | 1501 | tid = gstatus.tid; |
1501 | memset(&gstatus, 0, sizeof(gstatus)); | 1502 | memset(&gstatus, 0, sizeof(gstatus)); |
1502 | gstatus.tid = tid; | 1503 | gstatus.tid = tid; |
1503 | down(®ister_mutex); | 1504 | mutex_lock(®ister_mutex); |
1504 | t = snd_timer_find(&tid); | 1505 | t = snd_timer_find(&tid); |
1505 | if (t != NULL) { | 1506 | if (t != NULL) { |
1506 | if (t->hw.c_resolution) | 1507 | if (t->hw.c_resolution) |
@@ -1517,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file, | |||
1517 | } else { | 1518 | } else { |
1518 | err = -ENODEV; | 1519 | err = -ENODEV; |
1519 | } | 1520 | } |
1520 | up(®ister_mutex); | 1521 | mutex_unlock(®ister_mutex); |
1521 | if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) | 1522 | if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) |
1522 | err = -EFAULT; | 1523 | err = -EFAULT; |
1523 | return err; | 1524 | return err; |
@@ -1532,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file, | |||
1532 | int err = 0; | 1533 | int err = 0; |
1533 | 1534 | ||
1534 | tu = file->private_data; | 1535 | tu = file->private_data; |
1535 | down(&tu->tread_sem); | 1536 | mutex_lock(&tu->tread_sem); |
1536 | if (tu->timeri) { | 1537 | if (tu->timeri) { |
1537 | snd_timer_close(tu->timeri); | 1538 | snd_timer_close(tu->timeri); |
1538 | tu->timeri = NULL; | 1539 | tu->timeri = NULL; |
@@ -1576,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file, | |||
1576 | } | 1577 | } |
1577 | 1578 | ||
1578 | __err: | 1579 | __err: |
1579 | up(&tu->tread_sem); | 1580 | mutex_unlock(&tu->tread_sem); |
1580 | return err; | 1581 | return err; |
1581 | } | 1582 | } |
1582 | 1583 | ||
@@ -1797,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, | |||
1797 | { | 1798 | { |
1798 | int xarg; | 1799 | int xarg; |
1799 | 1800 | ||
1800 | down(&tu->tread_sem); | 1801 | mutex_lock(&tu->tread_sem); |
1801 | if (tu->timeri) { /* too late */ | 1802 | if (tu->timeri) { /* too late */ |
1802 | up(&tu->tread_sem); | 1803 | mutex_unlock(&tu->tread_sem); |
1803 | return -EBUSY; | 1804 | return -EBUSY; |
1804 | } | 1805 | } |
1805 | if (get_user(xarg, p)) { | 1806 | if (get_user(xarg, p)) { |
1806 | up(&tu->tread_sem); | 1807 | mutex_unlock(&tu->tread_sem); |
1807 | return -EFAULT; | 1808 | return -EFAULT; |
1808 | } | 1809 | } |
1809 | tu->tread = xarg ? 1 : 0; | 1810 | tu->tread = xarg ? 1 : 0; |
1810 | up(&tu->tread_sem); | 1811 | mutex_unlock(&tu->tread_sem); |
1811 | return 0; | 1812 | return 0; |
1812 | } | 1813 | } |
1813 | case SNDRV_TIMER_IOCTL_GINFO: | 1814 | case SNDRV_TIMER_IOCTL_GINFO: |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 14e1a671b5cf..e35fd5779a9d 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -669,8 +669,10 @@ static int __init alsa_card_dummy_init(void) | |||
669 | return err; | 669 | return err; |
670 | 670 | ||
671 | cards = 0; | 671 | cards = 0; |
672 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 672 | for (i = 0; i < SNDRV_CARDS; i++) { |
673 | struct platform_device *device; | 673 | struct platform_device *device; |
674 | if (! enable[i]) | ||
675 | continue; | ||
674 | device = platform_device_register_simple(SND_DUMMY_DRIVER, | 676 | device = platform_device_register_simple(SND_DUMMY_DRIVER, |
675 | i, NULL, 0); | 677 | i, NULL, 0); |
676 | if (IS_ERR(device)) { | 678 | if (IS_ERR(device)) { |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 915589a402ab..9d10d79e27af 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
@@ -240,8 +240,10 @@ static int __init alsa_card_mpu401_init(void) | |||
240 | return err; | 240 | return err; |
241 | 241 | ||
242 | devices = 0; | 242 | devices = 0; |
243 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 243 | for (i = 0; i < SNDRV_CARDS; i++) { |
244 | struct platform_device *device; | 244 | struct platform_device *device; |
245 | if (! enable[i]) | ||
246 | continue; | ||
245 | #ifdef CONFIG_PNP | 247 | #ifdef CONFIG_PNP |
246 | if (pnp[i]) | 248 | if (pnp[i]) |
247 | continue; | 249 | continue; |
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index 1e0c76b9acfc..4f8556976774 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c | |||
@@ -358,7 +358,7 @@ int snd_opl3_new(struct snd_card *card, | |||
358 | opl3->hardware = hardware; | 358 | opl3->hardware = hardware; |
359 | spin_lock_init(&opl3->reg_lock); | 359 | spin_lock_init(&opl3->reg_lock); |
360 | spin_lock_init(&opl3->timer_lock); | 360 | spin_lock_init(&opl3->timer_lock); |
361 | init_MUTEX(&opl3->access_mutex); | 361 | mutex_init(&opl3->access_mutex); |
362 | 362 | ||
363 | if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) { | 363 | if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) { |
364 | snd_opl3_free(opl3); | 364 | snd_opl3_free(opl3); |
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c index 0345ae647681..fccf019a6d85 100644 --- a/sound/drivers/opl3/opl3_oss.c +++ b/sound/drivers/opl3/opl3_oss.c | |||
@@ -104,8 +104,10 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3) | |||
104 | voices, voices, | 104 | voices, voices, |
105 | name); | 105 | name); |
106 | if (opl3->oss_chset->port < 0) { | 106 | if (opl3->oss_chset->port < 0) { |
107 | int port; | ||
108 | port = opl3->oss_chset->port; | ||
107 | snd_midi_channel_free_set(opl3->oss_chset); | 109 | snd_midi_channel_free_set(opl3->oss_chset); |
108 | return opl3->oss_chset->port; | 110 | return port; |
109 | } | 111 | } |
110 | return 0; | 112 | return 0; |
111 | } | 113 | } |
@@ -136,10 +138,10 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name) | |||
136 | arg->oper = oss_callback; | 138 | arg->oper = oss_callback; |
137 | arg->private_data = opl3; | 139 | arg->private_data = opl3; |
138 | 140 | ||
139 | snd_opl3_oss_create_port(opl3); | 141 | if (snd_opl3_oss_create_port(opl3)) { |
140 | 142 | /* register to OSS synth table */ | |
141 | /* register to OSS synth table */ | 143 | snd_device_register(opl3->card, dev); |
142 | snd_device_register(opl3->card, dev); | 144 | } |
143 | } | 145 | } |
144 | 146 | ||
145 | /* unregister */ | 147 | /* unregister */ |
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index c4ead790008a..57becf34f43e 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c | |||
@@ -52,13 +52,13 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3) | |||
52 | { | 52 | { |
53 | int idx; | 53 | int idx; |
54 | 54 | ||
55 | down(&opl3->access_mutex); | 55 | mutex_lock(&opl3->access_mutex); |
56 | if (opl3->used) { | 56 | if (opl3->used) { |
57 | up(&opl3->access_mutex); | 57 | mutex_unlock(&opl3->access_mutex); |
58 | return -EBUSY; | 58 | return -EBUSY; |
59 | } | 59 | } |
60 | opl3->used++; | 60 | opl3->used++; |
61 | up(&opl3->access_mutex); | 61 | mutex_unlock(&opl3->access_mutex); |
62 | 62 | ||
63 | snd_opl3_reset(opl3); | 63 | snd_opl3_reset(opl3); |
64 | 64 | ||
@@ -91,9 +91,9 @@ void snd_opl3_synth_cleanup(struct snd_opl3 * opl3) | |||
91 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); | 91 | spin_unlock_irqrestore(&opl3->sys_timer_lock, flags); |
92 | 92 | ||
93 | snd_opl3_reset(opl3); | 93 | snd_opl3_reset(opl3); |
94 | down(&opl3->access_mutex); | 94 | mutex_lock(&opl3->access_mutex); |
95 | opl3->used--; | 95 | opl3->used--; |
96 | up(&opl3->access_mutex); | 96 | mutex_unlock(&opl3->access_mutex); |
97 | } | 97 | } |
98 | 98 | ||
99 | static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info) | 99 | 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) | |||
207 | 16, voices, | 207 | 16, voices, |
208 | name); | 208 | name); |
209 | if (opl3->chset->port < 0) { | 209 | if (opl3->chset->port < 0) { |
210 | int port; | ||
211 | port = opl3->chset->port; | ||
210 | snd_midi_channel_free_set(opl3->chset); | 212 | snd_midi_channel_free_set(opl3->chset); |
211 | return opl3->chset->port; | 213 | return port; |
212 | } | 214 | } |
213 | return 0; | 215 | return 0; |
214 | } | 216 | } |
@@ -218,7 +220,7 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3) | |||
218 | static int snd_opl3_seq_new_device(struct snd_seq_device *dev) | 220 | static int snd_opl3_seq_new_device(struct snd_seq_device *dev) |
219 | { | 221 | { |
220 | struct snd_opl3 *opl3; | 222 | struct snd_opl3 *opl3; |
221 | int client; | 223 | int client, err; |
222 | char name[32]; | 224 | char name[32]; |
223 | int opl_ver; | 225 | int opl_ver; |
224 | 226 | ||
@@ -239,7 +241,11 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev) | |||
239 | if (client < 0) | 241 | if (client < 0) |
240 | return client; | 242 | return client; |
241 | 243 | ||
242 | snd_opl3_synth_create_port(opl3); | 244 | if ((err = snd_opl3_synth_create_port(opl3)) < 0) { |
245 | snd_seq_delete_kernel_client(client); | ||
246 | opl3->seq_client = -1; | ||
247 | return err; | ||
248 | } | ||
243 | 249 | ||
244 | /* initialize instrument list */ | 250 | /* initialize instrument list */ |
245 | opl3->ilist = snd_seq_instr_list_new(); | 251 | opl3->ilist = snd_seq_instr_list_new(); |
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index 3534a0e3342a..6db503f025b3 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c | |||
@@ -76,13 +76,13 @@ int snd_opl3_open(struct snd_hwdep * hw, struct file *file) | |||
76 | { | 76 | { |
77 | struct snd_opl3 *opl3 = hw->private_data; | 77 | struct snd_opl3 *opl3 = hw->private_data; |
78 | 78 | ||
79 | down(&opl3->access_mutex); | 79 | mutex_lock(&opl3->access_mutex); |
80 | if (opl3->used) { | 80 | if (opl3->used) { |
81 | up(&opl3->access_mutex); | 81 | mutex_unlock(&opl3->access_mutex); |
82 | return -EAGAIN; | 82 | return -EAGAIN; |
83 | } | 83 | } |
84 | opl3->used++; | 84 | opl3->used++; |
85 | up(&opl3->access_mutex); | 85 | mutex_unlock(&opl3->access_mutex); |
86 | 86 | ||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
@@ -179,9 +179,9 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file) | |||
179 | struct snd_opl3 *opl3 = hw->private_data; | 179 | struct snd_opl3 *opl3 = hw->private_data; |
180 | 180 | ||
181 | snd_opl3_reset(opl3); | 181 | snd_opl3_reset(opl3); |
182 | down(&opl3->access_mutex); | 182 | mutex_lock(&opl3->access_mutex); |
183 | opl3->used--; | 183 | opl3->used--; |
184 | up(&opl3->access_mutex); | 184 | mutex_unlock(&opl3->access_mutex); |
185 | 185 | ||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c index ddfc10d04be2..4bc860ae02de 100644 --- a/sound/drivers/opl4/opl4_lib.c +++ b/sound/drivers/opl4/opl4_lib.c | |||
@@ -214,7 +214,7 @@ int snd_opl4_create(struct snd_card *card, | |||
214 | opl4->fm_port = fm_port; | 214 | opl4->fm_port = fm_port; |
215 | opl4->pcm_port = pcm_port; | 215 | opl4->pcm_port = pcm_port; |
216 | spin_lock_init(&opl4->reg_lock); | 216 | spin_lock_init(&opl4->reg_lock); |
217 | init_MUTEX(&opl4->access_mutex); | 217 | mutex_init(&opl4->access_mutex); |
218 | 218 | ||
219 | err = snd_opl4_detect(opl4); | 219 | err = snd_opl4_detect(opl4); |
220 | if (err < 0) { | 220 | if (err < 0) { |
diff --git a/sound/drivers/opl4/opl4_local.h b/sound/drivers/opl4/opl4_local.h index 7e088a4a2f4c..470e5a758a02 100644 --- a/sound/drivers/opl4/opl4_local.h +++ b/sound/drivers/opl4/opl4_local.h | |||
@@ -182,7 +182,7 @@ struct snd_opl4 { | |||
182 | struct snd_info_entry *proc_entry; | 182 | struct snd_info_entry *proc_entry; |
183 | int memory_access; | 183 | int memory_access; |
184 | #endif | 184 | #endif |
185 | struct semaphore access_mutex; | 185 | struct mutex access_mutex; |
186 | 186 | ||
187 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) | 187 | #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) |
188 | int used; | 188 | int used; |
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index f4b4e74fcc18..e552ec34166f 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c | |||
@@ -28,13 +28,13 @@ static int snd_opl4_mem_proc_open(struct snd_info_entry *entry, | |||
28 | { | 28 | { |
29 | struct snd_opl4 *opl4 = entry->private_data; | 29 | struct snd_opl4 *opl4 = entry->private_data; |
30 | 30 | ||
31 | down(&opl4->access_mutex); | 31 | mutex_lock(&opl4->access_mutex); |
32 | if (opl4->memory_access) { | 32 | if (opl4->memory_access) { |
33 | up(&opl4->access_mutex); | 33 | mutex_unlock(&opl4->access_mutex); |
34 | return -EBUSY; | 34 | return -EBUSY; |
35 | } | 35 | } |
36 | opl4->memory_access++; | 36 | opl4->memory_access++; |
37 | up(&opl4->access_mutex); | 37 | mutex_unlock(&opl4->access_mutex); |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
40 | 40 | ||
@@ -43,9 +43,9 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry, | |||
43 | { | 43 | { |
44 | struct snd_opl4 *opl4 = entry->private_data; | 44 | struct snd_opl4 *opl4 = entry->private_data; |
45 | 45 | ||
46 | down(&opl4->access_mutex); | 46 | mutex_lock(&opl4->access_mutex); |
47 | opl4->memory_access--; | 47 | opl4->memory_access--; |
48 | up(&opl4->access_mutex); | 48 | mutex_unlock(&opl4->access_mutex); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c index e3480326e735..dc0dcdc6c313 100644 --- a/sound/drivers/opl4/opl4_seq.c +++ b/sound/drivers/opl4/opl4_seq.c | |||
@@ -62,10 +62,10 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i | |||
62 | struct snd_opl4 *opl4 = private_data; | 62 | struct snd_opl4 *opl4 = private_data; |
63 | int err; | 63 | int err; |
64 | 64 | ||
65 | down(&opl4->access_mutex); | 65 | mutex_lock(&opl4->access_mutex); |
66 | 66 | ||
67 | if (opl4->used) { | 67 | if (opl4->used) { |
68 | up(&opl4->access_mutex); | 68 | mutex_unlock(&opl4->access_mutex); |
69 | return -EBUSY; | 69 | return -EBUSY; |
70 | } | 70 | } |
71 | opl4->used++; | 71 | opl4->used++; |
@@ -73,12 +73,12 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i | |||
73 | if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) { | 73 | if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) { |
74 | err = snd_opl4_seq_use_inc(opl4); | 74 | err = snd_opl4_seq_use_inc(opl4); |
75 | if (err < 0) { | 75 | if (err < 0) { |
76 | up(&opl4->access_mutex); | 76 | mutex_unlock(&opl4->access_mutex); |
77 | return err; | 77 | return err; |
78 | } | 78 | } |
79 | } | 79 | } |
80 | 80 | ||
81 | up(&opl4->access_mutex); | 81 | mutex_unlock(&opl4->access_mutex); |
82 | 82 | ||
83 | snd_opl4_synth_reset(opl4); | 83 | snd_opl4_synth_reset(opl4); |
84 | return 0; | 84 | return 0; |
@@ -90,9 +90,9 @@ static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe | |||
90 | 90 | ||
91 | snd_opl4_synth_shutdown(opl4); | 91 | snd_opl4_synth_shutdown(opl4); |
92 | 92 | ||
93 | down(&opl4->access_mutex); | 93 | mutex_lock(&opl4->access_mutex); |
94 | opl4->used--; | 94 | opl4->used--; |
95 | up(&opl4->access_mutex); | 95 | mutex_unlock(&opl4->access_mutex); |
96 | 96 | ||
97 | if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) | 97 | if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) |
98 | snd_opl4_seq_use_dec(opl4); | 98 | snd_opl4_seq_use_dec(opl4); |
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 112ddf705402..1a7fbefe4740 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c | |||
@@ -789,6 +789,7 @@ static int __init snd_uart16550_create(struct snd_card *card, | |||
789 | 789 | ||
790 | if ((err = snd_uart16550_detect(uart)) <= 0) { | 790 | if ((err = snd_uart16550_detect(uart)) <= 0) { |
791 | printk(KERN_ERR "no UART detected at 0x%lx\n", iobase); | 791 | printk(KERN_ERR "no UART detected at 0x%lx\n", iobase); |
792 | snd_uart16550_free(uart); | ||
792 | return -ENODEV; | 793 | return -ENODEV; |
793 | } | 794 | } |
794 | 795 | ||
@@ -989,8 +990,10 @@ static int __init alsa_card_serial_init(void) | |||
989 | return err; | 990 | return err; |
990 | 991 | ||
991 | cards = 0; | 992 | cards = 0; |
992 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 993 | for (i = 0; i < SNDRV_CARDS; i++) { |
993 | struct platform_device *device; | 994 | struct platform_device *device; |
995 | if (! enable[i]) | ||
996 | continue; | ||
994 | device = platform_device_register_simple(SND_SERIAL_DRIVER, | 997 | device = platform_device_register_simple(SND_SERIAL_DRIVER, |
995 | i, NULL, 0); | 998 | i, NULL, 0); |
996 | if (IS_ERR(device)) { | 999 | if (IS_ERR(device)) { |
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index 4258723de2ab..a3ee306239c9 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c | |||
@@ -163,8 +163,10 @@ static int __init alsa_card_virmidi_init(void) | |||
163 | return err; | 163 | return err; |
164 | 164 | ||
165 | cards = 0; | 165 | cards = 0; |
166 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 166 | for (i = 0; i < SNDRV_CARDS; i++) { |
167 | struct platform_device *device; | 167 | struct platform_device *device; |
168 | if (! enable[i]) | ||
169 | continue; | ||
168 | device = platform_device_register_simple(SND_VIRMIDI_DRIVER, | 170 | device = platform_device_register_simple(SND_VIRMIDI_DRIVER, |
169 | i, NULL, 0); | 171 | i, NULL, 0); |
170 | if (IS_ERR(device)) { | 172 | if (IS_ERR(device)) { |
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index 43f615d7a545..fa4a2b5c2d8d 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c | |||
@@ -778,7 +778,7 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw, | |||
778 | chip->type = hw->type; | 778 | chip->type = hw->type; |
779 | chip->ops = ops; | 779 | chip->ops = ops; |
780 | tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip); | 780 | tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip); |
781 | init_MUTEX(&chip->mixer_mutex); | 781 | mutex_init(&chip->mixer_mutex); |
782 | 782 | ||
783 | chip->card = card; | 783 | chip->card = card; |
784 | card->private_data = chip; | 784 | card->private_data = chip; |
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c index 8ec2c605d2f0..c1d7fcdd1973 100644 --- a/sound/drivers/vx/vx_mixer.c +++ b/sound/drivers/vx/vx_mixer.c | |||
@@ -427,10 +427,10 @@ static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
427 | { | 427 | { |
428 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 428 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
429 | int codec = kcontrol->id.index; | 429 | int codec = kcontrol->id.index; |
430 | down(&chip->mixer_mutex); | 430 | mutex_lock(&chip->mixer_mutex); |
431 | ucontrol->value.integer.value[0] = chip->output_level[codec][0]; | 431 | ucontrol->value.integer.value[0] = chip->output_level[codec][0]; |
432 | ucontrol->value.integer.value[1] = chip->output_level[codec][1]; | 432 | ucontrol->value.integer.value[1] = chip->output_level[codec][1]; |
433 | up(&chip->mixer_mutex); | 433 | mutex_unlock(&chip->mixer_mutex); |
434 | return 0; | 434 | return 0; |
435 | } | 435 | } |
436 | 436 | ||
@@ -438,7 +438,7 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
438 | { | 438 | { |
439 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 439 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
440 | int codec = kcontrol->id.index; | 440 | int codec = kcontrol->id.index; |
441 | down(&chip->mixer_mutex); | 441 | mutex_lock(&chip->mixer_mutex); |
442 | if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] || | 442 | if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] || |
443 | ucontrol->value.integer.value[1] != chip->output_level[codec][1]) { | 443 | ucontrol->value.integer.value[1] != chip->output_level[codec][1]) { |
444 | vx_set_analog_output_level(chip, codec, | 444 | 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 | |||
446 | ucontrol->value.integer.value[1]); | 446 | ucontrol->value.integer.value[1]); |
447 | chip->output_level[codec][0] = ucontrol->value.integer.value[0]; | 447 | chip->output_level[codec][0] = ucontrol->value.integer.value[0]; |
448 | chip->output_level[codec][1] = ucontrol->value.integer.value[1]; | 448 | chip->output_level[codec][1] = ucontrol->value.integer.value[1]; |
449 | up(&chip->mixer_mutex); | 449 | mutex_unlock(&chip->mixer_mutex); |
450 | return 1; | 450 | return 1; |
451 | } | 451 | } |
452 | up(&chip->mixer_mutex); | 452 | mutex_unlock(&chip->mixer_mutex); |
453 | return 0; | 453 | return 0; |
454 | } | 454 | } |
455 | 455 | ||
@@ -502,14 +502,14 @@ static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
502 | static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 502 | static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
503 | { | 503 | { |
504 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 504 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
505 | down(&chip->mixer_mutex); | 505 | mutex_lock(&chip->mixer_mutex); |
506 | if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) { | 506 | if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) { |
507 | chip->audio_source_target = ucontrol->value.enumerated.item[0]; | 507 | chip->audio_source_target = ucontrol->value.enumerated.item[0]; |
508 | vx_sync_audio_source(chip); | 508 | vx_sync_audio_source(chip); |
509 | up(&chip->mixer_mutex); | 509 | mutex_unlock(&chip->mixer_mutex); |
510 | return 1; | 510 | return 1; |
511 | } | 511 | } |
512 | up(&chip->mixer_mutex); | 512 | mutex_unlock(&chip->mixer_mutex); |
513 | return 0; | 513 | return 0; |
514 | } | 514 | } |
515 | 515 | ||
@@ -550,14 +550,14 @@ static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
550 | static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 550 | static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
551 | { | 551 | { |
552 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 552 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
553 | down(&chip->mixer_mutex); | 553 | mutex_lock(&chip->mixer_mutex); |
554 | if (chip->clock_mode != ucontrol->value.enumerated.item[0]) { | 554 | if (chip->clock_mode != ucontrol->value.enumerated.item[0]) { |
555 | chip->clock_mode = ucontrol->value.enumerated.item[0]; | 555 | chip->clock_mode = ucontrol->value.enumerated.item[0]; |
556 | vx_set_clock(chip, chip->freq); | 556 | vx_set_clock(chip, chip->freq); |
557 | up(&chip->mixer_mutex); | 557 | mutex_unlock(&chip->mixer_mutex); |
558 | return 1; | 558 | return 1; |
559 | } | 559 | } |
560 | up(&chip->mixer_mutex); | 560 | mutex_unlock(&chip->mixer_mutex); |
561 | return 0; | 561 | return 0; |
562 | } | 562 | } |
563 | 563 | ||
@@ -587,10 +587,10 @@ static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
587 | int audio = kcontrol->private_value & 0xff; | 587 | int audio = kcontrol->private_value & 0xff; |
588 | int capture = (kcontrol->private_value >> 8) & 1; | 588 | int capture = (kcontrol->private_value >> 8) & 1; |
589 | 589 | ||
590 | down(&chip->mixer_mutex); | 590 | mutex_lock(&chip->mixer_mutex); |
591 | ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio]; | 591 | ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio]; |
592 | ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1]; | 592 | ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1]; |
593 | up(&chip->mixer_mutex); | 593 | mutex_unlock(&chip->mixer_mutex); |
594 | return 0; | 594 | return 0; |
595 | } | 595 | } |
596 | 596 | ||
@@ -600,15 +600,15 @@ static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
600 | int audio = kcontrol->private_value & 0xff; | 600 | int audio = kcontrol->private_value & 0xff; |
601 | int capture = (kcontrol->private_value >> 8) & 1; | 601 | int capture = (kcontrol->private_value >> 8) & 1; |
602 | 602 | ||
603 | down(&chip->mixer_mutex); | 603 | mutex_lock(&chip->mixer_mutex); |
604 | if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] || | 604 | if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] || |
605 | ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) { | 605 | ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) { |
606 | vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]); | 606 | vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]); |
607 | vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]); | 607 | vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]); |
608 | up(&chip->mixer_mutex); | 608 | mutex_unlock(&chip->mixer_mutex); |
609 | return 1; | 609 | return 1; |
610 | } | 610 | } |
611 | up(&chip->mixer_mutex); | 611 | mutex_unlock(&chip->mixer_mutex); |
612 | return 0; | 612 | return 0; |
613 | } | 613 | } |
614 | 614 | ||
@@ -617,10 +617,10 @@ static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
617 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 617 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
618 | int audio = kcontrol->private_value & 0xff; | 618 | int audio = kcontrol->private_value & 0xff; |
619 | 619 | ||
620 | down(&chip->mixer_mutex); | 620 | mutex_lock(&chip->mixer_mutex); |
621 | ucontrol->value.integer.value[0] = chip->audio_monitor[audio]; | 621 | ucontrol->value.integer.value[0] = chip->audio_monitor[audio]; |
622 | ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1]; | 622 | ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1]; |
623 | up(&chip->mixer_mutex); | 623 | mutex_unlock(&chip->mixer_mutex); |
624 | return 0; | 624 | return 0; |
625 | } | 625 | } |
626 | 626 | ||
@@ -629,17 +629,17 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
629 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 629 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
630 | int audio = kcontrol->private_value & 0xff; | 630 | int audio = kcontrol->private_value & 0xff; |
631 | 631 | ||
632 | down(&chip->mixer_mutex); | 632 | mutex_lock(&chip->mixer_mutex); |
633 | if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] || | 633 | if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] || |
634 | ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) { | 634 | ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) { |
635 | vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0], | 635 | vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0], |
636 | chip->audio_monitor_active[audio]); | 636 | chip->audio_monitor_active[audio]); |
637 | vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1], | 637 | vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1], |
638 | chip->audio_monitor_active[audio+1]); | 638 | chip->audio_monitor_active[audio+1]); |
639 | up(&chip->mixer_mutex); | 639 | mutex_unlock(&chip->mixer_mutex); |
640 | return 1; | 640 | return 1; |
641 | } | 641 | } |
642 | up(&chip->mixer_mutex); | 642 | mutex_unlock(&chip->mixer_mutex); |
643 | return 0; | 643 | return 0; |
644 | } | 644 | } |
645 | 645 | ||
@@ -657,10 +657,10 @@ static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
657 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 657 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
658 | int audio = kcontrol->private_value & 0xff; | 658 | int audio = kcontrol->private_value & 0xff; |
659 | 659 | ||
660 | down(&chip->mixer_mutex); | 660 | mutex_lock(&chip->mixer_mutex); |
661 | ucontrol->value.integer.value[0] = chip->audio_active[audio]; | 661 | ucontrol->value.integer.value[0] = chip->audio_active[audio]; |
662 | ucontrol->value.integer.value[1] = chip->audio_active[audio+1]; | 662 | ucontrol->value.integer.value[1] = chip->audio_active[audio+1]; |
663 | up(&chip->mixer_mutex); | 663 | mutex_unlock(&chip->mixer_mutex); |
664 | return 0; | 664 | return 0; |
665 | } | 665 | } |
666 | 666 | ||
@@ -669,15 +669,15 @@ static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
669 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 669 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
670 | int audio = kcontrol->private_value & 0xff; | 670 | int audio = kcontrol->private_value & 0xff; |
671 | 671 | ||
672 | down(&chip->mixer_mutex); | 672 | mutex_lock(&chip->mixer_mutex); |
673 | if (ucontrol->value.integer.value[0] != chip->audio_active[audio] || | 673 | if (ucontrol->value.integer.value[0] != chip->audio_active[audio] || |
674 | ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) { | 674 | ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) { |
675 | vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]); | 675 | vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]); |
676 | vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]); | 676 | vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]); |
677 | up(&chip->mixer_mutex); | 677 | mutex_unlock(&chip->mixer_mutex); |
678 | return 1; | 678 | return 1; |
679 | } | 679 | } |
680 | up(&chip->mixer_mutex); | 680 | mutex_unlock(&chip->mixer_mutex); |
681 | return 0; | 681 | return 0; |
682 | } | 682 | } |
683 | 683 | ||
@@ -686,10 +686,10 @@ static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
686 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 686 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
687 | int audio = kcontrol->private_value & 0xff; | 687 | int audio = kcontrol->private_value & 0xff; |
688 | 688 | ||
689 | down(&chip->mixer_mutex); | 689 | mutex_lock(&chip->mixer_mutex); |
690 | ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio]; | 690 | ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio]; |
691 | ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1]; | 691 | ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1]; |
692 | up(&chip->mixer_mutex); | 692 | mutex_unlock(&chip->mixer_mutex); |
693 | return 0; | 693 | return 0; |
694 | } | 694 | } |
695 | 695 | ||
@@ -698,17 +698,17 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
698 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 698 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
699 | int audio = kcontrol->private_value & 0xff; | 699 | int audio = kcontrol->private_value & 0xff; |
700 | 700 | ||
701 | down(&chip->mixer_mutex); | 701 | mutex_lock(&chip->mixer_mutex); |
702 | if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] || | 702 | if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] || |
703 | ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) { | 703 | ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) { |
704 | vx_set_monitor_level(chip, audio, chip->audio_monitor[audio], | 704 | vx_set_monitor_level(chip, audio, chip->audio_monitor[audio], |
705 | ucontrol->value.integer.value[0]); | 705 | ucontrol->value.integer.value[0]); |
706 | vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1], | 706 | vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1], |
707 | ucontrol->value.integer.value[1]); | 707 | ucontrol->value.integer.value[1]); |
708 | up(&chip->mixer_mutex); | 708 | mutex_unlock(&chip->mixer_mutex); |
709 | return 1; | 709 | return 1; |
710 | } | 710 | } |
711 | up(&chip->mixer_mutex); | 711 | mutex_unlock(&chip->mixer_mutex); |
712 | return 0; | 712 | return 0; |
713 | } | 713 | } |
714 | 714 | ||
@@ -756,12 +756,12 @@ static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
756 | { | 756 | { |
757 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); | 757 | struct vx_core *chip = snd_kcontrol_chip(kcontrol); |
758 | 758 | ||
759 | down(&chip->mixer_mutex); | 759 | mutex_lock(&chip->mixer_mutex); |
760 | ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff; | 760 | ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff; |
761 | ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff; | 761 | ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff; |
762 | ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff; | 762 | ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff; |
763 | ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff; | 763 | ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff; |
764 | up(&chip->mixer_mutex); | 764 | mutex_unlock(&chip->mixer_mutex); |
765 | return 0; | 765 | return 0; |
766 | } | 766 | } |
767 | 767 | ||
@@ -783,14 +783,14 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
783 | (ucontrol->value.iec958.status[1] << 8) | | 783 | (ucontrol->value.iec958.status[1] << 8) | |
784 | (ucontrol->value.iec958.status[2] << 16) | | 784 | (ucontrol->value.iec958.status[2] << 16) | |
785 | (ucontrol->value.iec958.status[3] << 24); | 785 | (ucontrol->value.iec958.status[3] << 24); |
786 | down(&chip->mixer_mutex); | 786 | mutex_lock(&chip->mixer_mutex); |
787 | if (chip->uer_bits != val) { | 787 | if (chip->uer_bits != val) { |
788 | chip->uer_bits = val; | 788 | chip->uer_bits = val; |
789 | vx_set_iec958_status(chip, val); | 789 | vx_set_iec958_status(chip, val); |
790 | up(&chip->mixer_mutex); | 790 | mutex_unlock(&chip->mixer_mutex); |
791 | return 1; | 791 | return 1; |
792 | } | 792 | } |
793 | up(&chip->mixer_mutex); | 793 | mutex_unlock(&chip->mixer_mutex); |
794 | return 0; | 794 | return 0; |
795 | } | 795 | } |
796 | 796 | ||
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index 464109e421d4..c4af84995d05 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c | |||
@@ -98,10 +98,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s | |||
98 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) | 98 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) |
99 | { | 99 | { |
100 | struct snd_pcm_runtime *runtime = subs->runtime; | 100 | struct snd_pcm_runtime *runtime = subs->runtime; |
101 | if (runtime->dma_area) { | 101 | |
102 | vfree(runtime->dma_area); | 102 | vfree(runtime->dma_area); |
103 | runtime->dma_area = NULL; | 103 | runtime->dma_area = NULL; |
104 | } | ||
105 | return 0; | 104 | return 0; |
106 | } | 105 | } |
107 | 106 | ||
@@ -1254,9 +1253,13 @@ static int vx_init_audio_io(struct vx_core *chip) | |||
1254 | 1253 | ||
1255 | /* allocate pipes */ | 1254 | /* allocate pipes */ |
1256 | chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL); | 1255 | chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL); |
1256 | if (!chip->playback_pipes) | ||
1257 | return -ENOMEM; | ||
1257 | chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL); | 1258 | chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL); |
1258 | if (! chip->playback_pipes || ! chip->capture_pipes) | 1259 | if (!chip->capture_pipes) { |
1260 | kfree(chip->playback_pipes); | ||
1259 | return -ENOMEM; | 1261 | return -ENOMEM; |
1262 | } | ||
1260 | 1263 | ||
1261 | memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs); | 1264 | memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs); |
1262 | memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins); | 1265 | memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins); |
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index 9deba80a587c..cb89f7eb9236 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c | |||
@@ -291,11 +291,13 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427) | |||
291 | { | 291 | { |
292 | struct cs8427 *chip; | 292 | struct cs8427 *chip; |
293 | unsigned long end_time; | 293 | unsigned long end_time; |
294 | int data; | 294 | int data, aes3input = 0; |
295 | 295 | ||
296 | snd_assert(cs8427, return); | 296 | snd_assert(cs8427, return); |
297 | chip = cs8427->private_data; | 297 | chip = cs8427->private_data; |
298 | snd_i2c_lock(cs8427->bus); | 298 | snd_i2c_lock(cs8427->bus); |
299 | if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == CS8427_RXDAES3INPUT) /* AES3 bit is set */ | ||
300 | aes3input = 1; | ||
299 | chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK); | 301 | chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK); |
300 | snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, | 302 | snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, |
301 | chip->regmap[CS8427_REG_CLOCKSOURCE]); | 303 | chip->regmap[CS8427_REG_CLOCKSOURCE]); |
@@ -316,7 +318,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427) | |||
316 | } | 318 | } |
317 | snd_i2c_lock(cs8427->bus); | 319 | snd_i2c_lock(cs8427->bus); |
318 | chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK; | 320 | chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK; |
319 | chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT; | 321 | if (aes3input) |
322 | chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT; | ||
320 | snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, | 323 | snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, |
321 | chip->regmap[CS8427_REG_CLOCKSOURCE]); | 324 | chip->regmap[CS8427_REG_CLOCKSOURCE]); |
322 | snd_i2c_unlock(cs8427->bus); | 325 | snd_i2c_unlock(cs8427->bus); |
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c index c4e1f2c23ced..edfe76fb0074 100644 --- a/sound/i2c/i2c.c +++ b/sound/i2c/i2c.c | |||
@@ -88,7 +88,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name, | |||
88 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); | 88 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); |
89 | if (bus == NULL) | 89 | if (bus == NULL) |
90 | return -ENOMEM; | 90 | return -ENOMEM; |
91 | init_MUTEX(&bus->lock_mutex); | 91 | mutex_init(&bus->lock_mutex); |
92 | INIT_LIST_HEAD(&bus->devices); | 92 | INIT_LIST_HEAD(&bus->devices); |
93 | INIT_LIST_HEAD(&bus->buses); | 93 | INIT_LIST_HEAD(&bus->buses); |
94 | bus->card = card; | 94 | bus->card = card; |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index ac0d808fff57..fd8fe16c09ee 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | /* | 1 | /* |
3 | ad1816a.c - lowlevel code for Analog Devices AD1816A chip. | 2 | ad1816a.c - lowlevel code for Analog Devices AD1816A chip. |
4 | Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it> | 3 | 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) | |||
175 | 174 | ||
176 | 175 | ||
177 | static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, | 176 | static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, |
178 | int channel, int cmd) | 177 | int channel, int cmd, int iscapture) |
179 | { | 178 | { |
180 | int error = 0; | 179 | int error = 0; |
181 | 180 | ||
@@ -184,10 +183,14 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what, | |||
184 | case SNDRV_PCM_TRIGGER_STOP: | 183 | case SNDRV_PCM_TRIGGER_STOP: |
185 | spin_lock(&chip->lock); | 184 | spin_lock(&chip->lock); |
186 | cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00; | 185 | cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00; |
187 | if (what & AD1816A_PLAYBACK_ENABLE) | 186 | /* if (what & AD1816A_PLAYBACK_ENABLE) */ |
187 | /* That is not valid, because playback and capture enable | ||
188 | * are the same bit pattern, just to different addresses | ||
189 | */ | ||
190 | if (! iscapture) | ||
188 | snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG, | 191 | snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG, |
189 | AD1816A_PLAYBACK_ENABLE, cmd); | 192 | AD1816A_PLAYBACK_ENABLE, cmd); |
190 | if (what & AD1816A_CAPTURE_ENABLE) | 193 | else |
191 | snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG, | 194 | snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG, |
192 | AD1816A_CAPTURE_ENABLE, cmd); | 195 | AD1816A_CAPTURE_ENABLE, cmd); |
193 | spin_unlock(&chip->lock); | 196 | spin_unlock(&chip->lock); |
@@ -204,14 +207,14 @@ static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int | |||
204 | { | 207 | { |
205 | struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); | 208 | struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); |
206 | return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE, | 209 | return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE, |
207 | SNDRV_PCM_STREAM_PLAYBACK, cmd); | 210 | SNDRV_PCM_STREAM_PLAYBACK, cmd, 0); |
208 | } | 211 | } |
209 | 212 | ||
210 | static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd) | 213 | static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd) |
211 | { | 214 | { |
212 | struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); | 215 | struct snd_ad1816a *chip = snd_pcm_substream_chip(substream); |
213 | return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE, | 216 | return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE, |
214 | SNDRV_PCM_STREAM_CAPTURE, cmd); | 217 | SNDRV_PCM_STREAM_CAPTURE, cmd, 1); |
215 | } | 218 | } |
216 | 219 | ||
217 | static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream, | 220 | static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream, |
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index e091bbeffd2a..326a057f752f 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c | |||
@@ -187,8 +187,10 @@ static int __init alsa_card_ad1848_init(void) | |||
187 | return err; | 187 | return err; |
188 | 188 | ||
189 | cards = 0; | 189 | cards = 0; |
190 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 190 | for (i = 0; i < SNDRV_CARDS; i++) { |
191 | struct platform_device *device; | 191 | struct platform_device *device; |
192 | if (! enable[i]) | ||
193 | continue; | ||
192 | device = platform_device_register_simple(SND_AD1848_DRIVER, | 194 | device = platform_device_register_simple(SND_AD1848_DRIVER, |
193 | i, NULL, 0); | 195 | i, NULL, 0); |
194 | if (IS_ERR(device)) { | 196 | if (IS_ERR(device)) { |
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c index b78530d7ea90..e0f8baa843b9 100644 --- a/sound/isa/ad1848/ad1848_lib.c +++ b/sound/isa/ad1848/ad1848_lib.c | |||
@@ -387,9 +387,9 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) | |||
387 | { | 387 | { |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | 389 | ||
390 | down(&chip->open_mutex); | 390 | mutex_lock(&chip->open_mutex); |
391 | if (chip->mode & AD1848_MODE_OPEN) { | 391 | if (chip->mode & AD1848_MODE_OPEN) { |
392 | up(&chip->open_mutex); | 392 | mutex_unlock(&chip->open_mutex); |
393 | return -EAGAIN; | 393 | return -EAGAIN; |
394 | } | 394 | } |
395 | snd_ad1848_mce_down(chip); | 395 | snd_ad1848_mce_down(chip); |
@@ -432,7 +432,7 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode) | |||
432 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 432 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
433 | 433 | ||
434 | chip->mode = mode; | 434 | chip->mode = mode; |
435 | up(&chip->open_mutex); | 435 | mutex_unlock(&chip->open_mutex); |
436 | 436 | ||
437 | return 0; | 437 | return 0; |
438 | } | 438 | } |
@@ -441,9 +441,9 @@ static void snd_ad1848_close(struct snd_ad1848 *chip) | |||
441 | { | 441 | { |
442 | unsigned long flags; | 442 | unsigned long flags; |
443 | 443 | ||
444 | down(&chip->open_mutex); | 444 | mutex_lock(&chip->open_mutex); |
445 | if (!chip->mode) { | 445 | if (!chip->mode) { |
446 | up(&chip->open_mutex); | 446 | mutex_unlock(&chip->open_mutex); |
447 | return; | 447 | return; |
448 | } | 448 | } |
449 | /* disable IRQ */ | 449 | /* disable IRQ */ |
@@ -471,7 +471,7 @@ static void snd_ad1848_close(struct snd_ad1848 *chip) | |||
471 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 471 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
472 | 472 | ||
473 | chip->mode = 0; | 473 | chip->mode = 0; |
474 | up(&chip->open_mutex); | 474 | mutex_unlock(&chip->open_mutex); |
475 | } | 475 | } |
476 | 476 | ||
477 | /* | 477 | /* |
@@ -889,7 +889,7 @@ int snd_ad1848_create(struct snd_card *card, | |||
889 | if (chip == NULL) | 889 | if (chip == NULL) |
890 | return -ENOMEM; | 890 | return -ENOMEM; |
891 | spin_lock_init(&chip->reg_lock); | 891 | spin_lock_init(&chip->reg_lock); |
892 | init_MUTEX(&chip->open_mutex); | 892 | mutex_init(&chip->open_mutex); |
893 | chip->card = card; | 893 | chip->card = card; |
894 | chip->port = port; | 894 | chip->port = port; |
895 | chip->irq = -1; | 895 | chip->irq = -1; |
@@ -1202,10 +1202,8 @@ int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int | |||
1202 | strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); | 1202 | strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); |
1203 | ctl->id.index = index; | 1203 | ctl->id.index = index; |
1204 | ctl->private_value = value; | 1204 | ctl->private_value = value; |
1205 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) { | 1205 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) |
1206 | snd_ctl_free_one(ctl); | ||
1207 | return err; | 1206 | return err; |
1208 | } | ||
1209 | return 0; | 1207 | return 0; |
1210 | } | 1208 | } |
1211 | 1209 | ||
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index ab67b5c2590d..a30dcd962525 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
@@ -203,8 +203,10 @@ static int __init alsa_card_cs4231_init(void) | |||
203 | return err; | 203 | return err; |
204 | 204 | ||
205 | cards = 0; | 205 | cards = 0; |
206 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 206 | for (i = 0; i < SNDRV_CARDS; i++) { |
207 | struct platform_device *device; | 207 | struct platform_device *device; |
208 | if (! enable[i]) | ||
209 | continue; | ||
208 | device = platform_device_register_simple(SND_CS4231_DRIVER, | 210 | device = platform_device_register_simple(SND_CS4231_DRIVER, |
209 | i, NULL, 0); | 211 | i, NULL, 0); |
210 | if (IS_ERR(device)) { | 212 | if (IS_ERR(device)) { |
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index eab7eb59b5f7..823db8246701 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c | |||
@@ -531,7 +531,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, | |||
531 | unsigned long flags; | 531 | unsigned long flags; |
532 | int full_calib = 1; | 532 | int full_calib = 1; |
533 | 533 | ||
534 | down(&chip->mce_mutex); | 534 | mutex_lock(&chip->mce_mutex); |
535 | snd_cs4231_calibrate_mute(chip, 1); | 535 | snd_cs4231_calibrate_mute(chip, 1); |
536 | if (chip->hardware == CS4231_HW_CS4231A || | 536 | if (chip->hardware == CS4231_HW_CS4231A || |
537 | (chip->hardware & CS4231_HW_CS4232_MASK)) { | 537 | (chip->hardware & CS4231_HW_CS4232_MASK)) { |
@@ -560,7 +560,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, | |||
560 | snd_cs4231_mce_down(chip); | 560 | snd_cs4231_mce_down(chip); |
561 | } | 561 | } |
562 | snd_cs4231_calibrate_mute(chip, 0); | 562 | snd_cs4231_calibrate_mute(chip, 0); |
563 | up(&chip->mce_mutex); | 563 | mutex_unlock(&chip->mce_mutex); |
564 | } | 564 | } |
565 | 565 | ||
566 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, | 566 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, |
@@ -570,7 +570,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, | |||
570 | unsigned long flags; | 570 | unsigned long flags; |
571 | int full_calib = 1; | 571 | int full_calib = 1; |
572 | 572 | ||
573 | down(&chip->mce_mutex); | 573 | mutex_lock(&chip->mce_mutex); |
574 | snd_cs4231_calibrate_mute(chip, 1); | 574 | snd_cs4231_calibrate_mute(chip, 1); |
575 | if (chip->hardware == CS4231_HW_CS4231A || | 575 | if (chip->hardware == CS4231_HW_CS4231A || |
576 | (chip->hardware & CS4231_HW_CS4232_MASK)) { | 576 | (chip->hardware & CS4231_HW_CS4232_MASK)) { |
@@ -603,7 +603,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, | |||
603 | snd_cs4231_mce_down(chip); | 603 | snd_cs4231_mce_down(chip); |
604 | } | 604 | } |
605 | snd_cs4231_calibrate_mute(chip, 0); | 605 | snd_cs4231_calibrate_mute(chip, 0); |
606 | up(&chip->mce_mutex); | 606 | mutex_unlock(&chip->mce_mutex); |
607 | } | 607 | } |
608 | 608 | ||
609 | /* | 609 | /* |
@@ -709,15 +709,15 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) | |||
709 | { | 709 | { |
710 | unsigned long flags; | 710 | unsigned long flags; |
711 | 711 | ||
712 | down(&chip->open_mutex); | 712 | mutex_lock(&chip->open_mutex); |
713 | if ((chip->mode & mode) || | 713 | if ((chip->mode & mode) || |
714 | ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { | 714 | ((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) { |
715 | up(&chip->open_mutex); | 715 | mutex_unlock(&chip->open_mutex); |
716 | return -EAGAIN; | 716 | return -EAGAIN; |
717 | } | 717 | } |
718 | if (chip->mode & CS4231_MODE_OPEN) { | 718 | if (chip->mode & CS4231_MODE_OPEN) { |
719 | chip->mode |= mode; | 719 | chip->mode |= mode; |
720 | up(&chip->open_mutex); | 720 | mutex_unlock(&chip->open_mutex); |
721 | return 0; | 721 | return 0; |
722 | } | 722 | } |
723 | /* ok. now enable and ack CODEC IRQ */ | 723 | /* ok. now enable and ack CODEC IRQ */ |
@@ -737,7 +737,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) | |||
737 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 737 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
738 | 738 | ||
739 | chip->mode = mode; | 739 | chip->mode = mode; |
740 | up(&chip->open_mutex); | 740 | mutex_unlock(&chip->open_mutex); |
741 | return 0; | 741 | return 0; |
742 | } | 742 | } |
743 | 743 | ||
@@ -745,10 +745,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
745 | { | 745 | { |
746 | unsigned long flags; | 746 | unsigned long flags; |
747 | 747 | ||
748 | down(&chip->open_mutex); | 748 | mutex_lock(&chip->open_mutex); |
749 | chip->mode &= ~mode; | 749 | chip->mode &= ~mode; |
750 | if (chip->mode & CS4231_MODE_OPEN) { | 750 | if (chip->mode & CS4231_MODE_OPEN) { |
751 | up(&chip->open_mutex); | 751 | mutex_unlock(&chip->open_mutex); |
752 | return; | 752 | return; |
753 | } | 753 | } |
754 | snd_cs4231_calibrate_mute(chip, 1); | 754 | snd_cs4231_calibrate_mute(chip, 1); |
@@ -785,7 +785,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
785 | snd_cs4231_calibrate_mute(chip, 0); | 785 | snd_cs4231_calibrate_mute(chip, 0); |
786 | 786 | ||
787 | chip->mode = 0; | 787 | chip->mode = 0; |
788 | up(&chip->open_mutex); | 788 | mutex_unlock(&chip->open_mutex); |
789 | } | 789 | } |
790 | 790 | ||
791 | /* | 791 | /* |
@@ -1408,8 +1408,8 @@ static int snd_cs4231_new(struct snd_card *card, | |||
1408 | chip->hwshare = hwshare; | 1408 | chip->hwshare = hwshare; |
1409 | 1409 | ||
1410 | spin_lock_init(&chip->reg_lock); | 1410 | spin_lock_init(&chip->reg_lock); |
1411 | init_MUTEX(&chip->mce_mutex); | 1411 | mutex_init(&chip->mce_mutex); |
1412 | init_MUTEX(&chip->open_mutex); | 1412 | mutex_init(&chip->open_mutex); |
1413 | chip->card = card; | 1413 | chip->card = card; |
1414 | chip->rate_constraint = snd_cs4231_xrate; | 1414 | chip->rate_constraint = snd_cs4231_xrate; |
1415 | chip->set_playback_format = snd_cs4231_playback_format; | 1415 | 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) | |||
1538 | return err; | 1538 | return err; |
1539 | 1539 | ||
1540 | spin_lock_init(&chip->reg_lock); | 1540 | spin_lock_init(&chip->reg_lock); |
1541 | init_MUTEX(&chip->mce_mutex); | 1541 | mutex_init(&chip->mce_mutex); |
1542 | init_MUTEX(&chip->open_mutex); | 1542 | mutex_init(&chip->open_mutex); |
1543 | 1543 | ||
1544 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); | 1544 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops); |
1545 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); | 1545 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops); |
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 99a42138bea0..4060918e0327 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
@@ -771,9 +771,9 @@ static int __init alsa_card_cs423x_init(void) | |||
771 | if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) | 771 | if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) |
772 | return err; | 772 | return err; |
773 | 773 | ||
774 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 774 | for (i = 0; i < SNDRV_CARDS; i++) { |
775 | struct platform_device *device; | 775 | struct platform_device *device; |
776 | if (is_isapnp_selected(i)) | 776 | if (! enable[i] || is_isapnp_selected(i)) |
777 | continue; | 777 | continue; |
778 | device = platform_device_register_simple(CS423X_DRIVER, | 778 | device = platform_device_register_simple(CS423X_DRIVER, |
779 | i, NULL, 0); | 779 | i, NULL, 0); |
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c index e36981d64ec5..7a5a6c71f5e4 100644 --- a/sound/isa/cs423x/cs4236_lib.c +++ b/sound/isa/cs423x/cs4236_lib.c | |||
@@ -644,7 +644,7 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s | |||
644 | val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2; | 644 | val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2; |
645 | change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)]; | 645 | change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)]; |
646 | snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1); | 646 | snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1); |
647 | snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val1); | 647 | snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2); |
648 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 648 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
649 | return change; | 649 | return change; |
650 | } | 650 | } |
@@ -841,7 +841,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn | |||
841 | 841 | ||
842 | enable = ucontrol->value.integer.value[0] & 1; | 842 | enable = ucontrol->value.integer.value[0] & 1; |
843 | 843 | ||
844 | down(&chip->mce_mutex); | 844 | mutex_lock(&chip->mce_mutex); |
845 | snd_cs4231_mce_up(chip); | 845 | snd_cs4231_mce_up(chip); |
846 | spin_lock_irqsave(&chip->reg_lock, flags); | 846 | spin_lock_irqsave(&chip->reg_lock, flags); |
847 | val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1); | 847 | 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 | |||
854 | snd_cs4236_ctrl_out(chip, 4, val); | 854 | snd_cs4236_ctrl_out(chip, 4, val); |
855 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 855 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
856 | snd_cs4231_mce_down(chip); | 856 | snd_cs4231_mce_down(chip); |
857 | up(&chip->mce_mutex); | 857 | mutex_unlock(&chip->mce_mutex); |
858 | 858 | ||
859 | #if 0 | 859 | #if 0 |
860 | printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", | 860 | printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", |
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 50d23cf3d7cc..2b69fc829265 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
@@ -207,8 +207,10 @@ static int __init alsa_card_es1688_init(void) | |||
207 | return err; | 207 | return err; |
208 | 208 | ||
209 | cards = 0; | 209 | cards = 0; |
210 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 210 | for (i = 0; i < SNDRV_CARDS; i++) { |
211 | struct platform_device *device; | 211 | struct platform_device *device; |
212 | if (! enable[i]) | ||
213 | continue; | ||
212 | device = platform_device_register_simple(ES1688_DRIVER, | 214 | device = platform_device_register_simple(ES1688_DRIVER, |
213 | i, NULL, 0); | 215 | i, NULL, 0); |
214 | if (IS_ERR(device)) { | 216 | if (IS_ERR(device)) { |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 08f032b51107..721955d26194 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -49,6 +49,10 @@ | |||
49 | * - contrarily to some pages in DS_1869.PDF the rates can be set | 49 | * - contrarily to some pages in DS_1869.PDF the rates can be set |
50 | * independently. | 50 | * independently. |
51 | * | 51 | * |
52 | * - Zoom Video is implemented by sharing the FM DAC, thus the user can | ||
53 | * have either FM playback or Video playback but not both simultaneously. | ||
54 | * The Video Playback Switch mixer control toggles this choice. | ||
55 | * | ||
52 | * BUGS: | 56 | * BUGS: |
53 | * | 57 | * |
54 | * - There is a major trouble I noted: | 58 | * - There is a major trouble I noted: |
@@ -63,7 +67,16 @@ | |||
63 | * | 67 | * |
64 | */ | 68 | */ |
65 | 69 | ||
66 | 70 | /* | |
71 | * ES1879 NOTES: | ||
72 | * - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback | ||
73 | * seems to be effected (speaker_test plays a lower frequency). Can't find | ||
74 | * anything in the datasheet to account for this, so a Video Playback Switch | ||
75 | * control has been included to allow ZV to be enabled only when necessary. | ||
76 | * Then again on at least one test system the 0x71 bit 6 enable bit is not | ||
77 | * needed for ZV, so maybe the datasheet is entirely wrong here. | ||
78 | */ | ||
79 | |||
67 | #include <sound/driver.h> | 80 | #include <sound/driver.h> |
68 | #include <linux/init.h> | 81 | #include <linux/init.h> |
69 | #include <linux/err.h> | 82 | #include <linux/err.h> |
@@ -148,7 +161,7 @@ struct snd_audiodrive { | |||
148 | #define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */ | 161 | #define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */ |
149 | #define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */ | 162 | #define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */ |
150 | #define ES18XX_AUXB 0x0040 /* AuxB mixer control */ | 163 | #define ES18XX_AUXB 0x0040 /* AuxB mixer control */ |
151 | #define ES18XX_HWV 0x0080 /* Has hardware volume */ | 164 | #define ES18XX_HWV 0x0080 /* Has seperate hardware volume mixer controls*/ |
152 | #define ES18XX_MONO 0x0100 /* Mono_in mixer control */ | 165 | #define ES18XX_MONO 0x0100 /* Mono_in mixer control */ |
153 | #define ES18XX_I2S 0x0200 /* I2S mixer control */ | 166 | #define ES18XX_I2S 0x0200 /* I2S mixer control */ |
154 | #define ES18XX_MUTEREC 0x0400 /* Record source can be muted */ | 167 | #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 | |||
788 | 801 | ||
789 | /* Hardware volume */ | 802 | /* Hardware volume */ |
790 | if (status & HWV_IRQ) { | 803 | if (status & HWV_IRQ) { |
791 | int split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; | 804 | int split = 0; |
792 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); | 805 | if (chip->caps & ES18XX_HWV) { |
793 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); | 806 | split = snd_es18xx_mixer_read(chip, 0x64) & 0x80; |
807 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id); | ||
808 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id); | ||
809 | } | ||
794 | if (!split) { | 810 | if (!split) { |
795 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); | 811 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id); |
796 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id); | 812 | 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) | |||
939 | * MIXER part | 955 | * MIXER part |
940 | */ | 956 | */ |
941 | 957 | ||
958 | /* Record source mux routines: | ||
959 | * Depending on the chipset this mux switches between 4, 5, or 8 possible inputs. | ||
960 | * bit table for the 4/5 source mux: | ||
961 | * reg 1C: | ||
962 | * b2 b1 b0 muxSource | ||
963 | * x 0 x microphone | ||
964 | * 0 1 x CD | ||
965 | * 1 1 0 line | ||
966 | * 1 1 1 mixer | ||
967 | * if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines | ||
968 | * either the play mixer or the capture mixer. | ||
969 | * | ||
970 | * "map4Source" translates from source number to reg bit pattern | ||
971 | * "invMap4Source" translates from reg bit pattern to source number | ||
972 | */ | ||
973 | |||
942 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 974 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
943 | { | 975 | { |
944 | static char *texts[8] = { | 976 | static char *texts4Source[4] = { |
977 | "Mic", "CD", "Line", "Master" | ||
978 | }; | ||
979 | static char *texts5Source[5] = { | ||
980 | "Mic", "CD", "Line", "Master", "Mix" | ||
981 | }; | ||
982 | static char *texts8Source[8] = { | ||
945 | "Mic", "Mic Master", "CD", "AOUT", | 983 | "Mic", "Mic Master", "CD", "AOUT", |
946 | "Mic1", "Mix", "Line", "Master" | 984 | "Mic1", "Mix", "Line", "Master" |
947 | }; | 985 | }; |
986 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); | ||
948 | 987 | ||
949 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 988 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
950 | uinfo->count = 1; | 989 | uinfo->count = 1; |
951 | uinfo->value.enumerated.items = 8; | 990 | switch (chip->version) { |
952 | if (uinfo->value.enumerated.item > 7) | 991 | case 0x1868: |
953 | uinfo->value.enumerated.item = 7; | 992 | case 0x1878: |
954 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | 993 | uinfo->value.enumerated.items = 4; |
994 | if (uinfo->value.enumerated.item > 3) | ||
995 | uinfo->value.enumerated.item = 3; | ||
996 | strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]); | ||
997 | break; | ||
998 | case 0x1887: | ||
999 | case 0x1888: | ||
1000 | uinfo->value.enumerated.items = 5; | ||
1001 | if (uinfo->value.enumerated.item > 4) | ||
1002 | uinfo->value.enumerated.item = 4; | ||
1003 | strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]); | ||
1004 | break; | ||
1005 | case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */ | ||
1006 | case 0x1879: | ||
1007 | uinfo->value.enumerated.items = 8; | ||
1008 | if (uinfo->value.enumerated.item > 7) | ||
1009 | uinfo->value.enumerated.item = 7; | ||
1010 | strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]); | ||
1011 | break; | ||
1012 | default: | ||
1013 | return -EINVAL; | ||
1014 | } | ||
955 | return 0; | 1015 | return 0; |
956 | } | 1016 | } |
957 | 1017 | ||
958 | static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1018 | static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
959 | { | 1019 | { |
1020 | static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3}; | ||
960 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); | 1021 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); |
961 | ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; | 1022 | int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07; |
1023 | if (!(chip->version == 0x1869 || chip->version == 0x1879)) { | ||
1024 | muxSource = invMap4Source[muxSource]; | ||
1025 | if (muxSource==3 && | ||
1026 | (chip->version == 0x1887 || chip->version == 0x1888) && | ||
1027 | (snd_es18xx_mixer_read(chip, 0x7a) & 0x08) | ||
1028 | ) | ||
1029 | muxSource = 4; | ||
1030 | } | ||
1031 | ucontrol->value.enumerated.item[0] = muxSource; | ||
962 | return 0; | 1032 | return 0; |
963 | } | 1033 | } |
964 | 1034 | ||
965 | static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1035 | static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
966 | { | 1036 | { |
1037 | static unsigned char map4Source[4] = {0, 2, 6, 7}; | ||
967 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); | 1038 | struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol); |
968 | unsigned char val = ucontrol->value.enumerated.item[0]; | 1039 | unsigned char val = ucontrol->value.enumerated.item[0]; |
969 | 1040 | unsigned char retVal = 0; | |
970 | if (val > 7) | 1041 | |
1042 | switch (chip->version) { | ||
1043 | /* 5 source chips */ | ||
1044 | case 0x1887: | ||
1045 | case 0x1888: | ||
1046 | if (val > 4) | ||
1047 | return -EINVAL; | ||
1048 | if (val == 4) { | ||
1049 | retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08; | ||
1050 | val = 3; | ||
1051 | } else | ||
1052 | retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00; | ||
1053 | /* 4 source chips */ | ||
1054 | case 0x1868: | ||
1055 | case 0x1878: | ||
1056 | if (val > 3) | ||
1057 | return -EINVAL; | ||
1058 | val = map4Source[val]; | ||
1059 | break; | ||
1060 | /* 8 source chips */ | ||
1061 | case 0x1869: | ||
1062 | case 0x1879: | ||
1063 | if (val > 7) | ||
1064 | return -EINVAL; | ||
1065 | break; | ||
1066 | default: | ||
971 | return -EINVAL; | 1067 | return -EINVAL; |
972 | return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val; | 1068 | } |
1069 | return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal; | ||
973 | } | 1070 | } |
974 | 1071 | ||
975 | static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1072 | 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 | |||
1191 | return change; | 1288 | return change; |
1192 | } | 1289 | } |
1193 | 1290 | ||
1291 | /* Mixer controls | ||
1292 | * These arrays contain setup data for mixer controls. | ||
1293 | * | ||
1294 | * The controls that are universal to all chipsets are fully initialized | ||
1295 | * here. | ||
1296 | */ | ||
1194 | static struct snd_kcontrol_new snd_es18xx_base_controls[] = { | 1297 | static struct snd_kcontrol_new snd_es18xx_base_controls[] = { |
1195 | ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0), | 1298 | ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0), |
1196 | ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1), | 1299 | ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1), |
1197 | ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0), | 1300 | ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0), |
1198 | ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0), | 1301 | ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0), |
1199 | ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0), | 1302 | ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0), |
1200 | ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), | ||
1201 | ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0), | 1303 | ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0), |
1202 | ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0), | 1304 | ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0), |
1203 | ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0), | ||
1204 | ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0), | 1305 | ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0), |
1205 | ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0), | 1306 | ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0), |
1206 | ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), | ||
1207 | { | 1307 | { |
1208 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1308 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1209 | .name = "Capture Source", | 1309 | .name = "Capture Source", |
@@ -1213,19 +1313,37 @@ ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), | |||
1213 | } | 1313 | } |
1214 | }; | 1314 | }; |
1215 | 1315 | ||
1216 | static struct snd_kcontrol_new snd_es18xx_mono_in_control = | ||
1217 | ES18XX_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0); | ||
1218 | |||
1219 | static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = { | 1316 | static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = { |
1220 | ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0), | 1317 | ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0), |
1221 | ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0), | 1318 | ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0), |
1222 | ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0), | 1319 | ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0), |
1223 | ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0), | 1320 | ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0), |
1224 | ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0), | ||
1225 | ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0), | 1321 | ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0), |
1226 | ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0) | 1322 | ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0) |
1227 | }; | 1323 | }; |
1228 | 1324 | ||
1325 | /* | ||
1326 | * The chipset specific mixer controls | ||
1327 | */ | ||
1328 | static struct snd_kcontrol_new snd_es18xx_opt_speaker = | ||
1329 | ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0); | ||
1330 | |||
1331 | static struct snd_kcontrol_new snd_es18xx_opt_1869[] = { | ||
1332 | ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1), | ||
1333 | ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0), | ||
1334 | ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), | ||
1335 | ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) | ||
1336 | }; | ||
1337 | |||
1338 | static struct snd_kcontrol_new snd_es18xx_opt_1878 = | ||
1339 | ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0); | ||
1340 | |||
1341 | static struct snd_kcontrol_new snd_es18xx_opt_1879[] = { | ||
1342 | ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0), | ||
1343 | ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0), | ||
1344 | ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0) | ||
1345 | }; | ||
1346 | |||
1229 | static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = { | 1347 | static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = { |
1230 | ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0), | 1348 | ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0), |
1231 | }; | 1349 | }; |
@@ -1270,7 +1388,6 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = { | |||
1270 | ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), | 1388 | ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), |
1271 | }; | 1389 | }; |
1272 | 1390 | ||
1273 | #if 0 | ||
1274 | static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) | 1391 | static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) |
1275 | { | 1392 | { |
1276 | int data; | 1393 | int data; |
@@ -1281,7 +1398,6 @@ static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned ch | |||
1281 | spin_unlock_irqrestore(&chip->ctrl_lock, flags); | 1398 | spin_unlock_irqrestore(&chip->ctrl_lock, flags); |
1282 | return data; | 1399 | return data; |
1283 | } | 1400 | } |
1284 | #endif | ||
1285 | 1401 | ||
1286 | static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, | 1402 | static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, |
1287 | unsigned char reg, unsigned char data) | 1403 | unsigned char reg, unsigned char data) |
@@ -1427,6 +1543,17 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) | |||
1427 | snd_es18xx_mixer_write(chip, 0x58, 0x94); | 1543 | snd_es18xx_mixer_write(chip, 0x58, 0x94); |
1428 | snd_es18xx_mixer_write(chip, 0x5a, 0x80); | 1544 | snd_es18xx_mixer_write(chip, 0x5a, 0x80); |
1429 | } | 1545 | } |
1546 | /* Flip the "enable I2S" bits for those chipsets that need it */ | ||
1547 | switch (chip->version) { | ||
1548 | case 0x1879: | ||
1549 | //Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow) | ||
1550 | //so a Switch control has been added to toggle this 0x71 bit on/off: | ||
1551 | //snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40); | ||
1552 | /* Note: we fall through on purpose here. */ | ||
1553 | case 0x1878: | ||
1554 | snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40); | ||
1555 | break; | ||
1556 | } | ||
1430 | /* Mute input source */ | 1557 | /* Mute input source */ |
1431 | if (chip->caps & ES18XX_MUTEREC) | 1558 | if (chip->caps & ES18XX_MUTEREC) |
1432 | mask = 0x10; | 1559 | mask = 0x10; |
@@ -1476,11 +1603,14 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip) | |||
1476 | } | 1603 | } |
1477 | 1604 | ||
1478 | outb(0x40, chip->port + 0x04); | 1605 | outb(0x40, chip->port + 0x04); |
1606 | udelay(10); | ||
1479 | hi = inb(chip->port + 0x05); | 1607 | hi = inb(chip->port + 0x05); |
1608 | udelay(10); | ||
1480 | lo = inb(chip->port + 0x05); | 1609 | lo = inb(chip->port + 0x05); |
1481 | if (hi != lo) { | 1610 | if (hi != lo) { |
1482 | chip->version = hi << 8 | lo; | 1611 | chip->version = hi << 8 | lo; |
1483 | chip->ctrl_port = inb(chip->port + 0x05) << 8; | 1612 | chip->ctrl_port = inb(chip->port + 0x05) << 8; |
1613 | udelay(10); | ||
1484 | chip->ctrl_port += inb(chip->port + 0x05); | 1614 | chip->ctrl_port += inb(chip->port + 0x05); |
1485 | 1615 | ||
1486 | if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) { | 1616 | 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) | |||
1519 | 1649 | ||
1520 | switch (chip->version) { | 1650 | switch (chip->version) { |
1521 | case 0x1868: | 1651 | case 0x1868: |
1522 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_HWV; | 1652 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL; |
1523 | break; | 1653 | break; |
1524 | case 0x1869: | 1654 | case 0x1869: |
1525 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV; | 1655 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV; |
1526 | break; | 1656 | break; |
1527 | case 0x1878: | 1657 | case 0x1878: |
1528 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; | 1658 | chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL; |
1529 | break; | 1659 | break; |
1530 | case 0x1879: | 1660 | case 0x1879: |
1531 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; | 1661 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; |
1532 | break; | 1662 | break; |
1533 | case 0x1887: | 1663 | case 0x1887: |
1534 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV; | 1664 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; |
1535 | break; | 1665 | break; |
1536 | case 0x1888: | 1666 | case 0x1888: |
1537 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV; | 1667 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; |
1538 | break; | 1668 | break; |
1539 | default: | 1669 | default: |
1540 | snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n", | 1670 | 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) | |||
1778 | } | 1908 | } |
1779 | } | 1909 | } |
1780 | 1910 | ||
1781 | if (chip->caps & ES18XX_MONO) { | ||
1782 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_mono_in_control, chip))) < 0) | ||
1783 | return err; | ||
1784 | } | ||
1785 | if (chip->caps & ES18XX_RECMIX) { | 1911 | if (chip->caps & ES18XX_RECMIX) { |
1786 | for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) { | 1912 | for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) { |
1787 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0) | 1913 | 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) | |||
1819 | 1945 | ||
1820 | } | 1946 | } |
1821 | } | 1947 | } |
1948 | /* finish initializing other chipset specific controls | ||
1949 | */ | ||
1950 | if (chip->version != 0x1868) { | ||
1951 | err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker, | ||
1952 | chip)); | ||
1953 | if (err < 0) | ||
1954 | return err; | ||
1955 | } | ||
1956 | if (chip->version == 0x1869) { | ||
1957 | for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) { | ||
1958 | err = snd_ctl_add(card, | ||
1959 | snd_ctl_new1(&snd_es18xx_opt_1869[idx], | ||
1960 | chip)); | ||
1961 | if (err < 0) | ||
1962 | return err; | ||
1963 | } | ||
1964 | } else if (chip->version == 0x1878) { | ||
1965 | err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878, | ||
1966 | chip)); | ||
1967 | if (err < 0) | ||
1968 | return err; | ||
1969 | } else if (chip->version == 0x1879) { | ||
1970 | for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) { | ||
1971 | err = snd_ctl_add(card, | ||
1972 | snd_ctl_new1(&snd_es18xx_opt_1879[idx], | ||
1973 | chip)); | ||
1974 | if (err < 0) | ||
1975 | return err; | ||
1976 | } | ||
1977 | } | ||
1822 | return 0; | 1978 | return 0; |
1823 | } | 1979 | } |
1824 | 1980 | ||
@@ -1927,6 +2083,7 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard, | |||
1927 | err = pnp_activate_dev(acard->devc); | 2083 | err = pnp_activate_dev(acard->devc); |
1928 | if (err < 0) { | 2084 | if (err < 0) { |
1929 | snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); | 2085 | snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n"); |
2086 | kfree(cfg); | ||
1930 | return -EAGAIN; | 2087 | return -EAGAIN; |
1931 | } | 2088 | } |
1932 | snd_printdd("pnp: port=0x%lx\n", pnp_port_start(acard->devc, 0)); | 2089 | 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) | |||
2225 | if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) | 2382 | if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) |
2226 | return err; | 2383 | return err; |
2227 | 2384 | ||
2228 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 2385 | for (i = 0; i < SNDRV_CARDS; i++) { |
2229 | struct platform_device *device; | 2386 | struct platform_device *device; |
2230 | if (is_isapnp_selected(i)) | 2387 | if (! enable[i] || is_isapnp_selected(i)) |
2231 | continue; | 2388 | continue; |
2232 | device = platform_device_register_simple(ES18XX_DRIVER, | 2389 | device = platform_device_register_simple(ES18XX_DRIVER, |
2233 | i, NULL, 0); | 2390 | i, NULL, 0); |
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 930f4bc56f34..44ee5d3674a1 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c | |||
@@ -149,10 +149,10 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) | |||
149 | 149 | ||
150 | int snd_gf1_dma_init(struct snd_gus_card * gus) | 150 | int snd_gf1_dma_init(struct snd_gus_card * gus) |
151 | { | 151 | { |
152 | down(&gus->dma_mutex); | 152 | mutex_lock(&gus->dma_mutex); |
153 | gus->gf1.dma_shared++; | 153 | gus->gf1.dma_shared++; |
154 | if (gus->gf1.dma_shared > 1) { | 154 | if (gus->gf1.dma_shared > 1) { |
155 | up(&gus->dma_mutex); | 155 | mutex_unlock(&gus->dma_mutex); |
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt; | 158 | gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt; |
@@ -160,7 +160,7 @@ int snd_gf1_dma_init(struct snd_gus_card * gus) | |||
160 | gus->gf1.dma_data_pcm_last = | 160 | gus->gf1.dma_data_pcm_last = |
161 | gus->gf1.dma_data_synth = | 161 | gus->gf1.dma_data_synth = |
162 | gus->gf1.dma_data_synth_last = NULL; | 162 | gus->gf1.dma_data_synth_last = NULL; |
163 | up(&gus->dma_mutex); | 163 | mutex_unlock(&gus->dma_mutex); |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
@@ -168,7 +168,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) | |||
168 | { | 168 | { |
169 | struct snd_gf1_dma_block *block; | 169 | struct snd_gf1_dma_block *block; |
170 | 170 | ||
171 | down(&gus->dma_mutex); | 171 | mutex_lock(&gus->dma_mutex); |
172 | gus->gf1.dma_shared--; | 172 | gus->gf1.dma_shared--; |
173 | if (!gus->gf1.dma_shared) { | 173 | if (!gus->gf1.dma_shared) { |
174 | snd_dma_disable(gus->gf1.dma1); | 174 | snd_dma_disable(gus->gf1.dma1); |
@@ -185,7 +185,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus) | |||
185 | gus->gf1.dma_data_pcm_last = | 185 | gus->gf1.dma_data_pcm_last = |
186 | gus->gf1.dma_data_synth_last = NULL; | 186 | gus->gf1.dma_data_synth_last = NULL; |
187 | } | 187 | } |
188 | up(&gus->dma_mutex); | 188 | mutex_unlock(&gus->dma_mutex); |
189 | return 0; | 189 | return 0; |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 6d15b3d18a87..53eeaf37007d 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c | |||
@@ -225,7 +225,7 @@ int snd_gus_create(struct snd_card *card, | |||
225 | spin_lock_init(&gus->dma_lock); | 225 | spin_lock_init(&gus->dma_lock); |
226 | spin_lock_init(&gus->pcm_volume_level_lock); | 226 | spin_lock_init(&gus->pcm_volume_level_lock); |
227 | spin_lock_init(&gus->uart_cmd_lock); | 227 | spin_lock_init(&gus->uart_cmd_lock); |
228 | init_MUTEX(&gus->dma_mutex); | 228 | mutex_init(&gus->dma_mutex); |
229 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) { | 229 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) { |
230 | snd_gus_free(gus); | 230 | snd_gus_free(gus); |
231 | return err; | 231 | return err; |
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index e8bdb860a19f..3c0d27aa08b3 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c | |||
@@ -34,9 +34,9 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, | |||
34 | void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup) | 34 | void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup) |
35 | { | 35 | { |
36 | if (!xup) { | 36 | if (!xup) { |
37 | down(&alloc->memory_mutex); | 37 | mutex_lock(&alloc->memory_mutex); |
38 | } else { | 38 | } else { |
39 | up(&alloc->memory_mutex); | 39 | mutex_unlock(&alloc->memory_mutex); |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
@@ -59,7 +59,7 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc, | |||
59 | alloc->first = nblock; | 59 | alloc->first = nblock; |
60 | else | 60 | else |
61 | nblock->prev->next = nblock; | 61 | nblock->prev->next = nblock; |
62 | up(&alloc->memory_mutex); | 62 | mutex_unlock(&alloc->memory_mutex); |
63 | return NULL; | 63 | return NULL; |
64 | } | 64 | } |
65 | pblock = pblock->next; | 65 | pblock = pblock->next; |
@@ -80,7 +80,7 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo | |||
80 | { | 80 | { |
81 | if (block->share) { /* ok.. shared block */ | 81 | if (block->share) { /* ok.. shared block */ |
82 | block->share--; | 82 | block->share--; |
83 | up(&alloc->memory_mutex); | 83 | mutex_unlock(&alloc->memory_mutex); |
84 | return 0; | 84 | return 0; |
85 | } | 85 | } |
86 | if (alloc->first == block) { | 86 | if (alloc->first == block) { |
@@ -244,7 +244,7 @@ int snd_gf1_mem_init(struct snd_gus_card * gus) | |||
244 | #endif | 244 | #endif |
245 | 245 | ||
246 | alloc = &gus->gf1.mem_alloc; | 246 | alloc = &gus->gf1.mem_alloc; |
247 | init_MUTEX(&alloc->memory_mutex); | 247 | mutex_init(&alloc->memory_mutex); |
248 | alloc->first = alloc->last = NULL; | 248 | alloc->first = alloc->last = NULL; |
249 | if (!gus->gf1.memory) | 249 | if (!gus->gf1.memory) |
250 | return 0; | 250 | return 0; |
@@ -299,7 +299,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry, | |||
299 | 299 | ||
300 | gus = entry->private_data; | 300 | gus = entry->private_data; |
301 | alloc = &gus->gf1.mem_alloc; | 301 | alloc = &gus->gf1.mem_alloc; |
302 | down(&alloc->memory_mutex); | 302 | mutex_lock(&alloc->memory_mutex); |
303 | snd_iprintf(buffer, "8-bit banks : \n "); | 303 | snd_iprintf(buffer, "8-bit banks : \n "); |
304 | for (i = 0; i < 4; i++) | 304 | for (i = 0; i < 4; i++) |
305 | snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : ""); | 305 | 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, | |||
343 | } | 343 | } |
344 | snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n", | 344 | snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n", |
345 | total, used, total - used); | 345 | total, used, total - used); |
346 | up(&alloc->memory_mutex); | 346 | mutex_unlock(&alloc->memory_mutex); |
347 | #if 0 | 347 | #if 0 |
348 | ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n", | 348 | ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n", |
349 | ultra_memory_free_size(card, &card->gf1.mem_alloc), | 349 | ultra_memory_free_size(card, &card->gf1.mem_alloc), |
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index d0829393ec8a..c7f95e7aa018 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c | |||
@@ -114,8 +114,6 @@ static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream) | |||
114 | unsigned char pan; | 114 | unsigned char pan; |
115 | unsigned int voice; | 115 | unsigned int voice; |
116 | 116 | ||
117 | if (substream == NULL) | ||
118 | return; | ||
119 | spin_lock_irqsave(&pcmp->lock, flags); | 117 | spin_lock_irqsave(&pcmp->lock, flags); |
120 | if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) { | 118 | if (pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE) { |
121 | spin_unlock_irqrestore(&pcmp->lock, flags); | 119 | spin_unlock_irqrestore(&pcmp->lock, flags); |
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c index 85a1b051f09a..2767cc187ae3 100644 --- a/sound/isa/gus/gus_synth.c +++ b/sound/isa/gus/gus_synth.c | |||
@@ -55,9 +55,9 @@ static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe * | |||
55 | 55 | ||
56 | if (info->voices > 32) | 56 | if (info->voices > 32) |
57 | return -EINVAL; | 57 | return -EINVAL; |
58 | down(&gus->register_mutex); | 58 | mutex_lock(&gus->register_mutex); |
59 | if (!snd_gus_use_inc(gus)) { | 59 | if (!snd_gus_use_inc(gus)) { |
60 | up(&gus->register_mutex); | 60 | mutex_unlock(&gus->register_mutex); |
61 | return -EFAULT; | 61 | return -EFAULT; |
62 | } | 62 | } |
63 | for (idx = 0; idx < info->voices; idx++) { | 63 | for (idx = 0; idx < info->voices; idx++) { |
@@ -65,12 +65,12 @@ static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe * | |||
65 | if (voice == NULL) { | 65 | if (voice == NULL) { |
66 | snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); | 66 | snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); |
67 | snd_gus_use_dec(gus); | 67 | snd_gus_use_dec(gus); |
68 | up(&gus->register_mutex); | 68 | mutex_unlock(&gus->register_mutex); |
69 | return -EBUSY; | 69 | return -EBUSY; |
70 | } | 70 | } |
71 | voice->index = idx; | 71 | voice->index = idx; |
72 | } | 72 | } |
73 | up(&gus->register_mutex); | 73 | mutex_unlock(&gus->register_mutex); |
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
@@ -79,10 +79,10 @@ static int snd_gus_synth_unuse(void *private_data, struct snd_seq_port_subscribe | |||
79 | struct snd_gus_port * port = private_data; | 79 | struct snd_gus_port * port = private_data; |
80 | struct snd_gus_card * gus = port->gus; | 80 | struct snd_gus_card * gus = port->gus; |
81 | 81 | ||
82 | down(&gus->register_mutex); | 82 | mutex_lock(&gus->register_mutex); |
83 | snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); | 83 | snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port); |
84 | snd_gus_use_dec(gus); | 84 | snd_gus_use_dec(gus); |
85 | up(&gus->register_mutex); | 85 | mutex_unlock(&gus->register_mutex); |
86 | return 0; | 86 | return 0; |
87 | } | 87 | } |
88 | 88 | ||
@@ -223,7 +223,7 @@ static int snd_gus_synth_new_device(struct snd_seq_device *dev) | |||
223 | if (gus == NULL) | 223 | if (gus == NULL) |
224 | return -EINVAL; | 224 | return -EINVAL; |
225 | 225 | ||
226 | init_MUTEX(&gus->register_mutex); | 226 | mutex_init(&gus->register_mutex); |
227 | gus->gf1.seq_client = -1; | 227 | gus->gf1.seq_client = -1; |
228 | 228 | ||
229 | /* allocate new client */ | 229 | /* allocate new client */ |
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 91c219116d7a..26dccfea2437 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c | |||
@@ -247,8 +247,10 @@ static int __init alsa_card_gusclassic_init(void) | |||
247 | return err; | 247 | return err; |
248 | 248 | ||
249 | cards = 0; | 249 | cards = 0; |
250 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 250 | for (i = 0; i < SNDRV_CARDS; i++) { |
251 | struct platform_device *device; | 251 | struct platform_device *device; |
252 | if (! enable[i]) | ||
253 | continue; | ||
252 | device = platform_device_register_simple(GUSCLASSIC_DRIVER, | 254 | device = platform_device_register_simple(GUSCLASSIC_DRIVER, |
253 | i, NULL, 0); | 255 | i, NULL, 0); |
254 | if (IS_ERR(device)) { | 256 | if (IS_ERR(device)) { |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 239f16e6b9ee..31dc20501d0c 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
@@ -357,8 +357,10 @@ static int __init alsa_card_gusextreme_init(void) | |||
357 | return err; | 357 | return err; |
358 | 358 | ||
359 | cards = 0; | 359 | cards = 0; |
360 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 360 | for (i = 0; i < SNDRV_CARDS; i++) { |
361 | struct platform_device *device; | 361 | struct platform_device *device; |
362 | if (! enable[i]) | ||
363 | continue; | ||
362 | device = platform_device_register_simple(GUSEXTREME_DRIVER, | 364 | device = platform_device_register_simple(GUSEXTREME_DRIVER, |
363 | i, NULL, 0); | 365 | i, NULL, 0); |
364 | if (IS_ERR(device)) { | 366 | if (IS_ERR(device)) { |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index d4d2b2a517d5..cafb9b67fa72 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
@@ -384,8 +384,10 @@ static int __init alsa_card_gusmax_init(void) | |||
384 | return err; | 384 | return err; |
385 | 385 | ||
386 | cards = 0; | 386 | cards = 0; |
387 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 387 | for (i = 0; i < SNDRV_CARDS; i++) { |
388 | struct platform_device *device; | 388 | struct platform_device *device; |
389 | if (! enable[i]) | ||
390 | continue; | ||
389 | device = platform_device_register_simple(GUSMAX_DRIVER, | 391 | device = platform_device_register_simple(GUSMAX_DRIVER, |
390 | i, NULL, 0); | 392 | i, NULL, 0); |
391 | if (IS_ERR(device)) { | 393 | if (IS_ERR(device)) { |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 9838d992b101..2cacd0fa6871 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
@@ -935,8 +935,10 @@ static int __init alsa_card_interwave_init(void) | |||
935 | if ((err = platform_driver_register(&snd_interwave_driver)) < 0) | 935 | if ((err = platform_driver_register(&snd_interwave_driver)) < 0) |
936 | return err; | 936 | return err; |
937 | 937 | ||
938 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 938 | for (i = 0; i < SNDRV_CARDS; i++) { |
939 | struct platform_device *device; | 939 | struct platform_device *device; |
940 | if (! enable[i]) | ||
941 | continue; | ||
940 | #ifdef CONFIG_PNP | 942 | #ifdef CONFIG_PNP |
941 | if (isapnp[i]) | 943 | if (isapnp[i]) |
942 | continue; | 944 | continue; |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 9d8431978501..56fcd8a946a4 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
@@ -949,8 +949,10 @@ static int __init alsa_card_opl3sa2_init(void) | |||
949 | if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) | 949 | if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) |
950 | return err; | 950 | return err; |
951 | 951 | ||
952 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 952 | for (i = 0; i < SNDRV_CARDS; i++) { |
953 | struct platform_device *device; | 953 | struct platform_device *device; |
954 | if (! enable[i]) | ||
955 | continue; | ||
954 | #ifdef CONFIG_PNP | 956 | #ifdef CONFIG_PNP |
955 | if (isapnp[i]) | 957 | if (isapnp[i]) |
956 | continue; | 958 | continue; |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 63d96be11b2b..65b28cbc0ebd 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -2088,9 +2088,11 @@ static int __init alsa_card_opti9xx_init(void) | |||
2088 | int error; | 2088 | int error; |
2089 | struct platform_device *device; | 2089 | struct platform_device *device; |
2090 | 2090 | ||
2091 | #ifdef CONFIG_PNP | ||
2091 | pnp_register_card_driver(&opti9xx_pnpc_driver); | 2092 | pnp_register_card_driver(&opti9xx_pnpc_driver); |
2092 | if (snd_opti9xx_pnp_is_probed) | 2093 | if (snd_opti9xx_pnp_is_probed) |
2093 | return 0; | 2094 | return 0; |
2095 | #endif | ||
2094 | if (! is_isapnp_selected()) { | 2096 | if (! is_isapnp_selected()) { |
2095 | error = platform_driver_register(&snd_opti9xx_driver); | 2097 | error = platform_driver_register(&snd_opti9xx_driver); |
2096 | if (error < 0) | 2098 | if (error < 0) |
@@ -2102,7 +2104,9 @@ static int __init alsa_card_opti9xx_init(void) | |||
2102 | } | 2104 | } |
2103 | platform_driver_unregister(&snd_opti9xx_driver); | 2105 | platform_driver_unregister(&snd_opti9xx_driver); |
2104 | } | 2106 | } |
2107 | #ifdef CONFIG_PNP | ||
2105 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); | 2108 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); |
2109 | #endif | ||
2106 | #ifdef MODULE | 2110 | #ifdef MODULE |
2107 | printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); | 2111 | printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); |
2108 | #endif | 2112 | #endif |
@@ -2115,7 +2119,9 @@ static void __exit alsa_card_opti9xx_exit(void) | |||
2115 | platform_device_unregister(snd_opti9xx_platform_device); | 2119 | platform_device_unregister(snd_opti9xx_platform_device); |
2116 | platform_driver_unregister(&snd_opti9xx_driver); | 2120 | platform_driver_unregister(&snd_opti9xx_driver); |
2117 | } | 2121 | } |
2122 | #ifdef CONFIG_PNP | ||
2118 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); | 2123 | pnp_unregister_card_driver(&opti9xx_pnpc_driver); |
2124 | #endif | ||
2119 | } | 2125 | } |
2120 | 2126 | ||
2121 | module_init(alsa_card_opti9xx_init) | 2127 | module_init(alsa_card_opti9xx_init) |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 0667bd14ad60..5737ab76160c 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
@@ -712,9 +712,9 @@ static int __init alsa_card_sb16_init(void) | |||
712 | if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) | 712 | if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) |
713 | return err; | 713 | return err; |
714 | 714 | ||
715 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 715 | for (i = 0; i < SNDRV_CARDS; i++) { |
716 | struct platform_device *device; | 716 | struct platform_device *device; |
717 | if (is_isapnp_selected(i)) | 717 | if (! enable[i] || is_isapnp_selected(i)) |
718 | continue; | 718 | continue; |
719 | device = platform_device_register_simple(SND_SB16_DRIVER, | 719 | device = platform_device_register_simple(SND_SB16_DRIVER, |
720 | i, NULL, 0); | 720 | i, NULL, 0); |
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 9c2b5efbacbf..9703c68e4e08 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c | |||
@@ -138,7 +138,7 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) | |||
138 | p->ops.csp_stop = snd_sb_csp_stop; | 138 | p->ops.csp_stop = snd_sb_csp_stop; |
139 | p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer; | 139 | p->ops.csp_qsound_transfer = snd_sb_csp_qsound_transfer; |
140 | 140 | ||
141 | init_MUTEX(&p->access_mutex); | 141 | mutex_init(&p->access_mutex); |
142 | sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f)); | 142 | sprintf(hw->name, "CSP v%d.%d", (version >> 4), (version & 0x0f)); |
143 | hw->iface = SNDRV_HWDEP_IFACE_SB16CSP; | 143 | hw->iface = SNDRV_HWDEP_IFACE_SB16CSP; |
144 | hw->private_data = p; | 144 | hw->private_data = p; |
@@ -265,13 +265,13 @@ static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file) | |||
265 | */ | 265 | */ |
266 | static int snd_sb_csp_use(struct snd_sb_csp * p) | 266 | static int snd_sb_csp_use(struct snd_sb_csp * p) |
267 | { | 267 | { |
268 | down(&p->access_mutex); | 268 | mutex_lock(&p->access_mutex); |
269 | if (p->used) { | 269 | if (p->used) { |
270 | up(&p->access_mutex); | 270 | mutex_unlock(&p->access_mutex); |
271 | return -EAGAIN; | 271 | return -EAGAIN; |
272 | } | 272 | } |
273 | p->used++; | 273 | p->used++; |
274 | up(&p->access_mutex); | 274 | mutex_unlock(&p->access_mutex); |
275 | 275 | ||
276 | return 0; | 276 | return 0; |
277 | 277 | ||
@@ -282,9 +282,9 @@ static int snd_sb_csp_use(struct snd_sb_csp * p) | |||
282 | */ | 282 | */ |
283 | static int snd_sb_csp_unuse(struct snd_sb_csp * p) | 283 | static int snd_sb_csp_unuse(struct snd_sb_csp * p) |
284 | { | 284 | { |
285 | down(&p->access_mutex); | 285 | mutex_lock(&p->access_mutex); |
286 | p->used--; | 286 | p->used--; |
287 | up(&p->access_mutex); | 287 | mutex_unlock(&p->access_mutex); |
288 | 288 | ||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 60ee79cd14a3..3efa23d303c3 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c | |||
@@ -258,8 +258,10 @@ static int __init alsa_card_sb8_init(void) | |||
258 | return err; | 258 | return err; |
259 | 259 | ||
260 | cards = 0; | 260 | cards = 0; |
261 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 261 | for (i = 0; i < SNDRV_CARDS; i++) { |
262 | struct platform_device *device; | 262 | struct platform_device *device; |
263 | if (! enable[i]) | ||
264 | continue; | ||
263 | device = platform_device_register_simple(SND_SB8_DRIVER, | 265 | device = platform_device_register_simple(SND_SB8_DRIVER, |
264 | i, NULL, 0); | 266 | i, NULL, 0); |
265 | if (IS_ERR(device)) { | 267 | if (IS_ERR(device)) { |
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c index 1a6ee344dddb..490b1ca5cf58 100644 --- a/sound/isa/sb/sb_mixer.c +++ b/sound/isa/sb/sb_mixer.c | |||
@@ -453,10 +453,8 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty | |||
453 | strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); | 453 | strlcpy(ctl->id.name, name, sizeof(ctl->id.name)); |
454 | ctl->id.index = index; | 454 | ctl->id.index = index; |
455 | ctl->private_value = value; | 455 | ctl->private_value = value; |
456 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) { | 456 | if ((err = snd_ctl_add(chip->card, ctl)) < 0) |
457 | snd_ctl_free_one(ctl); | ||
458 | return err; | 457 | return err; |
459 | } | ||
460 | return 0; | 458 | return 0; |
461 | } | 459 | } |
462 | 460 | ||
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 0dbbb35b242c..a60e66afbf90 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c | |||
@@ -360,8 +360,10 @@ static int __init alsa_card_sgalaxy_init(void) | |||
360 | return err; | 360 | return err; |
361 | 361 | ||
362 | cards = 0; | 362 | cards = 0; |
363 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 363 | for (i = 0; i < SNDRV_CARDS; i++) { |
364 | struct platform_device *device; | 364 | struct platform_device *device; |
365 | if (! enable[i]) | ||
366 | continue; | ||
365 | device = platform_device_register_simple(SND_SGALAXY_DRIVER, | 367 | device = platform_device_register_simple(SND_SGALAXY_DRIVER, |
366 | i, NULL, 0); | 368 | i, NULL, 0); |
367 | if (IS_ERR(device)) { | 369 | if (IS_ERR(device)) { |
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index fa3ab960de17..c0115bf9065e 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
@@ -710,8 +710,10 @@ static int __init alsa_card_wavefront_init(void) | |||
710 | if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) | 710 | if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) |
711 | return err; | 711 | return err; |
712 | 712 | ||
713 | for (i = 0; i < SNDRV_CARDS && enable[i]; i++) { | 713 | for (i = 0; i < SNDRV_CARDS; i++) { |
714 | struct platform_device *device; | 714 | struct platform_device *device; |
715 | if (! enable[i]) | ||
716 | continue; | ||
715 | #ifdef CONFIG_PNP | 717 | #ifdef CONFIG_PNP |
716 | if (isapnp[i]) | 718 | if (isapnp[i]) |
717 | continue; | 719 | continue; |
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index 6d8f8b3eabd0..cf476fe1ac56 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <sound/core.h> | 43 | #include <sound/core.h> |
44 | #include <sound/initval.h> | 44 | #include <sound/initval.h> |
45 | #include <sound/pcm.h> | 45 | #include <sound/pcm.h> |
46 | #include <sound/pcm_params.h> | ||
46 | #include <sound/ac97_codec.h> | 47 | #include <sound/ac97_codec.h> |
47 | #include <asm/mach-au1x00/au1000.h> | 48 | #include <asm/mach-au1x00/au1000.h> |
48 | #include <asm/mach-au1x00/au1000_dma.h> | 49 | #include <asm/mach-au1x00/au1000_dma.h> |
@@ -153,6 +154,7 @@ au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes, | |||
153 | { | 154 | { |
154 | struct snd_pcm_substream *substream = stream->substream; | 155 | struct snd_pcm_substream *substream = stream->substream; |
155 | struct snd_pcm_runtime *runtime = substream->runtime; | 156 | struct snd_pcm_runtime *runtime = substream->runtime; |
157 | struct au1000_period *pointer; | ||
156 | unsigned long dma_start; | 158 | unsigned long dma_start; |
157 | int i; | 159 | int i; |
158 | 160 | ||
@@ -559,12 +561,13 @@ snd_au1000_ac97_new(struct snd_au1000 *au1000) | |||
559 | .read = snd_au1000_ac97_read, | 561 | .read = snd_au1000_ac97_read, |
560 | }; | 562 | }; |
561 | 563 | ||
562 | if ((au1000->ac97_res_port = request_region(AC97C_CONFIG, | 564 | if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG), |
563 | sizeof(struct au1000_ac97_reg), "Au1x00 AC97")) == NULL) { | 565 | 0x100000, "Au1x00 AC97")) == NULL) { |
564 | snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n"); | 566 | snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n"); |
565 | return -EBUSY; | 567 | return -EBUSY; |
566 | } | 568 | } |
567 | au1000->ac97_ioport = (struct au1000_ac97_reg *) au1000->ac97_res_port->start; | 569 | au1000->ac97_ioport = (struct au1000_ac97_reg *) |
570 | KSEG1ADDR(au1000->ac97_res_port->start); | ||
568 | 571 | ||
569 | spin_lock_init(&au1000->ac97_lock); | 572 | spin_lock_init(&au1000->ac97_lock); |
570 | 573 | ||
@@ -610,14 +613,17 @@ snd_au1000_free(struct snd_card *card) | |||
610 | release_and_free_resource(au1000->ac97_res_port); | 613 | release_and_free_resource(au1000->ac97_res_port); |
611 | } | 614 | } |
612 | 615 | ||
613 | if (au1000->stream[PLAYBACK]->dma >= 0) | 616 | if (au1000->stream[PLAYBACK]) { |
614 | free_au1000_dma(au1000->stream[PLAYBACK]->dma); | 617 | if (au1000->stream[PLAYBACK]->dma >= 0) |
615 | 618 | free_au1000_dma(au1000->stream[PLAYBACK]->dma); | |
616 | if (au1000->stream[CAPTURE]->dma >= 0) | 619 | kfree(au1000->stream[PLAYBACK]); |
617 | free_au1000_dma(au1000->stream[CAPTURE]->dma); | 620 | } |
618 | 621 | ||
619 | kfree(au1000->stream[PLAYBACK]); | 622 | if (au1000->stream[CAPTURE]) { |
620 | kfree(au1000->stream[CAPTURE]); | 623 | if (au1000->stream[CAPTURE]->dma >= 0) |
624 | free_au1000_dma(au1000->stream[CAPTURE]->dma); | ||
625 | kfree(au1000->stream[CAPTURE]); | ||
626 | } | ||
621 | } | 627 | } |
622 | 628 | ||
623 | 629 | ||
@@ -636,15 +642,19 @@ au1000_init(void) | |||
636 | 642 | ||
637 | card->private_free = snd_au1000_free; | 643 | card->private_free = snd_au1000_free; |
638 | au1000 = card->private_data; | 644 | au1000 = card->private_data; |
639 | /* so that snd_au1000_free will work as intended */ | ||
640 | au1000->card = card; | 645 | au1000->card = card; |
641 | au1000->stream[PLAYBACK]->dma = -1; | 646 | |
642 | au1000->stream[CAPTURE]->dma = -1; | ||
643 | au1000->ac97_res_port = NULL; | ||
644 | au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); | 647 | au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); |
645 | au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); | 648 | au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL); |
649 | /* so that snd_au1000_free will work as intended */ | ||
650 | au1000->ac97_res_port = NULL; | ||
651 | if (au1000->stream[PLAYBACK]) | ||
652 | au1000->stream[PLAYBACK]->dma = -1; | ||
653 | if (au1000->stream[CAPTURE ]) | ||
654 | au1000->stream[CAPTURE ]->dma = -1; | ||
655 | |||
646 | if (au1000->stream[PLAYBACK] == NULL || | 656 | if (au1000->stream[PLAYBACK] == NULL || |
647 | au1000->stream[CAPTURE] == NULL) { | 657 | au1000->stream[CAPTURE ] == NULL) { |
648 | snd_card_free(card); | 658 | snd_card_free(card); |
649 | return -ENOMEM; | 659 | return -ENOMEM; |
650 | } | 660 | } |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3020ca2b602b..278319bbdea1 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | #include <linux/mutex.h> | ||
31 | #include <sound/core.h> | 32 | #include <sound/core.h> |
32 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
33 | #include <sound/ac97_codec.h> | 34 | #include <sound/ac97_codec.h> |
@@ -149,7 +150,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
149 | { 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL }, | 150 | { 0x49544561, 0xffffffff, "IT2646E", patch_it2646, NULL }, |
150 | { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk | 151 | { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk |
151 | { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, | 152 | { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, |
152 | { 0x4e534350, 0xffffffff, "LM4550", NULL, NULL }, | 153 | { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix |
153 | { 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, | 154 | { 0x50534304, 0xffffffff, "UCB1400", NULL, NULL }, |
154 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, | 155 | { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, |
155 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, | 156 | { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, |
@@ -191,9 +192,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { | |||
191 | 192 | ||
192 | static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) | 193 | static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg) |
193 | { | 194 | { |
194 | if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed)) | ||
195 | return 0; | ||
196 | |||
197 | /* filter some registers for buggy codecs */ | 195 | /* filter some registers for buggy codecs */ |
198 | switch (ac97->id) { | 196 | switch (ac97->id) { |
199 | case AC97_ID_AK4540: | 197 | case AC97_ID_AK4540: |
@@ -296,11 +294,11 @@ void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned sh | |||
296 | { | 294 | { |
297 | if (!snd_ac97_valid_reg(ac97, reg)) | 295 | if (!snd_ac97_valid_reg(ac97, reg)) |
298 | return; | 296 | return; |
299 | down(&ac97->reg_mutex); | 297 | mutex_lock(&ac97->reg_mutex); |
300 | ac97->regs[reg] = value; | 298 | ac97->regs[reg] = value; |
301 | ac97->bus->ops->write(ac97, reg, value); | 299 | ac97->bus->ops->write(ac97, reg, value); |
302 | set_bit(reg, ac97->reg_accessed); | 300 | set_bit(reg, ac97->reg_accessed); |
303 | up(&ac97->reg_mutex); | 301 | mutex_unlock(&ac97->reg_mutex); |
304 | } | 302 | } |
305 | 303 | ||
306 | /** | 304 | /** |
@@ -321,14 +319,14 @@ int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short va | |||
321 | 319 | ||
322 | if (!snd_ac97_valid_reg(ac97, reg)) | 320 | if (!snd_ac97_valid_reg(ac97, reg)) |
323 | return -EINVAL; | 321 | return -EINVAL; |
324 | down(&ac97->reg_mutex); | 322 | mutex_lock(&ac97->reg_mutex); |
325 | change = ac97->regs[reg] != value; | 323 | change = ac97->regs[reg] != value; |
326 | if (change) { | 324 | if (change) { |
327 | ac97->regs[reg] = value; | 325 | ac97->regs[reg] = value; |
328 | ac97->bus->ops->write(ac97, reg, value); | 326 | ac97->bus->ops->write(ac97, reg, value); |
329 | } | 327 | } |
330 | set_bit(reg, ac97->reg_accessed); | 328 | set_bit(reg, ac97->reg_accessed); |
331 | up(&ac97->reg_mutex); | 329 | mutex_unlock(&ac97->reg_mutex); |
332 | return change; | 330 | return change; |
333 | } | 331 | } |
334 | 332 | ||
@@ -351,9 +349,9 @@ int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned sho | |||
351 | 349 | ||
352 | if (!snd_ac97_valid_reg(ac97, reg)) | 350 | if (!snd_ac97_valid_reg(ac97, reg)) |
353 | return -EINVAL; | 351 | return -EINVAL; |
354 | down(&ac97->reg_mutex); | 352 | mutex_lock(&ac97->reg_mutex); |
355 | change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); | 353 | change = snd_ac97_update_bits_nolock(ac97, reg, mask, value); |
356 | up(&ac97->reg_mutex); | 354 | mutex_unlock(&ac97->reg_mutex); |
357 | return change; | 355 | return change; |
358 | } | 356 | } |
359 | 357 | ||
@@ -380,12 +378,12 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns | |||
380 | int change; | 378 | int change; |
381 | unsigned short old, new, cfg; | 379 | unsigned short old, new, cfg; |
382 | 380 | ||
383 | down(&ac97->page_mutex); | 381 | mutex_lock(&ac97->page_mutex); |
384 | old = ac97->spec.ad18xx.pcmreg[codec]; | 382 | old = ac97->spec.ad18xx.pcmreg[codec]; |
385 | new = (old & ~mask) | value; | 383 | new = (old & ~mask) | value; |
386 | change = old != new; | 384 | change = old != new; |
387 | if (change) { | 385 | if (change) { |
388 | down(&ac97->reg_mutex); | 386 | mutex_lock(&ac97->reg_mutex); |
389 | cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG); | 387 | cfg = snd_ac97_read_cache(ac97, AC97_AD_SERIAL_CFG); |
390 | ac97->spec.ad18xx.pcmreg[codec] = new; | 388 | ac97->spec.ad18xx.pcmreg[codec] = new; |
391 | /* select single codec */ | 389 | /* select single codec */ |
@@ -397,9 +395,9 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns | |||
397 | /* select all codecs */ | 395 | /* select all codecs */ |
398 | ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG, | 396 | ac97->bus->ops->write(ac97, AC97_AD_SERIAL_CFG, |
399 | cfg | 0x7000); | 397 | cfg | 0x7000); |
400 | up(&ac97->reg_mutex); | 398 | mutex_unlock(&ac97->reg_mutex); |
401 | } | 399 | } |
402 | up(&ac97->page_mutex); | 400 | mutex_unlock(&ac97->page_mutex); |
403 | return change; | 401 | return change; |
404 | } | 402 | } |
405 | 403 | ||
@@ -467,7 +465,7 @@ static int snd_ac97_page_save(struct snd_ac97 *ac97, int reg, struct snd_kcontro | |||
467 | (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 && | 465 | (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 && |
468 | (reg >= 0x60 && reg < 0x70)) { | 466 | (reg >= 0x60 && reg < 0x70)) { |
469 | unsigned short page = (kcontrol->private_value >> 26) & 0x0f; | 467 | unsigned short page = (kcontrol->private_value >> 26) & 0x0f; |
470 | down(&ac97->page_mutex); /* lock paging */ | 468 | mutex_lock(&ac97->page_mutex); /* lock paging */ |
471 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; | 469 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; |
472 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); | 470 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); |
473 | } | 471 | } |
@@ -478,7 +476,7 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) | |||
478 | { | 476 | { |
479 | if (page_save >= 0) { | 477 | if (page_save >= 0) { |
480 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); | 478 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); |
481 | up(&ac97->page_mutex); /* unlock paging */ | 479 | mutex_unlock(&ac97->page_mutex); /* unlock paging */ |
482 | } | 480 | } |
483 | } | 481 | } |
484 | 482 | ||
@@ -674,12 +672,12 @@ static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ | |||
674 | { | 672 | { |
675 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 673 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
676 | 674 | ||
677 | down(&ac97->reg_mutex); | 675 | mutex_lock(&ac97->reg_mutex); |
678 | ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff; | 676 | ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff; |
679 | ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff; | 677 | ucontrol->value.iec958.status[1] = (ac97->spdif_status >> 8) & 0xff; |
680 | ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff; | 678 | ucontrol->value.iec958.status[2] = (ac97->spdif_status >> 16) & 0xff; |
681 | ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff; | 679 | ucontrol->value.iec958.status[3] = (ac97->spdif_status >> 24) & 0xff; |
682 | up(&ac97->reg_mutex); | 680 | mutex_unlock(&ac97->reg_mutex); |
683 | return 0; | 681 | return 0; |
684 | } | 682 | } |
685 | 683 | ||
@@ -718,7 +716,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ | |||
718 | } | 716 | } |
719 | } | 717 | } |
720 | 718 | ||
721 | down(&ac97->reg_mutex); | 719 | mutex_lock(&ac97->reg_mutex); |
722 | change = ac97->spdif_status != new; | 720 | change = ac97->spdif_status != new; |
723 | ac97->spdif_status = new; | 721 | ac97->spdif_status = new; |
724 | 722 | ||
@@ -746,7 +744,7 @@ static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ | |||
746 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ | 744 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ |
747 | } | 745 | } |
748 | } | 746 | } |
749 | up(&ac97->reg_mutex); | 747 | mutex_unlock(&ac97->reg_mutex); |
750 | 748 | ||
751 | return change; | 749 | return change; |
752 | } | 750 | } |
@@ -763,7 +761,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
763 | 761 | ||
764 | value = (ucontrol->value.integer.value[0] & mask); | 762 | value = (ucontrol->value.integer.value[0] & mask); |
765 | 763 | ||
766 | down(&ac97->reg_mutex); | 764 | mutex_lock(&ac97->reg_mutex); |
767 | mask <<= shift; | 765 | mask <<= shift; |
768 | value <<= shift; | 766 | value <<= shift; |
769 | old = snd_ac97_read_cache(ac97, reg); | 767 | old = snd_ac97_read_cache(ac97, reg); |
@@ -777,7 +775,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
777 | if (extst & AC97_EA_SPDIF) | 775 | if (extst & AC97_EA_SPDIF) |
778 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ | 776 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); /* turn on again */ |
779 | } | 777 | } |
780 | up(&ac97->reg_mutex); | 778 | mutex_unlock(&ac97->reg_mutex); |
781 | return change; | 779 | return change; |
782 | } | 780 | } |
783 | 781 | ||
@@ -888,10 +886,10 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct | |||
888 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 886 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
889 | int codec = kcontrol->private_value & 3; | 887 | int codec = kcontrol->private_value & 3; |
890 | 888 | ||
891 | down(&ac97->page_mutex); | 889 | mutex_lock(&ac97->page_mutex); |
892 | ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); | 890 | ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31); |
893 | ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); | 891 | ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31); |
894 | up(&ac97->page_mutex); | 892 | mutex_unlock(&ac97->page_mutex); |
895 | return 0; | 893 | return 0; |
896 | } | 894 | } |
897 | 895 | ||
@@ -1007,9 +1005,6 @@ static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg) | |||
1007 | break; | 1005 | break; |
1008 | } | 1006 | } |
1009 | 1007 | ||
1010 | if (ac97->limited_regs && test_bit(reg, ac97->reg_accessed)) | ||
1011 | return 1; /* allow without check */ | ||
1012 | |||
1013 | val = snd_ac97_read(ac97, reg); | 1008 | val = snd_ac97_read(ac97, reg); |
1014 | if (!(val & mask)) { | 1009 | if (!(val & mask)) { |
1015 | /* nothing seems to be here - mute flag is not set */ | 1010 | /* nothing seems to be here - mute flag is not set */ |
@@ -1029,6 +1024,18 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha | |||
1029 | unsigned char max[3] = { 63, 31, 15 }; | 1024 | unsigned char max[3] = { 63, 31, 15 }; |
1030 | int i; | 1025 | int i; |
1031 | 1026 | ||
1027 | /* first look up the static resolution table */ | ||
1028 | if (ac97->res_table) { | ||
1029 | const struct snd_ac97_res_table *tbl; | ||
1030 | for (tbl = ac97->res_table; tbl->reg; tbl++) { | ||
1031 | if (tbl->reg == reg) { | ||
1032 | *lo_max = tbl->bits & 0xff; | ||
1033 | *hi_max = (tbl->bits >> 8) & 0xff; | ||
1034 | return; | ||
1035 | } | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1032 | *lo_max = *hi_max = 0; | 1039 | *lo_max = *hi_max = 0; |
1033 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { | 1040 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { |
1034 | unsigned short val; | 1041 | unsigned short val; |
@@ -1853,11 +1860,10 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, | |||
1853 | ac97->num = template->num; | 1860 | ac97->num = template->num; |
1854 | ac97->addr = template->addr; | 1861 | ac97->addr = template->addr; |
1855 | ac97->scaps = template->scaps; | 1862 | ac97->scaps = template->scaps; |
1856 | ac97->limited_regs = template->limited_regs; | 1863 | ac97->res_table = template->res_table; |
1857 | memcpy(ac97->reg_accessed, template->reg_accessed, sizeof(ac97->reg_accessed)); | ||
1858 | bus->codec[ac97->num] = ac97; | 1864 | bus->codec[ac97->num] = ac97; |
1859 | init_MUTEX(&ac97->reg_mutex); | 1865 | mutex_init(&ac97->reg_mutex); |
1860 | init_MUTEX(&ac97->page_mutex); | 1866 | mutex_init(&ac97->page_mutex); |
1861 | 1867 | ||
1862 | #ifdef CONFIG_PCI | 1868 | #ifdef CONFIG_PCI |
1863 | if (ac97->pci) { | 1869 | if (ac97->pci) { |
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index a444a78c7c94..4d9cf37300f7 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
@@ -55,12 +57,12 @@ static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsi | |||
55 | unsigned short page_save; | 57 | unsigned short page_save; |
56 | int ret; | 58 | int ret; |
57 | 59 | ||
58 | down(&ac97->page_mutex); | 60 | mutex_lock(&ac97->page_mutex); |
59 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; | 61 | page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK; |
60 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); | 62 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page); |
61 | ret = snd_ac97_update_bits(ac97, reg, mask, value); | 63 | ret = snd_ac97_update_bits(ac97, reg, mask, value); |
62 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); | 64 | snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save); |
63 | up(&ac97->page_mutex); /* unlock paging */ | 65 | mutex_unlock(&ac97->page_mutex); /* unlock paging */ |
64 | return ret; | 66 | return ret; |
65 | } | 67 | } |
66 | 68 | ||
@@ -897,12 +899,12 @@ static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ | |||
897 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); | 899 | struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); |
898 | int err; | 900 | int err; |
899 | 901 | ||
900 | down(&ac97->page_mutex); | 902 | mutex_lock(&ac97->page_mutex); |
901 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); | 903 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0xabba); |
902 | err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, | 904 | err = snd_ac97_update_bits(ac97, AC97_SIGMATEL_BIAS2, 0x0010, |
903 | (ucontrol->value.integer.value[0] & 1) << 4); | 905 | (ucontrol->value.integer.value[0] & 1) << 4); |
904 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); | 906 | snd_ac97_write(ac97, AC97_SIGMATEL_BIAS1, 0); |
905 | up(&ac97->page_mutex); | 907 | mutex_unlock(&ac97->page_mutex); |
906 | return err; | 908 | return err; |
907 | } | 909 | } |
908 | 910 | ||
@@ -2823,3 +2825,33 @@ int mpatch_si3036(struct snd_ac97 * ac97) | |||
2823 | snd_ac97_write_cache(ac97, 0x68, 0); | 2825 | snd_ac97_write_cache(ac97, 0x68, 0); |
2824 | return 0; | 2826 | return 0; |
2825 | } | 2827 | } |
2828 | |||
2829 | /* | ||
2830 | * LM 4550 Codec | ||
2831 | * | ||
2832 | * We use a static resolution table since LM4550 codec cannot be | ||
2833 | * properly autoprobed to determine the resolution via | ||
2834 | * check_volume_resolution(). | ||
2835 | */ | ||
2836 | |||
2837 | static struct snd_ac97_res_table lm4550_restbl[] = { | ||
2838 | { AC97_MASTER, 0x1f1f }, | ||
2839 | { AC97_HEADPHONE, 0x1f1f }, | ||
2840 | { AC97_MASTER_MONO, 0x001f }, | ||
2841 | { AC97_PC_BEEP, 0x001f }, /* LSB is ignored */ | ||
2842 | { AC97_PHONE, 0x001f }, | ||
2843 | { AC97_MIC, 0x001f }, | ||
2844 | { AC97_LINE, 0x1f1f }, | ||
2845 | { AC97_CD, 0x1f1f }, | ||
2846 | { AC97_VIDEO, 0x1f1f }, | ||
2847 | { AC97_AUX, 0x1f1f }, | ||
2848 | { AC97_PCM, 0x1f1f }, | ||
2849 | { AC97_REC_GAIN, 0x0f0f }, | ||
2850 | { } /* terminator */ | ||
2851 | }; | ||
2852 | |||
2853 | int patch_lm4550(struct snd_ac97 *ac97) | ||
2854 | { | ||
2855 | ac97->res_table = lm4550_restbl; | ||
2856 | return 0; | ||
2857 | } | ||
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 5060cb6f2ec3..adcaa04586cb 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h | |||
@@ -59,3 +59,4 @@ int patch_vt1616(struct snd_ac97 * ac97); | |||
59 | int patch_vt1617a(struct snd_ac97 * ac97); | 59 | int patch_vt1617a(struct snd_ac97 * ac97); |
60 | int patch_it2646(struct snd_ac97 * ac97); | 60 | int patch_it2646(struct snd_ac97 * ac97); |
61 | int mpatch_si3036(struct snd_ac97 * ac97); | 61 | int mpatch_si3036(struct snd_ac97 * ac97); |
62 | int patch_lm4550(struct snd_ac97 * ac97); | ||
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index c3e590bf7a02..512a3583b0ce 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 33 | #include <sound/pcm.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
@@ -206,7 +208,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) | |||
206 | mask = AC97_SC_SPSR_MASK; | 208 | mask = AC97_SC_SPSR_MASK; |
207 | } | 209 | } |
208 | 210 | ||
209 | down(&ac97->reg_mutex); | 211 | mutex_lock(&ac97->reg_mutex); |
210 | old = snd_ac97_read(ac97, reg) & mask; | 212 | old = snd_ac97_read(ac97, reg) & mask; |
211 | if (old != bits) { | 213 | if (old != bits) { |
212 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); | 214 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, 0); |
@@ -231,7 +233,7 @@ static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate) | |||
231 | ac97->spdif_status = sbits; | 233 | ac97->spdif_status = sbits; |
232 | } | 234 | } |
233 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); | 235 | snd_ac97_update_bits_nolock(ac97, AC97_EXTENDED_STATUS, AC97_EA_SPDIF, AC97_EA_SPDIF); |
234 | up(&ac97->reg_mutex); | 236 | mutex_unlock(&ac97->reg_mutex); |
235 | return 0; | 237 | return 0; |
236 | } | 238 | } |
237 | 239 | ||
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 7134b3f55fb5..4d523df79cc7 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #include <sound/driver.h> | 25 | #include <sound/driver.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/mutex.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include <sound/ac97_codec.h> | 30 | #include <sound/ac97_codec.h> |
29 | #include <sound/asoundef.h> | 31 | #include <sound/asoundef.h> |
@@ -338,7 +340,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf | |||
338 | { | 340 | { |
339 | struct snd_ac97 *ac97 = entry->private_data; | 341 | struct snd_ac97 *ac97 = entry->private_data; |
340 | 342 | ||
341 | down(&ac97->page_mutex); | 343 | mutex_lock(&ac97->page_mutex); |
342 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 | 344 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 |
343 | int idx; | 345 | int idx; |
344 | for (idx = 0; idx < 3; idx++) | 346 | for (idx = 0; idx < 3; idx++) |
@@ -364,7 +366,7 @@ static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buf | |||
364 | } else { | 366 | } else { |
365 | snd_ac97_proc_read_main(ac97, buffer, 0); | 367 | snd_ac97_proc_read_main(ac97, buffer, 0); |
366 | } | 368 | } |
367 | up(&ac97->page_mutex); | 369 | mutex_unlock(&ac97->page_mutex); |
368 | } | 370 | } |
369 | 371 | ||
370 | #ifdef CONFIG_SND_DEBUG | 372 | #ifdef CONFIG_SND_DEBUG |
@@ -374,7 +376,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in | |||
374 | struct snd_ac97 *ac97 = entry->private_data; | 376 | struct snd_ac97 *ac97 = entry->private_data; |
375 | char line[64]; | 377 | char line[64]; |
376 | unsigned int reg, val; | 378 | unsigned int reg, val; |
377 | down(&ac97->page_mutex); | 379 | mutex_lock(&ac97->page_mutex); |
378 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 380 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
379 | if (sscanf(line, "%x %x", ®, &val) != 2) | 381 | if (sscanf(line, "%x %x", ®, &val) != 2) |
380 | continue; | 382 | continue; |
@@ -382,7 +384,7 @@ static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_in | |||
382 | if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff) | 384 | if (reg < 0x80 && (reg & 1) == 0 && val <= 0xffff) |
383 | snd_ac97_write_cache(ac97, reg, val); | 385 | snd_ac97_write_cache(ac97, reg, val); |
384 | } | 386 | } |
385 | up(&ac97->page_mutex); | 387 | mutex_unlock(&ac97->page_mutex); |
386 | } | 388 | } |
387 | #endif | 389 | #endif |
388 | 390 | ||
@@ -401,7 +403,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, | |||
401 | { | 403 | { |
402 | struct snd_ac97 *ac97 = entry->private_data; | 404 | struct snd_ac97 *ac97 = entry->private_data; |
403 | 405 | ||
404 | down(&ac97->page_mutex); | 406 | mutex_lock(&ac97->page_mutex); |
405 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 | 407 | if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) { // Analog Devices AD1881/85/86 |
406 | 408 | ||
407 | int idx; | 409 | int idx; |
@@ -417,7 +419,7 @@ static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, | |||
417 | } else { | 419 | } else { |
418 | snd_ac97_proc_regs_read_main(ac97, buffer, 0); | 420 | snd_ac97_proc_regs_read_main(ac97, buffer, 0); |
419 | } | 421 | } |
420 | up(&ac97->page_mutex); | 422 | mutex_unlock(&ac97->page_mutex); |
421 | } | 423 | } |
422 | 424 | ||
423 | void snd_ac97_proc_init(struct snd_ac97 * ac97) | 425 | void snd_ac97_proc_init(struct snd_ac97 * ac97) |
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c index dcfb5036ff8b..0fb7b3407312 100644 --- a/sound/pci/ac97/ak4531_codec.c +++ b/sound/pci/ac97/ak4531_codec.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mutex.h> | ||
27 | |||
26 | #include <sound/core.h> | 28 | #include <sound/core.h> |
27 | #include <sound/ak4531_codec.h> | 29 | #include <sound/ak4531_codec.h> |
28 | 30 | ||
@@ -82,9 +84,9 @@ static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
82 | int invert = (kcontrol->private_value >> 22) & 1; | 84 | int invert = (kcontrol->private_value >> 22) & 1; |
83 | int val; | 85 | int val; |
84 | 86 | ||
85 | down(&ak4531->reg_mutex); | 87 | mutex_lock(&ak4531->reg_mutex); |
86 | val = (ak4531->regs[reg] >> shift) & mask; | 88 | val = (ak4531->regs[reg] >> shift) & mask; |
87 | up(&ak4531->reg_mutex); | 89 | mutex_unlock(&ak4531->reg_mutex); |
88 | if (invert) { | 90 | if (invert) { |
89 | val = mask - val; | 91 | val = mask - val; |
90 | } | 92 | } |
@@ -107,11 +109,11 @@ static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
107 | val = mask - val; | 109 | val = mask - val; |
108 | } | 110 | } |
109 | val <<= shift; | 111 | val <<= shift; |
110 | down(&ak4531->reg_mutex); | 112 | mutex_lock(&ak4531->reg_mutex); |
111 | val = (ak4531->regs[reg] & ~(mask << shift)) | val; | 113 | val = (ak4531->regs[reg] & ~(mask << shift)) | val; |
112 | change = val != ak4531->regs[reg]; | 114 | change = val != ak4531->regs[reg]; |
113 | ak4531->write(ak4531, reg, ak4531->regs[reg] = val); | 115 | ak4531->write(ak4531, reg, ak4531->regs[reg] = val); |
114 | up(&ak4531->reg_mutex); | 116 | mutex_unlock(&ak4531->reg_mutex); |
115 | return change; | 117 | return change; |
116 | } | 118 | } |
117 | 119 | ||
@@ -143,10 +145,10 @@ static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
143 | int invert = (kcontrol->private_value >> 22) & 1; | 145 | int invert = (kcontrol->private_value >> 22) & 1; |
144 | int left, right; | 146 | int left, right; |
145 | 147 | ||
146 | down(&ak4531->reg_mutex); | 148 | mutex_lock(&ak4531->reg_mutex); |
147 | left = (ak4531->regs[left_reg] >> left_shift) & mask; | 149 | left = (ak4531->regs[left_reg] >> left_shift) & mask; |
148 | right = (ak4531->regs[right_reg] >> right_shift) & mask; | 150 | right = (ak4531->regs[right_reg] >> right_shift) & mask; |
149 | up(&ak4531->reg_mutex); | 151 | mutex_unlock(&ak4531->reg_mutex); |
150 | if (invert) { | 152 | if (invert) { |
151 | left = mask - left; | 153 | left = mask - left; |
152 | right = mask - right; | 154 | right = mask - right; |
@@ -176,7 +178,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
176 | } | 178 | } |
177 | left <<= left_shift; | 179 | left <<= left_shift; |
178 | right <<= right_shift; | 180 | right <<= right_shift; |
179 | down(&ak4531->reg_mutex); | 181 | mutex_lock(&ak4531->reg_mutex); |
180 | if (left_reg == right_reg) { | 182 | if (left_reg == right_reg) { |
181 | left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; | 183 | left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right; |
182 | change = left != ak4531->regs[left_reg]; | 184 | change = left != ak4531->regs[left_reg]; |
@@ -188,7 +190,7 @@ static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
188 | ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); | 190 | ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left); |
189 | ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); | 191 | ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right); |
190 | } | 192 | } |
191 | up(&ak4531->reg_mutex); | 193 | mutex_unlock(&ak4531->reg_mutex); |
192 | return change; | 194 | return change; |
193 | } | 195 | } |
194 | 196 | ||
@@ -215,12 +217,12 @@ static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
215 | int left_shift = (kcontrol->private_value >> 16) & 0x0f; | 217 | int left_shift = (kcontrol->private_value >> 16) & 0x0f; |
216 | int right_shift = (kcontrol->private_value >> 24) & 0x0f; | 218 | int right_shift = (kcontrol->private_value >> 24) & 0x0f; |
217 | 219 | ||
218 | down(&ak4531->reg_mutex); | 220 | mutex_lock(&ak4531->reg_mutex); |
219 | ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; | 221 | ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1; |
220 | ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; | 222 | ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1; |
221 | ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; | 223 | ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1; |
222 | ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; | 224 | ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1; |
223 | up(&ak4531->reg_mutex); | 225 | mutex_unlock(&ak4531->reg_mutex); |
224 | return 0; | 226 | return 0; |
225 | } | 227 | } |
226 | 228 | ||
@@ -234,7 +236,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
234 | int change; | 236 | int change; |
235 | int val1, val2; | 237 | int val1, val2; |
236 | 238 | ||
237 | down(&ak4531->reg_mutex); | 239 | mutex_lock(&ak4531->reg_mutex); |
238 | val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); | 240 | val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift)); |
239 | val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); | 241 | val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift)); |
240 | val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; | 242 | val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift; |
@@ -244,7 +246,7 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
244 | change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; | 246 | change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2]; |
245 | ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); | 247 | ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1); |
246 | ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); | 248 | ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2); |
247 | up(&ak4531->reg_mutex); | 249 | mutex_unlock(&ak4531->reg_mutex); |
248 | return change; | 250 | return change; |
249 | } | 251 | } |
250 | 252 | ||
@@ -366,7 +368,7 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, | |||
366 | if (ak4531 == NULL) | 368 | if (ak4531 == NULL) |
367 | return -ENOMEM; | 369 | return -ENOMEM; |
368 | *ak4531 = *_ak4531; | 370 | *ak4531 = *_ak4531; |
369 | init_MUTEX(&ak4531->reg_mutex); | 371 | mutex_init(&ak4531->reg_mutex); |
370 | if ((err = snd_component_add(card, "AK4531")) < 0) { | 372 | if ((err = snd_component_add(card, "AK4531")) < 0) { |
371 | snd_ak4531_free(ak4531); | 373 | snd_ak4531_free(ak4531); |
372 | return err; | 374 | return err; |
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index a208075cdc1e..2aa5a7fdb6e0 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/dma-mapping.h> | ||
37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
38 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
39 | #include <linux/compiler.h> | 40 | #include <linux/compiler.h> |
@@ -909,10 +910,10 @@ snd_ad1889_create(struct snd_card *card, | |||
909 | 910 | ||
910 | if ((err = pci_enable_device(pci)) < 0) | 911 | if ((err = pci_enable_device(pci)) < 0) |
911 | return err; | 912 | return err; |
912 | 913 | ||
913 | /* check PCI availability (32bit DMA) */ | 914 | /* check PCI availability (32bit DMA) */ |
914 | if (pci_set_dma_mask(pci, 0xffffffff) < 0 || | 915 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || |
915 | pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) { | 916 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { |
916 | printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); | 917 | printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n"); |
917 | pci_disable_device(pci); | 918 | pci_disable_device(pci); |
918 | return -ENXIO; | 919 | return -ENXIO; |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index b7217adaf1d7..12e618851262 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/mutex.h> | ||
30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
32 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
@@ -277,7 +278,7 @@ struct atiixp { | |||
277 | unsigned int codec_not_ready_bits; /* for codec detection */ | 278 | unsigned int codec_not_ready_bits; /* for codec detection */ |
278 | 279 | ||
279 | int spdif_over_aclink; /* passed from the module option */ | 280 | int spdif_over_aclink; /* passed from the module option */ |
280 | struct semaphore open_mutex; /* playback open mutex */ | 281 | struct mutex open_mutex; /* playback open mutex */ |
281 | }; | 282 | }; |
282 | 283 | ||
283 | 284 | ||
@@ -1051,9 +1052,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) | |||
1051 | struct atiixp *chip = snd_pcm_substream_chip(substream); | 1052 | struct atiixp *chip = snd_pcm_substream_chip(substream); |
1052 | int err; | 1053 | int err; |
1053 | 1054 | ||
1054 | down(&chip->open_mutex); | 1055 | mutex_lock(&chip->open_mutex); |
1055 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); | 1056 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); |
1056 | up(&chip->open_mutex); | 1057 | mutex_unlock(&chip->open_mutex); |
1057 | if (err < 0) | 1058 | if (err < 0) |
1058 | return err; | 1059 | return err; |
1059 | substream->runtime->hw.channels_max = chip->max_channels; | 1060 | substream->runtime->hw.channels_max = chip->max_channels; |
@@ -1068,9 +1069,9 @@ static int snd_atiixp_playback_close(struct snd_pcm_substream *substream) | |||
1068 | { | 1069 | { |
1069 | struct atiixp *chip = snd_pcm_substream_chip(substream); | 1070 | struct atiixp *chip = snd_pcm_substream_chip(substream); |
1070 | int err; | 1071 | int err; |
1071 | down(&chip->open_mutex); | 1072 | mutex_lock(&chip->open_mutex); |
1072 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); | 1073 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); |
1073 | up(&chip->open_mutex); | 1074 | mutex_unlock(&chip->open_mutex); |
1074 | return err; | 1075 | return err; |
1075 | } | 1076 | } |
1076 | 1077 | ||
@@ -1090,12 +1091,12 @@ static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream) | |||
1090 | { | 1091 | { |
1091 | struct atiixp *chip = snd_pcm_substream_chip(substream); | 1092 | struct atiixp *chip = snd_pcm_substream_chip(substream); |
1092 | int err; | 1093 | int err; |
1093 | down(&chip->open_mutex); | 1094 | mutex_lock(&chip->open_mutex); |
1094 | if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */ | 1095 | if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */ |
1095 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2); | 1096 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2); |
1096 | else | 1097 | else |
1097 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1); | 1098 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1); |
1098 | up(&chip->open_mutex); | 1099 | mutex_unlock(&chip->open_mutex); |
1099 | return err; | 1100 | return err; |
1100 | } | 1101 | } |
1101 | 1102 | ||
@@ -1103,12 +1104,12 @@ static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream) | |||
1103 | { | 1104 | { |
1104 | struct atiixp *chip = snd_pcm_substream_chip(substream); | 1105 | struct atiixp *chip = snd_pcm_substream_chip(substream); |
1105 | int err; | 1106 | int err; |
1106 | down(&chip->open_mutex); | 1107 | mutex_lock(&chip->open_mutex); |
1107 | if (chip->spdif_over_aclink) | 1108 | if (chip->spdif_over_aclink) |
1108 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); | 1109 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); |
1109 | else | 1110 | else |
1110 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]); | 1111 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]); |
1111 | up(&chip->open_mutex); | 1112 | mutex_unlock(&chip->open_mutex); |
1112 | return err; | 1113 | return err; |
1113 | } | 1114 | } |
1114 | 1115 | ||
@@ -1560,7 +1561,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, | |||
1560 | } | 1561 | } |
1561 | 1562 | ||
1562 | spin_lock_init(&chip->reg_lock); | 1563 | spin_lock_init(&chip->reg_lock); |
1563 | init_MUTEX(&chip->open_mutex); | 1564 | mutex_init(&chip->open_mutex); |
1564 | chip->card = card; | 1565 | chip->card = card; |
1565 | chip->pci = pci; | 1566 | chip->pci = pci; |
1566 | chip->irq = -1; | 1567 | chip->irq = -1; |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 8d8fd5a4ed35..1d3766044643 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/mutex.h> | ||
30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
31 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
32 | #include <sound/pcm_params.h> | 33 | #include <sound/pcm_params.h> |
@@ -255,7 +256,7 @@ struct atiixp_modem { | |||
255 | unsigned int codec_not_ready_bits; /* for codec detection */ | 256 | unsigned int codec_not_ready_bits; /* for codec detection */ |
256 | 257 | ||
257 | int spdif_over_aclink; /* passed from the module option */ | 258 | int spdif_over_aclink; /* passed from the module option */ |
258 | struct semaphore open_mutex; /* playback open mutex */ | 259 | struct mutex open_mutex; /* playback open mutex */ |
259 | }; | 260 | }; |
260 | 261 | ||
261 | 262 | ||
@@ -911,9 +912,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) | |||
911 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); | 912 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); |
912 | int err; | 913 | int err; |
913 | 914 | ||
914 | down(&chip->open_mutex); | 915 | mutex_lock(&chip->open_mutex); |
915 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); | 916 | err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); |
916 | up(&chip->open_mutex); | 917 | mutex_unlock(&chip->open_mutex); |
917 | if (err < 0) | 918 | if (err < 0) |
918 | return err; | 919 | return err; |
919 | return 0; | 920 | return 0; |
@@ -923,9 +924,9 @@ static int snd_atiixp_playback_close(struct snd_pcm_substream *substream) | |||
923 | { | 924 | { |
924 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); | 925 | struct atiixp_modem *chip = snd_pcm_substream_chip(substream); |
925 | int err; | 926 | int err; |
926 | down(&chip->open_mutex); | 927 | mutex_lock(&chip->open_mutex); |
927 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); | 928 | err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); |
928 | up(&chip->open_mutex); | 929 | mutex_unlock(&chip->open_mutex); |
929 | return err; | 930 | return err; |
930 | } | 931 | } |
931 | 932 | ||
@@ -1233,7 +1234,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, | |||
1233 | } | 1234 | } |
1234 | 1235 | ||
1235 | spin_lock_init(&chip->reg_lock); | 1236 | spin_lock_init(&chip->reg_lock); |
1236 | init_MUTEX(&chip->open_mutex); | 1237 | mutex_init(&chip->open_mutex); |
1237 | chip->card = card; | 1238 | chip->card = card; |
1238 | chip->pci = pci; | 1239 | chip->pci = pci; |
1239 | chip->irq = -1; | 1240 | chip->irq = -1; |
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 7d9184f7367a..126870ec063a 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c | |||
@@ -151,14 +151,18 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
151 | // check PCI availability (DMA). | 151 | // check PCI availability (DMA). |
152 | if ((err = pci_enable_device(pci)) < 0) | 152 | if ((err = pci_enable_device(pci)) < 0) |
153 | return err; | 153 | return err; |
154 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK)) { | 154 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 || |
155 | pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) { | ||
155 | printk(KERN_ERR "error to set DMA mask\n"); | 156 | printk(KERN_ERR "error to set DMA mask\n"); |
157 | pci_disable_device(pci); | ||
156 | return -ENXIO; | 158 | return -ENXIO; |
157 | } | 159 | } |
158 | 160 | ||
159 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 161 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
160 | if (chip == NULL) | 162 | if (chip == NULL) { |
163 | pci_disable_device(pci); | ||
161 | return -ENOMEM; | 164 | return -ENOMEM; |
165 | } | ||
162 | 166 | ||
163 | chip->card = card; | 167 | chip->card = card; |
164 | 168 | ||
@@ -208,6 +212,8 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) | |||
208 | goto alloc_out; | 212 | goto alloc_out; |
209 | } | 213 | } |
210 | 214 | ||
215 | snd_card_set_dev(card, &pci->dev); | ||
216 | |||
211 | *rchip = chip; | 217 | *rchip = chip; |
212 | 218 | ||
213 | return 0; | 219 | return 0; |
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index c2ad2674bea7..d65ccb1866a0 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h | |||
@@ -39,8 +39,8 @@ | |||
39 | #include "au88x0_wt.h" | 39 | #include "au88x0_wt.h" |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #define hwread(x,y) readl((x)+((y)>>2)) | 42 | #define hwread(x,y) readl((x)+(y)) |
43 | #define hwwrite(x,y,z) writel((z),(x)+((y)>>2)) | 43 | #define hwwrite(x,y,z) writel((z),(x)+(y)) |
44 | 44 | ||
45 | /* Vortex MPU401 defines. */ | 45 | /* Vortex MPU401 defines. */ |
46 | #define MIDI_CLOCK_DIV 0x61 | 46 | #define MIDI_CLOCK_DIV 0x61 |
@@ -113,7 +113,7 @@ typedef struct { | |||
113 | //int this_08; /* Still unknown */ | 113 | //int this_08; /* Still unknown */ |
114 | int fifo_enabled; /* this_24 */ | 114 | int fifo_enabled; /* this_24 */ |
115 | int fifo_status; /* this_1c */ | 115 | int fifo_status; /* this_1c */ |
116 | int dma_ctrl; /* this_78 (ADB), this_7c (WT) */ | 116 | u32 dma_ctrl; /* this_78 (ADB), this_7c (WT) */ |
117 | int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */ | 117 | int dma_unknown; /* this_74 (ADB), this_78 (WT). WDM: +8 */ |
118 | int cfg0; | 118 | int cfg0; |
119 | int cfg1; | 119 | int cfg1; |
@@ -178,7 +178,7 @@ struct snd_vortex { | |||
178 | 178 | ||
179 | /* PCI hardware resources */ | 179 | /* PCI hardware resources */ |
180 | unsigned long io; | 180 | unsigned long io; |
181 | unsigned long __iomem *mmio; | 181 | void __iomem *mmio; |
182 | unsigned int irq; | 182 | unsigned int irq; |
183 | spinlock_t lock; | 183 | spinlock_t lock; |
184 | 184 | ||
@@ -201,14 +201,14 @@ static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, | |||
201 | int count); | 201 | int count); |
202 | static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, | 202 | static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, |
203 | int dir, int fmt, int d, | 203 | int dir, int fmt, int d, |
204 | unsigned long offset); | 204 | u32 offset); |
205 | static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); | 205 | static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); |
206 | #ifndef CHIP_AU8810 | 206 | #ifndef CHIP_AU8810 |
207 | static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, | 207 | static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, |
208 | struct snd_sg_buf * sgbuf, int size, | 208 | struct snd_sg_buf * sgbuf, int size, |
209 | int count); | 209 | int count); |
210 | static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ | 210 | static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ |
211 | unsigned long offset); | 211 | u32 offset); |
212 | static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); | 212 | static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); |
213 | #endif | 213 | #endif |
214 | 214 | ||
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index e3394fe63253..9cac02e93b25 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c | |||
@@ -376,7 +376,7 @@ vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch) | |||
376 | 376 | ||
377 | static void vortex_mixer_init(vortex_t * vortex) | 377 | static void vortex_mixer_init(vortex_t * vortex) |
378 | { | 378 | { |
379 | unsigned long addr; | 379 | u32 addr; |
380 | int x; | 380 | int x; |
381 | 381 | ||
382 | // FIXME: get rid of this crap. | 382 | // FIXME: get rid of this crap. |
@@ -639,7 +639,7 @@ static void vortex_src_setupchannel(vortex_t * card, unsigned char src, | |||
639 | 639 | ||
640 | static void vortex_srcblock_init(vortex_t * vortex) | 640 | static void vortex_srcblock_init(vortex_t * vortex) |
641 | { | 641 | { |
642 | unsigned long addr; | 642 | u32 addr; |
643 | int x; | 643 | int x; |
644 | hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff); | 644 | hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff); |
645 | /* | 645 | /* |
@@ -1035,7 +1035,7 @@ vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority, | |||
1035 | static void vortex_fifo_init(vortex_t * vortex) | 1035 | static void vortex_fifo_init(vortex_t * vortex) |
1036 | { | 1036 | { |
1037 | int x; | 1037 | int x; |
1038 | unsigned long addr; | 1038 | u32 addr; |
1039 | 1039 | ||
1040 | /* ADB DMA channels fifos. */ | 1040 | /* ADB DMA channels fifos. */ |
1041 | addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4); | 1041 | addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4); |
@@ -1054,7 +1054,7 @@ static void vortex_fifo_init(vortex_t * vortex) | |||
1054 | hwwrite(vortex->mmio, addr, FIFO_U0); | 1054 | hwwrite(vortex->mmio, addr, FIFO_U0); |
1055 | if (hwread(vortex->mmio, addr) != FIFO_U0) | 1055 | if (hwread(vortex->mmio, addr) != FIFO_U0) |
1056 | printk(KERN_ERR | 1056 | printk(KERN_ERR |
1057 | "bad wt fifo reset (0x%08lx, 0x%08x)!\n", | 1057 | "bad wt fifo reset (0x%08x, 0x%08x)!\n", |
1058 | addr, hwread(vortex->mmio, addr)); | 1058 | addr, hwread(vortex->mmio, addr)); |
1059 | vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); | 1059 | vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE); |
1060 | addr -= 4; | 1060 | addr -= 4; |
@@ -1152,7 +1152,7 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, | |||
1152 | 1152 | ||
1153 | static void | 1153 | static void |
1154 | vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, | 1154 | vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, |
1155 | int fmt, int d, unsigned long offset) | 1155 | int fmt, int d, u32 offset) |
1156 | { | 1156 | { |
1157 | stream_t *dma = &vortex->dma_adb[adbdma]; | 1157 | stream_t *dma = &vortex->dma_adb[adbdma]; |
1158 | 1158 | ||
@@ -1411,7 +1411,7 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, | |||
1411 | 1411 | ||
1412 | static void | 1412 | static void |
1413 | vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, | 1413 | vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, |
1414 | /*int e, */ unsigned long offset) | 1414 | /*int e, */ u32 offset) |
1415 | { | 1415 | { |
1416 | stream_t *dma = &vortex->dma_wt[wtdma]; | 1416 | stream_t *dma = &vortex->dma_wt[wtdma]; |
1417 | 1417 | ||
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c index c8280f82eb5a..64fbfbbaf816 100644 --- a/sound/pci/au88x0/au88x0_eq.c +++ b/sound/pci/au88x0/au88x0_eq.c | |||
@@ -377,23 +377,23 @@ static void vortex_EqHw_GetLevels(vortex_t * vortex, u16 a[]) | |||
377 | 377 | ||
378 | #endif | 378 | #endif |
379 | /* Global Control */ | 379 | /* Global Control */ |
380 | static void vortex_EqHw_SetControlReg(vortex_t * vortex, unsigned long reg) | 380 | static void vortex_EqHw_SetControlReg(vortex_t * vortex, u32 reg) |
381 | { | 381 | { |
382 | hwwrite(vortex->mmio, 0x2b440, reg); | 382 | hwwrite(vortex->mmio, 0x2b440, reg); |
383 | } | 383 | } |
384 | 384 | ||
385 | static void vortex_EqHw_SetSampleRate(vortex_t * vortex, int sr) | 385 | static void vortex_EqHw_SetSampleRate(vortex_t * vortex, u32 sr) |
386 | { | 386 | { |
387 | hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800); | 387 | hwwrite(vortex->mmio, 0x2b440, ((sr & 0x1f) << 3) | 0xb800); |
388 | } | 388 | } |
389 | 389 | ||
390 | #if 0 | 390 | #if 0 |
391 | static void vortex_EqHw_GetControlReg(vortex_t * vortex, unsigned long *reg) | 391 | static void vortex_EqHw_GetControlReg(vortex_t * vortex, u32 *reg) |
392 | { | 392 | { |
393 | *reg = hwread(vortex->mmio, 0x2b440); | 393 | *reg = hwread(vortex->mmio, 0x2b440); |
394 | } | 394 | } |
395 | 395 | ||
396 | static void vortex_EqHw_GetSampleRate(vortex_t * vortex, int *sr) | 396 | static void vortex_EqHw_GetSampleRate(vortex_t * vortex, u32 *sr) |
397 | { | 397 | { |
398 | *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f; | 398 | *sr = (hwread(vortex->mmio, 0x2b440) >> 3) & 0x1f; |
399 | } | 399 | } |
@@ -554,7 +554,7 @@ static void vortex_Eqlzr_SetRightGain(vortex_t * vortex, u16 index, u16 gain) | |||
554 | 554 | ||
555 | #if 0 | 555 | #if 0 |
556 | static int | 556 | static int |
557 | vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, unsigned long *cnt) | 557 | vortex_Eqlzr_GetAllBands(vortex_t * vortex, u16 * gains, s32 *cnt) |
558 | { | 558 | { |
559 | eqlzr_t *eq = &(vortex->eq); | 559 | eqlzr_t *eq = &(vortex->eq); |
560 | int si = 0; | 560 | int si = 0; |
@@ -586,7 +586,7 @@ static int vortex_Eqlzr_SetAllBandsFromActiveCoeffSet(vortex_t * vortex) | |||
586 | } | 586 | } |
587 | 587 | ||
588 | static int | 588 | static int |
589 | vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], unsigned long count) | 589 | vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], s32 count) |
590 | { | 590 | { |
591 | eqlzr_t *eq = &(vortex->eq); | 591 | eqlzr_t *eq = &(vortex->eq); |
592 | int i; | 592 | int i; |
@@ -604,11 +604,10 @@ vortex_Eqlzr_SetAllBands(vortex_t * vortex, u16 gains[], unsigned long count) | |||
604 | } | 604 | } |
605 | 605 | ||
606 | static void | 606 | static void |
607 | vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, unsigned long a, | 607 | vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, u32 a, u32 b) |
608 | unsigned long b) | ||
609 | { | 608 | { |
610 | eqlzr_t *eq = &(vortex->eq); | 609 | eqlzr_t *eq = &(vortex->eq); |
611 | int eax, ebx; | 610 | u32 eax, ebx; |
612 | 611 | ||
613 | eq->this58 = a; | 612 | eq->this58 = a; |
614 | eq->this5c = b; | 613 | eq->this5c = b; |
@@ -624,7 +623,7 @@ vortex_Eqlzr_SetA3dBypassGain(vortex_t * vortex, unsigned long a, | |||
624 | static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex) | 623 | static void vortex_Eqlzr_ProgramA3dBypassGain(vortex_t * vortex) |
625 | { | 624 | { |
626 | eqlzr_t *eq = &(vortex->eq); | 625 | eqlzr_t *eq = &(vortex->eq); |
627 | int eax, ebx; | 626 | u32 eax, ebx; |
628 | 627 | ||
629 | if (eq->this54) | 628 | if (eq->this54) |
630 | eax = eq->this0e; | 629 | eax = eq->this0e; |
@@ -641,7 +640,7 @@ static void vortex_Eqlzr_ShutDownA3d(vortex_t * vortex) | |||
641 | vortex_EqHw_ZeroA3DIO(vortex); | 640 | vortex_EqHw_ZeroA3DIO(vortex); |
642 | } | 641 | } |
643 | 642 | ||
644 | static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp) | 643 | static void vortex_Eqlzr_SetBypass(vortex_t * vortex, u32 bp) |
645 | { | 644 | { |
646 | eqlzr_t *eq = &(vortex->eq); | 645 | eqlzr_t *eq = &(vortex->eq); |
647 | 646 | ||
@@ -651,8 +650,8 @@ static void vortex_Eqlzr_SetBypass(vortex_t * vortex, long bp) | |||
651 | vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08); | 650 | vortex_EqHw_SetBypassGain(vortex, eq->this08, eq->this08); |
652 | } else { | 651 | } else { |
653 | /* EQ disabled. */ | 652 | /* EQ disabled. */ |
654 | vortex_EqHw_SetLeftGainsTarget(vortex, (u16 *) (eq->this14)); | 653 | vortex_EqHw_SetLeftGainsTarget(vortex, eq->this14_array); |
655 | vortex_EqHw_SetRightGainsTarget(vortex, (u16 *) (eq->this14)); | 654 | vortex_EqHw_SetRightGainsTarget(vortex, eq->this14_array); |
656 | vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c); | 655 | vortex_EqHw_SetBypassGain(vortex, eq->this0c, eq->this0c); |
657 | } | 656 | } |
658 | vortex_Eqlzr_ProgramA3dBypassGain(vortex); | 657 | vortex_Eqlzr_ProgramA3dBypassGain(vortex); |
@@ -706,7 +705,7 @@ static void vortex_Eqlzr_init(vortex_t * vortex) | |||
706 | eq->this5c = 0xffff; | 705 | eq->this5c = 0xffff; |
707 | 706 | ||
708 | /* Set gains. */ | 707 | /* Set gains. */ |
709 | memset(eq->this14, 0, 2 * 10); | 708 | memset(eq->this14_array, 0, sizeof(eq->this14_array)); |
710 | 709 | ||
711 | /* Actual init. */ | 710 | /* Actual init. */ |
712 | vortex_EqHw_ZeroState(vortex); | 711 | vortex_EqHw_ZeroState(vortex); |
@@ -792,7 +791,7 @@ snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon | |||
792 | { | 791 | { |
793 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); | 792 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); |
794 | int i = kcontrol->private_value; | 793 | int i = kcontrol->private_value; |
795 | u16 gainL, gainR; | 794 | u16 gainL = 0, gainR = 0; |
796 | 795 | ||
797 | vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); | 796 | vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); |
798 | vortex_Eqlzr_GetRightGain(vortex, i, &gainR); | 797 | vortex_Eqlzr_GetRightGain(vortex, i, &gainR); |
@@ -806,7 +805,7 @@ snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucon | |||
806 | { | 805 | { |
807 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); | 806 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); |
808 | int changed = 0, i = kcontrol->private_value; | 807 | int changed = 0, i = kcontrol->private_value; |
809 | u16 gainL, gainR; | 808 | u16 gainL = 0, gainR = 0; |
810 | 809 | ||
811 | vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); | 810 | vortex_Eqlzr_GetLeftGain(vortex, i, &gainL); |
812 | vortex_Eqlzr_GetRightGain(vortex, i, &gainR); | 811 | vortex_Eqlzr_GetRightGain(vortex, i, &gainR); |
diff --git a/sound/pci/au88x0/au88x0_eq.h b/sound/pci/au88x0/au88x0_eq.h index e49bc625c873..474cd0046294 100644 --- a/sound/pci/au88x0/au88x0_eq.h +++ b/sound/pci/au88x0/au88x0_eq.h | |||
@@ -13,31 +13,28 @@ | |||
13 | typedef struct { | 13 | typedef struct { |
14 | u16 LeftCoefs[50]; //0x4 | 14 | u16 LeftCoefs[50]; //0x4 |
15 | u16 RightCoefs[50]; // 0x68 | 15 | u16 RightCoefs[50]; // 0x68 |
16 | u16 LeftGains[20]; //0xd0 | 16 | u16 LeftGains[10]; //0xd0 |
17 | u16 RightGains[20]; //0xe4 | 17 | u16 RightGains[10]; //0xe4 |
18 | } auxxEqCoeffSet_t; | 18 | } auxxEqCoeffSet_t; |
19 | 19 | ||
20 | typedef struct { | 20 | typedef struct { |
21 | unsigned int *this00; /*CAsp4HwIO */ | 21 | s32 this04; /* How many filters for each side (default = 10) */ |
22 | long this04; /* How many filters for each side (default = 10) */ | 22 | s32 this08; /* inited to cero. Stereo flag? */ |
23 | long this08; /* inited to cero. Stereo flag? */ | ||
24 | } eqhw_t; | 23 | } eqhw_t; |
25 | 24 | ||
26 | typedef struct { | 25 | typedef struct { |
27 | unsigned int *this00; /*CAsp4Core */ | ||
28 | eqhw_t this04; /* CHwEq */ | 26 | eqhw_t this04; /* CHwEq */ |
29 | short this08; /* Bad codec flag ? SetBypassGain: bypass gain */ | 27 | u16 this08; /* Bad codec flag ? SetBypassGain: bypass gain */ |
30 | short this0a; | 28 | u16 this0a; |
31 | short this0c; /* SetBypassGain: bypass gain when this28 is not set. */ | 29 | u16 this0c; /* SetBypassGain: bypass gain when this28 is not set. */ |
32 | short this0e; | 30 | u16 this0e; |
33 | 31 | ||
34 | long this10; /* How many gains are used for each side (right or left). */ | 32 | s32 this10; /* How many gains are used for each side (right or left). */ |
35 | u16 this14[32]; /* SetLeftGainsTarget: Left (and right?) EQ gains */ | 33 | u16 this14_array[10]; /* SetLeftGainsTarget: Left (and right?) EQ gains */ |
36 | long this24; | 34 | s32 this28; /* flag related to EQ enabled or not. Gang flag ? */ |
37 | long this28; /* flag related to EQ enabled or not. Gang flag ? */ | 35 | s32 this54; /* SetBypass */ |
38 | long this54; /* SetBypass */ | 36 | s32 this58; |
39 | long this58; | 37 | s32 this5c; |
40 | long this5c; | ||
41 | /*0x60 */ auxxEqCoeffSet_t coefset; | 38 | /*0x60 */ auxxEqCoeffSet_t coefset; |
42 | /* 50 u16 word each channel. */ | 39 | /* 50 u16 word each channel. */ |
43 | u16 this130[20]; /* Left and Right gains */ | 40 | u16 this130[20]; /* Left and Right gains */ |
diff --git a/sound/pci/au88x0/au88x0_eqdata.c b/sound/pci/au88x0/au88x0_eqdata.c index abf8d6ac4c15..ce8dca8ce1e2 100644 --- a/sound/pci/au88x0/au88x0_eqdata.c +++ b/sound/pci/au88x0/au88x0_eqdata.c | |||
@@ -104,7 +104,11 @@ static u16 asEqOutStateZeros[48] = { | |||
104 | }; | 104 | }; |
105 | 105 | ||
106 | /*_rodataba0:*/ | 106 | /*_rodataba0:*/ |
107 | static long eq_levels[32] = { | 107 | static u16 eq_levels[64] = { |
108 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
109 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
110 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
111 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
108 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | 112 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
109 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | 113 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
110 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | 114 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 8ba6dd36222b..873f486b07b8 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c | |||
@@ -95,7 +95,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) | |||
95 | return temp; | 95 | return temp; |
96 | } | 96 | } |
97 | #else | 97 | #else |
98 | port = (unsigned long)(vortex->mmio + (VORTEX_MIDI_DATA >> 2)); | 98 | port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); |
99 | if ((temp = | 99 | if ((temp = |
100 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, | 100 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, |
101 | 1, 0, 0, &rmidi)) != 0) { | 101 | 1, 0, 0, &rmidi)) != 0) { |
@@ -105,7 +105,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) | |||
105 | return temp; | 105 | return temp; |
106 | } | 106 | } |
107 | mpu = rmidi->private_data; | 107 | mpu = rmidi->private_data; |
108 | mpu->cport = (unsigned long)(vortex->mmio + (VORTEX_MIDI_CMD >> 2)); | 108 | mpu->cport = (unsigned long)(vortex->mmio + VORTEX_MIDI_CMD); |
109 | #endif | 109 | #endif |
110 | vortex->rmidi = rmidi; | 110 | vortex->rmidi = rmidi; |
111 | return 0; | 111 | return 0; |
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c index 65f375bad43a..d3e662a1285d 100644 --- a/sound/pci/au88x0/au88x0_synth.c +++ b/sound/pci/au88x0/au88x0_synth.c | |||
@@ -32,7 +32,7 @@ static void vortex_connection_mixin_mix(vortex_t * vortex, int en, | |||
32 | unsigned char mix, int a); | 32 | unsigned char mix, int a); |
33 | static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j); | 33 | static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j); |
34 | static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, | 34 | static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, |
35 | unsigned long val); | 35 | u32 val); |
36 | 36 | ||
37 | /* WT */ | 37 | /* WT */ |
38 | 38 | ||
@@ -166,7 +166,7 @@ static int vortex_wt_GetReg(vortex_t * vortex, char reg, int wt) | |||
166 | /* WT hardware abstraction layer generic register interface. */ | 166 | /* WT hardware abstraction layer generic register interface. */ |
167 | static int | 167 | static int |
168 | vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, | 168 | vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, |
169 | unsigned short val) | 169 | u16 val) |
170 | { | 170 | { |
171 | /* | 171 | /* |
172 | int eax, edx; | 172 | int eax, edx; |
@@ -190,7 +190,7 @@ vortex_wt_SetReg2(vortex_t * vortex, unsigned char reg, int wt, | |||
190 | #endif | 190 | #endif |
191 | static int | 191 | static int |
192 | vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, | 192 | vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, |
193 | unsigned long val) | 193 | u32 val) |
194 | { | 194 | { |
195 | int ecx; | 195 | int ecx; |
196 | 196 | ||
@@ -279,7 +279,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt, | |||
279 | 279 | ||
280 | static void vortex_wt_init(vortex_t * vortex) | 280 | static void vortex_wt_init(vortex_t * vortex) |
281 | { | 281 | { |
282 | int var4, var8, varc, var10 = 0, edi; | 282 | u32 var4, var8, varc, var10 = 0, edi; |
283 | 283 | ||
284 | var10 &= 0xFFFFFFE3; | 284 | var10 &= 0xFFFFFFE3; |
285 | var10 |= 0x22; | 285 | var10 |= 0x22; |
@@ -353,7 +353,7 @@ static void vortex_wt_SetVolume(vortex_t * vortex, int wt, int vol[]) | |||
353 | static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr) | 353 | static void vortex_wt_SetFrequency(vortex_t * vortex, int wt, unsigned int sr) |
354 | { | 354 | { |
355 | wt_voice_t *voice = &(vortex->wt_voice[wt]); | 355 | wt_voice_t *voice = &(vortex->wt_voice[wt]); |
356 | long int eax, edx; | 356 | u32 eax, edx; |
357 | 357 | ||
358 | //FIXME: 64 bit operation. | 358 | //FIXME: 64 bit operation. |
359 | eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff; | 359 | eax = ((sr << 0xf) * 0x57619F1) & 0xffffffff; |
diff --git a/sound/pci/au88x0/au88x0_wt.h b/sound/pci/au88x0/au88x0_wt.h index d536c88b43bf..38d98f88a95c 100644 --- a/sound/pci/au88x0/au88x0_wt.h +++ b/sound/pci/au88x0/au88x0_wt.h | |||
@@ -53,11 +53,11 @@ enum { | |||
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | typedef struct { | 55 | typedef struct { |
56 | unsigned int parm0; /* this_1E4 */ | 56 | u32 parm0; /* this_1E4 */ |
57 | unsigned int parm1; /* this_1E8 */ | 57 | u32 parm1; /* this_1E8 */ |
58 | unsigned int parm2; /* this_1EC */ | 58 | u32 parm2; /* this_1EC */ |
59 | unsigned int parm3; /* this_1F0 */ | 59 | u32 parm3; /* this_1F0 */ |
60 | unsigned int this_1D0; | 60 | u32 this_1D0; |
61 | } wt_voice_t; | 61 | } wt_voice_t; |
62 | 62 | ||
63 | #endif /* _AU88X0_WT_H */ | 63 | #endif /* _AU88X0_WT_H */ |
diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c index df915fa3f88d..4534e1882ada 100644 --- a/sound/pci/au88x0/au88x0_xtalk.c +++ b/sound/pci/au88x0/au88x0_xtalk.c | |||
@@ -562,7 +562,7 @@ static void | |||
562 | vortex_XtalkHw_SetDelay(vortex_t * vortex, unsigned short right, | 562 | vortex_XtalkHw_SetDelay(vortex_t * vortex, unsigned short right, |
563 | unsigned short left) | 563 | unsigned short left) |
564 | { | 564 | { |
565 | int esp0 = 0; | 565 | u32 esp0 = 0; |
566 | 566 | ||
567 | esp0 &= 0x1FFFFFFF; | 567 | esp0 &= 0x1FFFFFFF; |
568 | esp0 |= 0xA0000000; | 568 | esp0 |= 0xA0000000; |
@@ -632,18 +632,18 @@ static void vortex_XtalkHw_GetRightDline(vortex_t * vortex, xtalk_dline_t dline) | |||
632 | /* Control/Global stuff */ | 632 | /* Control/Global stuff */ |
633 | 633 | ||
634 | #if 0 | 634 | #if 0 |
635 | static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, unsigned long ctrl) | 635 | static void vortex_XtalkHw_SetControlReg(vortex_t * vortex, u32 ctrl) |
636 | { | 636 | { |
637 | hwwrite(vortex->mmio, 0x24660, ctrl); | 637 | hwwrite(vortex->mmio, 0x24660, ctrl); |
638 | } | 638 | } |
639 | static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, unsigned long *ctrl) | 639 | static void vortex_XtalkHw_GetControlReg(vortex_t * vortex, u32 *ctrl) |
640 | { | 640 | { |
641 | *ctrl = hwread(vortex->mmio, 0x24660); | 641 | *ctrl = hwread(vortex->mmio, 0x24660); |
642 | } | 642 | } |
643 | #endif | 643 | #endif |
644 | static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr) | 644 | static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr) |
645 | { | 645 | { |
646 | int temp; | 646 | u32 temp; |
647 | 647 | ||
648 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; | 648 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; |
649 | temp = (temp & 0xffffff07) | ((sr & 0x1f) << 3); | 649 | temp = (temp & 0xffffff07) | ((sr & 0x1f) << 3); |
@@ -651,7 +651,7 @@ static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr) | |||
651 | } | 651 | } |
652 | 652 | ||
653 | #if 0 | 653 | #if 0 |
654 | static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, int *sr) | 654 | static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, u32 *sr) |
655 | { | 655 | { |
656 | *sr = (hwread(vortex->mmio, 0x24660) >> 3) & 0x1f; | 656 | *sr = (hwread(vortex->mmio, 0x24660) >> 3) & 0x1f; |
657 | } | 657 | } |
@@ -659,7 +659,7 @@ static void vortex_XtalkHw_GetSampleRate(vortex_t * vortex, int *sr) | |||
659 | #endif | 659 | #endif |
660 | static void vortex_XtalkHw_Enable(vortex_t * vortex) | 660 | static void vortex_XtalkHw_Enable(vortex_t * vortex) |
661 | { | 661 | { |
662 | int temp; | 662 | u32 temp; |
663 | 663 | ||
664 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; | 664 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; |
665 | temp |= 1; | 665 | temp |= 1; |
@@ -669,7 +669,7 @@ static void vortex_XtalkHw_Enable(vortex_t * vortex) | |||
669 | 669 | ||
670 | static void vortex_XtalkHw_Disable(vortex_t * vortex) | 670 | static void vortex_XtalkHw_Disable(vortex_t * vortex) |
671 | { | 671 | { |
672 | int temp; | 672 | u32 temp; |
673 | 673 | ||
674 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; | 674 | temp = (hwread(vortex->mmio, 0x24660) & 0x1FFFFFFF) | 0xC0000000; |
675 | temp &= 0xfffffffe; | 675 | temp &= 0xfffffffe; |
diff --git a/sound/pci/au88x0/au88x0_xtalk.h b/sound/pci/au88x0/au88x0_xtalk.h index 0b8d7b64012d..7f4534b94d00 100644 --- a/sound/pci/au88x0/au88x0_xtalk.h +++ b/sound/pci/au88x0/au88x0_xtalk.h | |||
@@ -39,16 +39,16 @@ | |||
39 | #define XT_SPEAKER1 3 | 39 | #define XT_SPEAKER1 3 |
40 | #define XT_DIAMOND 4 | 40 | #define XT_DIAMOND 4 |
41 | 41 | ||
42 | typedef long xtalk_dline_t[XTDLINE_SZ]; | 42 | typedef u32 xtalk_dline_t[XTDLINE_SZ]; |
43 | typedef short xtalk_gains_t[XTGAINS_SZ]; | 43 | typedef u16 xtalk_gains_t[XTGAINS_SZ]; |
44 | typedef short xtalk_instate_t[XTINST_SZ]; | 44 | typedef u16 xtalk_instate_t[XTINST_SZ]; |
45 | typedef short xtalk_coefs_t[5][5]; | 45 | typedef u16 xtalk_coefs_t[5][5]; |
46 | typedef short xtalk_state_t[5][4]; | 46 | typedef u16 xtalk_state_t[5][4]; |
47 | 47 | ||
48 | static void vortex_XtalkHw_SetGains(vortex_t * vortex, | 48 | static void vortex_XtalkHw_SetGains(vortex_t * vortex, |
49 | xtalk_gains_t const gains); | 49 | xtalk_gains_t const gains); |
50 | static void vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex); | 50 | static void vortex_XtalkHw_SetGainsAllChan(vortex_t * vortex); |
51 | static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, int sr); | 51 | static void vortex_XtalkHw_SetSampleRate(vortex_t * vortex, u32 sr); |
52 | static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); | 52 | static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); |
53 | static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); | 53 | static void vortex_XtalkHw_ProgramPipe(vortex_t * vortex); |
54 | static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex); | 54 | static void vortex_XtalkHw_ProgramXtalkWide(vortex_t * vortex); |
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c840a4c08e98..7b44a8db033d 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c | |||
@@ -783,6 +783,8 @@ static struct pci_device_id snd_bt87x_ids[] = { | |||
783 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), | 783 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), |
784 | /* AVerMedia Studio No. 103, 203, ...? */ | 784 | /* AVerMedia Studio No. 103, 203, ...? */ |
785 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), | 785 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1461, 0x0003, 48000), |
786 | /* Leadtek Winfast tv 2000xp delux */ | ||
787 | BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), | ||
786 | { } | 788 | { } |
787 | }; | 789 | }; |
788 | MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); | 790 | MODULE_DEVICE_TABLE(pci, snd_bt87x_ids); |
@@ -793,12 +795,15 @@ static struct { | |||
793 | unsigned short subvendor, subdevice; | 795 | unsigned short subvendor, subdevice; |
794 | } blacklist[] __devinitdata = { | 796 | } blacklist[] __devinitdata = { |
795 | {0x0071, 0x0101}, /* Nebula Electronics DigiTV */ | 797 | {0x0071, 0x0101}, /* Nebula Electronics DigiTV */ |
798 | {0x11bd, 0x001c}, /* Pinnacle PCTV Sat */ | ||
796 | {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */ | 799 | {0x11bd, 0x0026}, /* Pinnacle PCTV SAT CI */ |
797 | {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */ | 800 | {0x1461, 0x0761}, /* AVermedia AverTV DVB-T */ |
798 | {0x1461, 0x0771}, /* AVermedia DVB-T 771 */ | 801 | {0x1461, 0x0771}, /* AVermedia DVB-T 771 */ |
799 | {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */ | 802 | {0x1822, 0x0001}, /* Twinhan VisionPlus DVB-T */ |
803 | {0x18ac, 0xd500}, /* DVICO FusionHDTV 5 Lite */ | ||
800 | {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */ | 804 | {0x18ac, 0xdb10}, /* DVICO FusionHDTV DVB-T Lite */ |
801 | {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ | 805 | {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ |
806 | {0x7063, 0x2000}, /* pcHDTV HD-2000 TV */ | ||
802 | }; | 807 | }; |
803 | 808 | ||
804 | static struct pci_driver driver; | 809 | static struct pci_driver driver; |
@@ -816,13 +821,13 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) | |||
816 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) | 821 | for (i = 0; i < ARRAY_SIZE(blacklist); ++i) |
817 | if (blacklist[i].subvendor == pci->subsystem_vendor && | 822 | if (blacklist[i].subvendor == pci->subsystem_vendor && |
818 | blacklist[i].subdevice == pci->subsystem_device) { | 823 | blacklist[i].subdevice == pci->subsystem_device) { |
819 | snd_printdd(KERN_INFO "card %#04x:%#04x has no audio\n", | 824 | snd_printdd(KERN_INFO "card %#04x-%#04x:%#04x has no audio\n", |
820 | pci->subsystem_vendor, pci->subsystem_device); | 825 | pci->device, pci->subsystem_vendor, pci->subsystem_device); |
821 | return -EBUSY; | 826 | return -EBUSY; |
822 | } | 827 | } |
823 | 828 | ||
824 | snd_printk(KERN_INFO "unknown card %#04x:%#04x, using default rate 32000\n", | 829 | snd_printk(KERN_INFO "unknown card %#04x-%#04x:%#04x, using default rate 32000\n", |
825 | pci->subsystem_vendor, pci->subsystem_device); | 830 | pci->device, pci->subsystem_vendor, pci->subsystem_device); |
826 | snd_printk(KERN_DEBUG "please mail id, board name, and, " | 831 | snd_printk(KERN_DEBUG "please mail id, board name, and, " |
827 | "if it works, the correct digital_rate option to " | 832 | "if it works, the correct digital_rate option to " |
828 | "<alsa-devel@lists.sf.net>\n"); | 833 | "<alsa-devel@lists.sf.net>\n"); |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index c03b0a0a3b27..2ecbddbbdcf0 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/gameport.h> | 30 | #include <linux/gameport.h> |
31 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/mutex.h> | ||
32 | #include <sound/core.h> | 33 | #include <sound/core.h> |
33 | #include <sound/info.h> | 34 | #include <sound/info.h> |
34 | #include <sound/control.h> | 35 | #include <sound/control.h> |
@@ -439,7 +440,7 @@ struct cmipci { | |||
439 | struct snd_pcm_hardware *hw_info[3]; /* for playbacks */ | 440 | struct snd_pcm_hardware *hw_info[3]; /* for playbacks */ |
440 | 441 | ||
441 | int opened[2]; /* open mode */ | 442 | int opened[2]; /* open mode */ |
442 | struct semaphore open_mutex; | 443 | struct mutex open_mutex; |
443 | 444 | ||
444 | unsigned int mixer_insensitive: 1; | 445 | unsigned int mixer_insensitive: 1; |
445 | struct snd_kcontrol *mixer_res_ctl[CM_SAVED_MIXERS]; | 446 | struct snd_kcontrol *mixer_res_ctl[CM_SAVED_MIXERS]; |
@@ -641,14 +642,14 @@ static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream, | |||
641 | { | 642 | { |
642 | struct cmipci *cm = snd_pcm_substream_chip(substream); | 643 | struct cmipci *cm = snd_pcm_substream_chip(substream); |
643 | if (params_channels(hw_params) > 2) { | 644 | if (params_channels(hw_params) > 2) { |
644 | down(&cm->open_mutex); | 645 | mutex_lock(&cm->open_mutex); |
645 | if (cm->opened[CM_CH_PLAY]) { | 646 | if (cm->opened[CM_CH_PLAY]) { |
646 | up(&cm->open_mutex); | 647 | mutex_unlock(&cm->open_mutex); |
647 | return -EBUSY; | 648 | return -EBUSY; |
648 | } | 649 | } |
649 | /* reserve the channel A */ | 650 | /* reserve the channel A */ |
650 | cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI; | 651 | cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI; |
651 | up(&cm->open_mutex); | 652 | mutex_unlock(&cm->open_mutex); |
652 | } | 653 | } |
653 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 654 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
654 | } | 655 | } |
@@ -1461,9 +1462,9 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre | |||
1461 | * pcm framework doesn't pass file pointer before actually opened, | 1462 | * pcm framework doesn't pass file pointer before actually opened, |
1462 | * we can't know whether blocking mode or not in open callback.. | 1463 | * we can't know whether blocking mode or not in open callback.. |
1463 | */ | 1464 | */ |
1464 | down(&cm->open_mutex); | 1465 | mutex_lock(&cm->open_mutex); |
1465 | if (cm->opened[ch]) { | 1466 | if (cm->opened[ch]) { |
1466 | up(&cm->open_mutex); | 1467 | mutex_unlock(&cm->open_mutex); |
1467 | return -EBUSY; | 1468 | return -EBUSY; |
1468 | } | 1469 | } |
1469 | cm->opened[ch] = mode; | 1470 | cm->opened[ch] = mode; |
@@ -1475,7 +1476,7 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre | |||
1475 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC); | 1476 | snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC); |
1476 | spin_unlock_irq(&cm->reg_lock); | 1477 | spin_unlock_irq(&cm->reg_lock); |
1477 | } | 1478 | } |
1478 | up(&cm->open_mutex); | 1479 | mutex_unlock(&cm->open_mutex); |
1479 | return 0; | 1480 | return 0; |
1480 | } | 1481 | } |
1481 | 1482 | ||
@@ -1483,7 +1484,7 @@ static void close_device_check(struct cmipci *cm, int mode) | |||
1483 | { | 1484 | { |
1484 | int ch = mode & CM_OPEN_CH_MASK; | 1485 | int ch = mode & CM_OPEN_CH_MASK; |
1485 | 1486 | ||
1486 | down(&cm->open_mutex); | 1487 | mutex_lock(&cm->open_mutex); |
1487 | if (cm->opened[ch] == mode) { | 1488 | if (cm->opened[ch] == mode) { |
1488 | if (cm->channel[ch].substream) { | 1489 | if (cm->channel[ch].substream) { |
1489 | snd_cmipci_ch_reset(cm, ch); | 1490 | snd_cmipci_ch_reset(cm, ch); |
@@ -1499,7 +1500,7 @@ static void close_device_check(struct cmipci *cm, int mode) | |||
1499 | spin_unlock_irq(&cm->reg_lock); | 1500 | spin_unlock_irq(&cm->reg_lock); |
1500 | } | 1501 | } |
1501 | } | 1502 | } |
1502 | up(&cm->open_mutex); | 1503 | mutex_unlock(&cm->open_mutex); |
1503 | } | 1504 | } |
1504 | 1505 | ||
1505 | /* | 1506 | /* |
@@ -1546,7 +1547,7 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) | |||
1546 | if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */ | 1547 | if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */ |
1547 | return err; | 1548 | return err; |
1548 | runtime->hw = snd_cmipci_playback2; | 1549 | runtime->hw = snd_cmipci_playback2; |
1549 | down(&cm->open_mutex); | 1550 | mutex_lock(&cm->open_mutex); |
1550 | if (! cm->opened[CM_CH_PLAY]) { | 1551 | if (! cm->opened[CM_CH_PLAY]) { |
1551 | if (cm->can_multi_ch) { | 1552 | if (cm->can_multi_ch) { |
1552 | runtime->hw.channels_max = cm->max_channels; | 1553 | runtime->hw.channels_max = cm->max_channels; |
@@ -1559,7 +1560,7 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream) | |||
1559 | } | 1560 | } |
1560 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); | 1561 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000); |
1561 | } | 1562 | } |
1562 | up(&cm->open_mutex); | 1563 | mutex_unlock(&cm->open_mutex); |
1563 | return 0; | 1564 | return 0; |
1564 | } | 1565 | } |
1565 | 1566 | ||
@@ -2844,7 +2845,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc | |||
2844 | } | 2845 | } |
2845 | 2846 | ||
2846 | spin_lock_init(&cm->reg_lock); | 2847 | spin_lock_init(&cm->reg_lock); |
2847 | init_MUTEX(&cm->open_mutex); | 2848 | mutex_init(&cm->open_mutex); |
2848 | cm->device = pci->device; | 2849 | cm->device = pci->device; |
2849 | cm->card = card; | 2850 | cm->card = card; |
2850 | cm->pci = pci; | 2851 | cm->pci = pci; |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 8fb275d6eb77..69dbf542a6de 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/gameport.h> | 55 | #include <linux/gameport.h> |
56 | #include <linux/mutex.h> | ||
57 | |||
56 | 58 | ||
57 | #include <sound/core.h> | 59 | #include <sound/core.h> |
58 | #include <sound/control.h> | 60 | #include <sound/control.h> |
@@ -909,22 +911,22 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, | |||
909 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 911 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
910 | snd_assert (sample_rate != 0, return -ENXIO); | 912 | snd_assert (sample_rate != 0, return -ENXIO); |
911 | 913 | ||
912 | down (&chip->spos_mutex); | 914 | mutex_lock(&chip->spos_mutex); |
913 | 915 | ||
914 | if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { | 916 | if (_cs46xx_adjust_sample_rate (chip,cpcm,sample_rate)) { |
915 | up (&chip->spos_mutex); | 917 | mutex_unlock(&chip->spos_mutex); |
916 | return -ENXIO; | 918 | return -ENXIO; |
917 | } | 919 | } |
918 | 920 | ||
919 | snd_assert (cpcm->pcm_channel != NULL); | 921 | snd_assert (cpcm->pcm_channel != NULL); |
920 | if (!cpcm->pcm_channel) { | 922 | if (!cpcm->pcm_channel) { |
921 | up (&chip->spos_mutex); | 923 | mutex_unlock(&chip->spos_mutex); |
922 | return -ENXIO; | 924 | return -ENXIO; |
923 | } | 925 | } |
924 | 926 | ||
925 | 927 | ||
926 | if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { | 928 | if (cs46xx_dsp_pcm_channel_set_period (chip,cpcm->pcm_channel,period_size)) { |
927 | up (&chip->spos_mutex); | 929 | mutex_unlock(&chip->spos_mutex); |
928 | return -EINVAL; | 930 | return -EINVAL; |
929 | } | 931 | } |
930 | 932 | ||
@@ -965,7 +967,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, | |||
965 | } | 967 | } |
966 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { | 968 | if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0) { |
967 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 969 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
968 | up (&chip->spos_mutex); | 970 | mutex_unlock(&chip->spos_mutex); |
969 | #endif | 971 | #endif |
970 | return err; | 972 | return err; |
971 | } | 973 | } |
@@ -989,7 +991,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, | |||
989 | } | 991 | } |
990 | 992 | ||
991 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 993 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
992 | up (&chip->spos_mutex); | 994 | mutex_unlock(&chip->spos_mutex); |
993 | #endif | 995 | #endif |
994 | 996 | ||
995 | return 0; | 997 | return 0; |
@@ -1319,7 +1321,7 @@ static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,in | |||
1319 | 1321 | ||
1320 | cpcm->substream = substream; | 1322 | cpcm->substream = substream; |
1321 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1323 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1322 | down (&chip->spos_mutex); | 1324 | mutex_lock(&chip->spos_mutex); |
1323 | cpcm->pcm_channel = NULL; | 1325 | cpcm->pcm_channel = NULL; |
1324 | cpcm->pcm_channel_id = pcm_channel_id; | 1326 | cpcm->pcm_channel_id = pcm_channel_id; |
1325 | 1327 | ||
@@ -1328,7 +1330,7 @@ static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,in | |||
1328 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1330 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
1329 | &hw_constraints_period_sizes); | 1331 | &hw_constraints_period_sizes); |
1330 | 1332 | ||
1331 | up (&chip->spos_mutex); | 1333 | mutex_unlock(&chip->spos_mutex); |
1332 | #else | 1334 | #else |
1333 | chip->playback_pcm = cpcm; /* HACK */ | 1335 | chip->playback_pcm = cpcm; /* HACK */ |
1334 | #endif | 1336 | #endif |
@@ -1367,9 +1369,9 @@ static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream) | |||
1367 | 1369 | ||
1368 | snd_printdd("open raw iec958 channel\n"); | 1370 | snd_printdd("open raw iec958 channel\n"); |
1369 | 1371 | ||
1370 | down (&chip->spos_mutex); | 1372 | mutex_lock(&chip->spos_mutex); |
1371 | cs46xx_iec958_pre_open (chip); | 1373 | cs46xx_iec958_pre_open (chip); |
1372 | up (&chip->spos_mutex); | 1374 | mutex_unlock(&chip->spos_mutex); |
1373 | 1375 | ||
1374 | return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); | 1376 | return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL); |
1375 | } | 1377 | } |
@@ -1385,9 +1387,9 @@ static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream) | |||
1385 | 1387 | ||
1386 | err = snd_cs46xx_playback_close(substream); | 1388 | err = snd_cs46xx_playback_close(substream); |
1387 | 1389 | ||
1388 | down (&chip->spos_mutex); | 1390 | mutex_lock(&chip->spos_mutex); |
1389 | cs46xx_iec958_post_close (chip); | 1391 | cs46xx_iec958_post_close (chip); |
1390 | up (&chip->spos_mutex); | 1392 | mutex_unlock(&chip->spos_mutex); |
1391 | 1393 | ||
1392 | return err; | 1394 | return err; |
1393 | } | 1395 | } |
@@ -1428,12 +1430,12 @@ static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream) | |||
1428 | if (!cpcm) return -ENXIO; | 1430 | if (!cpcm) return -ENXIO; |
1429 | 1431 | ||
1430 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 1432 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
1431 | down (&chip->spos_mutex); | 1433 | mutex_lock(&chip->spos_mutex); |
1432 | if (cpcm->pcm_channel) { | 1434 | if (cpcm->pcm_channel) { |
1433 | cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); | 1435 | cs46xx_dsp_destroy_pcm_channel(chip,cpcm->pcm_channel); |
1434 | cpcm->pcm_channel = NULL; | 1436 | cpcm->pcm_channel = NULL; |
1435 | } | 1437 | } |
1436 | up (&chip->spos_mutex); | 1438 | mutex_unlock(&chip->spos_mutex); |
1437 | #else | 1439 | #else |
1438 | chip->playback_pcm = NULL; | 1440 | chip->playback_pcm = NULL; |
1439 | #endif | 1441 | #endif |
@@ -1848,7 +1850,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, | |||
1848 | 1850 | ||
1849 | switch (kcontrol->private_value) { | 1851 | switch (kcontrol->private_value) { |
1850 | case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: | 1852 | case CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT: |
1851 | down (&chip->spos_mutex); | 1853 | mutex_lock(&chip->spos_mutex); |
1852 | change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); | 1854 | change = (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED); |
1853 | if (ucontrol->value.integer.value[0] && !change) | 1855 | if (ucontrol->value.integer.value[0] && !change) |
1854 | cs46xx_dsp_enable_spdif_out(chip); | 1856 | cs46xx_dsp_enable_spdif_out(chip); |
@@ -1856,7 +1858,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, | |||
1856 | cs46xx_dsp_disable_spdif_out(chip); | 1858 | cs46xx_dsp_disable_spdif_out(chip); |
1857 | 1859 | ||
1858 | res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); | 1860 | res = (change != (chip->dsp_spos_instance->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED)); |
1859 | up (&chip->spos_mutex); | 1861 | mutex_unlock(&chip->spos_mutex); |
1860 | break; | 1862 | break; |
1861 | case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: | 1863 | case CS46XX_MIXER_SPDIF_INPUT_ELEMENT: |
1862 | change = chip->dsp_spos_instance->spdif_status_in; | 1864 | change = chip->dsp_spos_instance->spdif_status_in; |
@@ -1997,12 +1999,12 @@ static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol, | |||
1997 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 1999 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
1998 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 2000 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1999 | 2001 | ||
2000 | down (&chip->spos_mutex); | 2002 | mutex_lock(&chip->spos_mutex); |
2001 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); | 2003 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff); |
2002 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); | 2004 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_default >> 16) & 0xff); |
2003 | ucontrol->value.iec958.status[2] = 0; | 2005 | ucontrol->value.iec958.status[2] = 0; |
2004 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); | 2006 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_default) & 0xff); |
2005 | up (&chip->spos_mutex); | 2007 | mutex_unlock(&chip->spos_mutex); |
2006 | 2008 | ||
2007 | return 0; | 2009 | return 0; |
2008 | } | 2010 | } |
@@ -2015,7 +2017,7 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
2015 | unsigned int val; | 2017 | unsigned int val; |
2016 | int change; | 2018 | int change; |
2017 | 2019 | ||
2018 | down (&chip->spos_mutex); | 2020 | mutex_lock(&chip->spos_mutex); |
2019 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | | 2021 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | |
2020 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | | 2022 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[2]) << 16) | |
2021 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | | 2023 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | |
@@ -2029,7 +2031,7 @@ static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol, | |||
2029 | if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) | 2031 | if ( !(ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) ) |
2030 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); | 2032 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); |
2031 | 2033 | ||
2032 | up (&chip->spos_mutex); | 2034 | mutex_unlock(&chip->spos_mutex); |
2033 | 2035 | ||
2034 | return change; | 2036 | return change; |
2035 | } | 2037 | } |
@@ -2050,12 +2052,12 @@ static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol, | |||
2050 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); | 2052 | struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol); |
2051 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 2053 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
2052 | 2054 | ||
2053 | down (&chip->spos_mutex); | 2055 | mutex_lock(&chip->spos_mutex); |
2054 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); | 2056 | ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff); |
2055 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); | 2057 | ucontrol->value.iec958.status[1] = _wrap_all_bits((ins->spdif_csuv_stream >> 16) & 0xff); |
2056 | ucontrol->value.iec958.status[2] = 0; | 2058 | ucontrol->value.iec958.status[2] = 0; |
2057 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); | 2059 | ucontrol->value.iec958.status[3] = _wrap_all_bits((ins->spdif_csuv_stream) & 0xff); |
2058 | up (&chip->spos_mutex); | 2060 | mutex_unlock(&chip->spos_mutex); |
2059 | 2061 | ||
2060 | return 0; | 2062 | return 0; |
2061 | } | 2063 | } |
@@ -2068,7 +2070,7 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, | |||
2068 | unsigned int val; | 2070 | unsigned int val; |
2069 | int change; | 2071 | int change; |
2070 | 2072 | ||
2071 | down (&chip->spos_mutex); | 2073 | mutex_lock(&chip->spos_mutex); |
2072 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | | 2074 | val = ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[0]) << 24) | |
2073 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | | 2075 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[1]) << 16) | |
2074 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | | 2076 | ((unsigned int)_wrap_all_bits(ucontrol->value.iec958.status[3])) | |
@@ -2082,7 +2084,7 @@ static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol, | |||
2082 | if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) | 2084 | if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN ) |
2083 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); | 2085 | cs46xx_poke_via_dsp (chip,SP_SPDOUT_CSUV,val); |
2084 | 2086 | ||
2085 | up (&chip->spos_mutex); | 2087 | mutex_unlock(&chip->spos_mutex); |
2086 | 2088 | ||
2087 | return change; | 2089 | return change; |
2088 | } | 2090 | } |
@@ -3755,7 +3757,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card, | |||
3755 | } | 3757 | } |
3756 | spin_lock_init(&chip->reg_lock); | 3758 | spin_lock_init(&chip->reg_lock); |
3757 | #ifdef CONFIG_SND_CS46XX_NEW_DSP | 3759 | #ifdef CONFIG_SND_CS46XX_NEW_DSP |
3758 | init_MUTEX(&chip->spos_mutex); | 3760 | mutex_init(&chip->spos_mutex); |
3759 | #endif | 3761 | #endif |
3760 | chip->card = card; | 3762 | chip->card = card; |
3761 | chip->pci = pci; | 3763 | chip->pci = pci; |
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 445a448949e7..f407d2a5ce3b 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
31 | #include <linux/mutex.h> | ||
32 | |||
31 | #include <sound/core.h> | 33 | #include <sound/core.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
33 | #include <sound/info.h> | 35 | #include <sound/info.h> |
@@ -235,7 +237,7 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
235 | 237 | ||
236 | if (ins->symbol_table.symbols == NULL) { | 238 | if (ins->symbol_table.symbols == NULL) { |
237 | cs46xx_dsp_spos_destroy(chip); | 239 | cs46xx_dsp_spos_destroy(chip); |
238 | return NULL; | 240 | goto error; |
239 | } | 241 | } |
240 | 242 | ||
241 | ins->code.offset = 0; | 243 | ins->code.offset = 0; |
@@ -244,7 +246,7 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
244 | 246 | ||
245 | if (ins->code.data == NULL) { | 247 | if (ins->code.data == NULL) { |
246 | cs46xx_dsp_spos_destroy(chip); | 248 | cs46xx_dsp_spos_destroy(chip); |
247 | return NULL; | 249 | goto error; |
248 | } | 250 | } |
249 | 251 | ||
250 | ins->nscb = 0; | 252 | ins->nscb = 0; |
@@ -255,7 +257,7 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
255 | 257 | ||
256 | if (ins->modules == NULL) { | 258 | if (ins->modules == NULL) { |
257 | cs46xx_dsp_spos_destroy(chip); | 259 | cs46xx_dsp_spos_destroy(chip); |
258 | return NULL; | 260 | goto error; |
259 | } | 261 | } |
260 | 262 | ||
261 | /* default SPDIF input sample rate | 263 | /* default SPDIF input sample rate |
@@ -278,6 +280,10 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) | |||
278 | /* left and right validity bits */ (1 << 13) | (1 << 12); | 280 | /* left and right validity bits */ (1 << 13) | (1 << 12); |
279 | 281 | ||
280 | return ins; | 282 | return ins; |
283 | |||
284 | error: | ||
285 | kfree(ins); | ||
286 | return NULL; | ||
281 | } | 287 | } |
282 | 288 | ||
283 | void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) | 289 | void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) |
@@ -287,7 +293,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) | |||
287 | 293 | ||
288 | snd_assert(ins != NULL, return); | 294 | snd_assert(ins != NULL, return); |
289 | 295 | ||
290 | down(&chip->spos_mutex); | 296 | mutex_lock(&chip->spos_mutex); |
291 | for (i = 0; i < ins->nscb; ++i) { | 297 | for (i = 0; i < ins->nscb; ++i) { |
292 | if (ins->scbs[i].deleted) continue; | 298 | if (ins->scbs[i].deleted) continue; |
293 | 299 | ||
@@ -298,7 +304,7 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) | |||
298 | vfree(ins->symbol_table.symbols); | 304 | vfree(ins->symbol_table.symbols); |
299 | kfree(ins->modules); | 305 | kfree(ins->modules); |
300 | kfree(ins); | 306 | kfree(ins); |
301 | up(&chip->spos_mutex); | 307 | mutex_unlock(&chip->spos_mutex); |
302 | } | 308 | } |
303 | 309 | ||
304 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) | 310 | int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) |
@@ -497,7 +503,7 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry, | |||
497 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 503 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
498 | int i,j; | 504 | int i,j; |
499 | 505 | ||
500 | down(&chip->spos_mutex); | 506 | mutex_lock(&chip->spos_mutex); |
501 | snd_iprintf(buffer, "MODULES:\n"); | 507 | snd_iprintf(buffer, "MODULES:\n"); |
502 | for ( i = 0; i < ins->nmodules; ++i ) { | 508 | for ( i = 0; i < ins->nmodules; ++i ) { |
503 | snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name); | 509 | snd_iprintf(buffer, "\n%s:\n", ins->modules[i].module_name); |
@@ -510,7 +516,7 @@ static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry, | |||
510 | desc->segment_type,desc->offset, desc->size); | 516 | desc->segment_type,desc->offset, desc->size); |
511 | } | 517 | } |
512 | } | 518 | } |
513 | up(&chip->spos_mutex); | 519 | mutex_unlock(&chip->spos_mutex); |
514 | } | 520 | } |
515 | 521 | ||
516 | static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, | 522 | static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, |
@@ -521,7 +527,7 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, | |||
521 | int i, j, col; | 527 | int i, j, col; |
522 | void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; | 528 | void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; |
523 | 529 | ||
524 | down(&chip->spos_mutex); | 530 | mutex_lock(&chip->spos_mutex); |
525 | snd_iprintf(buffer, "TASK TREES:\n"); | 531 | snd_iprintf(buffer, "TASK TREES:\n"); |
526 | for ( i = 0; i < ins->ntask; ++i) { | 532 | for ( i = 0; i < ins->ntask; ++i) { |
527 | snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name); | 533 | snd_iprintf(buffer,"\n%04x %s:\n",ins->tasks[i].address,ins->tasks[i].task_name); |
@@ -538,7 +544,7 @@ static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry, | |||
538 | } | 544 | } |
539 | 545 | ||
540 | snd_iprintf(buffer,"\n"); | 546 | snd_iprintf(buffer,"\n"); |
541 | up(&chip->spos_mutex); | 547 | mutex_unlock(&chip->spos_mutex); |
542 | } | 548 | } |
543 | 549 | ||
544 | static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, | 550 | static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, |
@@ -548,7 +554,7 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, | |||
548 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 554 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
549 | int i; | 555 | int i; |
550 | 556 | ||
551 | down(&chip->spos_mutex); | 557 | mutex_lock(&chip->spos_mutex); |
552 | snd_iprintf(buffer, "SCB's:\n"); | 558 | snd_iprintf(buffer, "SCB's:\n"); |
553 | for ( i = 0; i < ins->nscb; ++i) { | 559 | for ( i = 0; i < ins->nscb; ++i) { |
554 | if (ins->scbs[i].deleted) | 560 | if (ins->scbs[i].deleted) |
@@ -571,7 +577,7 @@ static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry, | |||
571 | } | 577 | } |
572 | 578 | ||
573 | snd_iprintf(buffer,"\n"); | 579 | snd_iprintf(buffer,"\n"); |
574 | up(&chip->spos_mutex); | 580 | mutex_unlock(&chip->spos_mutex); |
575 | } | 581 | } |
576 | 582 | ||
577 | static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry, | 583 | static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry, |
@@ -852,14 +858,14 @@ int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip) | |||
852 | } | 858 | } |
853 | ins->proc_scb_info_entry = entry; | 859 | ins->proc_scb_info_entry = entry; |
854 | 860 | ||
855 | down(&chip->spos_mutex); | 861 | mutex_lock(&chip->spos_mutex); |
856 | /* register/update SCB's entries on proc */ | 862 | /* register/update SCB's entries on proc */ |
857 | for (i = 0; i < ins->nscb; ++i) { | 863 | for (i = 0; i < ins->nscb; ++i) { |
858 | if (ins->scbs[i].deleted) continue; | 864 | if (ins->scbs[i].deleted) continue; |
859 | 865 | ||
860 | cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i)); | 866 | cs46xx_dsp_proc_register_scb_desc (chip, (ins->scbs + i)); |
861 | } | 867 | } |
862 | up(&chip->spos_mutex); | 868 | mutex_unlock(&chip->spos_mutex); |
863 | 869 | ||
864 | return 0; | 870 | return 0; |
865 | } | 871 | } |
@@ -899,12 +905,12 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip) | |||
899 | ins->proc_task_info_entry = NULL; | 905 | ins->proc_task_info_entry = NULL; |
900 | } | 906 | } |
901 | 907 | ||
902 | down(&chip->spos_mutex); | 908 | mutex_lock(&chip->spos_mutex); |
903 | for (i = 0; i < ins->nscb; ++i) { | 909 | for (i = 0; i < ins->nscb; ++i) { |
904 | if (ins->scbs[i].deleted) continue; | 910 | if (ins->scbs[i].deleted) continue; |
905 | cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); | 911 | cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) ); |
906 | } | 912 | } |
907 | up(&chip->spos_mutex); | 913 | mutex_unlock(&chip->spos_mutex); |
908 | 914 | ||
909 | if (ins->proc_dsp_dir) { | 915 | if (ins->proc_dsp_dir) { |
910 | snd_info_unregister (ins->proc_dsp_dir); | 916 | snd_info_unregister (ins->proc_dsp_dir); |
@@ -1694,7 +1700,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip) | |||
1694 | snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); | 1700 | snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); |
1695 | snd_assert (ins->spdif_in_src != NULL,return -EINVAL); | 1701 | snd_assert (ins->spdif_in_src != NULL,return -EINVAL); |
1696 | 1702 | ||
1697 | down(&chip->spos_mutex); | 1703 | mutex_lock(&chip->spos_mutex); |
1698 | 1704 | ||
1699 | if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) { | 1705 | if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED) ) { |
1700 | /* time countdown enable */ | 1706 | /* time countdown enable */ |
@@ -1738,7 +1744,7 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip) | |||
1738 | 1744 | ||
1739 | /* monitor state */ | 1745 | /* monitor state */ |
1740 | ins->spdif_status_in = 1; | 1746 | ins->spdif_status_in = 1; |
1741 | up(&chip->spos_mutex); | 1747 | mutex_unlock(&chip->spos_mutex); |
1742 | 1748 | ||
1743 | return 0; | 1749 | return 0; |
1744 | } | 1750 | } |
@@ -1750,7 +1756,7 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip) | |||
1750 | snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); | 1756 | snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); |
1751 | snd_assert (ins->spdif_in_src != NULL,return -EINVAL); | 1757 | snd_assert (ins->spdif_in_src != NULL,return -EINVAL); |
1752 | 1758 | ||
1753 | down(&chip->spos_mutex); | 1759 | mutex_lock(&chip->spos_mutex); |
1754 | 1760 | ||
1755 | /* Remove the asynchronous receiver SCB */ | 1761 | /* Remove the asynchronous receiver SCB */ |
1756 | cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb); | 1762 | cs46xx_dsp_remove_scb (chip,ins->asynch_rx_scb); |
@@ -1760,7 +1766,7 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip) | |||
1760 | 1766 | ||
1761 | /* monitor state */ | 1767 | /* monitor state */ |
1762 | ins->spdif_status_in = 0; | 1768 | ins->spdif_status_in = 0; |
1763 | up(&chip->spos_mutex); | 1769 | mutex_unlock(&chip->spos_mutex); |
1764 | 1770 | ||
1765 | /* restore amplifier */ | 1771 | /* restore amplifier */ |
1766 | chip->active_ctrl(chip, -1); | 1772 | chip->active_ctrl(chip, -1); |
@@ -1776,10 +1782,10 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip) | |||
1776 | snd_assert (ins->pcm_input == NULL,return -EINVAL); | 1782 | snd_assert (ins->pcm_input == NULL,return -EINVAL); |
1777 | snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); | 1783 | snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); |
1778 | 1784 | ||
1779 | down(&chip->spos_mutex); | 1785 | mutex_lock(&chip->spos_mutex); |
1780 | ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, | 1786 | ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, |
1781 | "PCMSerialInput_Wave"); | 1787 | "PCMSerialInput_Wave"); |
1782 | up(&chip->spos_mutex); | 1788 | mutex_unlock(&chip->spos_mutex); |
1783 | 1789 | ||
1784 | return 0; | 1790 | return 0; |
1785 | } | 1791 | } |
@@ -1790,10 +1796,10 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip) | |||
1790 | 1796 | ||
1791 | snd_assert (ins->pcm_input != NULL,return -EINVAL); | 1797 | snd_assert (ins->pcm_input != NULL,return -EINVAL); |
1792 | 1798 | ||
1793 | down(&chip->spos_mutex); | 1799 | mutex_lock(&chip->spos_mutex); |
1794 | cs46xx_dsp_remove_scb (chip,ins->pcm_input); | 1800 | cs46xx_dsp_remove_scb (chip,ins->pcm_input); |
1795 | ins->pcm_input = NULL; | 1801 | ins->pcm_input = NULL; |
1796 | up(&chip->spos_mutex); | 1802 | mutex_unlock(&chip->spos_mutex); |
1797 | 1803 | ||
1798 | return 0; | 1804 | return 0; |
1799 | } | 1805 | } |
@@ -1805,10 +1811,10 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip) | |||
1805 | snd_assert (ins->adc_input == NULL,return -EINVAL); | 1811 | snd_assert (ins->adc_input == NULL,return -EINVAL); |
1806 | snd_assert (ins->codec_in_scb != NULL,return -EINVAL); | 1812 | snd_assert (ins->codec_in_scb != NULL,return -EINVAL); |
1807 | 1813 | ||
1808 | down(&chip->spos_mutex); | 1814 | mutex_lock(&chip->spos_mutex); |
1809 | ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, | 1815 | ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, |
1810 | "PCMSerialInput_ADC"); | 1816 | "PCMSerialInput_ADC"); |
1811 | up(&chip->spos_mutex); | 1817 | mutex_unlock(&chip->spos_mutex); |
1812 | 1818 | ||
1813 | return 0; | 1819 | return 0; |
1814 | } | 1820 | } |
@@ -1819,10 +1825,10 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip) | |||
1819 | 1825 | ||
1820 | snd_assert (ins->adc_input != NULL,return -EINVAL); | 1826 | snd_assert (ins->adc_input != NULL,return -EINVAL); |
1821 | 1827 | ||
1822 | down(&chip->spos_mutex); | 1828 | mutex_lock(&chip->spos_mutex); |
1823 | cs46xx_dsp_remove_scb (chip,ins->adc_input); | 1829 | cs46xx_dsp_remove_scb (chip,ins->adc_input); |
1824 | ins->adc_input = NULL; | 1830 | ins->adc_input = NULL; |
1825 | up(&chip->spos_mutex); | 1831 | mutex_unlock(&chip->spos_mutex); |
1826 | 1832 | ||
1827 | return 0; | 1833 | return 0; |
1828 | } | 1834 | } |
@@ -1869,7 +1875,7 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right) | |||
1869 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1875 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1870 | struct dsp_scb_descriptor * scb; | 1876 | struct dsp_scb_descriptor * scb; |
1871 | 1877 | ||
1872 | down(&chip->spos_mutex); | 1878 | mutex_lock(&chip->spos_mutex); |
1873 | 1879 | ||
1874 | /* main output */ | 1880 | /* main output */ |
1875 | scb = ins->master_mix_scb->sub_list_ptr; | 1881 | scb = ins->master_mix_scb->sub_list_ptr; |
@@ -1888,7 +1894,7 @@ int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right) | |||
1888 | ins->dac_volume_left = left; | 1894 | ins->dac_volume_left = left; |
1889 | ins->dac_volume_right = right; | 1895 | ins->dac_volume_right = right; |
1890 | 1896 | ||
1891 | up(&chip->spos_mutex); | 1897 | mutex_unlock(&chip->spos_mutex); |
1892 | 1898 | ||
1893 | return 0; | 1899 | return 0; |
1894 | } | 1900 | } |
@@ -1897,7 +1903,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) | |||
1897 | { | 1903 | { |
1898 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 1904 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
1899 | 1905 | ||
1900 | down(&chip->spos_mutex); | 1906 | mutex_lock(&chip->spos_mutex); |
1901 | 1907 | ||
1902 | if (ins->asynch_rx_scb != NULL) | 1908 | if (ins->asynch_rx_scb != NULL) |
1903 | cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb, | 1909 | cs46xx_dsp_scb_set_volume (chip,ins->asynch_rx_scb, |
@@ -1906,7 +1912,7 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) | |||
1906 | ins->spdif_input_volume_left = left; | 1912 | ins->spdif_input_volume_left = left; |
1907 | ins->spdif_input_volume_right = right; | 1913 | ins->spdif_input_volume_right = right; |
1908 | 1914 | ||
1909 | up(&chip->spos_mutex); | 1915 | mutex_unlock(&chip->spos_mutex); |
1910 | 1916 | ||
1911 | return 0; | 1917 | return 0; |
1912 | } | 1918 | } |
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index d4e0fb39bd06..2c4ee45fe10c 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/pm.h> | 28 | #include <linux/pm.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/mutex.h> | ||
32 | |||
31 | #include <sound/core.h> | 33 | #include <sound/core.h> |
32 | #include <sound/control.h> | 34 | #include <sound/control.h> |
33 | #include <sound/info.h> | 35 | #include <sound/info.h> |
@@ -77,7 +79,7 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, | |||
77 | 79 | ||
78 | ins = chip->dsp_spos_instance; | 80 | ins = chip->dsp_spos_instance; |
79 | 81 | ||
80 | down(&chip->spos_mutex); | 82 | mutex_lock(&chip->spos_mutex); |
81 | snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name); | 83 | snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name); |
82 | 84 | ||
83 | for (col = 0,j = 0;j < 0x10; j++,col++) { | 85 | for (col = 0,j = 0;j < 0x10; j++,col++) { |
@@ -105,7 +107,7 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, | |||
105 | scb->task_entry->address); | 107 | scb->task_entry->address); |
106 | 108 | ||
107 | snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count); | 109 | snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count); |
108 | up(&chip->spos_mutex); | 110 | mutex_unlock(&chip->spos_mutex); |
109 | } | 111 | } |
110 | #endif | 112 | #endif |
111 | 113 | ||
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 02e3721030b7..9fc7f3827461 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c | |||
@@ -62,7 +62,7 @@ static void wait_till_cmd_acked(struct cs5535audio *cs5535au, unsigned long time | |||
62 | tmp = cs_readl(cs5535au, ACC_CODEC_CNTL); | 62 | tmp = cs_readl(cs5535au, ACC_CODEC_CNTL); |
63 | if (!(tmp & CMD_NEW)) | 63 | if (!(tmp & CMD_NEW)) |
64 | break; | 64 | break; |
65 | msleep(10); | 65 | udelay(1); |
66 | } while (--timeout); | 66 | } while (--timeout); |
67 | if (!timeout) | 67 | if (!timeout) |
68 | snd_printk(KERN_ERR "Failure writing to cs5535 codec\n"); | 68 | snd_printk(KERN_ERR "Failure writing to cs5535 codec\n"); |
@@ -80,14 +80,14 @@ static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au, | |||
80 | regdata |= CMD_NEW; | 80 | regdata |= CMD_NEW; |
81 | 81 | ||
82 | cs_writel(cs5535au, ACC_CODEC_CNTL, regdata); | 82 | cs_writel(cs5535au, ACC_CODEC_CNTL, regdata); |
83 | wait_till_cmd_acked(cs5535au, 500); | 83 | wait_till_cmd_acked(cs5535au, 50); |
84 | 84 | ||
85 | timeout = 50; | 85 | timeout = 50; |
86 | do { | 86 | do { |
87 | val = cs_readl(cs5535au, ACC_CODEC_STATUS); | 87 | val = cs_readl(cs5535au, ACC_CODEC_STATUS); |
88 | if ((val & STS_NEW) && reg == (val >> 24)) | 88 | if ((val & STS_NEW) && reg == (val >> 24)) |
89 | break; | 89 | break; |
90 | msleep(10); | 90 | udelay(1); |
91 | } while (--timeout); | 91 | } while (--timeout); |
92 | if (!timeout) | 92 | if (!timeout) |
93 | snd_printk(KERN_ERR "Failure reading cs5535 codec\n"); | 93 | snd_printk(KERN_ERR "Failure reading cs5535 codec\n"); |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 3c7043b7d4c9..31cb9b48bb59 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/vmalloc.h> | 38 | #include <linux/vmalloc.h> |
39 | #include <linux/mutex.h> | ||
40 | |||
39 | 41 | ||
40 | #include <sound/core.h> | 42 | #include <sound/core.h> |
41 | #include <sound/emu10k1.h> | 43 | #include <sound/emu10k1.h> |
@@ -775,6 +777,14 @@ static int snd_emu10k1_dev_free(struct snd_device *device) | |||
775 | 777 | ||
776 | static struct snd_emu_chip_details emu_chip_details[] = { | 778 | static struct snd_emu_chip_details emu_chip_details[] = { |
777 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ | 779 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ |
780 | /* Audigy4 SB0400 */ | ||
781 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, | ||
782 | .driver = "Audigy2", .name = "Audigy 4 [SB0400]", | ||
783 | .id = "Audigy2", | ||
784 | .emu10k2_chip = 1, | ||
785 | .ca0108_chip = 1, | ||
786 | .spk71 = 1, | ||
787 | .ac97_chip = 1} , | ||
778 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | 788 | /* Tested by James@superbug.co.uk 3rd July 2005 */ |
779 | /* DSP: CA0108-IAT | 789 | /* DSP: CA0108-IAT |
780 | * DAC: CS4382-KQ | 790 | * DAC: CS4382-KQ |
@@ -1097,8 +1107,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card, | |||
1097 | spin_lock_init(&emu->voice_lock); | 1107 | spin_lock_init(&emu->voice_lock); |
1098 | spin_lock_init(&emu->synth_lock); | 1108 | spin_lock_init(&emu->synth_lock); |
1099 | spin_lock_init(&emu->memblk_lock); | 1109 | spin_lock_init(&emu->memblk_lock); |
1100 | init_MUTEX(&emu->ptb_lock); | 1110 | mutex_init(&emu->fx8010.lock); |
1101 | init_MUTEX(&emu->fx8010.lock); | ||
1102 | INIT_LIST_HEAD(&emu->mapped_link_head); | 1111 | INIT_LIST_HEAD(&emu->mapped_link_head); |
1103 | INIT_LIST_HEAD(&emu->mapped_order_link_head); | 1112 | INIT_LIST_HEAD(&emu->mapped_order_link_head); |
1104 | emu->pci = pci; | 1113 | emu->pci = pci; |
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c index 1fa393f22a99..204995a1dfbd 100644 --- a/sound/pci/emu10k1/emu10k1_synth.c +++ b/sound/pci/emu10k1/emu10k1_synth.c | |||
@@ -62,7 +62,6 @@ static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev) | |||
62 | 62 | ||
63 | if (snd_emux_register(emu, dev->card, arg->index, "Emu10k1") < 0) { | 63 | if (snd_emux_register(emu, dev->card, arg->index, "Emu10k1") < 0) { |
64 | snd_emux_free(emu); | 64 | snd_emux_free(emu); |
65 | emu->hw = NULL; | ||
66 | return -ENOMEM; | 65 | return -ENOMEM; |
67 | } | 66 | } |
68 | 67 | ||
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 1107c8ec7f78..2208dbd48be9 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/dma-mapping.h> | ||
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
37 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
38 | #include <sound/core.h> | 39 | #include <sound/core.h> |
@@ -893,24 +894,24 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card, | |||
893 | static struct snd_device_ops ops = { | 894 | static struct snd_device_ops ops = { |
894 | .dev_free = snd_emu10k1x_dev_free, | 895 | .dev_free = snd_emu10k1x_dev_free, |
895 | }; | 896 | }; |
896 | 897 | ||
897 | *rchip = NULL; | 898 | *rchip = NULL; |
898 | 899 | ||
899 | if ((err = pci_enable_device(pci)) < 0) | 900 | if ((err = pci_enable_device(pci)) < 0) |
900 | return err; | 901 | return err; |
901 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 902 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
902 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 903 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
903 | snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); | 904 | snd_printk(KERN_ERR "error to set 28bit mask DMA\n"); |
904 | pci_disable_device(pci); | 905 | pci_disable_device(pci); |
905 | return -ENXIO; | 906 | return -ENXIO; |
906 | } | 907 | } |
907 | 908 | ||
908 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 909 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
909 | if (chip == NULL) { | 910 | if (chip == NULL) { |
910 | pci_disable_device(pci); | 911 | pci_disable_device(pci); |
911 | return -ENOMEM; | 912 | return -ENOMEM; |
912 | } | 913 | } |
913 | 914 | ||
914 | chip->card = card; | 915 | chip->card = card; |
915 | chip->pci = pci; | 916 | chip->pci = pci; |
916 | chip->irq = -1; | 917 | chip->irq = -1; |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 509837252735..dfba00230d4d 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/mutex.h> | ||
36 | |||
35 | #include <sound/core.h> | 37 | #include <sound/core.h> |
36 | #include <sound/emu10k1.h> | 38 | #include <sound/emu10k1.h> |
37 | 39 | ||
@@ -874,7 +876,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, | |||
874 | { | 876 | { |
875 | int err = 0; | 877 | int err = 0; |
876 | 878 | ||
877 | down(&emu->fx8010.lock); | 879 | mutex_lock(&emu->fx8010.lock); |
878 | if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0) | 880 | if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0) |
879 | goto __error; | 881 | goto __error; |
880 | strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); | 882 | strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name)); |
@@ -897,7 +899,7 @@ static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu, | |||
897 | else | 899 | else |
898 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg); | 900 | snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg); |
899 | __error: | 901 | __error: |
900 | up(&emu->fx8010.lock); | 902 | mutex_unlock(&emu->fx8010.lock); |
901 | return err; | 903 | return err; |
902 | } | 904 | } |
903 | 905 | ||
@@ -906,7 +908,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, | |||
906 | { | 908 | { |
907 | int err; | 909 | int err; |
908 | 910 | ||
909 | down(&emu->fx8010.lock); | 911 | mutex_lock(&emu->fx8010.lock); |
910 | strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name)); | 912 | strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name)); |
911 | /* ok, do the main job */ | 913 | /* ok, do the main job */ |
912 | err = snd_emu10k1_gpr_peek(emu, icode); | 914 | err = snd_emu10k1_gpr_peek(emu, icode); |
@@ -916,7 +918,7 @@ static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu, | |||
916 | err = snd_emu10k1_code_peek(emu, icode); | 918 | err = snd_emu10k1_code_peek(emu, icode); |
917 | if (err >= 0) | 919 | if (err >= 0) |
918 | err = snd_emu10k1_list_controls(emu, icode); | 920 | err = snd_emu10k1_list_controls(emu, icode); |
919 | up(&emu->fx8010.lock); | 921 | mutex_unlock(&emu->fx8010.lock); |
920 | return err; | 922 | return err; |
921 | } | 923 | } |
922 | 924 | ||
@@ -932,7 +934,7 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, | |||
932 | if (ipcm->channels > 32) | 934 | if (ipcm->channels > 32) |
933 | return -EINVAL; | 935 | return -EINVAL; |
934 | pcm = &emu->fx8010.pcm[ipcm->substream]; | 936 | pcm = &emu->fx8010.pcm[ipcm->substream]; |
935 | down(&emu->fx8010.lock); | 937 | mutex_lock(&emu->fx8010.lock); |
936 | spin_lock_irq(&emu->reg_lock); | 938 | spin_lock_irq(&emu->reg_lock); |
937 | if (pcm->opened) { | 939 | if (pcm->opened) { |
938 | err = -EBUSY; | 940 | err = -EBUSY; |
@@ -962,7 +964,7 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, | |||
962 | } | 964 | } |
963 | __error: | 965 | __error: |
964 | spin_unlock_irq(&emu->reg_lock); | 966 | spin_unlock_irq(&emu->reg_lock); |
965 | up(&emu->fx8010.lock); | 967 | mutex_unlock(&emu->fx8010.lock); |
966 | return err; | 968 | return err; |
967 | } | 969 | } |
968 | 970 | ||
@@ -976,7 +978,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, | |||
976 | if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) | 978 | if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) |
977 | return -EINVAL; | 979 | return -EINVAL; |
978 | pcm = &emu->fx8010.pcm[ipcm->substream]; | 980 | pcm = &emu->fx8010.pcm[ipcm->substream]; |
979 | down(&emu->fx8010.lock); | 981 | mutex_lock(&emu->fx8010.lock); |
980 | spin_lock_irq(&emu->reg_lock); | 982 | spin_lock_irq(&emu->reg_lock); |
981 | ipcm->channels = pcm->channels; | 983 | ipcm->channels = pcm->channels; |
982 | ipcm->tram_start = pcm->tram_start; | 984 | ipcm->tram_start = pcm->tram_start; |
@@ -992,7 +994,7 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, | |||
992 | ipcm->res1 = ipcm->res2 = 0; | 994 | ipcm->res1 = ipcm->res2 = 0; |
993 | ipcm->pad = 0; | 995 | ipcm->pad = 0; |
994 | spin_unlock_irq(&emu->reg_lock); | 996 | spin_unlock_irq(&emu->reg_lock); |
995 | up(&emu->fx8010.lock); | 997 | mutex_unlock(&emu->fx8010.lock); |
996 | return err; | 998 | return err; |
997 | } | 999 | } |
998 | 1000 | ||
@@ -2308,9 +2310,9 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un | |||
2308 | return -EPERM; | 2310 | return -EPERM; |
2309 | if (get_user(addr, (unsigned int __user *)argp)) | 2311 | if (get_user(addr, (unsigned int __user *)argp)) |
2310 | return -EFAULT; | 2312 | return -EFAULT; |
2311 | down(&emu->fx8010.lock); | 2313 | mutex_lock(&emu->fx8010.lock); |
2312 | res = snd_emu10k1_fx8010_tram_setup(emu, addr); | 2314 | res = snd_emu10k1_fx8010_tram_setup(emu, addr); |
2313 | up(&emu->fx8010.lock); | 2315 | mutex_unlock(&emu->fx8010.lock); |
2314 | return res; | 2316 | return res; |
2315 | case SNDRV_EMU10K1_IOCTL_STOP: | 2317 | case SNDRV_EMU10K1_IOCTL_STOP: |
2316 | if (!capable(CAP_SYS_ADMIN)) | 2318 | if (!capable(CAP_SYS_ADMIN)) |
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 68c795c03109..e7ec98649f04 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <sound/driver.h> | 24 | #include <sound/driver.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/mutex.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include <sound/emu10k1.h> | 30 | #include <sound/emu10k1.h> |
29 | 31 | ||
@@ -302,10 +304,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst | |||
302 | hdr = emu->memhdr; | 304 | hdr = emu->memhdr; |
303 | snd_assert(hdr, return NULL); | 305 | snd_assert(hdr, return NULL); |
304 | 306 | ||
305 | down(&hdr->block_mutex); | 307 | mutex_lock(&hdr->block_mutex); |
306 | blk = search_empty(emu, runtime->dma_bytes); | 308 | blk = search_empty(emu, runtime->dma_bytes); |
307 | if (blk == NULL) { | 309 | if (blk == NULL) { |
308 | up(&hdr->block_mutex); | 310 | mutex_unlock(&hdr->block_mutex); |
309 | return NULL; | 311 | return NULL; |
310 | } | 312 | } |
311 | /* fill buffer addresses but pointers are not stored so that | 313 | /* fill buffer addresses but pointers are not stored so that |
@@ -318,14 +320,14 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst | |||
318 | if (idx >= sgbuf->pages) { | 320 | if (idx >= sgbuf->pages) { |
319 | printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n", | 321 | printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n", |
320 | blk->first_page, blk->last_page, sgbuf->pages); | 322 | blk->first_page, blk->last_page, sgbuf->pages); |
321 | up(&hdr->block_mutex); | 323 | mutex_unlock(&hdr->block_mutex); |
322 | return NULL; | 324 | return NULL; |
323 | } | 325 | } |
324 | #endif | 326 | #endif |
325 | addr = sgbuf->table[idx].addr; | 327 | addr = sgbuf->table[idx].addr; |
326 | if (! is_valid_page(emu, addr)) { | 328 | if (! is_valid_page(emu, addr)) { |
327 | printk(KERN_ERR "emu: failure page = %d\n", idx); | 329 | printk(KERN_ERR "emu: failure page = %d\n", idx); |
328 | up(&hdr->block_mutex); | 330 | mutex_unlock(&hdr->block_mutex); |
329 | return NULL; | 331 | return NULL; |
330 | } | 332 | } |
331 | emu->page_addr_table[page] = addr; | 333 | emu->page_addr_table[page] = addr; |
@@ -337,10 +339,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst | |||
337 | err = snd_emu10k1_memblk_map(emu, blk); | 339 | err = snd_emu10k1_memblk_map(emu, blk); |
338 | if (err < 0) { | 340 | if (err < 0) { |
339 | __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); | 341 | __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); |
340 | up(&hdr->block_mutex); | 342 | mutex_unlock(&hdr->block_mutex); |
341 | return NULL; | 343 | return NULL; |
342 | } | 344 | } |
343 | up(&hdr->block_mutex); | 345 | mutex_unlock(&hdr->block_mutex); |
344 | return (struct snd_util_memblk *)blk; | 346 | return (struct snd_util_memblk *)blk; |
345 | } | 347 | } |
346 | 348 | ||
@@ -369,19 +371,19 @@ snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size) | |||
369 | struct snd_emu10k1_memblk *blk; | 371 | struct snd_emu10k1_memblk *blk; |
370 | struct snd_util_memhdr *hdr = hw->memhdr; | 372 | struct snd_util_memhdr *hdr = hw->memhdr; |
371 | 373 | ||
372 | down(&hdr->block_mutex); | 374 | mutex_lock(&hdr->block_mutex); |
373 | blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size); | 375 | blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size); |
374 | if (blk == NULL) { | 376 | if (blk == NULL) { |
375 | up(&hdr->block_mutex); | 377 | mutex_unlock(&hdr->block_mutex); |
376 | return NULL; | 378 | return NULL; |
377 | } | 379 | } |
378 | if (synth_alloc_pages(hw, blk)) { | 380 | if (synth_alloc_pages(hw, blk)) { |
379 | __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); | 381 | __snd_util_mem_free(hdr, (struct snd_util_memblk *)blk); |
380 | up(&hdr->block_mutex); | 382 | mutex_unlock(&hdr->block_mutex); |
381 | return NULL; | 383 | return NULL; |
382 | } | 384 | } |
383 | snd_emu10k1_memblk_map(hw, blk); | 385 | snd_emu10k1_memblk_map(hw, blk); |
384 | up(&hdr->block_mutex); | 386 | mutex_unlock(&hdr->block_mutex); |
385 | return (struct snd_util_memblk *)blk; | 387 | return (struct snd_util_memblk *)blk; |
386 | } | 388 | } |
387 | 389 | ||
@@ -396,14 +398,14 @@ snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk) | |||
396 | struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk; | 398 | struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk; |
397 | unsigned long flags; | 399 | unsigned long flags; |
398 | 400 | ||
399 | down(&hdr->block_mutex); | 401 | mutex_lock(&hdr->block_mutex); |
400 | spin_lock_irqsave(&emu->memblk_lock, flags); | 402 | spin_lock_irqsave(&emu->memblk_lock, flags); |
401 | if (blk->mapped_page >= 0) | 403 | if (blk->mapped_page >= 0) |
402 | unmap_memblk(emu, blk); | 404 | unmap_memblk(emu, blk); |
403 | spin_unlock_irqrestore(&emu->memblk_lock, flags); | 405 | spin_unlock_irqrestore(&emu->memblk_lock, flags); |
404 | synth_free_pages(emu, blk); | 406 | synth_free_pages(emu, blk); |
405 | __snd_util_mem_free(hdr, memblk); | 407 | __snd_util_mem_free(hdr, memblk); |
406 | up(&hdr->block_mutex); | 408 | mutex_unlock(&hdr->block_mutex); |
407 | return 0; | 409 | return 0; |
408 | } | 410 | } |
409 | 411 | ||
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 55aaf110331a..a5533c86b0b6 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/gameport.h> | 36 | #include <linux/gameport.h> |
37 | #include <linux/moduleparam.h> | 37 | #include <linux/moduleparam.h> |
38 | #include <linux/mutex.h> | ||
39 | |||
38 | #include <sound/core.h> | 40 | #include <sound/core.h> |
39 | #include <sound/control.h> | 41 | #include <sound/control.h> |
40 | #include <sound/pcm.h> | 42 | #include <sound/pcm.h> |
@@ -379,7 +381,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); | |||
379 | 381 | ||
380 | struct ensoniq { | 382 | struct ensoniq { |
381 | spinlock_t reg_lock; | 383 | spinlock_t reg_lock; |
382 | struct semaphore src_mutex; | 384 | struct mutex src_mutex; |
383 | 385 | ||
384 | int irq; | 386 | int irq; |
385 | 387 | ||
@@ -609,7 +611,7 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, | |||
609 | struct ensoniq *ensoniq = ac97->private_data; | 611 | struct ensoniq *ensoniq = ac97->private_data; |
610 | unsigned int t, x; | 612 | unsigned int t, x; |
611 | 613 | ||
612 | down(&ensoniq->src_mutex); | 614 | mutex_lock(&ensoniq->src_mutex); |
613 | for (t = 0; t < POLL_COUNT; t++) { | 615 | for (t = 0; t < POLL_COUNT; t++) { |
614 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { | 616 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { |
615 | /* save the current state for latter */ | 617 | /* save the current state for latter */ |
@@ -634,11 +636,11 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, | |||
634 | /* restore SRC reg */ | 636 | /* restore SRC reg */ |
635 | snd_es1371_wait_src_ready(ensoniq); | 637 | snd_es1371_wait_src_ready(ensoniq); |
636 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); | 638 | outl(x, ES_REG(ensoniq, 1371_SMPRATE)); |
637 | up(&ensoniq->src_mutex); | 639 | mutex_unlock(&ensoniq->src_mutex); |
638 | return; | 640 | return; |
639 | } | 641 | } |
640 | } | 642 | } |
641 | up(&ensoniq->src_mutex); | 643 | mutex_unlock(&ensoniq->src_mutex); |
642 | snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", | 644 | snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", |
643 | ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); | 645 | ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); |
644 | } | 646 | } |
@@ -650,7 +652,7 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
650 | unsigned int t, x, fail = 0; | 652 | unsigned int t, x, fail = 0; |
651 | 653 | ||
652 | __again: | 654 | __again: |
653 | down(&ensoniq->src_mutex); | 655 | mutex_lock(&ensoniq->src_mutex); |
654 | for (t = 0; t < POLL_COUNT; t++) { | 656 | for (t = 0; t < POLL_COUNT; t++) { |
655 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { | 657 | if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { |
656 | /* save the current state for latter */ | 658 | /* save the current state for latter */ |
@@ -683,11 +685,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
683 | /* now wait for the stinkin' data (RDY) */ | 685 | /* now wait for the stinkin' data (RDY) */ |
684 | for (t = 0; t < POLL_COUNT; t++) { | 686 | for (t = 0; t < POLL_COUNT; t++) { |
685 | if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { | 687 | if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { |
686 | up(&ensoniq->src_mutex); | 688 | mutex_unlock(&ensoniq->src_mutex); |
687 | return ES_1371_CODEC_READ(x); | 689 | return ES_1371_CODEC_READ(x); |
688 | } | 690 | } |
689 | } | 691 | } |
690 | up(&ensoniq->src_mutex); | 692 | mutex_unlock(&ensoniq->src_mutex); |
691 | if (++fail > 10) { | 693 | if (++fail > 10) { |
692 | snd_printk(KERN_ERR "codec read timeout (final) " | 694 | snd_printk(KERN_ERR "codec read timeout (final) " |
693 | "at 0x%lx, reg = 0x%x [0x%x]\n", | 695 | "at 0x%lx, reg = 0x%x [0x%x]\n", |
@@ -698,7 +700,7 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, | |||
698 | goto __again; | 700 | goto __again; |
699 | } | 701 | } |
700 | } | 702 | } |
701 | up(&ensoniq->src_mutex); | 703 | mutex_unlock(&ensoniq->src_mutex); |
702 | snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", | 704 | snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", |
703 | ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); | 705 | ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); |
704 | return 0; | 706 | return 0; |
@@ -717,7 +719,7 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate) | |||
717 | { | 719 | { |
718 | unsigned int n, truncm, freq, result; | 720 | unsigned int n, truncm, freq, result; |
719 | 721 | ||
720 | down(&ensoniq->src_mutex); | 722 | mutex_lock(&ensoniq->src_mutex); |
721 | n = rate / 3000; | 723 | n = rate / 3000; |
722 | if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) | 724 | if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) |
723 | n--; | 725 | n--; |
@@ -742,14 +744,14 @@ static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate) | |||
742 | snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); | 744 | snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); |
743 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8); | 745 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8); |
744 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8); | 746 | snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8); |
745 | up(&ensoniq->src_mutex); | 747 | mutex_unlock(&ensoniq->src_mutex); |
746 | } | 748 | } |
747 | 749 | ||
748 | static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) | 750 | static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) |
749 | { | 751 | { |
750 | unsigned int freq, r; | 752 | unsigned int freq, r; |
751 | 753 | ||
752 | down(&ensoniq->src_mutex); | 754 | mutex_lock(&ensoniq->src_mutex); |
753 | freq = ((rate << 15) + 1500) / 3000; | 755 | freq = ((rate << 15) + 1500) / 3000; |
754 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 756 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
755 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | | 757 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | |
@@ -763,14 +765,14 @@ static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate) | |||
763 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 765 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
764 | ES_1371_DIS_P2 | ES_1371_DIS_R1)); | 766 | ES_1371_DIS_P2 | ES_1371_DIS_R1)); |
765 | outl(r, ES_REG(ensoniq, 1371_SMPRATE)); | 767 | outl(r, ES_REG(ensoniq, 1371_SMPRATE)); |
766 | up(&ensoniq->src_mutex); | 768 | mutex_unlock(&ensoniq->src_mutex); |
767 | } | 769 | } |
768 | 770 | ||
769 | static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) | 771 | static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) |
770 | { | 772 | { |
771 | unsigned int freq, r; | 773 | unsigned int freq, r; |
772 | 774 | ||
773 | down(&ensoniq->src_mutex); | 775 | mutex_lock(&ensoniq->src_mutex); |
774 | freq = ((rate << 15) + 1500) / 3000; | 776 | freq = ((rate << 15) + 1500) / 3000; |
775 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 777 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
776 | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | | 778 | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | |
@@ -785,7 +787,7 @@ static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate) | |||
785 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | | 787 | r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | |
786 | ES_1371_DIS_P1 | ES_1371_DIS_R1)); | 788 | ES_1371_DIS_P1 | ES_1371_DIS_R1)); |
787 | outl(r, ES_REG(ensoniq, 1371_SMPRATE)); | 789 | outl(r, ES_REG(ensoniq, 1371_SMPRATE)); |
788 | up(&ensoniq->src_mutex); | 790 | mutex_unlock(&ensoniq->src_mutex); |
789 | } | 791 | } |
790 | 792 | ||
791 | #endif /* CHIP1371 */ | 793 | #endif /* CHIP1371 */ |
@@ -2061,6 +2063,13 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state) | |||
2061 | #ifdef CHIP1371 | 2063 | #ifdef CHIP1371 |
2062 | snd_ac97_suspend(ensoniq->u.es1371.ac97); | 2064 | snd_ac97_suspend(ensoniq->u.es1371.ac97); |
2063 | #else | 2065 | #else |
2066 | /* try to reset AK4531 */ | ||
2067 | outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x02), ES_REG(ensoniq, 1370_CODEC)); | ||
2068 | inw(ES_REG(ensoniq, 1370_CODEC)); | ||
2069 | udelay(100); | ||
2070 | outw(ES_1370_CODEC_WRITE(AK4531_RESET, 0x03), ES_REG(ensoniq, 1370_CODEC)); | ||
2071 | inw(ES_REG(ensoniq, 1370_CODEC)); | ||
2072 | udelay(100); | ||
2064 | snd_ak4531_suspend(ensoniq->u.es1370.ak4531); | 2073 | snd_ak4531_suspend(ensoniq->u.es1370.ak4531); |
2065 | #endif | 2074 | #endif |
2066 | pci_set_power_state(pci, PCI_D3hot); | 2075 | pci_set_power_state(pci, PCI_D3hot); |
@@ -2116,7 +2125,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card, | |||
2116 | return -ENOMEM; | 2125 | return -ENOMEM; |
2117 | } | 2126 | } |
2118 | spin_lock_init(&ensoniq->reg_lock); | 2127 | spin_lock_init(&ensoniq->reg_lock); |
2119 | init_MUTEX(&ensoniq->src_mutex); | 2128 | mutex_init(&ensoniq->src_mutex); |
2120 | ensoniq->card = card; | 2129 | ensoniq->card = card; |
2121 | ensoniq->pci = pci; | 2130 | ensoniq->pci = pci; |
2122 | ensoniq->irq = -1; | 2131 | ensoniq->irq = -1; |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 3747a436f0cd..dd465a186e11 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -100,9 +100,12 @@ | |||
100 | #include <linux/interrupt.h> | 100 | #include <linux/interrupt.h> |
101 | #include <linux/init.h> | 101 | #include <linux/init.h> |
102 | #include <linux/pci.h> | 102 | #include <linux/pci.h> |
103 | #include <linux/dma-mapping.h> | ||
103 | #include <linux/slab.h> | 104 | #include <linux/slab.h> |
104 | #include <linux/gameport.h> | 105 | #include <linux/gameport.h> |
105 | #include <linux/moduleparam.h> | 106 | #include <linux/moduleparam.h> |
107 | #include <linux/mutex.h> | ||
108 | |||
106 | #include <sound/core.h> | 109 | #include <sound/core.h> |
107 | #include <sound/pcm.h> | 110 | #include <sound/pcm.h> |
108 | #include <sound/mpu401.h> | 111 | #include <sound/mpu401.h> |
@@ -569,7 +572,7 @@ struct es1968 { | |||
569 | u16 maestro_map[32]; | 572 | u16 maestro_map[32]; |
570 | int bobclient; /* active timer instancs */ | 573 | int bobclient; /* active timer instancs */ |
571 | int bob_freq; /* timer frequency */ | 574 | int bob_freq; /* timer frequency */ |
572 | struct semaphore memory_mutex; /* memory lock */ | 575 | struct mutex memory_mutex; /* memory lock */ |
573 | 576 | ||
574 | /* APU states */ | 577 | /* APU states */ |
575 | unsigned char apu[NR_APUS]; | 578 | unsigned char apu[NR_APUS]; |
@@ -1356,13 +1359,13 @@ static int calc_available_memory_size(struct es1968 *chip) | |||
1356 | struct list_head *p; | 1359 | struct list_head *p; |
1357 | int max_size = 0; | 1360 | int max_size = 0; |
1358 | 1361 | ||
1359 | down(&chip->memory_mutex); | 1362 | mutex_lock(&chip->memory_mutex); |
1360 | list_for_each(p, &chip->buf_list) { | 1363 | list_for_each(p, &chip->buf_list) { |
1361 | struct esm_memory *buf = list_entry(p, struct esm_memory, list); | 1364 | struct esm_memory *buf = list_entry(p, struct esm_memory, list); |
1362 | if (buf->empty && buf->buf.bytes > max_size) | 1365 | if (buf->empty && buf->buf.bytes > max_size) |
1363 | max_size = buf->buf.bytes; | 1366 | max_size = buf->buf.bytes; |
1364 | } | 1367 | } |
1365 | up(&chip->memory_mutex); | 1368 | mutex_unlock(&chip->memory_mutex); |
1366 | if (max_size >= 128*1024) | 1369 | if (max_size >= 128*1024) |
1367 | max_size = 127*1024; | 1370 | max_size = 127*1024; |
1368 | return max_size; | 1371 | return max_size; |
@@ -1375,20 +1378,20 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) | |||
1375 | struct list_head *p; | 1378 | struct list_head *p; |
1376 | 1379 | ||
1377 | size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN; | 1380 | size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN; |
1378 | down(&chip->memory_mutex); | 1381 | mutex_lock(&chip->memory_mutex); |
1379 | list_for_each(p, &chip->buf_list) { | 1382 | list_for_each(p, &chip->buf_list) { |
1380 | buf = list_entry(p, struct esm_memory, list); | 1383 | buf = list_entry(p, struct esm_memory, list); |
1381 | if (buf->empty && buf->buf.bytes >= size) | 1384 | if (buf->empty && buf->buf.bytes >= size) |
1382 | goto __found; | 1385 | goto __found; |
1383 | } | 1386 | } |
1384 | up(&chip->memory_mutex); | 1387 | mutex_unlock(&chip->memory_mutex); |
1385 | return NULL; | 1388 | return NULL; |
1386 | 1389 | ||
1387 | __found: | 1390 | __found: |
1388 | if (buf->buf.bytes > size) { | 1391 | if (buf->buf.bytes > size) { |
1389 | struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); | 1392 | struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); |
1390 | if (chunk == NULL) { | 1393 | if (chunk == NULL) { |
1391 | up(&chip->memory_mutex); | 1394 | mutex_unlock(&chip->memory_mutex); |
1392 | return NULL; | 1395 | return NULL; |
1393 | } | 1396 | } |
1394 | chunk->buf = buf->buf; | 1397 | chunk->buf = buf->buf; |
@@ -1400,7 +1403,7 @@ __found: | |||
1400 | list_add(&chunk->list, &buf->list); | 1403 | list_add(&chunk->list, &buf->list); |
1401 | } | 1404 | } |
1402 | buf->empty = 0; | 1405 | buf->empty = 0; |
1403 | up(&chip->memory_mutex); | 1406 | mutex_unlock(&chip->memory_mutex); |
1404 | return buf; | 1407 | return buf; |
1405 | } | 1408 | } |
1406 | 1409 | ||
@@ -1409,7 +1412,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) | |||
1409 | { | 1412 | { |
1410 | struct esm_memory *chunk; | 1413 | struct esm_memory *chunk; |
1411 | 1414 | ||
1412 | down(&chip->memory_mutex); | 1415 | mutex_lock(&chip->memory_mutex); |
1413 | buf->empty = 1; | 1416 | buf->empty = 1; |
1414 | if (buf->list.prev != &chip->buf_list) { | 1417 | if (buf->list.prev != &chip->buf_list) { |
1415 | chunk = list_entry(buf->list.prev, struct esm_memory, list); | 1418 | chunk = list_entry(buf->list.prev, struct esm_memory, list); |
@@ -1428,7 +1431,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) | |||
1428 | kfree(chunk); | 1431 | kfree(chunk); |
1429 | } | 1432 | } |
1430 | } | 1433 | } |
1431 | up(&chip->memory_mutex); | 1434 | mutex_unlock(&chip->memory_mutex); |
1432 | } | 1435 | } |
1433 | 1436 | ||
1434 | static void snd_es1968_free_dmabuf(struct es1968 *chip) | 1437 | static void snd_es1968_free_dmabuf(struct es1968 *chip) |
@@ -2559,8 +2562,8 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2559 | if ((err = pci_enable_device(pci)) < 0) | 2562 | if ((err = pci_enable_device(pci)) < 0) |
2560 | return err; | 2563 | return err; |
2561 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2564 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2562 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 2565 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
2563 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 2566 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
2564 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2567 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2565 | pci_disable_device(pci); | 2568 | pci_disable_device(pci); |
2566 | return -ENXIO; | 2569 | return -ENXIO; |
@@ -2579,7 +2582,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2579 | INIT_LIST_HEAD(&chip->buf_list); | 2582 | INIT_LIST_HEAD(&chip->buf_list); |
2580 | INIT_LIST_HEAD(&chip->substream_list); | 2583 | INIT_LIST_HEAD(&chip->substream_list); |
2581 | spin_lock_init(&chip->ac97_lock); | 2584 | spin_lock_init(&chip->ac97_lock); |
2582 | init_MUTEX(&chip->memory_mutex); | 2585 | mutex_init(&chip->memory_mutex); |
2583 | tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); | 2586 | tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip); |
2584 | chip->card = card; | 2587 | chip->card = card; |
2585 | chip->pci = pci; | 2588 | chip->pci = pci; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4a6dd97deba6..b42dff7ceed0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include "hda_codec.h" | 30 | #include "hda_codec.h" |
30 | #include <sound/asoundef.h> | 31 | #include <sound/asoundef.h> |
@@ -76,12 +77,12 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire | |||
76 | unsigned int verb, unsigned int parm) | 77 | unsigned int verb, unsigned int parm) |
77 | { | 78 | { |
78 | unsigned int res; | 79 | unsigned int res; |
79 | down(&codec->bus->cmd_mutex); | 80 | mutex_lock(&codec->bus->cmd_mutex); |
80 | if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) | 81 | if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) |
81 | res = codec->bus->ops.get_response(codec); | 82 | res = codec->bus->ops.get_response(codec); |
82 | else | 83 | else |
83 | res = (unsigned int)-1; | 84 | res = (unsigned int)-1; |
84 | up(&codec->bus->cmd_mutex); | 85 | mutex_unlock(&codec->bus->cmd_mutex); |
85 | return res; | 86 | return res; |
86 | } | 87 | } |
87 | 88 | ||
@@ -101,9 +102,9 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
101 | unsigned int verb, unsigned int parm) | 102 | unsigned int verb, unsigned int parm) |
102 | { | 103 | { |
103 | int err; | 104 | int err; |
104 | down(&codec->bus->cmd_mutex); | 105 | mutex_lock(&codec->bus->cmd_mutex); |
105 | err = codec->bus->ops.command(codec, nid, direct, verb, parm); | 106 | err = codec->bus->ops.command(codec, nid, direct, verb, parm); |
106 | up(&codec->bus->cmd_mutex); | 107 | mutex_unlock(&codec->bus->cmd_mutex); |
107 | return err; | 108 | return err; |
108 | } | 109 | } |
109 | 110 | ||
@@ -371,7 +372,7 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, | |||
371 | bus->modelname = temp->modelname; | 372 | bus->modelname = temp->modelname; |
372 | bus->ops = temp->ops; | 373 | bus->ops = temp->ops; |
373 | 374 | ||
374 | init_MUTEX(&bus->cmd_mutex); | 375 | mutex_init(&bus->cmd_mutex); |
375 | INIT_LIST_HEAD(&bus->codec_list); | 376 | INIT_LIST_HEAD(&bus->codec_list); |
376 | 377 | ||
377 | if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { | 378 | if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { |
@@ -523,13 +524,19 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
523 | 524 | ||
524 | codec->bus = bus; | 525 | codec->bus = bus; |
525 | codec->addr = codec_addr; | 526 | codec->addr = codec_addr; |
526 | init_MUTEX(&codec->spdif_mutex); | 527 | mutex_init(&codec->spdif_mutex); |
527 | init_amp_hash(codec); | 528 | init_amp_hash(codec); |
528 | 529 | ||
529 | list_add_tail(&codec->list, &bus->codec_list); | 530 | list_add_tail(&codec->list, &bus->codec_list); |
530 | bus->caddr_tbl[codec_addr] = codec; | 531 | bus->caddr_tbl[codec_addr] = codec; |
531 | 532 | ||
532 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); | 533 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); |
534 | if (codec->vendor_id == -1) | ||
535 | /* read again, hopefully the access method was corrected | ||
536 | * in the last read... | ||
537 | */ | ||
538 | codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, | ||
539 | AC_PAR_VENDOR_ID); | ||
533 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); | 540 | codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); |
534 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); | 541 | codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); |
535 | 542 | ||
@@ -722,7 +729,8 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
722 | /* | 729 | /* |
723 | * read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit. | 730 | * read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit. |
724 | */ | 731 | */ |
725 | static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) | 732 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, |
733 | int direction, int index) | ||
726 | { | 734 | { |
727 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); | 735 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); |
728 | if (! info) | 736 | if (! info) |
@@ -733,7 +741,8 @@ static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch | |||
733 | /* | 741 | /* |
734 | * update the AMP value, mask = bit mask to set, val = the value | 742 | * update the AMP value, mask = bit mask to set, val = the value |
735 | */ | 743 | */ |
736 | static int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val) | 744 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
745 | int direction, int idx, int mask, int val) | ||
737 | { | 746 | { |
738 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); | 747 | struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); |
739 | 748 | ||
@@ -881,12 +890,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
881 | unsigned long pval; | 890 | unsigned long pval; |
882 | int err; | 891 | int err; |
883 | 892 | ||
884 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | 893 | mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ |
885 | pval = kcontrol->private_value; | 894 | pval = kcontrol->private_value; |
886 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | 895 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ |
887 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | 896 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); |
888 | kcontrol->private_value = pval; | 897 | kcontrol->private_value = pval; |
889 | up(&codec->spdif_mutex); | 898 | mutex_unlock(&codec->spdif_mutex); |
890 | return err; | 899 | return err; |
891 | } | 900 | } |
892 | 901 | ||
@@ -896,7 +905,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
896 | unsigned long pval; | 905 | unsigned long pval; |
897 | int i, indices, err = 0, change = 0; | 906 | int i, indices, err = 0, change = 0; |
898 | 907 | ||
899 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | 908 | mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ |
900 | pval = kcontrol->private_value; | 909 | pval = kcontrol->private_value; |
901 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | 910 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; |
902 | for (i = 0; i < indices; i++) { | 911 | for (i = 0; i < indices; i++) { |
@@ -907,7 +916,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
907 | change |= err; | 916 | change |= err; |
908 | } | 917 | } |
909 | kcontrol->private_value = pval; | 918 | kcontrol->private_value = pval; |
910 | up(&codec->spdif_mutex); | 919 | mutex_unlock(&codec->spdif_mutex); |
911 | return err < 0 ? err : change; | 920 | return err < 0 ? err : change; |
912 | } | 921 | } |
913 | 922 | ||
@@ -1011,7 +1020,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c | |||
1011 | unsigned short val; | 1020 | unsigned short val; |
1012 | int change; | 1021 | int change; |
1013 | 1022 | ||
1014 | down(&codec->spdif_mutex); | 1023 | mutex_lock(&codec->spdif_mutex); |
1015 | codec->spdif_status = ucontrol->value.iec958.status[0] | | 1024 | codec->spdif_status = ucontrol->value.iec958.status[0] | |
1016 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | | 1025 | ((unsigned int)ucontrol->value.iec958.status[1] << 8) | |
1017 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | | 1026 | ((unsigned int)ucontrol->value.iec958.status[2] << 16) | |
@@ -1026,7 +1035,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c | |||
1026 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); | 1035 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); |
1027 | } | 1036 | } |
1028 | 1037 | ||
1029 | up(&codec->spdif_mutex); | 1038 | mutex_unlock(&codec->spdif_mutex); |
1030 | return change; | 1039 | return change; |
1031 | } | 1040 | } |
1032 | 1041 | ||
@@ -1054,7 +1063,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn | |||
1054 | unsigned short val; | 1063 | unsigned short val; |
1055 | int change; | 1064 | int change; |
1056 | 1065 | ||
1057 | down(&codec->spdif_mutex); | 1066 | mutex_lock(&codec->spdif_mutex); |
1058 | val = codec->spdif_ctls & ~1; | 1067 | val = codec->spdif_ctls & ~1; |
1059 | if (ucontrol->value.integer.value[0]) | 1068 | if (ucontrol->value.integer.value[0]) |
1060 | val |= 1; | 1069 | val |= 1; |
@@ -1066,7 +1075,7 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn | |||
1066 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | | 1075 | AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | |
1067 | AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); | 1076 | AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); |
1068 | } | 1077 | } |
1069 | up(&codec->spdif_mutex); | 1078 | mutex_unlock(&codec->spdif_mutex); |
1070 | return change; | 1079 | return change; |
1071 | } | 1080 | } |
1072 | 1081 | ||
@@ -1150,13 +1159,13 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd | |||
1150 | unsigned int val = !!ucontrol->value.integer.value[0]; | 1159 | unsigned int val = !!ucontrol->value.integer.value[0]; |
1151 | int change; | 1160 | int change; |
1152 | 1161 | ||
1153 | down(&codec->spdif_mutex); | 1162 | mutex_lock(&codec->spdif_mutex); |
1154 | change = codec->spdif_in_enable != val; | 1163 | change = codec->spdif_in_enable != val; |
1155 | if (change || codec->in_resume) { | 1164 | if (change || codec->in_resume) { |
1156 | codec->spdif_in_enable = val; | 1165 | codec->spdif_in_enable = val; |
1157 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); | 1166 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); |
1158 | } | 1167 | } |
1159 | up(&codec->spdif_mutex); | 1168 | mutex_unlock(&codec->spdif_mutex); |
1160 | return change; | 1169 | return change; |
1161 | } | 1170 | } |
1162 | 1171 | ||
@@ -1824,13 +1833,13 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i | |||
1824 | */ | 1833 | */ |
1825 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) | 1834 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) |
1826 | { | 1835 | { |
1827 | down(&codec->spdif_mutex); | 1836 | mutex_lock(&codec->spdif_mutex); |
1828 | if (mout->dig_out_used) { | 1837 | if (mout->dig_out_used) { |
1829 | up(&codec->spdif_mutex); | 1838 | mutex_unlock(&codec->spdif_mutex); |
1830 | return -EBUSY; /* already being used */ | 1839 | return -EBUSY; /* already being used */ |
1831 | } | 1840 | } |
1832 | mout->dig_out_used = HDA_DIG_EXCLUSIVE; | 1841 | mout->dig_out_used = HDA_DIG_EXCLUSIVE; |
1833 | up(&codec->spdif_mutex); | 1842 | mutex_unlock(&codec->spdif_mutex); |
1834 | return 0; | 1843 | return 0; |
1835 | } | 1844 | } |
1836 | 1845 | ||
@@ -1839,9 +1848,9 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mo | |||
1839 | */ | 1848 | */ |
1840 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) | 1849 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) |
1841 | { | 1850 | { |
1842 | down(&codec->spdif_mutex); | 1851 | mutex_lock(&codec->spdif_mutex); |
1843 | mout->dig_out_used = 0; | 1852 | mout->dig_out_used = 0; |
1844 | up(&codec->spdif_mutex); | 1853 | mutex_unlock(&codec->spdif_mutex); |
1845 | return 0; | 1854 | return 0; |
1846 | } | 1855 | } |
1847 | 1856 | ||
@@ -1869,7 +1878,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o | |||
1869 | int chs = substream->runtime->channels; | 1878 | int chs = substream->runtime->channels; |
1870 | int i; | 1879 | int i; |
1871 | 1880 | ||
1872 | down(&codec->spdif_mutex); | 1881 | mutex_lock(&codec->spdif_mutex); |
1873 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { | 1882 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { |
1874 | if (chs == 2 && | 1883 | if (chs == 2 && |
1875 | snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && | 1884 | snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && |
@@ -1883,13 +1892,20 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o | |||
1883 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); | 1892 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); |
1884 | } | 1893 | } |
1885 | } | 1894 | } |
1886 | up(&codec->spdif_mutex); | 1895 | mutex_unlock(&codec->spdif_mutex); |
1887 | 1896 | ||
1888 | /* front */ | 1897 | /* front */ |
1889 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); | 1898 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); |
1890 | if (mout->hp_nid) | 1899 | if (mout->hp_nid) |
1891 | /* headphone out will just decode front left/right (stereo) */ | 1900 | /* headphone out will just decode front left/right (stereo) */ |
1892 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); | 1901 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); |
1902 | /* extra outputs copied from front */ | ||
1903 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | ||
1904 | if (mout->extra_out_nid[i]) | ||
1905 | snd_hda_codec_setup_stream(codec, | ||
1906 | mout->extra_out_nid[i], | ||
1907 | stream_tag, 0, format); | ||
1908 | |||
1893 | /* surrounds */ | 1909 | /* surrounds */ |
1894 | for (i = 1; i < mout->num_dacs; i++) { | 1910 | for (i = 1; i < mout->num_dacs; i++) { |
1895 | if (chs >= (i + 1) * 2) /* independent out */ | 1911 | if (chs >= (i + 1) * 2) /* independent out */ |
@@ -1914,12 +1930,17 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o | |||
1914 | snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); | 1930 | snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); |
1915 | if (mout->hp_nid) | 1931 | if (mout->hp_nid) |
1916 | snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); | 1932 | snd_hda_codec_setup_stream(codec, mout->hp_nid, 0, 0, 0); |
1917 | down(&codec->spdif_mutex); | 1933 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) |
1934 | if (mout->extra_out_nid[i]) | ||
1935 | snd_hda_codec_setup_stream(codec, | ||
1936 | mout->extra_out_nid[i], | ||
1937 | 0, 0, 0); | ||
1938 | mutex_lock(&codec->spdif_mutex); | ||
1918 | if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { | 1939 | if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { |
1919 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); | 1940 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); |
1920 | mout->dig_out_used = 0; | 1941 | mout->dig_out_used = 0; |
1921 | } | 1942 | } |
1922 | up(&codec->spdif_mutex); | 1943 | mutex_unlock(&codec->spdif_mutex); |
1923 | return 0; | 1944 | return 0; |
1924 | } | 1945 | } |
1925 | 1946 | ||
@@ -1935,13 +1956,29 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | |||
1935 | return 0; | 1956 | return 0; |
1936 | } | 1957 | } |
1937 | 1958 | ||
1938 | /* parse all pin widgets and store the useful pin nids to cfg */ | 1959 | /* |
1960 | * Parse all pin widgets and store the useful pin nids to cfg | ||
1961 | * | ||
1962 | * The number of line-outs or any primary output is stored in line_outs, | ||
1963 | * and the corresponding output pins are assigned to line_out_pins[], | ||
1964 | * in the order of front, rear, CLFE, side, ... | ||
1965 | * | ||
1966 | * If more extra outputs (speaker and headphone) are found, the pins are | ||
1967 | * assisnged to hp_pin and speaker_pins[], respectively. If no line-out jack | ||
1968 | * is detected, one of speaker of HP pins is assigned as the primary | ||
1969 | * output, i.e. to line_out_pins[0]. So, line_outs is always positive | ||
1970 | * if any analog output exists. | ||
1971 | * | ||
1972 | * The analog input pins are assigned to input_pins array. | ||
1973 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | ||
1974 | * respectively. | ||
1975 | */ | ||
1939 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, | 1976 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, |
1940 | hda_nid_t *ignore_nids) | 1977 | hda_nid_t *ignore_nids) |
1941 | { | 1978 | { |
1942 | hda_nid_t nid, nid_start; | 1979 | hda_nid_t nid, nid_start; |
1943 | int i, j, nodes; | 1980 | int i, j, nodes; |
1944 | short seq, sequences[4], assoc_line_out; | 1981 | short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; |
1945 | 1982 | ||
1946 | memset(cfg, 0, sizeof(*cfg)); | 1983 | memset(cfg, 0, sizeof(*cfg)); |
1947 | 1984 | ||
@@ -1983,7 +2020,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
1983 | cfg->line_outs++; | 2020 | cfg->line_outs++; |
1984 | break; | 2021 | break; |
1985 | case AC_JACK_SPEAKER: | 2022 | case AC_JACK_SPEAKER: |
1986 | cfg->speaker_pin = nid; | 2023 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) |
2024 | continue; | ||
2025 | cfg->speaker_pins[cfg->speaker_outs] = nid; | ||
2026 | cfg->speaker_outs++; | ||
1987 | break; | 2027 | break; |
1988 | case AC_JACK_HP_OUT: | 2028 | case AC_JACK_HP_OUT: |
1989 | cfg->hp_pin = nid; | 2029 | cfg->hp_pin = nid; |
@@ -2048,6 +2088,46 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
2048 | break; | 2088 | break; |
2049 | } | 2089 | } |
2050 | 2090 | ||
2091 | /* | ||
2092 | * debug prints of the parsed results | ||
2093 | */ | ||
2094 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
2095 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
2096 | cfg->line_out_pins[2], cfg->line_out_pins[3], | ||
2097 | cfg->line_out_pins[4]); | ||
2098 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
2099 | cfg->speaker_outs, cfg->speaker_pins[0], | ||
2100 | cfg->speaker_pins[1], cfg->speaker_pins[2], | ||
2101 | cfg->speaker_pins[3], cfg->speaker_pins[4]); | ||
2102 | snd_printd(" hp=0x%x, dig_out=0x%x, din_in=0x%x\n", | ||
2103 | cfg->hp_pin, cfg->dig_out_pin, cfg->dig_in_pin); | ||
2104 | snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," | ||
2105 | " cd=0x%x, aux=0x%x\n", | ||
2106 | cfg->input_pins[AUTO_PIN_MIC], | ||
2107 | cfg->input_pins[AUTO_PIN_FRONT_MIC], | ||
2108 | cfg->input_pins[AUTO_PIN_LINE], | ||
2109 | cfg->input_pins[AUTO_PIN_FRONT_LINE], | ||
2110 | cfg->input_pins[AUTO_PIN_CD], | ||
2111 | cfg->input_pins[AUTO_PIN_AUX]); | ||
2112 | |||
2113 | /* | ||
2114 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | ||
2115 | * as a primary output | ||
2116 | */ | ||
2117 | if (! cfg->line_outs) { | ||
2118 | if (cfg->speaker_outs) { | ||
2119 | cfg->line_outs = cfg->speaker_outs; | ||
2120 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
2121 | sizeof(cfg->speaker_pins)); | ||
2122 | cfg->speaker_outs = 0; | ||
2123 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
2124 | } else if (cfg->hp_pin) { | ||
2125 | cfg->line_outs = 1; | ||
2126 | cfg->line_out_pins[0] = cfg->hp_pin; | ||
2127 | cfg->hp_pin = 0; | ||
2128 | } | ||
2129 | } | ||
2130 | |||
2051 | return 0; | 2131 | return 0; |
2052 | } | 2132 | } |
2053 | 2133 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 63e26c7a2b7a..40520e9d5a4b 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -438,7 +438,7 @@ struct hda_bus { | |||
438 | struct list_head codec_list; | 438 | struct list_head codec_list; |
439 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ | 439 | struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */ |
440 | 440 | ||
441 | struct semaphore cmd_mutex; | 441 | struct mutex cmd_mutex; |
442 | 442 | ||
443 | /* unsolicited event queue */ | 443 | /* unsolicited event queue */ |
444 | struct hda_bus_unsolicited *unsol; | 444 | struct hda_bus_unsolicited *unsol; |
@@ -559,7 +559,7 @@ struct hda_codec { | |||
559 | int amp_info_size; | 559 | int amp_info_size; |
560 | struct hda_amp_info *amp_info; | 560 | struct hda_amp_info *amp_info; |
561 | 561 | ||
562 | struct semaphore spdif_mutex; | 562 | struct mutex spdif_mutex; |
563 | unsigned int spdif_status; /* IEC958 status bits */ | 563 | unsigned int spdif_status; /* IEC958 status bits */ |
564 | unsigned short spdif_ctls; /* SPDIF control bits */ | 564 | unsigned short spdif_ctls; /* SPDIF control bits */ |
565 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 565 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 39edfcfd3abd..85ad164ada59 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -47,10 +47,10 @@ struct hda_gnode { | |||
47 | 47 | ||
48 | /* patch-specific record */ | 48 | /* patch-specific record */ |
49 | struct hda_gspec { | 49 | struct hda_gspec { |
50 | struct hda_gnode *dac_node; /* DAC node */ | 50 | struct hda_gnode *dac_node[2]; /* DAC node */ |
51 | struct hda_gnode *out_pin_node; /* Output pin (Line-Out) node */ | 51 | struct hda_gnode *out_pin_node[2]; /* Output pin (Line-Out) node */ |
52 | struct hda_gnode *pcm_vol_node; /* Node for PCM volume */ | 52 | struct hda_gnode *pcm_vol_node[2]; /* Node for PCM volume */ |
53 | unsigned int pcm_vol_index; /* connection of PCM volume */ | 53 | unsigned int pcm_vol_index[2]; /* connection of PCM volume */ |
54 | 54 | ||
55 | struct hda_gnode *adc_node; /* ADC node */ | 55 | struct hda_gnode *adc_node; /* ADC node */ |
56 | struct hda_gnode *cap_vol_node; /* Node for capture volume */ | 56 | struct hda_gnode *cap_vol_node; /* Node for capture volume */ |
@@ -69,8 +69,12 @@ struct hda_gspec { | |||
69 | /* | 69 | /* |
70 | * retrieve the default device type from the default config value | 70 | * retrieve the default device type from the default config value |
71 | */ | 71 | */ |
72 | #define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 72 | #define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> \ |
73 | #define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | 73 | AC_DEFCFG_DEVICE_SHIFT) |
74 | #define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> \ | ||
75 | AC_DEFCFG_LOCATION_SHIFT) | ||
76 | #define defcfg_port_conn(node) (((node)->def_cfg & AC_DEFCFG_PORT_CONN) >> \ | ||
77 | AC_DEFCFG_PORT_CONN_SHIFT) | ||
74 | 78 | ||
75 | /* | 79 | /* |
76 | * destructor | 80 | * destructor |
@@ -261,7 +265,7 @@ static void clear_check_flags(struct hda_gspec *spec) | |||
261 | * returns 0 if not found, 1 if found, or a negative error code. | 265 | * returns 0 if not found, 1 if found, or a negative error code. |
262 | */ | 266 | */ |
263 | static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, | 267 | static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, |
264 | struct hda_gnode *node) | 268 | struct hda_gnode *node, int dac_idx) |
265 | { | 269 | { |
266 | int i, err; | 270 | int i, err; |
267 | struct hda_gnode *child; | 271 | struct hda_gnode *child; |
@@ -276,14 +280,14 @@ static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, | |||
276 | return 0; | 280 | return 0; |
277 | } | 281 | } |
278 | snd_printdd("AUD_OUT found %x\n", node->nid); | 282 | snd_printdd("AUD_OUT found %x\n", node->nid); |
279 | if (spec->dac_node) { | 283 | if (spec->dac_node[dac_idx]) { |
280 | /* already DAC node is assigned, just unmute & connect */ | 284 | /* already DAC node is assigned, just unmute & connect */ |
281 | return node == spec->dac_node; | 285 | return node == spec->dac_node[dac_idx]; |
282 | } | 286 | } |
283 | spec->dac_node = node; | 287 | spec->dac_node[dac_idx] = node; |
284 | if (node->wid_caps & AC_WCAP_OUT_AMP) { | 288 | if (node->wid_caps & AC_WCAP_OUT_AMP) { |
285 | spec->pcm_vol_node = node; | 289 | spec->pcm_vol_node[dac_idx] = node; |
286 | spec->pcm_vol_index = 0; | 290 | spec->pcm_vol_index[dac_idx] = 0; |
287 | } | 291 | } |
288 | return 1; /* found */ | 292 | return 1; /* found */ |
289 | } | 293 | } |
@@ -292,7 +296,7 @@ static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, | |||
292 | child = hda_get_node(spec, node->conn_list[i]); | 296 | child = hda_get_node(spec, node->conn_list[i]); |
293 | if (! child) | 297 | if (! child) |
294 | continue; | 298 | continue; |
295 | err = parse_output_path(codec, spec, child); | 299 | err = parse_output_path(codec, spec, child, dac_idx); |
296 | if (err < 0) | 300 | if (err < 0) |
297 | return err; | 301 | return err; |
298 | else if (err > 0) { | 302 | else if (err > 0) { |
@@ -303,13 +307,13 @@ static int parse_output_path(struct hda_codec *codec, struct hda_gspec *spec, | |||
303 | select_input_connection(codec, node, i); | 307 | select_input_connection(codec, node, i); |
304 | unmute_input(codec, node, i); | 308 | unmute_input(codec, node, i); |
305 | unmute_output(codec, node); | 309 | unmute_output(codec, node); |
306 | if (! spec->pcm_vol_node) { | 310 | if (! spec->pcm_vol_node[dac_idx]) { |
307 | if (node->wid_caps & AC_WCAP_IN_AMP) { | 311 | if (node->wid_caps & AC_WCAP_IN_AMP) { |
308 | spec->pcm_vol_node = node; | 312 | spec->pcm_vol_node[dac_idx] = node; |
309 | spec->pcm_vol_index = i; | 313 | spec->pcm_vol_index[dac_idx] = i; |
310 | } else if (node->wid_caps & AC_WCAP_OUT_AMP) { | 314 | } else if (node->wid_caps & AC_WCAP_OUT_AMP) { |
311 | spec->pcm_vol_node = node; | 315 | spec->pcm_vol_node[dac_idx] = node; |
312 | spec->pcm_vol_index = 0; | 316 | spec->pcm_vol_index[dac_idx] = 0; |
313 | } | 317 | } |
314 | } | 318 | } |
315 | return 1; | 319 | return 1; |
@@ -339,6 +343,8 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, | |||
339 | /* output capable? */ | 343 | /* output capable? */ |
340 | if (! (node->pin_caps & AC_PINCAP_OUT)) | 344 | if (! (node->pin_caps & AC_PINCAP_OUT)) |
341 | continue; | 345 | continue; |
346 | if (defcfg_port_conn(node) == AC_JACK_PORT_NONE) | ||
347 | continue; /* unconnected */ | ||
342 | if (jack_type >= 0) { | 348 | if (jack_type >= 0) { |
343 | if (jack_type != defcfg_type(node)) | 349 | if (jack_type != defcfg_type(node)) |
344 | continue; | 350 | continue; |
@@ -350,10 +356,15 @@ static struct hda_gnode *parse_output_jack(struct hda_codec *codec, | |||
350 | continue; | 356 | continue; |
351 | } | 357 | } |
352 | clear_check_flags(spec); | 358 | clear_check_flags(spec); |
353 | err = parse_output_path(codec, spec, node); | 359 | err = parse_output_path(codec, spec, node, 0); |
354 | if (err < 0) | 360 | if (err < 0) |
355 | return NULL; | 361 | return NULL; |
356 | else if (err > 0) { | 362 | if (! err && spec->out_pin_node[0]) { |
363 | err = parse_output_path(codec, spec, node, 1); | ||
364 | if (err < 0) | ||
365 | return NULL; | ||
366 | } | ||
367 | if (err > 0) { | ||
357 | /* unmute the PIN output */ | 368 | /* unmute the PIN output */ |
358 | unmute_output(codec, node); | 369 | unmute_output(codec, node); |
359 | /* set PIN-Out enable */ | 370 | /* set PIN-Out enable */ |
@@ -381,20 +392,28 @@ static int parse_output(struct hda_codec *codec) | |||
381 | /* first, look for the line-out pin */ | 392 | /* first, look for the line-out pin */ |
382 | node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT); | 393 | node = parse_output_jack(codec, spec, AC_JACK_LINE_OUT); |
383 | if (node) /* found, remember the PIN node */ | 394 | if (node) /* found, remember the PIN node */ |
384 | spec->out_pin_node = node; | 395 | spec->out_pin_node[0] = node; |
396 | else { | ||
397 | /* if no line-out is found, try speaker out */ | ||
398 | node = parse_output_jack(codec, spec, AC_JACK_SPEAKER); | ||
399 | if (node) | ||
400 | spec->out_pin_node[0] = node; | ||
401 | } | ||
385 | /* look for the HP-out pin */ | 402 | /* look for the HP-out pin */ |
386 | node = parse_output_jack(codec, spec, AC_JACK_HP_OUT); | 403 | node = parse_output_jack(codec, spec, AC_JACK_HP_OUT); |
387 | if (node) { | 404 | if (node) { |
388 | if (! spec->out_pin_node) | 405 | if (! spec->out_pin_node[0]) |
389 | spec->out_pin_node = node; | 406 | spec->out_pin_node[0] = node; |
407 | else | ||
408 | spec->out_pin_node[1] = node; | ||
390 | } | 409 | } |
391 | 410 | ||
392 | if (! spec->out_pin_node) { | 411 | if (! spec->out_pin_node[0]) { |
393 | /* no line-out or HP pins found, | 412 | /* no line-out or HP pins found, |
394 | * then choose for the first output pin | 413 | * then choose for the first output pin |
395 | */ | 414 | */ |
396 | spec->out_pin_node = parse_output_jack(codec, spec, -1); | 415 | spec->out_pin_node[0] = parse_output_jack(codec, spec, -1); |
397 | if (! spec->out_pin_node) | 416 | if (! spec->out_pin_node[0]) |
398 | snd_printd("hda_generic: no proper output path found\n"); | 417 | snd_printd("hda_generic: no proper output path found\n"); |
399 | } | 418 | } |
400 | 419 | ||
@@ -505,6 +524,9 @@ static int parse_adc_sub_nodes(struct hda_codec *codec, struct hda_gspec *spec, | |||
505 | if (! (node->pin_caps & AC_PINCAP_IN)) | 524 | if (! (node->pin_caps & AC_PINCAP_IN)) |
506 | return 0; | 525 | return 0; |
507 | 526 | ||
527 | if (defcfg_port_conn(node) == AC_JACK_PORT_NONE) | ||
528 | return 0; /* unconnected */ | ||
529 | |||
508 | if (node->wid_caps & AC_WCAP_DIGITAL) | 530 | if (node->wid_caps & AC_WCAP_DIGITAL) |
509 | return 0; /* skip SPDIF */ | 531 | return 0; /* skip SPDIF */ |
510 | 532 | ||
@@ -703,12 +725,16 @@ static int check_existing_control(struct hda_codec *codec, const char *type, con | |||
703 | static int build_output_controls(struct hda_codec *codec) | 725 | static int build_output_controls(struct hda_codec *codec) |
704 | { | 726 | { |
705 | struct hda_gspec *spec = codec->spec; | 727 | struct hda_gspec *spec = codec->spec; |
706 | int err; | 728 | static const char *types[2] = { "Master", "Headphone" }; |
729 | int i, err; | ||
707 | 730 | ||
708 | err = create_mixer(codec, spec->pcm_vol_node, spec->pcm_vol_index, | 731 | for (i = 0; i < 2 && spec->pcm_vol_node[i]; i++) { |
709 | "PCM", "Playback"); | 732 | err = create_mixer(codec, spec->pcm_vol_node[i], |
710 | if (err < 0) | 733 | spec->pcm_vol_index[i], |
711 | return err; | 734 | types[i], "Playback"); |
735 | if (err < 0) | ||
736 | return err; | ||
737 | } | ||
712 | return 0; | 738 | return 0; |
713 | } | 739 | } |
714 | 740 | ||
@@ -805,7 +831,7 @@ static int build_loopback_controls(struct hda_codec *codec) | |||
805 | int err; | 831 | int err; |
806 | const char *type; | 832 | const char *type; |
807 | 833 | ||
808 | if (! spec->out_pin_node) | 834 | if (! spec->out_pin_node[0]) |
809 | return 0; | 835 | return 0; |
810 | 836 | ||
811 | list_for_each(p, &spec->nid_list) { | 837 | list_for_each(p, &spec->nid_list) { |
@@ -820,7 +846,8 @@ static int build_loopback_controls(struct hda_codec *codec) | |||
820 | if (check_existing_control(codec, type, "Playback")) | 846 | if (check_existing_control(codec, type, "Playback")) |
821 | continue; | 847 | continue; |
822 | clear_check_flags(spec); | 848 | clear_check_flags(spec); |
823 | err = parse_loopback_path(codec, spec, spec->out_pin_node, | 849 | err = parse_loopback_path(codec, spec, |
850 | spec->out_pin_node[0], | ||
824 | node, type); | 851 | node, type); |
825 | if (err < 0) | 852 | if (err < 0) |
826 | return err; | 853 | return err; |
@@ -855,12 +882,37 @@ static struct hda_pcm_stream generic_pcm_playback = { | |||
855 | .channels_max = 2, | 882 | .channels_max = 2, |
856 | }; | 883 | }; |
857 | 884 | ||
885 | static int generic_pcm2_prepare(struct hda_pcm_stream *hinfo, | ||
886 | struct hda_codec *codec, | ||
887 | unsigned int stream_tag, | ||
888 | unsigned int format, | ||
889 | struct snd_pcm_substream *substream) | ||
890 | { | ||
891 | struct hda_gspec *spec = codec->spec; | ||
892 | |||
893 | snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); | ||
894 | snd_hda_codec_setup_stream(codec, spec->dac_node[1]->nid, | ||
895 | stream_tag, 0, format); | ||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | static int generic_pcm2_cleanup(struct hda_pcm_stream *hinfo, | ||
900 | struct hda_codec *codec, | ||
901 | struct snd_pcm_substream *substream) | ||
902 | { | ||
903 | struct hda_gspec *spec = codec->spec; | ||
904 | |||
905 | snd_hda_codec_setup_stream(codec, hinfo->nid, 0, 0, 0); | ||
906 | snd_hda_codec_setup_stream(codec, spec->dac_node[1]->nid, 0, 0, 0); | ||
907 | return 0; | ||
908 | } | ||
909 | |||
858 | static int build_generic_pcms(struct hda_codec *codec) | 910 | static int build_generic_pcms(struct hda_codec *codec) |
859 | { | 911 | { |
860 | struct hda_gspec *spec = codec->spec; | 912 | struct hda_gspec *spec = codec->spec; |
861 | struct hda_pcm *info = &spec->pcm_rec; | 913 | struct hda_pcm *info = &spec->pcm_rec; |
862 | 914 | ||
863 | if (! spec->dac_node && ! spec->adc_node) { | 915 | if (! spec->dac_node[0] && ! spec->adc_node) { |
864 | snd_printd("hda_generic: no PCM found\n"); | 916 | snd_printd("hda_generic: no PCM found\n"); |
865 | return 0; | 917 | return 0; |
866 | } | 918 | } |
@@ -869,9 +921,13 @@ static int build_generic_pcms(struct hda_codec *codec) | |||
869 | codec->pcm_info = info; | 921 | codec->pcm_info = info; |
870 | 922 | ||
871 | info->name = "HDA Generic"; | 923 | info->name = "HDA Generic"; |
872 | if (spec->dac_node) { | 924 | if (spec->dac_node[0]) { |
873 | info->stream[0] = generic_pcm_playback; | 925 | info->stream[0] = generic_pcm_playback; |
874 | info->stream[0].nid = spec->dac_node->nid; | 926 | info->stream[0].nid = spec->dac_node[0]->nid; |
927 | if (spec->dac_node[1]) { | ||
928 | info->stream[0].ops.prepare = generic_pcm2_prepare; | ||
929 | info->stream[0].ops.cleanup = generic_pcm2_cleanup; | ||
930 | } | ||
875 | } | 931 | } |
876 | if (spec->adc_node) { | 932 | if (spec->adc_node) { |
877 | info->stream[1] = generic_pcm_playback; | 933 | info->stream[1] = generic_pcm_playback; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fd12b6991fe4..c096606970ff 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/mutex.h> | ||
46 | #include <sound/core.h> | 47 | #include <sound/core.h> |
47 | #include <sound/initval.h> | 48 | #include <sound/initval.h> |
48 | #include "hda_codec.h" | 49 | #include "hda_codec.h" |
@@ -53,6 +54,7 @@ static char *id = SNDRV_DEFAULT_STR1; | |||
53 | static char *model; | 54 | static char *model; |
54 | static int position_fix; | 55 | static int position_fix; |
55 | static int probe_mask = -1; | 56 | static int probe_mask = -1; |
57 | static int single_cmd; | ||
56 | 58 | ||
57 | module_param(index, int, 0444); | 59 | module_param(index, int, 0444); |
58 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 60 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -64,6 +66,8 @@ module_param(position_fix, int, 0444); | |||
64 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 66 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
65 | module_param(probe_mask, int, 0444); | 67 | module_param(probe_mask, int, 0444); |
66 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 68 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
69 | module_param(single_cmd, bool, 0444); | ||
70 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs (for debugging only)."); | ||
67 | 71 | ||
68 | 72 | ||
69 | /* just for backward compatibility */ | 73 | /* just for backward compatibility */ |
@@ -235,12 +239,6 @@ enum { | |||
235 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f | 239 | #define NVIDIA_HDA_ENABLE_COHBITS 0x0f |
236 | 240 | ||
237 | /* | 241 | /* |
238 | * Use CORB/RIRB for communication from/to codecs. | ||
239 | * This is the way recommended by Intel (see below). | ||
240 | */ | ||
241 | #define USE_CORB_RIRB | ||
242 | |||
243 | /* | ||
244 | */ | 242 | */ |
245 | 243 | ||
246 | struct azx_dev { | 244 | struct azx_dev { |
@@ -252,7 +250,6 @@ struct azx_dev { | |||
252 | unsigned int fragsize; /* size of each period in bytes */ | 250 | unsigned int fragsize; /* size of each period in bytes */ |
253 | unsigned int frags; /* number for period in the play buffer */ | 251 | unsigned int frags; /* number for period in the play buffer */ |
254 | unsigned int fifo_size; /* FIFO size */ | 252 | unsigned int fifo_size; /* FIFO size */ |
255 | unsigned int last_pos; /* last updated period position */ | ||
256 | 253 | ||
257 | void __iomem *sd_addr; /* stream descriptor pointer */ | 254 | void __iomem *sd_addr; /* stream descriptor pointer */ |
258 | 255 | ||
@@ -263,10 +260,11 @@ struct azx_dev { | |||
263 | unsigned int format_val; /* format value to be set in the controller and the codec */ | 260 | unsigned int format_val; /* format value to be set in the controller and the codec */ |
264 | unsigned char stream_tag; /* assigned stream */ | 261 | unsigned char stream_tag; /* assigned stream */ |
265 | unsigned char index; /* stream index */ | 262 | unsigned char index; /* stream index */ |
263 | /* for sanity check of position buffer */ | ||
264 | unsigned int period_intr; | ||
266 | 265 | ||
267 | unsigned int opened: 1; | 266 | unsigned int opened: 1; |
268 | unsigned int running: 1; | 267 | unsigned int running: 1; |
269 | unsigned int period_updating: 1; | ||
270 | }; | 268 | }; |
271 | 269 | ||
272 | /* CORB/RIRB */ | 270 | /* CORB/RIRB */ |
@@ -300,7 +298,7 @@ struct azx { | |||
300 | 298 | ||
301 | /* locks */ | 299 | /* locks */ |
302 | spinlock_t reg_lock; | 300 | spinlock_t reg_lock; |
303 | struct semaphore open_mutex; | 301 | struct mutex open_mutex; |
304 | 302 | ||
305 | /* streams (x num_streams) */ | 303 | /* streams (x num_streams) */ |
306 | struct azx_dev *azx_dev; | 304 | struct azx_dev *azx_dev; |
@@ -325,6 +323,7 @@ struct azx { | |||
325 | /* flags */ | 323 | /* flags */ |
326 | int position_fix; | 324 | int position_fix; |
327 | unsigned int initialized: 1; | 325 | unsigned int initialized: 1; |
326 | unsigned int single_cmd: 1; | ||
328 | }; | 327 | }; |
329 | 328 | ||
330 | /* driver types */ | 329 | /* driver types */ |
@@ -388,7 +387,6 @@ static char *driver_short_names[] __devinitdata = { | |||
388 | * Interface for HD codec | 387 | * Interface for HD codec |
389 | */ | 388 | */ |
390 | 389 | ||
391 | #ifdef USE_CORB_RIRB | ||
392 | /* | 390 | /* |
393 | * CORB / RIRB interface | 391 | * CORB / RIRB interface |
394 | */ | 392 | */ |
@@ -436,11 +434,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
436 | /* set N=1, get RIRB response interrupt for new entry */ | 434 | /* set N=1, get RIRB response interrupt for new entry */ |
437 | azx_writew(chip, RINTCNT, 1); | 435 | azx_writew(chip, RINTCNT, 1); |
438 | /* enable rirb dma and response irq */ | 436 | /* enable rirb dma and response irq */ |
439 | #ifdef USE_CORB_RIRB | ||
440 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); | 437 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN | ICH6_RBCTL_IRQ_EN); |
441 | #else | ||
442 | azx_writeb(chip, RIRBCTL, ICH6_RBCTL_DMA_EN); | ||
443 | #endif | ||
444 | chip->rirb.rp = chip->rirb.cmds = 0; | 438 | chip->rirb.rp = chip->rirb.cmds = 0; |
445 | } | 439 | } |
446 | 440 | ||
@@ -452,8 +446,8 @@ static void azx_free_cmd_io(struct azx *chip) | |||
452 | } | 446 | } |
453 | 447 | ||
454 | /* send a command */ | 448 | /* send a command */ |
455 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 449 | static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, |
456 | unsigned int verb, unsigned int para) | 450 | unsigned int verb, unsigned int para) |
457 | { | 451 | { |
458 | struct azx *chip = codec->bus->private_data; | 452 | struct azx *chip = codec->bus->private_data; |
459 | unsigned int wp; | 453 | unsigned int wp; |
@@ -509,18 +503,21 @@ static void azx_update_rirb(struct azx *chip) | |||
509 | } | 503 | } |
510 | 504 | ||
511 | /* receive a response */ | 505 | /* receive a response */ |
512 | static unsigned int azx_get_response(struct hda_codec *codec) | 506 | static unsigned int azx_rirb_get_response(struct hda_codec *codec) |
513 | { | 507 | { |
514 | struct azx *chip = codec->bus->private_data; | 508 | struct azx *chip = codec->bus->private_data; |
515 | int timeout = 50; | 509 | int timeout = 50; |
516 | 510 | ||
517 | while (chip->rirb.cmds) { | 511 | while (chip->rirb.cmds) { |
518 | if (! --timeout) { | 512 | if (! --timeout) { |
519 | if (printk_ratelimit()) | 513 | snd_printk(KERN_ERR |
520 | snd_printk(KERN_ERR | 514 | "hda_intel: azx_get_response timeout, " |
521 | "azx_get_response timeout\n"); | 515 | "switching to single_cmd mode...\n"); |
522 | chip->rirb.rp = azx_readb(chip, RIRBWP); | 516 | chip->rirb.rp = azx_readb(chip, RIRBWP); |
523 | chip->rirb.cmds = 0; | 517 | chip->rirb.cmds = 0; |
518 | /* switch to single_cmd mode */ | ||
519 | chip->single_cmd = 1; | ||
520 | azx_free_cmd_io(chip); | ||
524 | return -1; | 521 | return -1; |
525 | } | 522 | } |
526 | msleep(1); | 523 | msleep(1); |
@@ -528,7 +525,6 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
528 | return chip->rirb.res; /* the last value */ | 525 | return chip->rirb.res; /* the last value */ |
529 | } | 526 | } |
530 | 527 | ||
531 | #else | ||
532 | /* | 528 | /* |
533 | * Use the single immediate command instead of CORB/RIRB for simplicity | 529 | * Use the single immediate command instead of CORB/RIRB for simplicity |
534 | * | 530 | * |
@@ -539,13 +535,10 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
539 | * I left the codes, however, for debugging/testing purposes. | 535 | * I left the codes, however, for debugging/testing purposes. |
540 | */ | 536 | */ |
541 | 537 | ||
542 | #define azx_alloc_cmd_io(chip) 0 | ||
543 | #define azx_init_cmd_io(chip) | ||
544 | #define azx_free_cmd_io(chip) | ||
545 | |||
546 | /* send a command */ | 538 | /* send a command */ |
547 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | 539 | static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, |
548 | unsigned int verb, unsigned int para) | 540 | int direct, unsigned int verb, |
541 | unsigned int para) | ||
549 | { | 542 | { |
550 | struct azx *chip = codec->bus->private_data; | 543 | struct azx *chip = codec->bus->private_data; |
551 | u32 val; | 544 | u32 val; |
@@ -573,7 +566,7 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, | |||
573 | } | 566 | } |
574 | 567 | ||
575 | /* receive a response */ | 568 | /* receive a response */ |
576 | static unsigned int azx_get_response(struct hda_codec *codec) | 569 | static unsigned int azx_single_get_response(struct hda_codec *codec) |
577 | { | 570 | { |
578 | struct azx *chip = codec->bus->private_data; | 571 | struct azx *chip = codec->bus->private_data; |
579 | int timeout = 50; | 572 | int timeout = 50; |
@@ -588,9 +581,35 @@ static unsigned int azx_get_response(struct hda_codec *codec) | |||
588 | return (unsigned int)-1; | 581 | return (unsigned int)-1; |
589 | } | 582 | } |
590 | 583 | ||
591 | #define azx_update_rirb(chip) | 584 | /* |
585 | * The below are the main callbacks from hda_codec. | ||
586 | * | ||
587 | * They are just the skeleton to call sub-callbacks according to the | ||
588 | * current setting of chip->single_cmd. | ||
589 | */ | ||
590 | |||
591 | /* send a command */ | ||
592 | static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, | ||
593 | int direct, unsigned int verb, | ||
594 | unsigned int para) | ||
595 | { | ||
596 | struct azx *chip = codec->bus->private_data; | ||
597 | if (chip->single_cmd) | ||
598 | return azx_single_send_cmd(codec, nid, direct, verb, para); | ||
599 | else | ||
600 | return azx_corb_send_cmd(codec, nid, direct, verb, para); | ||
601 | } | ||
602 | |||
603 | /* get a response */ | ||
604 | static unsigned int azx_get_response(struct hda_codec *codec) | ||
605 | { | ||
606 | struct azx *chip = codec->bus->private_data; | ||
607 | if (chip->single_cmd) | ||
608 | return azx_single_get_response(codec); | ||
609 | else | ||
610 | return azx_rirb_get_response(codec); | ||
611 | } | ||
592 | 612 | ||
593 | #endif /* USE_CORB_RIRB */ | ||
594 | 613 | ||
595 | /* reset codec link */ | 614 | /* reset codec link */ |
596 | static int azx_reset(struct azx *chip) | 615 | static int azx_reset(struct azx *chip) |
@@ -737,7 +756,8 @@ static void azx_init_chip(struct azx *chip) | |||
737 | azx_int_enable(chip); | 756 | azx_int_enable(chip); |
738 | 757 | ||
739 | /* initialize the codec command I/O */ | 758 | /* initialize the codec command I/O */ |
740 | azx_init_cmd_io(chip); | 759 | if (! chip->single_cmd) |
760 | azx_init_cmd_io(chip); | ||
741 | 761 | ||
742 | /* program the position buffer */ | 762 | /* program the position buffer */ |
743 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 763 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -784,11 +804,10 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
784 | if (status & azx_dev->sd_int_sta_mask) { | 804 | if (status & azx_dev->sd_int_sta_mask) { |
785 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); | 805 | azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); |
786 | if (azx_dev->substream && azx_dev->running) { | 806 | if (azx_dev->substream && azx_dev->running) { |
787 | azx_dev->period_updating = 1; | 807 | azx_dev->period_intr++; |
788 | spin_unlock(&chip->reg_lock); | 808 | spin_unlock(&chip->reg_lock); |
789 | snd_pcm_period_elapsed(azx_dev->substream); | 809 | snd_pcm_period_elapsed(azx_dev->substream); |
790 | spin_lock(&chip->reg_lock); | 810 | spin_lock(&chip->reg_lock); |
791 | azx_dev->period_updating = 0; | ||
792 | } | 811 | } |
793 | } | 812 | } |
794 | } | 813 | } |
@@ -796,7 +815,7 @@ static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs) | |||
796 | /* clear rirb int */ | 815 | /* clear rirb int */ |
797 | status = azx_readb(chip, RIRBSTS); | 816 | status = azx_readb(chip, RIRBSTS); |
798 | if (status & RIRB_INT_MASK) { | 817 | if (status & RIRB_INT_MASK) { |
799 | if (status & RIRB_INT_RESPONSE) | 818 | if (! chip->single_cmd && (status & RIRB_INT_RESPONSE)) |
800 | azx_update_rirb(chip); | 819 | azx_update_rirb(chip); |
801 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); | 820 | azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); |
802 | } | 821 | } |
@@ -1002,10 +1021,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1002 | unsigned long flags; | 1021 | unsigned long flags; |
1003 | int err; | 1022 | int err; |
1004 | 1023 | ||
1005 | down(&chip->open_mutex); | 1024 | mutex_lock(&chip->open_mutex); |
1006 | azx_dev = azx_assign_device(chip, substream->stream); | 1025 | azx_dev = azx_assign_device(chip, substream->stream); |
1007 | if (azx_dev == NULL) { | 1026 | if (azx_dev == NULL) { |
1008 | up(&chip->open_mutex); | 1027 | mutex_unlock(&chip->open_mutex); |
1009 | return -EBUSY; | 1028 | return -EBUSY; |
1010 | } | 1029 | } |
1011 | runtime->hw = azx_pcm_hw; | 1030 | runtime->hw = azx_pcm_hw; |
@@ -1017,7 +1036,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1017 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1036 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
1018 | if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { | 1037 | if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { |
1019 | azx_release_device(azx_dev); | 1038 | azx_release_device(azx_dev); |
1020 | up(&chip->open_mutex); | 1039 | mutex_unlock(&chip->open_mutex); |
1021 | return err; | 1040 | return err; |
1022 | } | 1041 | } |
1023 | spin_lock_irqsave(&chip->reg_lock, flags); | 1042 | spin_lock_irqsave(&chip->reg_lock, flags); |
@@ -1026,7 +1045,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1026 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1045 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1027 | 1046 | ||
1028 | runtime->private_data = azx_dev; | 1047 | runtime->private_data = azx_dev; |
1029 | up(&chip->open_mutex); | 1048 | mutex_unlock(&chip->open_mutex); |
1030 | return 0; | 1049 | return 0; |
1031 | } | 1050 | } |
1032 | 1051 | ||
@@ -1038,14 +1057,14 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
1038 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1057 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1039 | unsigned long flags; | 1058 | unsigned long flags; |
1040 | 1059 | ||
1041 | down(&chip->open_mutex); | 1060 | mutex_lock(&chip->open_mutex); |
1042 | spin_lock_irqsave(&chip->reg_lock, flags); | 1061 | spin_lock_irqsave(&chip->reg_lock, flags); |
1043 | azx_dev->substream = NULL; | 1062 | azx_dev->substream = NULL; |
1044 | azx_dev->running = 0; | 1063 | azx_dev->running = 0; |
1045 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1064 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1046 | azx_release_device(azx_dev); | 1065 | azx_release_device(azx_dev); |
1047 | hinfo->ops.close(hinfo, apcm->codec, substream); | 1066 | hinfo->ops.close(hinfo, apcm->codec, substream); |
1048 | up(&chip->open_mutex); | 1067 | mutex_unlock(&chip->open_mutex); |
1049 | return 0; | 1068 | return 0; |
1050 | } | 1069 | } |
1051 | 1070 | ||
@@ -1099,7 +1118,6 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1099 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; | 1118 | azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; |
1100 | else | 1119 | else |
1101 | azx_dev->fifo_size = 0; | 1120 | azx_dev->fifo_size = 0; |
1102 | azx_dev->last_pos = 0; | ||
1103 | 1121 | ||
1104 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, | 1122 | return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag, |
1105 | azx_dev->format_val, substream); | 1123 | azx_dev->format_val, substream); |
@@ -1147,10 +1165,20 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | |||
1147 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1165 | struct azx_dev *azx_dev = get_azx_dev(substream); |
1148 | unsigned int pos; | 1166 | unsigned int pos; |
1149 | 1167 | ||
1150 | if (chip->position_fix == POS_FIX_POSBUF) { | 1168 | if (chip->position_fix == POS_FIX_POSBUF || |
1169 | chip->position_fix == POS_FIX_AUTO) { | ||
1151 | /* use the position buffer */ | 1170 | /* use the position buffer */ |
1152 | pos = *azx_dev->posbuf; | 1171 | pos = *azx_dev->posbuf; |
1172 | if (chip->position_fix == POS_FIX_AUTO && | ||
1173 | azx_dev->period_intr == 1 && ! pos) { | ||
1174 | printk(KERN_WARNING | ||
1175 | "hda-intel: Invalid position buffer, " | ||
1176 | "using LPIB read method instead.\n"); | ||
1177 | chip->position_fix = POS_FIX_NONE; | ||
1178 | goto read_lpib; | ||
1179 | } | ||
1153 | } else { | 1180 | } else { |
1181 | read_lpib: | ||
1154 | /* read LPIB */ | 1182 | /* read LPIB */ |
1155 | pos = azx_sd_readl(azx_dev, SD_LPIB); | 1183 | pos = azx_sd_readl(azx_dev, SD_LPIB); |
1156 | if (chip->position_fix == POS_FIX_FIFO) | 1184 | if (chip->position_fix == POS_FIX_FIFO) |
@@ -1415,13 +1443,14 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1415 | } | 1443 | } |
1416 | 1444 | ||
1417 | spin_lock_init(&chip->reg_lock); | 1445 | spin_lock_init(&chip->reg_lock); |
1418 | init_MUTEX(&chip->open_mutex); | 1446 | mutex_init(&chip->open_mutex); |
1419 | chip->card = card; | 1447 | chip->card = card; |
1420 | chip->pci = pci; | 1448 | chip->pci = pci; |
1421 | chip->irq = -1; | 1449 | chip->irq = -1; |
1422 | chip->driver_type = driver_type; | 1450 | chip->driver_type = driver_type; |
1423 | 1451 | ||
1424 | chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF; | 1452 | chip->position_fix = position_fix; |
1453 | chip->single_cmd = single_cmd; | ||
1425 | 1454 | ||
1426 | #if BITS_PER_LONG != 64 | 1455 | #if BITS_PER_LONG != 64 |
1427 | /* Fix up base address on ULI M5461 */ | 1456 | /* Fix up base address on ULI M5461 */ |
@@ -1492,8 +1521,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1492 | goto errout; | 1521 | goto errout; |
1493 | } | 1522 | } |
1494 | /* allocate CORB/RIRB */ | 1523 | /* allocate CORB/RIRB */ |
1495 | if ((err = azx_alloc_cmd_io(chip)) < 0) | 1524 | if (! chip->single_cmd) |
1496 | goto errout; | 1525 | if ((err = azx_alloc_cmd_io(chip)) < 0) |
1526 | goto errout; | ||
1497 | 1527 | ||
1498 | /* initialize streams */ | 1528 | /* initialize streams */ |
1499 | azx_init_stream(chip); | 1529 | azx_init_stream(chip); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index c82d2a72d13e..14e8aa2806ed 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -66,6 +66,11 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
66 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); | 66 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); |
67 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 67 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); |
68 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 68 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); |
69 | /* lowlevel accessor with caching; use carefully */ | ||
70 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
71 | int direction, int index); | ||
72 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | ||
73 | int direction, int idx, int mask, int val); | ||
69 | 74 | ||
70 | /* mono switch binding multiple inputs */ | 75 | /* mono switch binding multiple inputs */ |
71 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | 76 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ |
@@ -130,6 +135,7 @@ struct hda_multi_out { | |||
130 | int num_dacs; /* # of DACs, must be more than 1 */ | 135 | int num_dacs; /* # of DACs, must be more than 1 */ |
131 | hda_nid_t *dac_nids; /* DAC list */ | 136 | hda_nid_t *dac_nids; /* DAC list */ |
132 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ | 137 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ |
138 | hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ | ||
133 | hda_nid_t dig_out_nid; /* digital out audio widget */ | 139 | hda_nid_t dig_out_nid; /* digital out audio widget */ |
134 | int max_channels; /* currently supported analog channels */ | 140 | int max_channels; /* currently supported analog channels */ |
135 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ | 141 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ |
@@ -216,7 +222,8 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; | |||
216 | struct auto_pin_cfg { | 222 | struct auto_pin_cfg { |
217 | int line_outs; | 223 | int line_outs; |
218 | hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ | 224 | hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ |
219 | hda_nid_t speaker_pin; | 225 | int speaker_outs; |
226 | hda_nid_t speaker_pins[5]; | ||
220 | hda_nid_t hp_pin; | 227 | hda_nid_t hp_pin; |
221 | hda_nid_t input_pins[AUTO_PIN_LAST]; | 228 | hda_nid_t input_pins[AUTO_PIN_LAST]; |
222 | hda_nid_t dig_out_pin; | 229 | hda_nid_t dig_out_pin; |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 1ada1b075c9a..32401bd8c229 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/mutex.h> | ||
27 | |||
26 | #include <sound/core.h> | 28 | #include <sound/core.h> |
27 | #include "hda_codec.h" | 29 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 30 | #include "hda_local.h" |
@@ -60,7 +62,7 @@ struct ad198x_spec { | |||
60 | /* PCM information */ | 62 | /* PCM information */ |
61 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 63 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ |
62 | 64 | ||
63 | struct semaphore amp_mutex; /* PCM volume/mute control mutex */ | 65 | struct mutex amp_mutex; /* PCM volume/mute control mutex */ |
64 | unsigned int spdif_route; | 66 | unsigned int spdif_route; |
65 | 67 | ||
66 | /* dynamic controls, init_verbs and input_mux */ | 68 | /* dynamic controls, init_verbs and input_mux */ |
@@ -308,7 +310,7 @@ static int ad198x_resume(struct hda_codec *codec) | |||
308 | struct ad198x_spec *spec = codec->spec; | 310 | struct ad198x_spec *spec = codec->spec; |
309 | int i; | 311 | int i; |
310 | 312 | ||
311 | ad198x_init(codec); | 313 | codec->patch_ops.init(codec); |
312 | for (i = 0; i < spec->num_mixers; i++) | 314 | for (i = 0; i < spec->num_mixers; i++) |
313 | snd_hda_resume_ctls(codec, spec->mixers[i]); | 315 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
314 | if (spec->multiout.dig_out_nid) | 316 | if (spec->multiout.dig_out_nid) |
@@ -331,6 +333,61 @@ static struct hda_codec_ops ad198x_patch_ops = { | |||
331 | 333 | ||
332 | 334 | ||
333 | /* | 335 | /* |
336 | * EAPD control | ||
337 | * the private value = nid | (invert << 8) | ||
338 | */ | ||
339 | static int ad198x_eapd_info(struct snd_kcontrol *kcontrol, | ||
340 | struct snd_ctl_elem_info *uinfo) | ||
341 | { | ||
342 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
343 | uinfo->count = 1; | ||
344 | uinfo->value.integer.min = 0; | ||
345 | uinfo->value.integer.max = 1; | ||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, | ||
350 | struct snd_ctl_elem_value *ucontrol) | ||
351 | { | ||
352 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
353 | struct ad198x_spec *spec = codec->spec; | ||
354 | int invert = (kcontrol->private_value >> 8) & 1; | ||
355 | if (invert) | ||
356 | ucontrol->value.integer.value[0] = ! spec->cur_eapd; | ||
357 | else | ||
358 | ucontrol->value.integer.value[0] = spec->cur_eapd; | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, | ||
363 | struct snd_ctl_elem_value *ucontrol) | ||
364 | { | ||
365 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
366 | struct ad198x_spec *spec = codec->spec; | ||
367 | int invert = (kcontrol->private_value >> 8) & 1; | ||
368 | hda_nid_t nid = kcontrol->private_value & 0xff; | ||
369 | unsigned int eapd; | ||
370 | eapd = ucontrol->value.integer.value[0]; | ||
371 | if (invert) | ||
372 | eapd = !eapd; | ||
373 | if (eapd == spec->cur_eapd && ! codec->in_resume) | ||
374 | return 0; | ||
375 | spec->cur_eapd = eapd; | ||
376 | snd_hda_codec_write(codec, nid, | ||
377 | 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
378 | eapd ? 0x02 : 0x00); | ||
379 | return 1; | ||
380 | } | ||
381 | |||
382 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
383 | struct snd_ctl_elem_info *uinfo); | ||
384 | static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
385 | struct snd_ctl_elem_value *ucontrol); | ||
386 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
387 | struct snd_ctl_elem_value *ucontrol); | ||
388 | |||
389 | |||
390 | /* | ||
334 | * AD1986A specific | 391 | * AD1986A specific |
335 | */ | 392 | */ |
336 | 393 | ||
@@ -344,6 +401,7 @@ static hda_nid_t ad1986a_dac_nids[3] = { | |||
344 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC | 401 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC |
345 | }; | 402 | }; |
346 | static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; | 403 | static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; |
404 | static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; | ||
347 | 405 | ||
348 | static struct hda_input_mux ad1986a_capture_source = { | 406 | static struct hda_input_mux ad1986a_capture_source = { |
349 | .num_items = 7, | 407 | .num_items = 7, |
@@ -371,9 +429,9 @@ static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
371 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 429 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
372 | struct ad198x_spec *ad = codec->spec; | 430 | struct ad198x_spec *ad = codec->spec; |
373 | 431 | ||
374 | down(&ad->amp_mutex); | 432 | mutex_lock(&ad->amp_mutex); |
375 | snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); | 433 | snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); |
376 | up(&ad->amp_mutex); | 434 | mutex_unlock(&ad->amp_mutex); |
377 | return 0; | 435 | return 0; |
378 | } | 436 | } |
379 | 437 | ||
@@ -383,13 +441,13 @@ static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
383 | struct ad198x_spec *ad = codec->spec; | 441 | struct ad198x_spec *ad = codec->spec; |
384 | int i, change = 0; | 442 | int i, change = 0; |
385 | 443 | ||
386 | down(&ad->amp_mutex); | 444 | mutex_lock(&ad->amp_mutex); |
387 | for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { | 445 | for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { |
388 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); | 446 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); |
389 | change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); | 447 | change |= snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); |
390 | } | 448 | } |
391 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); | 449 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); |
392 | up(&ad->amp_mutex); | 450 | mutex_unlock(&ad->amp_mutex); |
393 | return change; | 451 | return change; |
394 | } | 452 | } |
395 | 453 | ||
@@ -400,9 +458,9 @@ static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
400 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 458 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
401 | struct ad198x_spec *ad = codec->spec; | 459 | struct ad198x_spec *ad = codec->spec; |
402 | 460 | ||
403 | down(&ad->amp_mutex); | 461 | mutex_lock(&ad->amp_mutex); |
404 | snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | 462 | snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); |
405 | up(&ad->amp_mutex); | 463 | mutex_unlock(&ad->amp_mutex); |
406 | return 0; | 464 | return 0; |
407 | } | 465 | } |
408 | 466 | ||
@@ -412,13 +470,13 @@ static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
412 | struct ad198x_spec *ad = codec->spec; | 470 | struct ad198x_spec *ad = codec->spec; |
413 | int i, change = 0; | 471 | int i, change = 0; |
414 | 472 | ||
415 | down(&ad->amp_mutex); | 473 | mutex_lock(&ad->amp_mutex); |
416 | for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { | 474 | for (i = 0; i < ARRAY_SIZE(ad1986a_dac_nids); i++) { |
417 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); | 475 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(ad1986a_dac_nids[i], 3, 0, HDA_OUTPUT); |
418 | change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 476 | change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
419 | } | 477 | } |
420 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); | 478 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT); |
421 | up(&ad->amp_mutex); | 479 | mutex_unlock(&ad->amp_mutex); |
422 | return change; | 480 | return change; |
423 | } | 481 | } |
424 | 482 | ||
@@ -477,6 +535,143 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { | |||
477 | { } /* end */ | 535 | { } /* end */ |
478 | }; | 536 | }; |
479 | 537 | ||
538 | /* additional mixers for 3stack mode */ | ||
539 | static struct snd_kcontrol_new ad1986a_3st_mixers[] = { | ||
540 | { | ||
541 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
542 | .name = "Channel Mode", | ||
543 | .info = ad198x_ch_mode_info, | ||
544 | .get = ad198x_ch_mode_get, | ||
545 | .put = ad198x_ch_mode_put, | ||
546 | }, | ||
547 | { } /* end */ | ||
548 | }; | ||
549 | |||
550 | /* laptop model - 2ch only */ | ||
551 | static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; | ||
552 | |||
553 | static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { | ||
554 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
555 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
556 | HDA_CODEC_VOLUME("Master Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | ||
557 | HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
558 | /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), | ||
559 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), */ | ||
560 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
561 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
562 | HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), | ||
563 | HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), | ||
564 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), | ||
565 | HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
566 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
567 | HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
568 | /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), | ||
569 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), | ||
570 | HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), | ||
571 | HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ | ||
572 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), | ||
573 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), | ||
574 | { | ||
575 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
576 | .name = "Capture Source", | ||
577 | .info = ad198x_mux_enum_info, | ||
578 | .get = ad198x_mux_enum_get, | ||
579 | .put = ad198x_mux_enum_put, | ||
580 | }, | ||
581 | { } /* end */ | ||
582 | }; | ||
583 | |||
584 | /* laptop-eapd model - 2ch only */ | ||
585 | |||
586 | /* master controls both pins 0x1a and 0x1b */ | ||
587 | static int ad1986a_laptop_master_vol_put(struct snd_kcontrol *kcontrol, | ||
588 | struct snd_ctl_elem_value *ucontrol) | ||
589 | { | ||
590 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
591 | long *valp = ucontrol->value.integer.value; | ||
592 | int change; | ||
593 | |||
594 | change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, | ||
595 | 0x7f, valp[0] & 0x7f); | ||
596 | change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, | ||
597 | 0x7f, valp[1] & 0x7f); | ||
598 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | ||
599 | 0x7f, valp[0] & 0x7f); | ||
600 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | ||
601 | 0x7f, valp[1] & 0x7f); | ||
602 | return change; | ||
603 | } | ||
604 | |||
605 | static int ad1986a_laptop_master_sw_put(struct snd_kcontrol *kcontrol, | ||
606 | struct snd_ctl_elem_value *ucontrol) | ||
607 | { | ||
608 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
609 | long *valp = ucontrol->value.integer.value; | ||
610 | int change; | ||
611 | |||
612 | change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, | ||
613 | 0x80, valp[0] ? 0 : 0x80); | ||
614 | change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, | ||
615 | 0x80, valp[1] ? 0 : 0x80); | ||
616 | snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, | ||
617 | 0x80, valp[0] ? 0 : 0x80); | ||
618 | snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, | ||
619 | 0x80, valp[1] ? 0 : 0x80); | ||
620 | return change; | ||
621 | } | ||
622 | |||
623 | static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { | ||
624 | .num_items = 3, | ||
625 | .items = { | ||
626 | { "Mic", 0x0 }, | ||
627 | { "Internal Mic", 0x4 }, | ||
628 | { "Mix", 0x5 }, | ||
629 | }, | ||
630 | }; | ||
631 | |||
632 | static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | ||
633 | { | ||
634 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
635 | .name = "Master Playback Volume", | ||
636 | .info = snd_hda_mixer_amp_volume_info, | ||
637 | .get = snd_hda_mixer_amp_volume_get, | ||
638 | .put = ad1986a_laptop_master_vol_put, | ||
639 | .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), | ||
640 | }, | ||
641 | { | ||
642 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
643 | .name = "Master Playback Switch", | ||
644 | .info = snd_hda_mixer_amp_switch_info, | ||
645 | .get = snd_hda_mixer_amp_switch_get, | ||
646 | .put = ad1986a_laptop_master_sw_put, | ||
647 | .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), | ||
648 | }, | ||
649 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
650 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
651 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), | ||
652 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), | ||
653 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
654 | HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
655 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), | ||
656 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), | ||
657 | { | ||
658 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
659 | .name = "Capture Source", | ||
660 | .info = ad198x_mux_enum_info, | ||
661 | .get = ad198x_mux_enum_get, | ||
662 | .put = ad198x_mux_enum_put, | ||
663 | }, | ||
664 | { | ||
665 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
666 | .name = "External Amplifier", | ||
667 | .info = ad198x_eapd_info, | ||
668 | .get = ad198x_eapd_get, | ||
669 | .put = ad198x_eapd_put, | ||
670 | .private_value = 0x1b | (1 << 8), /* port-D, inversed */ | ||
671 | }, | ||
672 | { } /* end */ | ||
673 | }; | ||
674 | |||
480 | /* | 675 | /* |
481 | * initialization verbs | 676 | * initialization verbs |
482 | */ | 677 | */ |
@@ -535,16 +730,89 @@ static struct hda_verb ad1986a_init_verbs[] = { | |||
535 | { } /* end */ | 730 | { } /* end */ |
536 | }; | 731 | }; |
537 | 732 | ||
733 | /* additional verbs for 3-stack model */ | ||
734 | static struct hda_verb ad1986a_3st_init_verbs[] = { | ||
735 | /* Mic and line-in selectors */ | ||
736 | {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
737 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
738 | { } /* end */ | ||
739 | }; | ||
740 | |||
741 | static struct hda_verb ad1986a_ch2_init[] = { | ||
742 | /* Surround out -> Line In */ | ||
743 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
744 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
745 | /* CLFE -> Mic in */ | ||
746 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
747 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
748 | { } /* end */ | ||
749 | }; | ||
750 | |||
751 | static struct hda_verb ad1986a_ch4_init[] = { | ||
752 | /* Surround out -> Surround */ | ||
753 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
754 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
755 | /* CLFE -> Mic in */ | ||
756 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
757 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
758 | { } /* end */ | ||
759 | }; | ||
760 | |||
761 | static struct hda_verb ad1986a_ch6_init[] = { | ||
762 | /* Surround out -> Surround out */ | ||
763 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
764 | { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
765 | /* CLFE -> CLFE */ | ||
766 | { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
767 | { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
768 | { } /* end */ | ||
769 | }; | ||
770 | |||
771 | static struct hda_channel_mode ad1986a_modes[3] = { | ||
772 | { 2, ad1986a_ch2_init }, | ||
773 | { 4, ad1986a_ch4_init }, | ||
774 | { 6, ad1986a_ch6_init }, | ||
775 | }; | ||
776 | |||
777 | /* eapd initialization */ | ||
778 | static struct hda_verb ad1986a_eapd_init_verbs[] = { | ||
779 | {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, | ||
780 | {} | ||
781 | }; | ||
782 | |||
783 | /* models */ | ||
784 | enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD }; | ||
785 | |||
786 | static struct hda_board_config ad1986a_cfg_tbl[] = { | ||
787 | { .modelname = "6stack", .config = AD1986A_6STACK }, | ||
788 | { .modelname = "3stack", .config = AD1986A_3STACK }, | ||
789 | { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, | ||
790 | .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ | ||
791 | { .modelname = "laptop", .config = AD1986A_LAPTOP }, | ||
792 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, | ||
793 | .config = AD1986A_LAPTOP }, /* FSC V2060 */ | ||
794 | { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, | ||
795 | .config = AD1986A_LAPTOP }, /* Samsung M50 */ | ||
796 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, | ||
797 | .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ | ||
798 | { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, | ||
799 | { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, | ||
800 | .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ | ||
801 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213, | ||
802 | .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ | ||
803 | {} | ||
804 | }; | ||
538 | 805 | ||
539 | static int patch_ad1986a(struct hda_codec *codec) | 806 | static int patch_ad1986a(struct hda_codec *codec) |
540 | { | 807 | { |
541 | struct ad198x_spec *spec; | 808 | struct ad198x_spec *spec; |
809 | int board_config; | ||
542 | 810 | ||
543 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 811 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
544 | if (spec == NULL) | 812 | if (spec == NULL) |
545 | return -ENOMEM; | 813 | return -ENOMEM; |
546 | 814 | ||
547 | init_MUTEX(&spec->amp_mutex); | 815 | mutex_init(&spec->amp_mutex); |
548 | codec->spec = spec; | 816 | codec->spec = spec; |
549 | 817 | ||
550 | spec->multiout.max_channels = 6; | 818 | spec->multiout.max_channels = 6; |
@@ -553,7 +821,7 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
553 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; | 821 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; |
554 | spec->num_adc_nids = 1; | 822 | spec->num_adc_nids = 1; |
555 | spec->adc_nids = ad1986a_adc_nids; | 823 | spec->adc_nids = ad1986a_adc_nids; |
556 | spec->capsrc_nids = ad1986a_adc_nids; | 824 | spec->capsrc_nids = ad1986a_capsrc_nids; |
557 | spec->input_mux = &ad1986a_capture_source; | 825 | spec->input_mux = &ad1986a_capture_source; |
558 | spec->num_mixers = 1; | 826 | spec->num_mixers = 1; |
559 | spec->mixers[0] = ad1986a_mixers; | 827 | spec->mixers[0] = ad1986a_mixers; |
@@ -562,6 +830,35 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
562 | 830 | ||
563 | codec->patch_ops = ad198x_patch_ops; | 831 | codec->patch_ops = ad198x_patch_ops; |
564 | 832 | ||
833 | /* override some parameters */ | ||
834 | board_config = snd_hda_check_board_config(codec, ad1986a_cfg_tbl); | ||
835 | switch (board_config) { | ||
836 | case AD1986A_3STACK: | ||
837 | spec->num_mixers = 2; | ||
838 | spec->mixers[1] = ad1986a_3st_mixers; | ||
839 | spec->num_init_verbs = 2; | ||
840 | spec->init_verbs[1] = ad1986a_3st_init_verbs; | ||
841 | spec->channel_mode = ad1986a_modes; | ||
842 | spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); | ||
843 | break; | ||
844 | case AD1986A_LAPTOP: | ||
845 | spec->mixers[0] = ad1986a_laptop_mixers; | ||
846 | spec->multiout.max_channels = 2; | ||
847 | spec->multiout.num_dacs = 1; | ||
848 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; | ||
849 | break; | ||
850 | case AD1986A_LAPTOP_EAPD: | ||
851 | spec->mixers[0] = ad1986a_laptop_eapd_mixers; | ||
852 | spec->num_init_verbs = 2; | ||
853 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; | ||
854 | spec->multiout.max_channels = 2; | ||
855 | spec->multiout.num_dacs = 1; | ||
856 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; | ||
857 | spec->multiout.dig_out_nid = 0; | ||
858 | spec->input_mux = &ad1986a_laptop_eapd_capture_source; | ||
859 | break; | ||
860 | } | ||
861 | |||
565 | return 0; | 862 | return 0; |
566 | } | 863 | } |
567 | 864 | ||
@@ -575,6 +872,7 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
575 | 872 | ||
576 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; | 873 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; |
577 | static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; | 874 | static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; |
875 | static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; | ||
578 | 876 | ||
579 | static struct hda_input_mux ad1983_capture_source = { | 877 | static struct hda_input_mux ad1983_capture_source = { |
580 | .num_items = 4, | 878 | .num_items = 4, |
@@ -708,7 +1006,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
708 | if (spec == NULL) | 1006 | if (spec == NULL) |
709 | return -ENOMEM; | 1007 | return -ENOMEM; |
710 | 1008 | ||
711 | init_MUTEX(&spec->amp_mutex); | 1009 | mutex_init(&spec->amp_mutex); |
712 | codec->spec = spec; | 1010 | codec->spec = spec; |
713 | 1011 | ||
714 | spec->multiout.max_channels = 2; | 1012 | spec->multiout.max_channels = 2; |
@@ -717,7 +1015,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
717 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; | 1015 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; |
718 | spec->num_adc_nids = 1; | 1016 | spec->num_adc_nids = 1; |
719 | spec->adc_nids = ad1983_adc_nids; | 1017 | spec->adc_nids = ad1983_adc_nids; |
720 | spec->capsrc_nids = ad1983_adc_nids; | 1018 | spec->capsrc_nids = ad1983_capsrc_nids; |
721 | spec->input_mux = &ad1983_capture_source; | 1019 | spec->input_mux = &ad1983_capture_source; |
722 | spec->num_mixers = 1; | 1020 | spec->num_mixers = 1; |
723 | spec->mixers[0] = ad1983_mixers; | 1021 | spec->mixers[0] = ad1983_mixers; |
@@ -741,6 +1039,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
741 | 1039 | ||
742 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; | 1040 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; |
743 | static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; | 1041 | static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; |
1042 | static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; | ||
744 | 1043 | ||
745 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ | 1044 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ |
746 | static struct hda_input_mux ad1981_capture_source = { | 1045 | static struct hda_input_mux ad1981_capture_source = { |
@@ -846,15 +1145,200 @@ static struct hda_verb ad1981_init_verbs[] = { | |||
846 | { } /* end */ | 1145 | { } /* end */ |
847 | }; | 1146 | }; |
848 | 1147 | ||
1148 | /* | ||
1149 | * Patch for HP nx6320 | ||
1150 | * | ||
1151 | * nx6320 uses EAPD in the reserve way - EAPD-on means the internal | ||
1152 | * speaker output enabled _and_ mute-LED off. | ||
1153 | */ | ||
1154 | |||
1155 | #define AD1981_HP_EVENT 0x37 | ||
1156 | #define AD1981_MIC_EVENT 0x38 | ||
1157 | |||
1158 | static struct hda_verb ad1981_hp_init_verbs[] = { | ||
1159 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ | ||
1160 | /* pin sensing on HP and Mic jacks */ | ||
1161 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, | ||
1162 | {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, | ||
1163 | {} | ||
1164 | }; | ||
1165 | |||
1166 | /* turn on/off EAPD (+ mute HP) as a master switch */ | ||
1167 | static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
1168 | struct snd_ctl_elem_value *ucontrol) | ||
1169 | { | ||
1170 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1171 | struct ad198x_spec *spec = codec->spec; | ||
1172 | |||
1173 | if (! ad198x_eapd_put(kcontrol, ucontrol)) | ||
1174 | return 0; | ||
1175 | |||
1176 | /* toggle HP mute appropriately */ | ||
1177 | snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, | ||
1178 | 0x80, spec->cur_eapd ? 0 : 0x80); | ||
1179 | snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, | ||
1180 | 0x80, spec->cur_eapd ? 0 : 0x80); | ||
1181 | return 1; | ||
1182 | } | ||
1183 | |||
1184 | /* bind volumes of both NID 0x05 and 0x06 */ | ||
1185 | static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol, | ||
1186 | struct snd_ctl_elem_value *ucontrol) | ||
1187 | { | ||
1188 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1189 | long *valp = ucontrol->value.integer.value; | ||
1190 | int change; | ||
1191 | |||
1192 | change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1193 | 0x7f, valp[0] & 0x7f); | ||
1194 | change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1195 | 0x7f, valp[1] & 0x7f); | ||
1196 | snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0, | ||
1197 | 0x7f, valp[0] & 0x7f); | ||
1198 | snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0, | ||
1199 | 0x7f, valp[1] & 0x7f); | ||
1200 | return change; | ||
1201 | } | ||
1202 | |||
1203 | /* mute internal speaker if HP is plugged */ | ||
1204 | static void ad1981_hp_automute(struct hda_codec *codec) | ||
1205 | { | ||
1206 | unsigned int present; | ||
1207 | |||
1208 | present = snd_hda_codec_read(codec, 0x06, 0, | ||
1209 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1210 | snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1211 | 0x80, present ? 0x80 : 0); | ||
1212 | snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1213 | 0x80, present ? 0x80 : 0); | ||
1214 | } | ||
1215 | |||
1216 | /* toggle input of built-in and mic jack appropriately */ | ||
1217 | static void ad1981_hp_automic(struct hda_codec *codec) | ||
1218 | { | ||
1219 | static struct hda_verb mic_jack_on[] = { | ||
1220 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1221 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1222 | {} | ||
1223 | }; | ||
1224 | static struct hda_verb mic_jack_off[] = { | ||
1225 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | ||
1226 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
1227 | {} | ||
1228 | }; | ||
1229 | unsigned int present; | ||
1230 | |||
1231 | present = snd_hda_codec_read(codec, 0x08, 0, | ||
1232 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1233 | if (present) | ||
1234 | snd_hda_sequence_write(codec, mic_jack_on); | ||
1235 | else | ||
1236 | snd_hda_sequence_write(codec, mic_jack_off); | ||
1237 | } | ||
1238 | |||
1239 | /* unsolicited event for HP jack sensing */ | ||
1240 | static void ad1981_hp_unsol_event(struct hda_codec *codec, | ||
1241 | unsigned int res) | ||
1242 | { | ||
1243 | res >>= 26; | ||
1244 | switch (res) { | ||
1245 | case AD1981_HP_EVENT: | ||
1246 | ad1981_hp_automute(codec); | ||
1247 | break; | ||
1248 | case AD1981_MIC_EVENT: | ||
1249 | ad1981_hp_automic(codec); | ||
1250 | break; | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | static struct hda_input_mux ad1981_hp_capture_source = { | ||
1255 | .num_items = 3, | ||
1256 | .items = { | ||
1257 | { "Mic", 0x0 }, | ||
1258 | { "Docking-Station", 0x1 }, | ||
1259 | { "Mix", 0x2 }, | ||
1260 | }, | ||
1261 | }; | ||
1262 | |||
1263 | static struct snd_kcontrol_new ad1981_hp_mixers[] = { | ||
1264 | { | ||
1265 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1266 | .name = "Master Playback Volume", | ||
1267 | .info = snd_hda_mixer_amp_volume_info, | ||
1268 | .get = snd_hda_mixer_amp_volume_get, | ||
1269 | .put = ad1981_hp_master_vol_put, | ||
1270 | .private_value = HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), | ||
1271 | }, | ||
1272 | { | ||
1273 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1274 | .name = "Master Playback Switch", | ||
1275 | .info = ad198x_eapd_info, | ||
1276 | .get = ad198x_eapd_get, | ||
1277 | .put = ad1981_hp_master_sw_put, | ||
1278 | .private_value = 0x05, | ||
1279 | }, | ||
1280 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | ||
1281 | HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), | ||
1282 | #if 0 | ||
1283 | /* FIXME: analog mic/line loopback doesn't work with my tests... | ||
1284 | * (although recording is OK) | ||
1285 | */ | ||
1286 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), | ||
1287 | HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), | ||
1288 | HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
1289 | HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
1290 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), | ||
1291 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), | ||
1292 | /* FIXME: does this laptop have analog CD connection? */ | ||
1293 | HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | ||
1294 | HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), | ||
1295 | #endif | ||
1296 | HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), | ||
1297 | HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), | ||
1298 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), | ||
1299 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), | ||
1300 | { | ||
1301 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1302 | .name = "Capture Source", | ||
1303 | .info = ad198x_mux_enum_info, | ||
1304 | .get = ad198x_mux_enum_get, | ||
1305 | .put = ad198x_mux_enum_put, | ||
1306 | }, | ||
1307 | { } /* end */ | ||
1308 | }; | ||
1309 | |||
1310 | /* initialize jack-sensing, too */ | ||
1311 | static int ad1981_hp_init(struct hda_codec *codec) | ||
1312 | { | ||
1313 | ad198x_init(codec); | ||
1314 | ad1981_hp_automute(codec); | ||
1315 | ad1981_hp_automic(codec); | ||
1316 | return 0; | ||
1317 | } | ||
1318 | |||
1319 | /* models */ | ||
1320 | enum { AD1981_BASIC, AD1981_HP }; | ||
1321 | |||
1322 | static struct hda_board_config ad1981_cfg_tbl[] = { | ||
1323 | { .modelname = "hp", .config = AD1981_HP }, | ||
1324 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x30aa, | ||
1325 | .config = AD1981_HP }, /* HP nx6320 */ | ||
1326 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x309f, | ||
1327 | .config = AD1981_HP }, /* HP nx9420 AngelFire */ | ||
1328 | { .modelname = "basic", .config = AD1981_BASIC }, | ||
1329 | {} | ||
1330 | }; | ||
1331 | |||
849 | static int patch_ad1981(struct hda_codec *codec) | 1332 | static int patch_ad1981(struct hda_codec *codec) |
850 | { | 1333 | { |
851 | struct ad198x_spec *spec; | 1334 | struct ad198x_spec *spec; |
1335 | int board_config; | ||
852 | 1336 | ||
853 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1337 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
854 | if (spec == NULL) | 1338 | if (spec == NULL) |
855 | return -ENOMEM; | 1339 | return -ENOMEM; |
856 | 1340 | ||
857 | init_MUTEX(&spec->amp_mutex); | 1341 | mutex_init(&spec->amp_mutex); |
858 | codec->spec = spec; | 1342 | codec->spec = spec; |
859 | 1343 | ||
860 | spec->multiout.max_channels = 2; | 1344 | spec->multiout.max_channels = 2; |
@@ -863,7 +1347,7 @@ static int patch_ad1981(struct hda_codec *codec) | |||
863 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; | 1347 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; |
864 | spec->num_adc_nids = 1; | 1348 | spec->num_adc_nids = 1; |
865 | spec->adc_nids = ad1981_adc_nids; | 1349 | spec->adc_nids = ad1981_adc_nids; |
866 | spec->capsrc_nids = ad1981_adc_nids; | 1350 | spec->capsrc_nids = ad1981_capsrc_nids; |
867 | spec->input_mux = &ad1981_capture_source; | 1351 | spec->input_mux = &ad1981_capture_source; |
868 | spec->num_mixers = 1; | 1352 | spec->num_mixers = 1; |
869 | spec->mixers[0] = ad1981_mixers; | 1353 | spec->mixers[0] = ad1981_mixers; |
@@ -873,6 +1357,21 @@ static int patch_ad1981(struct hda_codec *codec) | |||
873 | 1357 | ||
874 | codec->patch_ops = ad198x_patch_ops; | 1358 | codec->patch_ops = ad198x_patch_ops; |
875 | 1359 | ||
1360 | /* override some parameters */ | ||
1361 | board_config = snd_hda_check_board_config(codec, ad1981_cfg_tbl); | ||
1362 | switch (board_config) { | ||
1363 | case AD1981_HP: | ||
1364 | spec->mixers[0] = ad1981_hp_mixers; | ||
1365 | spec->num_init_verbs = 2; | ||
1366 | spec->init_verbs[1] = ad1981_hp_init_verbs; | ||
1367 | spec->multiout.dig_out_nid = 0; | ||
1368 | spec->input_mux = &ad1981_hp_capture_source; | ||
1369 | |||
1370 | codec->patch_ops.init = ad1981_hp_init; | ||
1371 | codec->patch_ops.unsol_event = ad1981_hp_unsol_event; | ||
1372 | break; | ||
1373 | } | ||
1374 | |||
876 | return 0; | 1375 | return 0; |
877 | } | 1376 | } |
878 | 1377 | ||
@@ -1060,44 +1559,6 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
1060 | spec->num_channel_mode, &spec->multiout.max_channels); | 1559 | spec->num_channel_mode, &spec->multiout.max_channels); |
1061 | } | 1560 | } |
1062 | 1561 | ||
1063 | /* | ||
1064 | * EAPD control | ||
1065 | */ | ||
1066 | static int ad1988_eapd_info(struct snd_kcontrol *kcontrol, | ||
1067 | struct snd_ctl_elem_info *uinfo) | ||
1068 | { | ||
1069 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1070 | uinfo->count = 1; | ||
1071 | uinfo->value.integer.min = 0; | ||
1072 | uinfo->value.integer.max = 1; | ||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | static int ad1988_eapd_get(struct snd_kcontrol *kcontrol, | ||
1077 | struct snd_ctl_elem_value *ucontrol) | ||
1078 | { | ||
1079 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1080 | struct ad198x_spec *spec = codec->spec; | ||
1081 | ucontrol->value.enumerated.item[0] = ! spec->cur_eapd; | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static int ad1988_eapd_put(struct snd_kcontrol *kcontrol, | ||
1086 | struct snd_ctl_elem_value *ucontrol) | ||
1087 | { | ||
1088 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1089 | struct ad198x_spec *spec = codec->spec; | ||
1090 | unsigned int eapd; | ||
1091 | eapd = ! ucontrol->value.enumerated.item[0]; | ||
1092 | if (eapd == spec->cur_eapd && ! codec->in_resume) | ||
1093 | return 0; | ||
1094 | spec->cur_eapd = eapd; | ||
1095 | snd_hda_codec_write(codec, 0x12 /* port-D */, | ||
1096 | 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
1097 | eapd ? 0x02 : 0x00); | ||
1098 | return 0; | ||
1099 | } | ||
1100 | |||
1101 | /* 6-stack mode */ | 1562 | /* 6-stack mode */ |
1102 | static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | 1563 | static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { |
1103 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 1564 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
@@ -1220,9 +1681,10 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { | |||
1220 | { | 1681 | { |
1221 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1682 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1222 | .name = "External Amplifier", | 1683 | .name = "External Amplifier", |
1223 | .info = ad1988_eapd_info, | 1684 | .info = ad198x_eapd_info, |
1224 | .get = ad1988_eapd_get, | 1685 | .get = ad198x_eapd_get, |
1225 | .put = ad1988_eapd_put, | 1686 | .put = ad198x_eapd_put, |
1687 | .private_value = 0x12 | (1 << 8), /* port-D, inversed */ | ||
1226 | }, | 1688 | }, |
1227 | 1689 | ||
1228 | { } /* end */ | 1690 | { } /* end */ |
@@ -1795,14 +2257,11 @@ static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
1795 | 2257 | ||
1796 | idx = ad1988_pin_idx(pin); | 2258 | idx = ad1988_pin_idx(pin); |
1797 | nid = ad1988_idx_to_dac(codec, idx); | 2259 | nid = ad1988_idx_to_dac(codec, idx); |
1798 | if (! spec->multiout.dac_nids[0]) { | 2260 | /* specify the DAC as the extra output */ |
1799 | /* use this as the primary output */ | 2261 | if (! spec->multiout.hp_nid) |
1800 | spec->multiout.dac_nids[0] = nid; | ||
1801 | if (! spec->multiout.num_dacs) | ||
1802 | spec->multiout.num_dacs = 1; | ||
1803 | } else | ||
1804 | /* specify the DAC as the extra output */ | ||
1805 | spec->multiout.hp_nid = nid; | 2262 | spec->multiout.hp_nid = nid; |
2263 | else | ||
2264 | spec->multiout.extra_out_nid[0] = nid; | ||
1806 | /* control HP volume/switch on the output mixer amp */ | 2265 | /* control HP volume/switch on the output mixer amp */ |
1807 | sprintf(name, "%s Playback Volume", pfx); | 2266 | sprintf(name, "%s Playback Volume", pfx); |
1808 | if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, | 2267 | if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name, |
@@ -1921,7 +2380,7 @@ static void ad1988_auto_init_extra_out(struct hda_codec *codec) | |||
1921 | struct ad198x_spec *spec = codec->spec; | 2380 | struct ad198x_spec *spec = codec->spec; |
1922 | hda_nid_t pin; | 2381 | hda_nid_t pin; |
1923 | 2382 | ||
1924 | pin = spec->autocfg.speaker_pin; | 2383 | pin = spec->autocfg.speaker_pins[0]; |
1925 | if (pin) /* connect to front */ | 2384 | if (pin) /* connect to front */ |
1926 | ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 2385 | ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
1927 | pin = spec->autocfg.hp_pin; | 2386 | pin = spec->autocfg.hp_pin; |
@@ -1970,13 +2429,13 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) | |||
1970 | return err; | 2429 | return err; |
1971 | if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | 2430 | if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) |
1972 | return err; | 2431 | return err; |
1973 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 2432 | if (! spec->autocfg.line_outs) |
1974 | ! spec->autocfg.hp_pin) | ||
1975 | return 0; /* can't find valid BIOS pin config */ | 2433 | return 0; /* can't find valid BIOS pin config */ |
1976 | if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 2434 | if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
1977 | (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, | 2435 | (err = ad1988_auto_create_extra_out(codec, |
2436 | spec->autocfg.speaker_pins[0], | ||
1978 | "Speaker")) < 0 || | 2437 | "Speaker")) < 0 || |
1979 | (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin, | 2438 | (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pin, |
1980 | "Headphone")) < 0 || | 2439 | "Headphone")) < 0 || |
1981 | (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 2440 | (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) |
1982 | return err; | 2441 | return err; |
@@ -2032,7 +2491,7 @@ static int patch_ad1988(struct hda_codec *codec) | |||
2032 | if (spec == NULL) | 2491 | if (spec == NULL) |
2033 | return -ENOMEM; | 2492 | return -ENOMEM; |
2034 | 2493 | ||
2035 | init_MUTEX(&spec->amp_mutex); | 2494 | mutex_init(&spec->amp_mutex); |
2036 | codec->spec = spec; | 2495 | codec->spec = spec; |
2037 | 2496 | ||
2038 | if (codec->revision_id == AD1988A_REV2) | 2497 | if (codec->revision_id == AD1988A_REV2) |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b76755264730..4c6c9ec8ea5b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> | 6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> |
7 | * PeiSen Hou <pshou@realtek.com.tw> | 7 | * PeiSen Hou <pshou@realtek.com.tw> |
8 | * Takashi Iwai <tiwai@suse.de> | 8 | * Takashi Iwai <tiwai@suse.de> |
9 | * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> | ||
9 | * | 10 | * |
10 | * This driver is free software; you can redistribute it and/or modify | 11 | * This driver is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
@@ -50,6 +51,7 @@ enum { | |||
50 | ALC880_UNIWILL_DIG, | 51 | ALC880_UNIWILL_DIG, |
51 | ALC880_CLEVO, | 52 | ALC880_CLEVO, |
52 | ALC880_TCL_S700, | 53 | ALC880_TCL_S700, |
54 | ALC880_LG, | ||
53 | #ifdef CONFIG_SND_DEBUG | 55 | #ifdef CONFIG_SND_DEBUG |
54 | ALC880_TEST, | 56 | ALC880_TEST, |
55 | #endif | 57 | #endif |
@@ -63,6 +65,10 @@ enum { | |||
63 | ALC260_HP, | 65 | ALC260_HP, |
64 | ALC260_HP_3013, | 66 | ALC260_HP_3013, |
65 | ALC260_FUJITSU_S702X, | 67 | ALC260_FUJITSU_S702X, |
68 | ALC260_ACER, | ||
69 | #ifdef CONFIG_SND_DEBUG | ||
70 | ALC260_TEST, | ||
71 | #endif | ||
66 | ALC260_AUTO, | 72 | ALC260_AUTO, |
67 | ALC260_MODEL_LAST /* last tag */ | 73 | ALC260_MODEL_LAST /* last tag */ |
68 | }; | 74 | }; |
@@ -70,6 +76,7 @@ enum { | |||
70 | /* ALC262 models */ | 76 | /* ALC262 models */ |
71 | enum { | 77 | enum { |
72 | ALC262_BASIC, | 78 | ALC262_BASIC, |
79 | ALC262_FUJITSU, | ||
73 | ALC262_AUTO, | 80 | ALC262_AUTO, |
74 | ALC262_MODEL_LAST /* last tag */ | 81 | ALC262_MODEL_LAST /* last tag */ |
75 | }; | 82 | }; |
@@ -132,7 +139,7 @@ struct alc_spec { | |||
132 | int num_channel_mode; | 139 | int num_channel_mode; |
133 | 140 | ||
134 | /* PCM information */ | 141 | /* PCM information */ |
135 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 142 | struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ |
136 | 143 | ||
137 | /* dynamic controls, init_verbs and input_mux */ | 144 | /* dynamic controls, init_verbs and input_mux */ |
138 | struct auto_pin_cfg autocfg; | 145 | struct auto_pin_cfg autocfg; |
@@ -140,6 +147,14 @@ struct alc_spec { | |||
140 | struct snd_kcontrol_new *kctl_alloc; | 147 | struct snd_kcontrol_new *kctl_alloc; |
141 | struct hda_input_mux private_imux; | 148 | struct hda_input_mux private_imux; |
142 | hda_nid_t private_dac_nids[5]; | 149 | hda_nid_t private_dac_nids[5]; |
150 | |||
151 | /* hooks */ | ||
152 | void (*init_hook)(struct hda_codec *codec); | ||
153 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | ||
154 | |||
155 | /* for pin sensing */ | ||
156 | unsigned int sense_updated: 1; | ||
157 | unsigned int jack_present: 1; | ||
143 | }; | 158 | }; |
144 | 159 | ||
145 | /* | 160 | /* |
@@ -158,6 +173,8 @@ struct alc_config_preset { | |||
158 | unsigned int num_channel_mode; | 173 | unsigned int num_channel_mode; |
159 | const struct hda_channel_mode *channel_mode; | 174 | const struct hda_channel_mode *channel_mode; |
160 | const struct hda_input_mux *input_mux; | 175 | const struct hda_input_mux *input_mux; |
176 | void (*unsol_event)(struct hda_codec *, unsigned int); | ||
177 | void (*init_hook)(struct hda_codec *); | ||
161 | }; | 178 | }; |
162 | 179 | ||
163 | 180 | ||
@@ -218,56 +235,231 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
218 | spec->num_channel_mode, &spec->multiout.max_channels); | 235 | spec->num_channel_mode, &spec->multiout.max_channels); |
219 | } | 236 | } |
220 | 237 | ||
221 | |||
222 | /* | 238 | /* |
223 | * Control of pin widget settings via the mixer. Only boolean settings are | 239 | * Control the mode of pin widget settings via the mixer. "pc" is used |
224 | * supported, so VrefEn can't be controlled using these functions as they | 240 | * instead of "%" to avoid consequences of accidently treating the % as |
225 | * stand. | 241 | * being part of a format specifier. Maximum allowed length of a value is |
242 | * 63 characters plus NULL terminator. | ||
243 | * | ||
244 | * Note: some retasking pin complexes seem to ignore requests for input | ||
245 | * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these | ||
246 | * are requested. Therefore order this list so that this behaviour will not | ||
247 | * cause problems when mixer clients move through the enum sequentially. | ||
248 | * NIDs 0x0f and 0x10 have been observed to have this behaviour. | ||
226 | */ | 249 | */ |
227 | static int alc_pinctl_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 250 | static char *alc_pin_mode_names[] = { |
251 | "Mic 50pc bias", "Mic 80pc bias", | ||
252 | "Line in", "Line out", "Headphone out", | ||
253 | }; | ||
254 | static unsigned char alc_pin_mode_values[] = { | ||
255 | PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, | ||
256 | }; | ||
257 | /* The control can present all 5 options, or it can limit the options based | ||
258 | * in the pin being assumed to be exclusively an input or an output pin. | ||
259 | */ | ||
260 | #define ALC_PIN_DIR_IN 0x00 | ||
261 | #define ALC_PIN_DIR_OUT 0x01 | ||
262 | #define ALC_PIN_DIR_INOUT 0x02 | ||
263 | |||
264 | /* Info about the pin modes supported by the three different pin directions. | ||
265 | * For each direction the minimum and maximum values are given. | ||
266 | */ | ||
267 | static signed char alc_pin_mode_dir_info[3][2] = { | ||
268 | { 0, 2 }, /* ALC_PIN_DIR_IN */ | ||
269 | { 3, 4 }, /* ALC_PIN_DIR_OUT */ | ||
270 | { 0, 4 }, /* ALC_PIN_DIR_INOUT */ | ||
271 | }; | ||
272 | #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) | ||
273 | #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) | ||
274 | #define alc_pin_mode_n_items(_dir) \ | ||
275 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) | ||
276 | |||
277 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
228 | { | 278 | { |
229 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 279 | unsigned int item_num = uinfo->value.enumerated.item; |
280 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | ||
281 | |||
282 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
230 | uinfo->count = 1; | 283 | uinfo->count = 1; |
231 | uinfo->value.integer.min = 0; | 284 | uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); |
232 | uinfo->value.integer.max = 1; | 285 | |
286 | if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) | ||
287 | item_num = alc_pin_mode_min(dir); | ||
288 | strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); | ||
233 | return 0; | 289 | return 0; |
234 | } | 290 | } |
235 | 291 | ||
236 | static int alc_pinctl_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 292 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
237 | { | 293 | { |
294 | unsigned int i; | ||
238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 295 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
239 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 296 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
240 | long mask = (kcontrol->private_value >> 16) & 0xff; | 297 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
241 | long *valp = ucontrol->value.integer.value; | 298 | long *valp = ucontrol->value.integer.value; |
299 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | ||
242 | 300 | ||
243 | *valp = 0; | 301 | /* Find enumerated value for current pinctl setting */ |
244 | if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask) | 302 | i = alc_pin_mode_min(dir); |
245 | *valp = 1; | 303 | while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir)) |
304 | i++; | ||
305 | *valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir); | ||
246 | return 0; | 306 | return 0; |
247 | } | 307 | } |
248 | 308 | ||
249 | static int alc_pinctl_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 309 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
250 | { | 310 | { |
311 | signed int change; | ||
251 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 312 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
252 | hda_nid_t nid = kcontrol->private_value & 0xffff; | 313 | hda_nid_t nid = kcontrol->private_value & 0xffff; |
253 | long mask = (kcontrol->private_value >> 16) & 0xff; | 314 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; |
254 | long *valp = ucontrol->value.integer.value; | 315 | long val = *ucontrol->value.integer.value; |
255 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); | 316 | unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00); |
256 | int change = ((pinctl & mask)!=0) != *valp; | ||
257 | 317 | ||
258 | if (change) | 318 | if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir)) |
319 | val = alc_pin_mode_min(dir); | ||
320 | |||
321 | change = pinctl != alc_pin_mode_values[val]; | ||
322 | if (change) { | ||
323 | /* Set pin mode to that requested */ | ||
259 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, | 324 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL, |
260 | *valp?(pinctl|mask):(pinctl&~mask)); | 325 | alc_pin_mode_values[val]); |
326 | |||
327 | /* Also enable the retasking pin's input/output as required | ||
328 | * for the requested pin mode. Enum values of 2 or less are | ||
329 | * input modes. | ||
330 | * | ||
331 | * Dynamically switching the input/output buffers probably | ||
332 | * reduces noise slightly, particularly on input. However, | ||
333 | * havingboth input and output buffers enabled | ||
334 | * simultaneously doesn't seem to be problematic. | ||
335 | */ | ||
336 | if (val <= 2) { | ||
337 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | ||
338 | AMP_OUT_MUTE); | ||
339 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | ||
340 | AMP_IN_UNMUTE(0)); | ||
341 | } else { | ||
342 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | ||
343 | AMP_IN_MUTE(0)); | ||
344 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE, | ||
345 | AMP_OUT_UNMUTE); | ||
346 | } | ||
347 | } | ||
261 | return change; | 348 | return change; |
262 | } | 349 | } |
263 | 350 | ||
264 | #define ALC_PINCTL_SWITCH(xname, nid, mask) \ | 351 | #define ALC_PIN_MODE(xname, nid, dir) \ |
265 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | 352 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ |
266 | .info = alc_pinctl_switch_info, \ | 353 | .info = alc_pin_mode_info, \ |
267 | .get = alc_pinctl_switch_get, \ | 354 | .get = alc_pin_mode_get, \ |
268 | .put = alc_pinctl_switch_put, \ | 355 | .put = alc_pin_mode_put, \ |
269 | .private_value = (nid) | (mask<<16) } | 356 | .private_value = nid | (dir<<16) } |
357 | |||
358 | /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged | ||
359 | * together using a mask with more than one bit set. This control is | ||
360 | * currently used only by the ALC260 test model. At this stage they are not | ||
361 | * needed for any "production" models. | ||
362 | */ | ||
363 | #ifdef CONFIG_SND_DEBUG | ||
364 | static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
365 | { | ||
366 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
367 | uinfo->count = 1; | ||
368 | uinfo->value.integer.min = 0; | ||
369 | uinfo->value.integer.max = 1; | ||
370 | return 0; | ||
371 | } | ||
372 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
373 | { | ||
374 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
375 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
376 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
377 | long *valp = ucontrol->value.integer.value; | ||
378 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | ||
270 | 379 | ||
380 | *valp = (val & mask) != 0; | ||
381 | return 0; | ||
382 | } | ||
383 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
384 | { | ||
385 | signed int change; | ||
386 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
387 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
388 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
389 | long val = *ucontrol->value.integer.value; | ||
390 | unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00); | ||
391 | |||
392 | /* Set/unset the masked GPIO bit(s) as needed */ | ||
393 | change = (val==0?0:mask) != (gpio_data & mask); | ||
394 | if (val==0) | ||
395 | gpio_data &= ~mask; | ||
396 | else | ||
397 | gpio_data |= mask; | ||
398 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data); | ||
399 | |||
400 | return change; | ||
401 | } | ||
402 | #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ | ||
403 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
404 | .info = alc_gpio_data_info, \ | ||
405 | .get = alc_gpio_data_get, \ | ||
406 | .put = alc_gpio_data_put, \ | ||
407 | .private_value = nid | (mask<<16) } | ||
408 | #endif /* CONFIG_SND_DEBUG */ | ||
409 | |||
410 | /* A switch control to allow the enabling of the digital IO pins on the | ||
411 | * ALC260. This is incredibly simplistic; the intention of this control is | ||
412 | * to provide something in the test model allowing digital outputs to be | ||
413 | * identified if present. If models are found which can utilise these | ||
414 | * outputs a more complete mixer control can be devised for those models if | ||
415 | * necessary. | ||
416 | */ | ||
417 | #ifdef CONFIG_SND_DEBUG | ||
418 | static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | ||
419 | { | ||
420 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
421 | uinfo->count = 1; | ||
422 | uinfo->value.integer.min = 0; | ||
423 | uinfo->value.integer.max = 1; | ||
424 | return 0; | ||
425 | } | ||
426 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
427 | { | ||
428 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
429 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
430 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
431 | long *valp = ucontrol->value.integer.value; | ||
432 | unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | ||
433 | |||
434 | *valp = (val & mask) != 0; | ||
435 | return 0; | ||
436 | } | ||
437 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | ||
438 | { | ||
439 | signed int change; | ||
440 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
441 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
442 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
443 | long val = *ucontrol->value.integer.value; | ||
444 | unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00); | ||
445 | |||
446 | /* Set/unset the masked control bit(s) as needed */ | ||
447 | change = (val==0?0:mask) != (ctrl_data & mask); | ||
448 | if (val==0) | ||
449 | ctrl_data &= ~mask; | ||
450 | else | ||
451 | ctrl_data |= mask; | ||
452 | snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data); | ||
453 | |||
454 | return change; | ||
455 | } | ||
456 | #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ | ||
457 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
458 | .info = alc_spdif_ctrl_info, \ | ||
459 | .get = alc_spdif_ctrl_get, \ | ||
460 | .put = alc_spdif_ctrl_put, \ | ||
461 | .private_value = nid | (mask<<16) } | ||
462 | #endif /* CONFIG_SND_DEBUG */ | ||
271 | 463 | ||
272 | /* | 464 | /* |
273 | * set up from the preset table | 465 | * set up from the preset table |
@@ -296,6 +488,9 @@ static void setup_preset(struct alc_spec *spec, const struct alc_config_preset * | |||
296 | spec->num_adc_nids = preset->num_adc_nids; | 488 | spec->num_adc_nids = preset->num_adc_nids; |
297 | spec->adc_nids = preset->adc_nids; | 489 | spec->adc_nids = preset->adc_nids; |
298 | spec->dig_in_nid = preset->dig_in_nid; | 490 | spec->dig_in_nid = preset->dig_in_nid; |
491 | |||
492 | spec->unsol_event = preset->unsol_event; | ||
493 | spec->init_hook = preset->init_hook; | ||
299 | } | 494 | } |
300 | 495 | ||
301 | /* | 496 | /* |
@@ -1098,6 +1293,141 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { | |||
1098 | }; | 1293 | }; |
1099 | 1294 | ||
1100 | /* | 1295 | /* |
1296 | * LG m1 express dual | ||
1297 | * | ||
1298 | * Pin assignment: | ||
1299 | * Rear Line-In/Out (blue): 0x14 | ||
1300 | * Build-in Mic-In: 0x15 | ||
1301 | * Speaker-out: 0x17 | ||
1302 | * HP-Out (green): 0x1b | ||
1303 | * Mic-In/Out (red): 0x19 | ||
1304 | * SPDIF-Out: 0x1e | ||
1305 | */ | ||
1306 | |||
1307 | /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ | ||
1308 | static hda_nid_t alc880_lg_dac_nids[3] = { | ||
1309 | 0x05, 0x02, 0x03 | ||
1310 | }; | ||
1311 | |||
1312 | /* seems analog CD is not working */ | ||
1313 | static struct hda_input_mux alc880_lg_capture_source = { | ||
1314 | .num_items = 3, | ||
1315 | .items = { | ||
1316 | { "Mic", 0x1 }, | ||
1317 | { "Line", 0x5 }, | ||
1318 | { "Internal Mic", 0x6 }, | ||
1319 | }, | ||
1320 | }; | ||
1321 | |||
1322 | /* 2,4,6 channel modes */ | ||
1323 | static struct hda_verb alc880_lg_ch2_init[] = { | ||
1324 | /* set line-in and mic-in to input */ | ||
1325 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
1326 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
1327 | { } | ||
1328 | }; | ||
1329 | |||
1330 | static struct hda_verb alc880_lg_ch4_init[] = { | ||
1331 | /* set line-in to out and mic-in to input */ | ||
1332 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
1333 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
1334 | { } | ||
1335 | }; | ||
1336 | |||
1337 | static struct hda_verb alc880_lg_ch6_init[] = { | ||
1338 | /* set line-in and mic-in to output */ | ||
1339 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
1340 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
1341 | { } | ||
1342 | }; | ||
1343 | |||
1344 | static struct hda_channel_mode alc880_lg_ch_modes[3] = { | ||
1345 | { 2, alc880_lg_ch2_init }, | ||
1346 | { 4, alc880_lg_ch4_init }, | ||
1347 | { 6, alc880_lg_ch6_init }, | ||
1348 | }; | ||
1349 | |||
1350 | static struct snd_kcontrol_new alc880_lg_mixer[] = { | ||
1351 | /* FIXME: it's not really "master" but front channels */ | ||
1352 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
1353 | HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT), | ||
1354 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1355 | HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1356 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), | ||
1357 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), | ||
1358 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), | ||
1359 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | ||
1360 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
1361 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
1362 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
1363 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
1364 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), | ||
1365 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), | ||
1366 | { | ||
1367 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1368 | .name = "Channel Mode", | ||
1369 | .info = alc_ch_mode_info, | ||
1370 | .get = alc_ch_mode_get, | ||
1371 | .put = alc_ch_mode_put, | ||
1372 | }, | ||
1373 | { } /* end */ | ||
1374 | }; | ||
1375 | |||
1376 | static struct hda_verb alc880_lg_init_verbs[] = { | ||
1377 | /* set capture source to mic-in */ | ||
1378 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1379 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1380 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1381 | /* mute all amp mixer inputs */ | ||
1382 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
1383 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, | ||
1384 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)}, | ||
1385 | /* line-in to input */ | ||
1386 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1387 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1388 | /* built-in mic */ | ||
1389 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1390 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1391 | /* speaker-out */ | ||
1392 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1393 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1394 | /* mic-in to input */ | ||
1395 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1396 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1397 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1398 | /* HP-out */ | ||
1399 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
1400 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1401 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1402 | /* jack sense */ | ||
1403 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1}, | ||
1404 | { } | ||
1405 | }; | ||
1406 | |||
1407 | /* toggle speaker-output according to the hp-jack state */ | ||
1408 | static void alc880_lg_automute(struct hda_codec *codec) | ||
1409 | { | ||
1410 | unsigned int present; | ||
1411 | |||
1412 | present = snd_hda_codec_read(codec, 0x1b, 0, | ||
1413 | AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; | ||
1414 | snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, | ||
1415 | 0x80, present ? 0x80 : 0); | ||
1416 | snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, | ||
1417 | 0x80, present ? 0x80 : 0); | ||
1418 | } | ||
1419 | |||
1420 | static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1421 | { | ||
1422 | /* Looks like the unsol event is incompatible with the standard | ||
1423 | * definition. 4bit tag is placed at 28 bit! | ||
1424 | */ | ||
1425 | if ((res >> 28) == 0x01) | ||
1426 | alc880_lg_automute(codec); | ||
1427 | } | ||
1428 | |||
1429 | /* | ||
1430 | * Common callbacks | ||
1101 | */ | 1431 | */ |
1102 | 1432 | ||
1103 | static int alc_init(struct hda_codec *codec) | 1433 | static int alc_init(struct hda_codec *codec) |
@@ -1107,9 +1437,21 @@ static int alc_init(struct hda_codec *codec) | |||
1107 | 1437 | ||
1108 | for (i = 0; i < spec->num_init_verbs; i++) | 1438 | for (i = 0; i < spec->num_init_verbs; i++) |
1109 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 1439 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
1440 | |||
1441 | if (spec->init_hook) | ||
1442 | spec->init_hook(codec); | ||
1443 | |||
1110 | return 0; | 1444 | return 0; |
1111 | } | 1445 | } |
1112 | 1446 | ||
1447 | static void alc_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1448 | { | ||
1449 | struct alc_spec *spec = codec->spec; | ||
1450 | |||
1451 | if (spec->unsol_event) | ||
1452 | spec->unsol_event(codec, res); | ||
1453 | } | ||
1454 | |||
1113 | #ifdef CONFIG_PM | 1455 | #ifdef CONFIG_PM |
1114 | /* | 1456 | /* |
1115 | * resume | 1457 | * resume |
@@ -1250,6 +1592,13 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = { | |||
1250 | /* NID is set in alc_build_pcms */ | 1592 | /* NID is set in alc_build_pcms */ |
1251 | }; | 1593 | }; |
1252 | 1594 | ||
1595 | /* Used by alc_build_pcms to flag that a PCM has no playback stream */ | ||
1596 | static struct hda_pcm_stream alc_pcm_null_playback = { | ||
1597 | .substreams = 0, | ||
1598 | .channels_min = 0, | ||
1599 | .channels_max = 0, | ||
1600 | }; | ||
1601 | |||
1253 | static int alc_build_pcms(struct hda_codec *codec) | 1602 | static int alc_build_pcms(struct hda_codec *codec) |
1254 | { | 1603 | { |
1255 | struct alc_spec *spec = codec->spec; | 1604 | struct alc_spec *spec = codec->spec; |
@@ -1280,6 +1629,23 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
1280 | } | 1629 | } |
1281 | } | 1630 | } |
1282 | 1631 | ||
1632 | /* If the use of more than one ADC is requested for the current | ||
1633 | * model, configure a second analog capture-only PCM. | ||
1634 | */ | ||
1635 | if (spec->num_adc_nids > 1) { | ||
1636 | codec->num_pcms++; | ||
1637 | info++; | ||
1638 | info->name = spec->stream_name_analog; | ||
1639 | /* No playback stream for second PCM */ | ||
1640 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback; | ||
1641 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; | ||
1642 | if (spec->stream_analog_capture) { | ||
1643 | snd_assert(spec->adc_nids, return -EINVAL); | ||
1644 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); | ||
1645 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1]; | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1283 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 1649 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
1284 | codec->num_pcms++; | 1650 | codec->num_pcms++; |
1285 | info++; | 1651 | info++; |
@@ -1322,6 +1688,7 @@ static struct hda_codec_ops alc_patch_ops = { | |||
1322 | .build_pcms = alc_build_pcms, | 1688 | .build_pcms = alc_build_pcms, |
1323 | .init = alc_init, | 1689 | .init = alc_init, |
1324 | .free = alc_free, | 1690 | .free = alc_free, |
1691 | .unsol_event = alc_unsol_event, | ||
1325 | #ifdef CONFIG_PM | 1692 | #ifdef CONFIG_PM |
1326 | .resume = alc_resume, | 1693 | .resume = alc_resume, |
1327 | #endif | 1694 | #endif |
@@ -1340,13 +1707,15 @@ static hda_nid_t alc880_test_dac_nids[4] = { | |||
1340 | }; | 1707 | }; |
1341 | 1708 | ||
1342 | static struct hda_input_mux alc880_test_capture_source = { | 1709 | static struct hda_input_mux alc880_test_capture_source = { |
1343 | .num_items = 5, | 1710 | .num_items = 7, |
1344 | .items = { | 1711 | .items = { |
1345 | { "In-1", 0x0 }, | 1712 | { "In-1", 0x0 }, |
1346 | { "In-2", 0x1 }, | 1713 | { "In-2", 0x1 }, |
1347 | { "In-3", 0x2 }, | 1714 | { "In-3", 0x2 }, |
1348 | { "In-4", 0x3 }, | 1715 | { "In-4", 0x3 }, |
1349 | { "CD", 0x4 }, | 1716 | { "CD", 0x4 }, |
1717 | { "Front", 0x5 }, | ||
1718 | { "Surround", 0x6 }, | ||
1350 | }, | 1719 | }, |
1351 | }; | 1720 | }; |
1352 | 1721 | ||
@@ -1653,6 +2022,8 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1653 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, | 2022 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, |
1654 | { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, | 2023 | { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, |
1655 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, | 2024 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, |
2025 | { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560, | ||
2026 | .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */ | ||
1656 | /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ | 2027 | /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ |
1657 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, | 2028 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, |
1658 | /* note subvendor = 0 below */ | 2029 | /* note subvendor = 0 below */ |
@@ -1680,6 +2051,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1680 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, | 2051 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG }, |
1681 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, | 2052 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG }, |
1682 | { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ | 2053 | { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */ |
2054 | { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */ | ||
1683 | 2055 | ||
1684 | { .modelname = "asus", .config = ALC880_ASUS }, | 2056 | { .modelname = "asus", .config = ALC880_ASUS }, |
1685 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, | 2057 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG }, |
@@ -1693,6 +2065,7 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1693 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, | 2065 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG }, |
1694 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, | 2066 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS }, |
1695 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, | 2067 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V }, |
2068 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */ | ||
1696 | { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, | 2069 | { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 }, |
1697 | 2070 | ||
1698 | { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, | 2071 | { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG }, |
@@ -1702,6 +2075,9 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1702 | { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, | 2075 | { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 }, |
1703 | { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, | 2076 | { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 }, |
1704 | 2077 | ||
2078 | { .modelname = "lg", .config = ALC880_LG }, | ||
2079 | { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG }, | ||
2080 | |||
1705 | #ifdef CONFIG_SND_DEBUG | 2081 | #ifdef CONFIG_SND_DEBUG |
1706 | { .modelname = "test", .config = ALC880_TEST }, | 2082 | { .modelname = "test", .config = ALC880_TEST }, |
1707 | #endif | 2083 | #endif |
@@ -1879,6 +2255,19 @@ static struct alc_config_preset alc880_presets[] = { | |||
1879 | .channel_mode = alc880_threestack_modes, | 2255 | .channel_mode = alc880_threestack_modes, |
1880 | .input_mux = &alc880_capture_source, | 2256 | .input_mux = &alc880_capture_source, |
1881 | }, | 2257 | }, |
2258 | [ALC880_LG] = { | ||
2259 | .mixers = { alc880_lg_mixer }, | ||
2260 | .init_verbs = { alc880_volume_init_verbs, | ||
2261 | alc880_lg_init_verbs }, | ||
2262 | .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), | ||
2263 | .dac_nids = alc880_lg_dac_nids, | ||
2264 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
2265 | .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), | ||
2266 | .channel_mode = alc880_lg_ch_modes, | ||
2267 | .input_mux = &alc880_lg_capture_source, | ||
2268 | .unsol_event = alc880_lg_unsol_event, | ||
2269 | .init_hook = alc880_lg_automute, | ||
2270 | }, | ||
1882 | #ifdef CONFIG_SND_DEBUG | 2271 | #ifdef CONFIG_SND_DEBUG |
1883 | [ALC880_TEST] = { | 2272 | [ALC880_TEST] = { |
1884 | .mixers = { alc880_test_mixer }, | 2273 | .mixers = { alc880_test_mixer }, |
@@ -2043,14 +2432,11 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2043 | 2432 | ||
2044 | if (alc880_is_fixed_pin(pin)) { | 2433 | if (alc880_is_fixed_pin(pin)) { |
2045 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 2434 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
2046 | if (! spec->multiout.dac_nids[0]) { | 2435 | /* specify the DAC as the extra output */ |
2047 | /* use this as the primary output */ | 2436 | if (! spec->multiout.hp_nid) |
2048 | spec->multiout.dac_nids[0] = nid; | ||
2049 | if (! spec->multiout.num_dacs) | ||
2050 | spec->multiout.num_dacs = 1; | ||
2051 | } else | ||
2052 | /* specify the DAC as the extra output */ | ||
2053 | spec->multiout.hp_nid = nid; | 2437 | spec->multiout.hp_nid = nid; |
2438 | else | ||
2439 | spec->multiout.extra_out_nid[0] = nid; | ||
2054 | /* control HP volume/switch on the output mixer amp */ | 2440 | /* control HP volume/switch on the output mixer amp */ |
2055 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | 2441 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); |
2056 | sprintf(name, "%s Playback Volume", pfx); | 2442 | sprintf(name, "%s Playback Volume", pfx); |
@@ -2063,12 +2449,6 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2063 | return err; | 2449 | return err; |
2064 | } else if (alc880_is_multi_pin(pin)) { | 2450 | } else if (alc880_is_multi_pin(pin)) { |
2065 | /* set manual connection */ | 2451 | /* set manual connection */ |
2066 | if (! spec->multiout.dac_nids[0]) { | ||
2067 | /* use this as the primary output */ | ||
2068 | spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin)); | ||
2069 | if (! spec->multiout.num_dacs) | ||
2070 | spec->multiout.num_dacs = 1; | ||
2071 | } | ||
2072 | /* we have only a switch on HP-out PIN */ | 2452 | /* we have only a switch on HP-out PIN */ |
2073 | sprintf(name, "%s Playback Switch", pfx); | 2453 | sprintf(name, "%s Playback Switch", pfx); |
2074 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 2454 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
@@ -2152,7 +2532,7 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec) | |||
2152 | struct alc_spec *spec = codec->spec; | 2532 | struct alc_spec *spec = codec->spec; |
2153 | hda_nid_t pin; | 2533 | hda_nid_t pin; |
2154 | 2534 | ||
2155 | pin = spec->autocfg.speaker_pin; | 2535 | pin = spec->autocfg.speaker_pins[0]; |
2156 | if (pin) /* connect to front */ | 2536 | if (pin) /* connect to front */ |
2157 | alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 2537 | alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
2158 | pin = spec->autocfg.hp_pin; | 2538 | pin = spec->autocfg.hp_pin; |
@@ -2188,15 +2568,15 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
2188 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 2568 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
2189 | alc880_ignore)) < 0) | 2569 | alc880_ignore)) < 0) |
2190 | return err; | 2570 | return err; |
2191 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 2571 | if (! spec->autocfg.line_outs) |
2192 | ! spec->autocfg.hp_pin) | ||
2193 | return 0; /* can't find valid BIOS pin config */ | 2572 | return 0; /* can't find valid BIOS pin config */ |
2194 | 2573 | ||
2195 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 2574 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || |
2196 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 2575 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
2197 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, | 2576 | (err = alc880_auto_create_extra_out(spec, |
2577 | spec->autocfg.speaker_pins[0], | ||
2198 | "Speaker")) < 0 || | 2578 | "Speaker")) < 0 || |
2199 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, | 2579 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin, |
2200 | "Headphone")) < 0 || | 2580 | "Headphone")) < 0 || |
2201 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 2581 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) |
2202 | return err; | 2582 | return err; |
@@ -2218,14 +2598,12 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
2218 | return 1; | 2598 | return 1; |
2219 | } | 2599 | } |
2220 | 2600 | ||
2221 | /* init callback for auto-configuration model -- overriding the default init */ | 2601 | /* additional initialization for auto-configuration model */ |
2222 | static int alc880_auto_init(struct hda_codec *codec) | 2602 | static void alc880_auto_init(struct hda_codec *codec) |
2223 | { | 2603 | { |
2224 | alc_init(codec); | ||
2225 | alc880_auto_init_multi_out(codec); | 2604 | alc880_auto_init_multi_out(codec); |
2226 | alc880_auto_init_extra_out(codec); | 2605 | alc880_auto_init_extra_out(codec); |
2227 | alc880_auto_init_analog_input(codec); | 2606 | alc880_auto_init_analog_input(codec); |
2228 | return 0; | ||
2229 | } | 2607 | } |
2230 | 2608 | ||
2231 | /* | 2609 | /* |
@@ -2292,7 +2670,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
2292 | 2670 | ||
2293 | codec->patch_ops = alc_patch_ops; | 2671 | codec->patch_ops = alc_patch_ops; |
2294 | if (board_config == ALC880_AUTO) | 2672 | if (board_config == ALC880_AUTO) |
2295 | codec->patch_ops.init = alc880_auto_init; | 2673 | spec->init_hook = alc880_auto_init; |
2296 | 2674 | ||
2297 | return 0; | 2675 | return 0; |
2298 | } | 2676 | } |
@@ -2322,6 +2700,14 @@ static hda_nid_t alc260_hp_adc_nids[2] = { | |||
2322 | 0x05, 0x04 | 2700 | 0x05, 0x04 |
2323 | }; | 2701 | }; |
2324 | 2702 | ||
2703 | /* NIDs used when simultaneous access to both ADCs makes sense. Note that | ||
2704 | * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. | ||
2705 | */ | ||
2706 | static hda_nid_t alc260_dual_adc_nids[2] = { | ||
2707 | /* ADC0, ADC1 */ | ||
2708 | 0x04, 0x05 | ||
2709 | }; | ||
2710 | |||
2325 | #define ALC260_DIGOUT_NID 0x03 | 2711 | #define ALC260_DIGOUT_NID 0x03 |
2326 | #define ALC260_DIGIN_NID 0x06 | 2712 | #define ALC260_DIGIN_NID 0x06 |
2327 | 2713 | ||
@@ -2335,14 +2721,28 @@ static struct hda_input_mux alc260_capture_source = { | |||
2335 | }, | 2721 | }, |
2336 | }; | 2722 | }; |
2337 | 2723 | ||
2338 | /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack | 2724 | /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, |
2339 | * and the internal CD lines. | 2725 | * headphone jack and the internal CD lines. |
2340 | */ | 2726 | */ |
2341 | static struct hda_input_mux alc260_fujitsu_capture_source = { | 2727 | static struct hda_input_mux alc260_fujitsu_capture_source = { |
2342 | .num_items = 2, | 2728 | .num_items = 3, |
2343 | .items = { | 2729 | .items = { |
2344 | { "Mic/Line", 0x0 }, | 2730 | { "Mic/Line", 0x0 }, |
2345 | { "CD", 0x4 }, | 2731 | { "CD", 0x4 }, |
2732 | { "Headphone", 0x2 }, | ||
2733 | }, | ||
2734 | }; | ||
2735 | |||
2736 | /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configutation to | ||
2737 | * the Fujitsu S702x, but jacks are marked differently. We won't allow | ||
2738 | * retasking the Headphone jack, so it won't be available here. | ||
2739 | */ | ||
2740 | static struct hda_input_mux alc260_acer_capture_source = { | ||
2741 | .num_items = 3, | ||
2742 | .items = { | ||
2743 | { "Mic", 0x0 }, | ||
2744 | { "Line", 0x2 }, | ||
2745 | { "CD", 0x4 }, | ||
2346 | }, | 2746 | }, |
2347 | }; | 2747 | }; |
2348 | 2748 | ||
@@ -2363,6 +2763,7 @@ static struct hda_channel_mode alc260_modes[1] = { | |||
2363 | * HP: base_output + input + capture_alt | 2763 | * HP: base_output + input + capture_alt |
2364 | * HP_3013: hp_3013 + input + capture | 2764 | * HP_3013: hp_3013 + input + capture |
2365 | * fujitsu: fujitsu + capture | 2765 | * fujitsu: fujitsu + capture |
2766 | * acer: acer + capture | ||
2366 | */ | 2767 | */ |
2367 | 2768 | ||
2368 | static struct snd_kcontrol_new alc260_base_output_mixer[] = { | 2769 | static struct snd_kcontrol_new alc260_base_output_mixer[] = { |
@@ -2408,11 +2809,12 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
2408 | static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | 2809 | static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { |
2409 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2810 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2410 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | 2811 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), |
2411 | ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP), | 2812 | ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), |
2412 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2813 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2413 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2814 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
2414 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), | 2815 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), |
2415 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), | 2816 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), |
2817 | ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
2416 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | 2818 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), |
2417 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | 2819 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), |
2418 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2820 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
@@ -2420,6 +2822,22 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | |||
2420 | { } /* end */ | 2822 | { } /* end */ |
2421 | }; | 2823 | }; |
2422 | 2824 | ||
2825 | static struct snd_kcontrol_new alc260_acer_mixer[] = { | ||
2826 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
2827 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
2828 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
2829 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
2830 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
2831 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
2832 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
2833 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
2834 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
2835 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
2836 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
2837 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
2838 | { } /* end */ | ||
2839 | }; | ||
2840 | |||
2423 | /* capture mixer elements */ | 2841 | /* capture mixer elements */ |
2424 | static struct snd_kcontrol_new alc260_capture_mixer[] = { | 2842 | static struct snd_kcontrol_new alc260_capture_mixer[] = { |
2425 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 2843 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
@@ -2629,52 +3047,327 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { | |||
2629 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3047 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
2630 | /* Headphone/Line-out jack connects to Line1 pin; make it an output */ | 3048 | /* Headphone/Line-out jack connects to Line1 pin; make it an output */ |
2631 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 3049 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2632 | /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ | 3050 | /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ |
2633 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 3051 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2634 | /* Ensure all other unused pins are disabled and muted. | 3052 | /* Ensure all other unused pins are disabled and muted. */ |
2635 | * Note: trying to set widget 0x15 to anything blocks all audio | 3053 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2636 | * output for some reason, so just leave that at the default. | 3054 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
3055 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3056 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3057 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3058 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3059 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3060 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3061 | |||
3062 | /* Disable digital (SPDIF) pins */ | ||
3063 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
3064 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
3065 | |||
3066 | /* Ensure Line1 pin widget takes its input from the OUT1 sum bus | ||
3067 | * when acting as an output. | ||
3068 | */ | ||
3069 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
3070 | |||
3071 | /* Start with output sum widgets muted and their output gains at min */ | ||
3072 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3073 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3074 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3075 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3076 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3077 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3078 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3079 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3080 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3081 | |||
3082 | /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ | ||
3083 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3084 | /* Unmute Line1 pin widget output buffer since it starts as an output. | ||
3085 | * If the pin mode is changed by the user the pin mode control will | ||
3086 | * take care of enabling the pin's input/output buffers as needed. | ||
3087 | * Therefore there's no need to enable the input buffer at this | ||
3088 | * stage. | ||
3089 | */ | ||
3090 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3091 | /* Unmute input buffer of pin widget used for Line-in (no equiv | ||
3092 | * mixer ctrl) | ||
3093 | */ | ||
3094 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3095 | |||
3096 | /* Mute capture amp left and right */ | ||
3097 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3098 | /* Set ADC connection select to match default mixer setting - line | ||
3099 | * in (on mic1 pin) | ||
2637 | */ | 3100 | */ |
2638 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3101 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, |
2639 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3102 | |
3103 | /* Do the same for the second ADC: mute capture input amp and | ||
3104 | * set ADC connection to line in (on mic1 pin) | ||
3105 | */ | ||
3106 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3107 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3108 | |||
3109 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
3110 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
3111 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
3112 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
3113 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
3114 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
3115 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
3116 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
3117 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
3118 | |||
3119 | { } | ||
3120 | }; | ||
3121 | |||
3122 | /* Initialisation sequence for ALC260 as configured in Acer TravelMate and | ||
3123 | * similar laptops (adapted from Fujitsu init verbs). | ||
3124 | */ | ||
3125 | static struct hda_verb alc260_acer_init_verbs[] = { | ||
3126 | /* On TravelMate laptops, GPIO 0 enables the internal speaker and | ||
3127 | * the headphone jack. Turn this on and rely on the standard mute | ||
3128 | * methods whenever the user wants to turn these outputs off. | ||
3129 | */ | ||
3130 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
3131 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
3132 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
3133 | /* Internal speaker/Headphone jack is connected to Line-out pin */ | ||
3134 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
3135 | /* Internal microphone/Mic jack is connected to Mic1 pin */ | ||
3136 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
3137 | /* Line In jack is connected to Line1 pin */ | ||
3138 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
3139 | /* Ensure all other unused pins are disabled and muted. */ | ||
3140 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
3141 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
2640 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3142 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2641 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3143 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2642 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 3144 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2643 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3145 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2644 | /* Disable digital (SPDIF) pins */ | 3146 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2645 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | 3147 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2646 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | 3148 | /* Disable digital (SPDIF) pins */ |
2647 | 3149 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | |
2648 | /* Start with mixer outputs muted */ | 3150 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, |
2649 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3151 | |
2650 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3152 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum |
2651 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3153 | * bus when acting as outputs. |
2652 | 3154 | */ | |
2653 | /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ | 3155 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, |
2654 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3156 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, |
2655 | /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */ | 3157 | |
2656 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3158 | /* Start with output sum widgets muted and their output gains at min */ |
2657 | /* Unmute pin widget used for Line-in (no equiv mixer ctrl) */ | 3159 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2658 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 3160 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2659 | 3161 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | |
2660 | /* Mute capture amp left and right */ | 3162 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2661 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 3163 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2662 | /* Set ADC connection select to line in (on mic1 pin) */ | 3164 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
2663 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | 3165 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2664 | 3166 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | |
2665 | /* Mute all inputs to mixer widget (even unconnected ones) */ | 3167 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
2666 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | 3168 | |
2667 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | 3169 | /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ |
2668 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | 3170 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2669 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | 3171 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as |
2670 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | 3172 | * inputs. If the pin mode is changed by the user the pin mode control |
2671 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | 3173 | * will take care of enabling the pin's input/output buffers as needed. |
2672 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | 3174 | * Therefore there's no need to enable the input buffer at this |
2673 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | 3175 | * stage. |
3176 | */ | ||
3177 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3178 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
3179 | |||
3180 | /* Mute capture amp left and right */ | ||
3181 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3182 | /* Set ADC connection select to match default mixer setting - mic | ||
3183 | * (on mic1 pin) | ||
3184 | */ | ||
3185 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3186 | |||
3187 | /* Do similar with the second ADC: mute capture input amp and | ||
3188 | * set ADC connection to line (on line1 pin) | ||
3189 | */ | ||
3190 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3191 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
3192 | |||
3193 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
3194 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
3195 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
3196 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
3197 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
3198 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
3199 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
3200 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
3201 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
2674 | 3202 | ||
2675 | { } | 3203 | { } |
2676 | }; | 3204 | }; |
2677 | 3205 | ||
3206 | /* Test configuration for debugging, modelled after the ALC880 test | ||
3207 | * configuration. | ||
3208 | */ | ||
3209 | #ifdef CONFIG_SND_DEBUG | ||
3210 | static hda_nid_t alc260_test_dac_nids[1] = { | ||
3211 | 0x02, | ||
3212 | }; | ||
3213 | static hda_nid_t alc260_test_adc_nids[2] = { | ||
3214 | 0x04, 0x05, | ||
3215 | }; | ||
3216 | /* This is a bit messy since the two input muxes in the ALC260 have slight | ||
3217 | * variations in their signal assignments. The ideal way to deal with this | ||
3218 | * is to extend alc_spec.input_mux to allow a different input MUX for each | ||
3219 | * ADC. For the purposes of the test model it's sufficient to just list | ||
3220 | * both options for affected signal indices. The separate input mux | ||
3221 | * functionality only needs to be considered if a model comes along which | ||
3222 | * actually uses signals 0x5, 0x6 and 0x7 for something which makes sense to | ||
3223 | * record. | ||
3224 | */ | ||
3225 | static struct hda_input_mux alc260_test_capture_source = { | ||
3226 | .num_items = 8, | ||
3227 | .items = { | ||
3228 | { "MIC1 pin", 0x0 }, | ||
3229 | { "MIC2 pin", 0x1 }, | ||
3230 | { "LINE1 pin", 0x2 }, | ||
3231 | { "LINE2 pin", 0x3 }, | ||
3232 | { "CD pin", 0x4 }, | ||
3233 | { "LINE-OUT pin (cap1), Mixer (cap2)", 0x5 }, | ||
3234 | { "HP-OUT pin (cap1), LINE-OUT pin (cap2)", 0x6 }, | ||
3235 | { "HP-OUT pin (cap2 only)", 0x7 }, | ||
3236 | }, | ||
3237 | }; | ||
3238 | static struct snd_kcontrol_new alc260_test_mixer[] = { | ||
3239 | /* Output driver widgets */ | ||
3240 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
3241 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
3242 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
3243 | HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), | ||
3244 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
3245 | HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), | ||
3246 | |||
3247 | /* Modes for retasking pin widgets */ | ||
3248 | ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), | ||
3249 | ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
3250 | ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), | ||
3251 | ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), | ||
3252 | ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), | ||
3253 | ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), | ||
3254 | |||
3255 | /* Loopback mixer controls */ | ||
3256 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), | ||
3257 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), | ||
3258 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
3259 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
3260 | HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
3261 | HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
3262 | HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), | ||
3263 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), | ||
3264 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
3265 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
3266 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | ||
3267 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | ||
3268 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
3269 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
3270 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), | ||
3271 | HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), | ||
3272 | |||
3273 | /* Controls for GPIO pins, assuming they are configured as outputs */ | ||
3274 | ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
3275 | ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
3276 | ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
3277 | ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
3278 | |||
3279 | /* Switches to allow the digital IO pins to be enabled. The datasheet | ||
3280 | * is ambigious as to which NID is which; testing on laptops which | ||
3281 | * make this output available should provide clarification. | ||
3282 | */ | ||
3283 | ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), | ||
3284 | ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), | ||
3285 | |||
3286 | { } /* end */ | ||
3287 | }; | ||
3288 | static struct hda_verb alc260_test_init_verbs[] = { | ||
3289 | /* Enable all GPIOs as outputs with an initial value of 0 */ | ||
3290 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | ||
3291 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
3292 | {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, | ||
3293 | |||
3294 | /* Enable retasking pins as output, initially without power amp */ | ||
3295 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3296 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3297 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3298 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3299 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3300 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
3301 | |||
3302 | /* Disable digital (SPDIF) pins initially, but users can enable | ||
3303 | * them via a mixer switch. In the case of SPDIF-out, this initverb | ||
3304 | * payload also sets the generation to 0, output to be in "consumer" | ||
3305 | * PCM format, copyright asserted, no pre-emphasis and no validity | ||
3306 | * control. | ||
3307 | */ | ||
3308 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
3309 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
3310 | |||
3311 | /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the | ||
3312 | * OUT1 sum bus when acting as an output. | ||
3313 | */ | ||
3314 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
3315 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, | ||
3316 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
3317 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, | ||
3318 | |||
3319 | /* Start with output sum widgets muted and their output gains at min */ | ||
3320 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3321 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3322 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3323 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3324 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3325 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3326 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3327 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
3328 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
3329 | |||
3330 | /* Unmute retasking pin widget output buffers since the default | ||
3331 | * state appears to be output. As the pin mode is changed by the | ||
3332 | * user the pin mode control will take care of enabling the pin's | ||
3333 | * input/output buffers as needed. | ||
3334 | */ | ||
3335 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3336 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3337 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3338 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3339 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3340 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3341 | /* Also unmute the mono-out pin widget */ | ||
3342 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
3343 | |||
3344 | /* Mute capture amp left and right */ | ||
3345 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3346 | /* Set ADC connection select to match default mixer setting (mic1 | ||
3347 | * pin) | ||
3348 | */ | ||
3349 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3350 | |||
3351 | /* Do the same for the second ADC: mute capture input amp and | ||
3352 | * set ADC connection to mic1 pin | ||
3353 | */ | ||
3354 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
3355 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
3356 | |||
3357 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
3358 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
3359 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
3360 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
3361 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
3362 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
3363 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
3364 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
3365 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
3366 | |||
3367 | { } | ||
3368 | }; | ||
3369 | #endif | ||
3370 | |||
2678 | static struct hda_pcm_stream alc260_pcm_analog_playback = { | 3371 | static struct hda_pcm_stream alc260_pcm_analog_playback = { |
2679 | .substreams = 1, | 3372 | .substreams = 1, |
2680 | .channels_min = 2, | 3373 | .channels_min = 2, |
@@ -2744,7 +3437,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
2744 | return err; | 3437 | return err; |
2745 | } | 3438 | } |
2746 | 3439 | ||
2747 | nid = cfg->speaker_pin; | 3440 | nid = cfg->speaker_pins[0]; |
2748 | if (nid) { | 3441 | if (nid) { |
2749 | err = alc260_add_playback_controls(spec, nid, "Speaker"); | 3442 | err = alc260_add_playback_controls(spec, nid, "Speaker"); |
2750 | if (err < 0) | 3443 | if (err < 0) |
@@ -2817,7 +3510,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
2817 | if (nid) | 3510 | if (nid) |
2818 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 3511 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); |
2819 | 3512 | ||
2820 | nid = spec->autocfg.speaker_pin; | 3513 | nid = spec->autocfg.speaker_pins[0]; |
2821 | if (nid) | 3514 | if (nid) |
2822 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 3515 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); |
2823 | 3516 | ||
@@ -2932,13 +3625,11 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
2932 | return 1; | 3625 | return 1; |
2933 | } | 3626 | } |
2934 | 3627 | ||
2935 | /* init callback for auto-configuration model -- overriding the default init */ | 3628 | /* additional initialization for auto-configuration model */ |
2936 | static int alc260_auto_init(struct hda_codec *codec) | 3629 | static void alc260_auto_init(struct hda_codec *codec) |
2937 | { | 3630 | { |
2938 | alc_init(codec); | ||
2939 | alc260_auto_init_multi_out(codec); | 3631 | alc260_auto_init_multi_out(codec); |
2940 | alc260_auto_init_analog_input(codec); | 3632 | alc260_auto_init_analog_input(codec); |
2941 | return 0; | ||
2942 | } | 3633 | } |
2943 | 3634 | ||
2944 | /* | 3635 | /* |
@@ -2948,6 +3639,8 @@ static struct hda_board_config alc260_cfg_tbl[] = { | |||
2948 | { .modelname = "basic", .config = ALC260_BASIC }, | 3639 | { .modelname = "basic", .config = ALC260_BASIC }, |
2949 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, | 3640 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, |
2950 | .config = ALC260_BASIC }, /* Sony VAIO */ | 3641 | .config = ALC260_BASIC }, /* Sony VAIO */ |
3642 | { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, | ||
3643 | .config = ALC260_BASIC }, /* CTL Travel Master U553W */ | ||
2951 | { .modelname = "hp", .config = ALC260_HP }, | 3644 | { .modelname = "hp", .config = ALC260_HP }, |
2952 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, | 3645 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, |
2953 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, | 3646 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, |
@@ -2958,6 +3651,11 @@ static struct hda_board_config alc260_cfg_tbl[] = { | |||
2958 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, | 3651 | { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP }, |
2959 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, | 3652 | { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X }, |
2960 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, | 3653 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X }, |
3654 | { .modelname = "acer", .config = ALC260_ACER }, | ||
3655 | { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER }, | ||
3656 | #ifdef CONFIG_SND_DEBUG | ||
3657 | { .modelname = "test", .config = ALC260_TEST }, | ||
3658 | #endif | ||
2961 | { .modelname = "auto", .config = ALC260_AUTO }, | 3659 | { .modelname = "auto", .config = ALC260_AUTO }, |
2962 | {} | 3660 | {} |
2963 | }; | 3661 | }; |
@@ -3009,12 +3707,38 @@ static struct alc_config_preset alc260_presets[] = { | |||
3009 | .init_verbs = { alc260_fujitsu_init_verbs }, | 3707 | .init_verbs = { alc260_fujitsu_init_verbs }, |
3010 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | 3708 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), |
3011 | .dac_nids = alc260_dac_nids, | 3709 | .dac_nids = alc260_dac_nids, |
3012 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | 3710 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), |
3013 | .adc_nids = alc260_adc_nids, | 3711 | .adc_nids = alc260_dual_adc_nids, |
3014 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 3712 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
3015 | .channel_mode = alc260_modes, | 3713 | .channel_mode = alc260_modes, |
3016 | .input_mux = &alc260_fujitsu_capture_source, | 3714 | .input_mux = &alc260_fujitsu_capture_source, |
3017 | }, | 3715 | }, |
3716 | [ALC260_ACER] = { | ||
3717 | .mixers = { alc260_acer_mixer, | ||
3718 | alc260_capture_mixer }, | ||
3719 | .init_verbs = { alc260_acer_init_verbs }, | ||
3720 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
3721 | .dac_nids = alc260_dac_nids, | ||
3722 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
3723 | .adc_nids = alc260_dual_adc_nids, | ||
3724 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
3725 | .channel_mode = alc260_modes, | ||
3726 | .input_mux = &alc260_acer_capture_source, | ||
3727 | }, | ||
3728 | #ifdef CONFIG_SND_DEBUG | ||
3729 | [ALC260_TEST] = { | ||
3730 | .mixers = { alc260_test_mixer, | ||
3731 | alc260_capture_mixer }, | ||
3732 | .init_verbs = { alc260_test_init_verbs }, | ||
3733 | .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), | ||
3734 | .dac_nids = alc260_test_dac_nids, | ||
3735 | .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), | ||
3736 | .adc_nids = alc260_test_adc_nids, | ||
3737 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
3738 | .channel_mode = alc260_modes, | ||
3739 | .input_mux = &alc260_test_capture_source, | ||
3740 | }, | ||
3741 | #endif | ||
3018 | }; | 3742 | }; |
3019 | 3743 | ||
3020 | static int patch_alc260(struct hda_codec *codec) | 3744 | static int patch_alc260(struct hda_codec *codec) |
@@ -3059,7 +3783,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
3059 | 3783 | ||
3060 | codec->patch_ops = alc_patch_ops; | 3784 | codec->patch_ops = alc_patch_ops; |
3061 | if (board_config == ALC260_AUTO) | 3785 | if (board_config == ALC260_AUTO) |
3062 | codec->patch_ops.init = alc260_auto_init; | 3786 | spec->init_hook = alc260_auto_init; |
3063 | 3787 | ||
3064 | return 0; | 3788 | return 0; |
3065 | } | 3789 | } |
@@ -3534,14 +4258,12 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
3534 | return err; | 4258 | return err; |
3535 | } | 4259 | } |
3536 | 4260 | ||
3537 | /* init callback for auto-configuration model -- overriding the default init */ | 4261 | /* additional initialization for auto-configuration model */ |
3538 | static int alc882_auto_init(struct hda_codec *codec) | 4262 | static void alc882_auto_init(struct hda_codec *codec) |
3539 | { | 4263 | { |
3540 | alc_init(codec); | ||
3541 | alc882_auto_init_multi_out(codec); | 4264 | alc882_auto_init_multi_out(codec); |
3542 | alc882_auto_init_hp_out(codec); | 4265 | alc882_auto_init_hp_out(codec); |
3543 | alc882_auto_init_analog_input(codec); | 4266 | alc882_auto_init_analog_input(codec); |
3544 | return 0; | ||
3545 | } | 4267 | } |
3546 | 4268 | ||
3547 | /* | 4269 | /* |
@@ -3608,7 +4330,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
3608 | 4330 | ||
3609 | codec->patch_ops = alc_patch_ops; | 4331 | codec->patch_ops = alc_patch_ops; |
3610 | if (board_config == ALC882_AUTO) | 4332 | if (board_config == ALC882_AUTO) |
3611 | codec->patch_ops.init = alc882_auto_init; | 4333 | spec->init_hook = alc882_auto_init; |
3612 | 4334 | ||
3613 | return 0; | 4335 | return 0; |
3614 | } | 4336 | } |
@@ -3644,19 +4366,9 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
3644 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 4366 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
3645 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 4367 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
3646 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | 4368 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), |
3647 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
3648 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
3649 | { | ||
3650 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3651 | .name = "Capture Source", | ||
3652 | .count = 1, | ||
3653 | .info = alc882_mux_enum_info, | ||
3654 | .get = alc882_mux_enum_get, | ||
3655 | .put = alc882_mux_enum_put, | ||
3656 | }, | ||
3657 | { } /* end */ | 4369 | { } /* end */ |
3658 | }; | 4370 | }; |
3659 | 4371 | ||
3660 | #define alc262_capture_mixer alc882_capture_mixer | 4372 | #define alc262_capture_mixer alc882_capture_mixer |
3661 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer | 4373 | #define alc262_capture_alt_mixer alc882_capture_alt_mixer |
3662 | 4374 | ||
@@ -3739,6 +4451,129 @@ static struct hda_verb alc262_init_verbs[] = { | |||
3739 | { } | 4451 | { } |
3740 | }; | 4452 | }; |
3741 | 4453 | ||
4454 | /* | ||
4455 | * fujitsu model | ||
4456 | * 0x14 = headphone/spdif-out, 0x15 = internal speaker | ||
4457 | */ | ||
4458 | |||
4459 | #define ALC_HP_EVENT 0x37 | ||
4460 | |||
4461 | static struct hda_verb alc262_fujitsu_unsol_verbs[] = { | ||
4462 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
4463 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
4464 | {} | ||
4465 | }; | ||
4466 | |||
4467 | static struct hda_input_mux alc262_fujitsu_capture_source = { | ||
4468 | .num_items = 2, | ||
4469 | .items = { | ||
4470 | { "Mic", 0x0 }, | ||
4471 | { "CD", 0x4 }, | ||
4472 | }, | ||
4473 | }; | ||
4474 | |||
4475 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
4476 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | ||
4477 | { | ||
4478 | struct alc_spec *spec = codec->spec; | ||
4479 | unsigned int mute; | ||
4480 | |||
4481 | if (force || ! spec->sense_updated) { | ||
4482 | unsigned int present; | ||
4483 | /* need to execute and sync at first */ | ||
4484 | snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
4485 | present = snd_hda_codec_read(codec, 0x14, 0, | ||
4486 | AC_VERB_GET_PIN_SENSE, 0); | ||
4487 | spec->jack_present = (present & 0x80000000) != 0; | ||
4488 | spec->sense_updated = 1; | ||
4489 | } | ||
4490 | if (spec->jack_present) { | ||
4491 | /* mute internal speaker */ | ||
4492 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
4493 | 0x80, 0x80); | ||
4494 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
4495 | 0x80, 0x80); | ||
4496 | } else { | ||
4497 | /* unmute internal speaker if necessary */ | ||
4498 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); | ||
4499 | snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, | ||
4500 | 0x80, mute & 0x80); | ||
4501 | mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0); | ||
4502 | snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, | ||
4503 | 0x80, mute & 0x80); | ||
4504 | } | ||
4505 | } | ||
4506 | |||
4507 | /* unsolicited event for HP jack sensing */ | ||
4508 | static void alc262_fujitsu_unsol_event(struct hda_codec *codec, | ||
4509 | unsigned int res) | ||
4510 | { | ||
4511 | if ((res >> 26) != ALC_HP_EVENT) | ||
4512 | return; | ||
4513 | alc262_fujitsu_automute(codec, 1); | ||
4514 | } | ||
4515 | |||
4516 | /* bind volumes of both NID 0x0c and 0x0d */ | ||
4517 | static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol, | ||
4518 | struct snd_ctl_elem_value *ucontrol) | ||
4519 | { | ||
4520 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
4521 | long *valp = ucontrol->value.integer.value; | ||
4522 | int change; | ||
4523 | |||
4524 | change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0, | ||
4525 | 0x7f, valp[0] & 0x7f); | ||
4526 | change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0, | ||
4527 | 0x7f, valp[1] & 0x7f); | ||
4528 | snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0, | ||
4529 | 0x7f, valp[0] & 0x7f); | ||
4530 | snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0, | ||
4531 | 0x7f, valp[1] & 0x7f); | ||
4532 | return change; | ||
4533 | } | ||
4534 | |||
4535 | /* bind hp and internal speaker mute (with plug check) */ | ||
4536 | static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, | ||
4537 | struct snd_ctl_elem_value *ucontrol) | ||
4538 | { | ||
4539 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
4540 | long *valp = ucontrol->value.integer.value; | ||
4541 | int change; | ||
4542 | |||
4543 | change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, | ||
4544 | 0x80, valp[0] ? 0 : 0x80); | ||
4545 | change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, | ||
4546 | 0x80, valp[1] ? 0 : 0x80); | ||
4547 | if (change || codec->in_resume) | ||
4548 | alc262_fujitsu_automute(codec, codec->in_resume); | ||
4549 | return change; | ||
4550 | } | ||
4551 | |||
4552 | static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { | ||
4553 | { | ||
4554 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4555 | .name = "Master Playback Volume", | ||
4556 | .info = snd_hda_mixer_amp_volume_info, | ||
4557 | .get = snd_hda_mixer_amp_volume_get, | ||
4558 | .put = alc262_fujitsu_master_vol_put, | ||
4559 | .private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), | ||
4560 | }, | ||
4561 | { | ||
4562 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
4563 | .name = "Master Playback Switch", | ||
4564 | .info = snd_hda_mixer_amp_switch_info, | ||
4565 | .get = snd_hda_mixer_amp_switch_get, | ||
4566 | .put = alc262_fujitsu_master_sw_put, | ||
4567 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
4568 | }, | ||
4569 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
4570 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
4571 | HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), | ||
4572 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
4573 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
4574 | { } /* end */ | ||
4575 | }; | ||
4576 | |||
3742 | /* add playback controls from the parsed DAC table */ | 4577 | /* add playback controls from the parsed DAC table */ |
3743 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) | 4578 | static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) |
3744 | { | 4579 | { |
@@ -3759,7 +4594,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
3759 | return err; | 4594 | return err; |
3760 | } | 4595 | } |
3761 | 4596 | ||
3762 | nid = cfg->speaker_pin; | 4597 | nid = cfg->speaker_pins[0]; |
3763 | if (nid) { | 4598 | if (nid) { |
3764 | if (nid == 0x16) { | 4599 | if (nid == 0x16) { |
3765 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | 4600 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", |
@@ -3769,10 +4604,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
3769 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 4604 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) |
3770 | return err; | 4605 | return err; |
3771 | } else { | 4606 | } else { |
3772 | if (! cfg->line_out_pins[0]) | ||
3773 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | ||
3774 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | ||
3775 | return err; | ||
3776 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 4607 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", |
3777 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 4608 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) |
3778 | return err; | 4609 | return err; |
@@ -3789,10 +4620,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
3789 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 4620 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) |
3790 | return err; | 4621 | return err; |
3791 | } else { | 4622 | } else { |
3792 | if (! cfg->line_out_pins[0]) | ||
3793 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", | ||
3794 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | ||
3795 | return err; | ||
3796 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 4623 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", |
3797 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 4624 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) |
3798 | return err; | 4625 | return err; |
@@ -3886,8 +4713,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
3886 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 4713 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
3887 | alc262_ignore)) < 0) | 4714 | alc262_ignore)) < 0) |
3888 | return err; | 4715 | return err; |
3889 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 4716 | if (! spec->autocfg.line_outs) |
3890 | ! spec->autocfg.hp_pin) | ||
3891 | return 0; /* can't find valid BIOS pin config */ | 4717 | return 0; /* can't find valid BIOS pin config */ |
3892 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 4718 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
3893 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 4719 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) |
@@ -3915,13 +4741,11 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
3915 | 4741 | ||
3916 | 4742 | ||
3917 | /* init callback for auto-configuration model -- overriding the default init */ | 4743 | /* init callback for auto-configuration model -- overriding the default init */ |
3918 | static int alc262_auto_init(struct hda_codec *codec) | 4744 | static void alc262_auto_init(struct hda_codec *codec) |
3919 | { | 4745 | { |
3920 | alc_init(codec); | ||
3921 | alc262_auto_init_multi_out(codec); | 4746 | alc262_auto_init_multi_out(codec); |
3922 | alc262_auto_init_hp_out(codec); | 4747 | alc262_auto_init_hp_out(codec); |
3923 | alc262_auto_init_analog_input(codec); | 4748 | alc262_auto_init_analog_input(codec); |
3924 | return 0; | ||
3925 | } | 4749 | } |
3926 | 4750 | ||
3927 | /* | 4751 | /* |
@@ -3929,6 +4753,8 @@ static int alc262_auto_init(struct hda_codec *codec) | |||
3929 | */ | 4753 | */ |
3930 | static struct hda_board_config alc262_cfg_tbl[] = { | 4754 | static struct hda_board_config alc262_cfg_tbl[] = { |
3931 | { .modelname = "basic", .config = ALC262_BASIC }, | 4755 | { .modelname = "basic", .config = ALC262_BASIC }, |
4756 | { .modelname = "fujitsu", .config = ALC262_FUJITSU }, | ||
4757 | { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU }, | ||
3932 | { .modelname = "auto", .config = ALC262_AUTO }, | 4758 | { .modelname = "auto", .config = ALC262_AUTO }, |
3933 | {} | 4759 | {} |
3934 | }; | 4760 | }; |
@@ -3944,6 +4770,18 @@ static struct alc_config_preset alc262_presets[] = { | |||
3944 | .channel_mode = alc262_modes, | 4770 | .channel_mode = alc262_modes, |
3945 | .input_mux = &alc262_capture_source, | 4771 | .input_mux = &alc262_capture_source, |
3946 | }, | 4772 | }, |
4773 | [ALC262_FUJITSU] = { | ||
4774 | .mixers = { alc262_fujitsu_mixer }, | ||
4775 | .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, | ||
4776 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
4777 | .dac_nids = alc262_dac_nids, | ||
4778 | .hp_nid = 0x03, | ||
4779 | .dig_out_nid = ALC262_DIGOUT_NID, | ||
4780 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
4781 | .channel_mode = alc262_modes, | ||
4782 | .input_mux = &alc262_fujitsu_capture_source, | ||
4783 | .unsol_event = alc262_fujitsu_unsol_event, | ||
4784 | }, | ||
3947 | }; | 4785 | }; |
3948 | 4786 | ||
3949 | static int patch_alc262(struct hda_codec *codec) | 4787 | static int patch_alc262(struct hda_codec *codec) |
@@ -4017,8 +4855,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
4017 | 4855 | ||
4018 | codec->patch_ops = alc_patch_ops; | 4856 | codec->patch_ops = alc_patch_ops; |
4019 | if (board_config == ALC262_AUTO) | 4857 | if (board_config == ALC262_AUTO) |
4020 | codec->patch_ops.init = alc262_auto_init; | 4858 | spec->init_hook = alc262_auto_init; |
4021 | 4859 | ||
4022 | return 0; | 4860 | return 0; |
4023 | } | 4861 | } |
4024 | 4862 | ||
@@ -4549,8 +5387,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
4549 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5387 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
4550 | alc861_ignore)) < 0) | 5388 | alc861_ignore)) < 0) |
4551 | return err; | 5389 | return err; |
4552 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 5390 | if (! spec->autocfg.line_outs) |
4553 | ! spec->autocfg.hp_pin) | ||
4554 | return 0; /* can't find valid BIOS pin config */ | 5391 | return 0; /* can't find valid BIOS pin config */ |
4555 | 5392 | ||
4556 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 5393 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || |
@@ -4579,15 +5416,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
4579 | return 1; | 5416 | return 1; |
4580 | } | 5417 | } |
4581 | 5418 | ||
4582 | /* init callback for auto-configuration model -- overriding the default init */ | 5419 | /* additional initialization for auto-configuration model */ |
4583 | static int alc861_auto_init(struct hda_codec *codec) | 5420 | static void alc861_auto_init(struct hda_codec *codec) |
4584 | { | 5421 | { |
4585 | alc_init(codec); | ||
4586 | alc861_auto_init_multi_out(codec); | 5422 | alc861_auto_init_multi_out(codec); |
4587 | alc861_auto_init_hp_out(codec); | 5423 | alc861_auto_init_hp_out(codec); |
4588 | alc861_auto_init_analog_input(codec); | 5424 | alc861_auto_init_analog_input(codec); |
4589 | |||
4590 | return 0; | ||
4591 | } | 5425 | } |
4592 | 5426 | ||
4593 | 5427 | ||
@@ -4685,7 +5519,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
4685 | 5519 | ||
4686 | codec->patch_ops = alc_patch_ops; | 5520 | codec->patch_ops = alc_patch_ops; |
4687 | if (board_config == ALC861_AUTO) | 5521 | if (board_config == ALC861_AUTO) |
4688 | codec->patch_ops.init = alc861_auto_init; | 5522 | spec->init_hook = alc861_auto_init; |
4689 | 5523 | ||
4690 | return 0; | 5524 | return 0; |
4691 | } | 5525 | } |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 35c2823a0a2b..b56ca4019392 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -51,6 +51,7 @@ struct sigmatel_spec { | |||
51 | unsigned int line_switch: 1; | 51 | unsigned int line_switch: 1; |
52 | unsigned int mic_switch: 1; | 52 | unsigned int mic_switch: 1; |
53 | unsigned int alt_switch: 1; | 53 | unsigned int alt_switch: 1; |
54 | unsigned int hp_detect: 1; | ||
54 | 55 | ||
55 | /* playback */ | 56 | /* playback */ |
56 | struct hda_multi_out multiout; | 57 | struct hda_multi_out multiout; |
@@ -303,6 +304,12 @@ static struct hda_board_config stac922x_cfg_tbl[] = { | |||
303 | .pci_subdevice = 0x0101, | 304 | .pci_subdevice = 0x0101, |
304 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ | 305 | .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ |
305 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 306 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
307 | .pci_subdevice = 0x0202, | ||
308 | .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack, 9221 A1 */ | ||
309 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
310 | .pci_subdevice = 0x0b0b, | ||
311 | .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */ | ||
312 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | ||
306 | .pci_subdevice = 0x0404, | 313 | .pci_subdevice = 0x0404, |
307 | .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ | 314 | .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ |
308 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, | 315 | { .pci_subvendor = PCI_VENDOR_ID_INTEL, |
@@ -691,13 +698,7 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut | |||
691 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | 698 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; |
692 | } | 699 | } |
693 | 700 | ||
694 | if (cfg->line_outs) | 701 | spec->multiout.num_dacs = cfg->line_outs; |
695 | spec->multiout.num_dacs = cfg->line_outs; | ||
696 | else if (cfg->hp_pin) { | ||
697 | spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0, | ||
698 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
699 | spec->multiout.num_dacs = 1; | ||
700 | } | ||
701 | 702 | ||
702 | return 0; | 703 | return 0; |
703 | } | 704 | } |
@@ -766,11 +767,13 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin | |||
766 | return 0; | 767 | return 0; |
767 | 768 | ||
768 | wid_caps = get_wcaps(codec, pin); | 769 | wid_caps = get_wcaps(codec, pin); |
769 | if (wid_caps & AC_WCAP_UNSOL_CAP) | 770 | if (wid_caps & AC_WCAP_UNSOL_CAP) { |
770 | /* Enable unsolicited responses on the HP widget */ | 771 | /* Enable unsolicited responses on the HP widget */ |
771 | snd_hda_codec_write(codec, pin, 0, | 772 | snd_hda_codec_write(codec, pin, 0, |
772 | AC_VERB_SET_UNSOLICITED_ENABLE, | 773 | AC_VERB_SET_UNSOLICITED_ENABLE, |
773 | STAC_UNSOL_ENABLE); | 774 | STAC_UNSOL_ENABLE); |
775 | spec->hp_detect = 1; | ||
776 | } | ||
774 | 777 | ||
775 | nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | 778 | nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; |
776 | for (i = 0; i < cfg->line_outs; i++) { | 779 | for (i = 0; i < cfg->line_outs; i++) { |
@@ -804,9 +807,6 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const | |||
804 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 807 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
805 | int index = -1; | 808 | int index = -1; |
806 | if (cfg->input_pins[i]) { | 809 | if (cfg->input_pins[i]) { |
807 | /* Enable active pin widget as an input */ | ||
808 | stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN); | ||
809 | |||
810 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | 810 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; |
811 | 811 | ||
812 | for (j=0; j<spec->num_muxes; j++) { | 812 | for (j=0; j<spec->num_muxes; j++) { |
@@ -855,10 +855,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
855 | 855 | ||
856 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) | 856 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) |
857 | return err; | 857 | return err; |
858 | if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) | 858 | if (! spec->autocfg.line_outs) |
859 | return 0; /* can't find valid pin config */ | 859 | return 0; /* can't find valid pin config */ |
860 | stac92xx_auto_init_multi_out(codec); | ||
861 | stac92xx_auto_init_hp_out(codec); | ||
862 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) | 860 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) |
863 | return err; | 861 | return err; |
864 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | 862 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) |
@@ -873,14 +871,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
873 | if (spec->multiout.max_channels > 2) | 871 | if (spec->multiout.max_channels > 2) |
874 | spec->surr_switch = 1; | 872 | spec->surr_switch = 1; |
875 | 873 | ||
876 | if (spec->autocfg.dig_out_pin) { | 874 | if (spec->autocfg.dig_out_pin) |
877 | spec->multiout.dig_out_nid = dig_out; | 875 | spec->multiout.dig_out_nid = dig_out; |
878 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); | 876 | if (spec->autocfg.dig_in_pin) |
879 | } | ||
880 | if (spec->autocfg.dig_in_pin) { | ||
881 | spec->dig_in_nid = dig_in; | 877 | spec->dig_in_nid = dig_in; |
882 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); | ||
883 | } | ||
884 | 878 | ||
885 | if (spec->kctl_alloc) | 879 | if (spec->kctl_alloc) |
886 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 880 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
@@ -890,6 +884,29 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
890 | return 1; | 884 | return 1; |
891 | } | 885 | } |
892 | 886 | ||
887 | /* add playback controls for HP output */ | ||
888 | static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, | ||
889 | struct auto_pin_cfg *cfg) | ||
890 | { | ||
891 | struct sigmatel_spec *spec = codec->spec; | ||
892 | hda_nid_t pin = cfg->hp_pin; | ||
893 | unsigned int wid_caps; | ||
894 | |||
895 | if (! pin) | ||
896 | return 0; | ||
897 | |||
898 | wid_caps = get_wcaps(codec, pin); | ||
899 | if (wid_caps & AC_WCAP_UNSOL_CAP) { | ||
900 | /* Enable unsolicited responses on the HP widget */ | ||
901 | snd_hda_codec_write(codec, pin, 0, | ||
902 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
903 | STAC_UNSOL_ENABLE); | ||
904 | spec->hp_detect = 1; | ||
905 | } | ||
906 | |||
907 | return 0; | ||
908 | } | ||
909 | |||
893 | static int stac9200_parse_auto_config(struct hda_codec *codec) | 910 | static int stac9200_parse_auto_config(struct hda_codec *codec) |
894 | { | 911 | { |
895 | struct sigmatel_spec *spec = codec->spec; | 912 | struct sigmatel_spec *spec = codec->spec; |
@@ -901,14 +918,13 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
901 | if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) | 918 | if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) |
902 | return err; | 919 | return err; |
903 | 920 | ||
904 | if (spec->autocfg.dig_out_pin) { | 921 | if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) |
922 | return err; | ||
923 | |||
924 | if (spec->autocfg.dig_out_pin) | ||
905 | spec->multiout.dig_out_nid = 0x05; | 925 | spec->multiout.dig_out_nid = 0x05; |
906 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); | 926 | if (spec->autocfg.dig_in_pin) |
907 | } | ||
908 | if (spec->autocfg.dig_in_pin) { | ||
909 | spec->dig_in_nid = 0x04; | 927 | spec->dig_in_nid = 0x04; |
910 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); | ||
911 | } | ||
912 | 928 | ||
913 | if (spec->kctl_alloc) | 929 | if (spec->kctl_alloc) |
914 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 930 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
@@ -921,9 +937,31 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
921 | static int stac92xx_init(struct hda_codec *codec) | 937 | static int stac92xx_init(struct hda_codec *codec) |
922 | { | 938 | { |
923 | struct sigmatel_spec *spec = codec->spec; | 939 | struct sigmatel_spec *spec = codec->spec; |
940 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
941 | int i; | ||
924 | 942 | ||
925 | snd_hda_sequence_write(codec, spec->init); | 943 | snd_hda_sequence_write(codec, spec->init); |
926 | 944 | ||
945 | /* set up pins */ | ||
946 | if (spec->hp_detect) { | ||
947 | /* fake event to set up pins */ | ||
948 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
949 | } else { | ||
950 | stac92xx_auto_init_multi_out(codec); | ||
951 | stac92xx_auto_init_hp_out(codec); | ||
952 | } | ||
953 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
954 | if (cfg->input_pins[i]) | ||
955 | stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], | ||
956 | AC_PINCTL_IN_EN); | ||
957 | } | ||
958 | if (cfg->dig_out_pin) | ||
959 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | ||
960 | AC_PINCTL_OUT_EN); | ||
961 | if (cfg->dig_in_pin) | ||
962 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | ||
963 | AC_PINCTL_IN_EN); | ||
964 | |||
927 | return 0; | 965 | return 0; |
928 | } | 966 | } |
929 | 967 | ||
@@ -1142,6 +1180,166 @@ static int patch_stac927x(struct hda_codec *codec) | |||
1142 | } | 1180 | } |
1143 | 1181 | ||
1144 | /* | 1182 | /* |
1183 | * STAC 7661(?) hack | ||
1184 | */ | ||
1185 | |||
1186 | /* static config for Sony VAIO FE550G */ | ||
1187 | static hda_nid_t vaio_dacs[] = { 0x2 }; | ||
1188 | #define VAIO_HP_DAC 0x5 | ||
1189 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | ||
1190 | static hda_nid_t vaio_mux_nids[] = { 0x15 }; | ||
1191 | |||
1192 | static struct hda_input_mux vaio_mux = { | ||
1193 | .num_items = 2, | ||
1194 | .items = { | ||
1195 | /* { "HP", 0x0 }, | ||
1196 | { "Unknown", 0x1 }, */ | ||
1197 | { "Mic", 0x2 }, | ||
1198 | { "PCM", 0x3 }, | ||
1199 | } | ||
1200 | }; | ||
1201 | |||
1202 | static struct hda_verb vaio_init[] = { | ||
1203 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
1204 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
1205 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
1206 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
1207 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
1208 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ | ||
1209 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
1210 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
1211 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
1212 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
1213 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
1214 | {} | ||
1215 | }; | ||
1216 | |||
1217 | /* bind volumes of both NID 0x02 and 0x05 */ | ||
1218 | static int vaio_master_vol_put(struct snd_kcontrol *kcontrol, | ||
1219 | struct snd_ctl_elem_value *ucontrol) | ||
1220 | { | ||
1221 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1222 | long *valp = ucontrol->value.integer.value; | ||
1223 | int change; | ||
1224 | |||
1225 | change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, | ||
1226 | 0x7f, valp[0] & 0x7f); | ||
1227 | change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, | ||
1228 | 0x7f, valp[1] & 0x7f); | ||
1229 | snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1230 | 0x7f, valp[0] & 0x7f); | ||
1231 | snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1232 | 0x7f, valp[1] & 0x7f); | ||
1233 | return change; | ||
1234 | } | ||
1235 | |||
1236 | /* bind volumes of both NID 0x02 and 0x05 */ | ||
1237 | static int vaio_master_sw_put(struct snd_kcontrol *kcontrol, | ||
1238 | struct snd_ctl_elem_value *ucontrol) | ||
1239 | { | ||
1240 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1241 | long *valp = ucontrol->value.integer.value; | ||
1242 | int change; | ||
1243 | |||
1244 | change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0, | ||
1245 | 0x80, valp[0] & 0x80); | ||
1246 | change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0, | ||
1247 | 0x80, valp[1] & 0x80); | ||
1248 | snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0, | ||
1249 | 0x80, valp[0] & 0x80); | ||
1250 | snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0, | ||
1251 | 0x80, valp[1] & 0x80); | ||
1252 | return change; | ||
1253 | } | ||
1254 | |||
1255 | static struct snd_kcontrol_new vaio_mixer[] = { | ||
1256 | { | ||
1257 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1258 | .name = "Master Playback Volume", | ||
1259 | .info = snd_hda_mixer_amp_volume_info, | ||
1260 | .get = snd_hda_mixer_amp_volume_get, | ||
1261 | .put = vaio_master_vol_put, | ||
1262 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1263 | }, | ||
1264 | { | ||
1265 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1266 | .name = "Master Playback Switch", | ||
1267 | .info = snd_hda_mixer_amp_switch_info, | ||
1268 | .get = snd_hda_mixer_amp_switch_get, | ||
1269 | .put = vaio_master_sw_put, | ||
1270 | .private_value = HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
1271 | }, | ||
1272 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
1273 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
1274 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
1275 | { | ||
1276 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1277 | .name = "Capture Source", | ||
1278 | .count = 1, | ||
1279 | .info = stac92xx_mux_enum_info, | ||
1280 | .get = stac92xx_mux_enum_get, | ||
1281 | .put = stac92xx_mux_enum_put, | ||
1282 | }, | ||
1283 | {} | ||
1284 | }; | ||
1285 | |||
1286 | static struct hda_codec_ops stac7661_patch_ops = { | ||
1287 | .build_controls = stac92xx_build_controls, | ||
1288 | .build_pcms = stac92xx_build_pcms, | ||
1289 | .init = stac92xx_init, | ||
1290 | .free = stac92xx_free, | ||
1291 | #ifdef CONFIG_PM | ||
1292 | .resume = stac92xx_resume, | ||
1293 | #endif | ||
1294 | }; | ||
1295 | |||
1296 | enum { STAC7661_VAIO }; | ||
1297 | |||
1298 | static struct hda_board_config stac7661_cfg_tbl[] = { | ||
1299 | { .modelname = "vaio", .config = STAC7661_VAIO }, | ||
1300 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, | ||
1301 | .config = STAC7661_VAIO }, | ||
1302 | { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, | ||
1303 | .config = STAC7661_VAIO }, | ||
1304 | {} | ||
1305 | }; | ||
1306 | |||
1307 | static int patch_stac7661(struct hda_codec *codec) | ||
1308 | { | ||
1309 | struct sigmatel_spec *spec; | ||
1310 | int board_config; | ||
1311 | |||
1312 | board_config = snd_hda_check_board_config(codec, stac7661_cfg_tbl); | ||
1313 | if (board_config < 0) | ||
1314 | /* unknown config, let generic-parser do its job... */ | ||
1315 | return snd_hda_parse_generic_codec(codec); | ||
1316 | |||
1317 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1318 | if (spec == NULL) | ||
1319 | return -ENOMEM; | ||
1320 | |||
1321 | codec->spec = spec; | ||
1322 | switch (board_config) { | ||
1323 | case STAC7661_VAIO: | ||
1324 | spec->mixer = vaio_mixer; | ||
1325 | spec->init = vaio_init; | ||
1326 | spec->multiout.max_channels = 2; | ||
1327 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
1328 | spec->multiout.dac_nids = vaio_dacs; | ||
1329 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
1330 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
1331 | spec->adc_nids = vaio_adcs; | ||
1332 | spec->input_mux = &vaio_mux; | ||
1333 | spec->mux_nids = vaio_mux_nids; | ||
1334 | break; | ||
1335 | } | ||
1336 | |||
1337 | codec->patch_ops = stac7661_patch_ops; | ||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | /* | ||
1145 | * patch entries | 1343 | * patch entries |
1146 | */ | 1344 | */ |
1147 | struct hda_codec_preset snd_hda_preset_sigmatel[] = { | 1345 | struct hda_codec_preset snd_hda_preset_sigmatel[] = { |
@@ -1162,5 +1360,6 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
1162 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, | 1360 | { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, |
1163 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, | 1361 | { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, |
1164 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, | 1362 | { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, |
1363 | { .id = 0x83847661, .name = "STAC7661", .patch = patch_stac7661 }, | ||
1165 | {} /* terminator */ | 1364 | {} /* terminator */ |
1166 | }; | 1365 | }; |
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 8809812a1c22..7e6608b14abc 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c | |||
@@ -53,6 +53,8 @@ | |||
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
56 | #include <linux/mutex.h> | ||
57 | |||
56 | #include <sound/core.h> | 58 | #include <sound/core.h> |
57 | 59 | ||
58 | #include "ice1712.h" | 60 | #include "ice1712.h" |
@@ -210,14 +212,14 @@ static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
210 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 212 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
211 | unsigned short vol; | 213 | unsigned short vol; |
212 | 214 | ||
213 | down(&ice->gpio_mutex); | 215 | mutex_lock(&ice->gpio_mutex); |
214 | 216 | ||
215 | vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); | 217 | vol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); |
216 | ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F); | 218 | ucontrol->value.integer.value[0] = 0x1F - (vol & 0x1F); |
217 | if (kcontrol->private_value & AUREON_AC97_STEREO) | 219 | if (kcontrol->private_value & AUREON_AC97_STEREO) |
218 | ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F); | 220 | ucontrol->value.integer.value[1] = 0x1F - ((vol >> 8) & 0x1F); |
219 | 221 | ||
220 | up(&ice->gpio_mutex); | 222 | mutex_unlock(&ice->gpio_mutex); |
221 | return 0; | 223 | return 0; |
222 | } | 224 | } |
223 | 225 | ||
@@ -252,11 +254,11 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
252 | { | 254 | { |
253 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 255 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
254 | 256 | ||
255 | down(&ice->gpio_mutex); | 257 | mutex_lock(&ice->gpio_mutex); |
256 | 258 | ||
257 | ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; | 259 | ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; |
258 | 260 | ||
259 | up(&ice->gpio_mutex); | 261 | mutex_unlock(&ice->gpio_mutex); |
260 | return 0; | 262 | return 0; |
261 | } | 263 | } |
262 | 264 | ||
@@ -288,11 +290,11 @@ static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ct | |||
288 | { | 290 | { |
289 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 291 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
290 | 292 | ||
291 | down(&ice->gpio_mutex); | 293 | mutex_lock(&ice->gpio_mutex); |
292 | 294 | ||
293 | ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1; | 295 | ucontrol->value.integer.value[0] = aureon_ac97_read(ice, AC97_MIC) & 0x0020 ? 0 : 1; |
294 | 296 | ||
295 | up(&ice->gpio_mutex); | 297 | mutex_unlock(&ice->gpio_mutex); |
296 | return 0; | 298 | return 0; |
297 | } | 299 | } |
298 | 300 | ||
@@ -322,36 +324,48 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned | |||
322 | { | 324 | { |
323 | unsigned int tmp; | 325 | unsigned int tmp; |
324 | int i; | 326 | int i; |
327 | unsigned int mosi, clk; | ||
325 | 328 | ||
326 | tmp = snd_ice1712_gpio_read(ice); | 329 | tmp = snd_ice1712_gpio_read(ice); |
327 | 330 | ||
328 | snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| | 331 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) { |
329 | AUREON_WM_CS|AUREON_CS8415_CS)); | 332 | snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); |
330 | tmp |= AUREON_WM_RW; | 333 | mosi = PRODIGY_SPI_MOSI; |
334 | clk = PRODIGY_SPI_CLK; | ||
335 | } | ||
336 | else { | ||
337 | snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| | ||
338 | AUREON_WM_CS|AUREON_CS8415_CS)); | ||
339 | mosi = AUREON_SPI_MOSI; | ||
340 | clk = AUREON_SPI_CLK; | ||
341 | |||
342 | tmp |= AUREON_WM_RW; | ||
343 | } | ||
344 | |||
331 | tmp &= ~cs; | 345 | tmp &= ~cs; |
332 | snd_ice1712_gpio_write(ice, tmp); | 346 | snd_ice1712_gpio_write(ice, tmp); |
333 | udelay(1); | 347 | udelay(1); |
334 | 348 | ||
335 | for (i = bits - 1; i >= 0; i--) { | 349 | for (i = bits - 1; i >= 0; i--) { |
336 | tmp &= ~AUREON_SPI_CLK; | 350 | tmp &= ~clk; |
337 | snd_ice1712_gpio_write(ice, tmp); | 351 | snd_ice1712_gpio_write(ice, tmp); |
338 | udelay(1); | 352 | udelay(1); |
339 | if (data & (1 << i)) | 353 | if (data & (1 << i)) |
340 | tmp |= AUREON_SPI_MOSI; | 354 | tmp |= mosi; |
341 | else | 355 | else |
342 | tmp &= ~AUREON_SPI_MOSI; | 356 | tmp &= ~mosi; |
343 | snd_ice1712_gpio_write(ice, tmp); | 357 | snd_ice1712_gpio_write(ice, tmp); |
344 | udelay(1); | 358 | udelay(1); |
345 | tmp |= AUREON_SPI_CLK; | 359 | tmp |= clk; |
346 | snd_ice1712_gpio_write(ice, tmp); | 360 | snd_ice1712_gpio_write(ice, tmp); |
347 | udelay(1); | 361 | udelay(1); |
348 | } | 362 | } |
349 | 363 | ||
350 | tmp &= ~AUREON_SPI_CLK; | 364 | tmp &= ~clk; |
351 | tmp |= cs; | 365 | tmp |= cs; |
352 | snd_ice1712_gpio_write(ice, tmp); | 366 | snd_ice1712_gpio_write(ice, tmp); |
353 | udelay(1); | 367 | udelay(1); |
354 | tmp |= AUREON_SPI_CLK; | 368 | tmp |= clk; |
355 | snd_ice1712_gpio_write(ice, tmp); | 369 | snd_ice1712_gpio_write(ice, tmp); |
356 | udelay(1); | 370 | udelay(1); |
357 | } | 371 | } |
@@ -440,7 +454,9 @@ static unsigned short wm_get(struct snd_ice1712 *ice, int reg) | |||
440 | */ | 454 | */ |
441 | static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) | 455 | static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) |
442 | { | 456 | { |
443 | aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16); | 457 | aureon_spi_write(ice, |
458 | (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS), | ||
459 | (reg << 9) | (val & 0x1ff), 16); | ||
444 | } | 460 | } |
445 | 461 | ||
446 | /* | 462 | /* |
@@ -474,11 +490,11 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
474 | { | 490 | { |
475 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 491 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
476 | 492 | ||
477 | down(&ice->gpio_mutex); | 493 | mutex_lock(&ice->gpio_mutex); |
478 | 494 | ||
479 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01; | 495 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX1) >> 1) & 0x01; |
480 | 496 | ||
481 | up(&ice->gpio_mutex); | 497 | mutex_unlock(&ice->gpio_mutex); |
482 | return 0; | 498 | return 0; |
483 | } | 499 | } |
484 | 500 | ||
@@ -543,9 +559,9 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
543 | { | 559 | { |
544 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 560 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
545 | 561 | ||
546 | down(&ice->gpio_mutex); | 562 | mutex_lock(&ice->gpio_mutex); |
547 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; | 563 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; |
548 | up(&ice->gpio_mutex); | 564 | mutex_unlock(&ice->gpio_mutex); |
549 | return 0; | 565 | return 0; |
550 | } | 566 | } |
551 | 567 | ||
@@ -768,11 +784,11 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
768 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 784 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
769 | unsigned short val; | 785 | unsigned short val; |
770 | 786 | ||
771 | down(&ice->gpio_mutex); | 787 | mutex_lock(&ice->gpio_mutex); |
772 | val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; | 788 | val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; |
773 | val = val > PCM_MIN ? (val - PCM_MIN) : 0; | 789 | val = val > PCM_MIN ? (val - PCM_MIN) : 0; |
774 | ucontrol->value.integer.value[0] = val; | 790 | ucontrol->value.integer.value[0] = val; |
775 | up(&ice->gpio_mutex); | 791 | mutex_unlock(&ice->gpio_mutex); |
776 | return 0; | 792 | return 0; |
777 | } | 793 | } |
778 | 794 | ||
@@ -813,12 +829,12 @@ static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
813 | unsigned short val; | 829 | unsigned short val; |
814 | int i; | 830 | int i; |
815 | 831 | ||
816 | down(&ice->gpio_mutex); | 832 | mutex_lock(&ice->gpio_mutex); |
817 | for (i = 0; i < 2; i++) { | 833 | for (i = 0; i < 2; i++) { |
818 | val = wm_get(ice, WM_ADC_GAIN + i); | 834 | val = wm_get(ice, WM_ADC_GAIN + i); |
819 | ucontrol->value.integer.value[i] = ~val>>5 & 0x1; | 835 | ucontrol->value.integer.value[i] = ~val>>5 & 0x1; |
820 | } | 836 | } |
821 | up(&ice->gpio_mutex); | 837 | mutex_unlock(&ice->gpio_mutex); |
822 | return 0; | 838 | return 0; |
823 | } | 839 | } |
824 | 840 | ||
@@ -860,13 +876,13 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
860 | int i, idx; | 876 | int i, idx; |
861 | unsigned short vol; | 877 | unsigned short vol; |
862 | 878 | ||
863 | down(&ice->gpio_mutex); | 879 | mutex_lock(&ice->gpio_mutex); |
864 | for (i = 0; i < 2; i++) { | 880 | for (i = 0; i < 2; i++) { |
865 | idx = WM_ADC_GAIN + i; | 881 | idx = WM_ADC_GAIN + i; |
866 | vol = wm_get(ice, idx) & 0x1f; | 882 | vol = wm_get(ice, idx) & 0x1f; |
867 | ucontrol->value.integer.value[i] = vol; | 883 | ucontrol->value.integer.value[i] = vol; |
868 | } | 884 | } |
869 | up(&ice->gpio_mutex); | 885 | mutex_unlock(&ice->gpio_mutex); |
870 | return 0; | 886 | return 0; |
871 | } | 887 | } |
872 | 888 | ||
@@ -937,11 +953,11 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
937 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 953 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
938 | unsigned short val; | 954 | unsigned short val; |
939 | 955 | ||
940 | down(&ice->gpio_mutex); | 956 | mutex_lock(&ice->gpio_mutex); |
941 | val = wm_get(ice, WM_ADC_MUX); | 957 | val = wm_get(ice, WM_ADC_MUX); |
942 | ucontrol->value.integer.value[0] = val & 7; | 958 | ucontrol->value.enumerated.item[0] = val & 7; |
943 | ucontrol->value.integer.value[1] = (val >> 4) & 7; | 959 | ucontrol->value.enumerated.item[1] = (val >> 4) & 7; |
944 | up(&ice->gpio_mutex); | 960 | mutex_unlock(&ice->gpio_mutex); |
945 | return 0; | 961 | return 0; |
946 | } | 962 | } |
947 | 963 | ||
@@ -954,8 +970,8 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
954 | snd_ice1712_save_gpio_status(ice); | 970 | snd_ice1712_save_gpio_status(ice); |
955 | oval = wm_get(ice, WM_ADC_MUX); | 971 | oval = wm_get(ice, WM_ADC_MUX); |
956 | nval = oval & ~0x77; | 972 | nval = oval & ~0x77; |
957 | nval |= ucontrol->value.integer.value[0] & 7; | 973 | nval |= ucontrol->value.enumerated.item[0] & 7; |
958 | nval |= (ucontrol->value.integer.value[1] & 7) << 4; | 974 | nval |= (ucontrol->value.enumerated.item[1] & 7) << 4; |
959 | change = (oval != nval); | 975 | change = (oval != nval); |
960 | if (change) | 976 | if (change) |
961 | wm_put(ice, WM_ADC_MUX, nval); | 977 | wm_put(ice, WM_ADC_MUX, nval); |
@@ -995,7 +1011,7 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
995 | 1011 | ||
996 | //snd_ice1712_save_gpio_status(ice); | 1012 | //snd_ice1712_save_gpio_status(ice); |
997 | //val = aureon_cs8415_get(ice, CS8415_CTRL2); | 1013 | //val = aureon_cs8415_get(ice, CS8415_CTRL2); |
998 | ucontrol->value.integer.value[0] = ice->spec.aureon.cs8415_mux; | 1014 | ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux; |
999 | //snd_ice1712_restore_gpio_status(ice); | 1015 | //snd_ice1712_restore_gpio_status(ice); |
1000 | return 0; | 1016 | return 0; |
1001 | } | 1017 | } |
@@ -1009,12 +1025,12 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1009 | snd_ice1712_save_gpio_status(ice); | 1025 | snd_ice1712_save_gpio_status(ice); |
1010 | oval = aureon_cs8415_get(ice, CS8415_CTRL2); | 1026 | oval = aureon_cs8415_get(ice, CS8415_CTRL2); |
1011 | nval = oval & ~0x07; | 1027 | nval = oval & ~0x07; |
1012 | nval |= ucontrol->value.integer.value[0] & 7; | 1028 | nval |= ucontrol->value.enumerated.item[0] & 7; |
1013 | change = (oval != nval); | 1029 | change = (oval != nval); |
1014 | if (change) | 1030 | if (change) |
1015 | aureon_cs8415_put(ice, CS8415_CTRL2, nval); | 1031 | aureon_cs8415_put(ice, CS8415_CTRL2, nval); |
1016 | snd_ice1712_restore_gpio_status(ice); | 1032 | snd_ice1712_restore_gpio_status(ice); |
1017 | ice->spec.aureon.cs8415_mux = ucontrol->value.integer.value[0]; | 1033 | ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0]; |
1018 | return change; | 1034 | return change; |
1019 | } | 1035 | } |
1020 | 1036 | ||
@@ -1659,7 +1675,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) | |||
1659 | return err; | 1675 | return err; |
1660 | } | 1676 | } |
1661 | } | 1677 | } |
1662 | else { | 1678 | else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { |
1663 | for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { | 1679 | for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { |
1664 | err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); | 1680 | err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); |
1665 | if (err < 0) | 1681 | if (err < 0) |
@@ -1667,7 +1683,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) | |||
1667 | } | 1683 | } |
1668 | } | 1684 | } |
1669 | 1685 | ||
1670 | { | 1686 | if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { |
1671 | unsigned char id; | 1687 | unsigned char id; |
1672 | snd_ice1712_save_gpio_status(ice); | 1688 | snd_ice1712_save_gpio_status(ice); |
1673 | id = aureon_cs8415_get(ice, CS8415_ID); | 1689 | id = aureon_cs8415_get(ice, CS8415_ID); |
@@ -1822,7 +1838,8 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
1822 | udelay(1); | 1838 | udelay(1); |
1823 | 1839 | ||
1824 | /* initialize WM8770 codec */ | 1840 | /* initialize WM8770 codec */ |
1825 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71) | 1841 | if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || |
1842 | ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) | ||
1826 | p = wm_inits_prodigy; | 1843 | p = wm_inits_prodigy; |
1827 | else | 1844 | else |
1828 | p = wm_inits_aureon; | 1845 | p = wm_inits_aureon; |
@@ -1830,11 +1847,13 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) | |||
1830 | wm_put(ice, p[0], p[1]); | 1847 | wm_put(ice, p[0], p[1]); |
1831 | 1848 | ||
1832 | /* initialize CS8415A codec */ | 1849 | /* initialize CS8415A codec */ |
1833 | for (p = cs_inits; *p != (unsigned short)-1; p++) | 1850 | if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { |
1834 | aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); | 1851 | for (p = cs_inits; *p != (unsigned short)-1; p++) |
1835 | ice->spec.aureon.cs8415_mux = 1; | 1852 | aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); |
1853 | ice->spec.aureon.cs8415_mux = 1; | ||
1836 | 1854 | ||
1837 | aureon_set_headphone_amp(ice, 1); | 1855 | aureon_set_headphone_amp(ice, 1); |
1856 | } | ||
1838 | 1857 | ||
1839 | snd_ice1712_restore_gpio_status(ice); | 1858 | snd_ice1712_restore_gpio_status(ice); |
1840 | 1859 | ||
@@ -1902,6 +1921,23 @@ static unsigned char prodigy71_eeprom[] __devinitdata = { | |||
1902 | 0x00, /* GPIO_STATE2 */ | 1921 | 0x00, /* GPIO_STATE2 */ |
1903 | }; | 1922 | }; |
1904 | 1923 | ||
1924 | static unsigned char prodigy71lt_eeprom[] __devinitdata = { | ||
1925 | 0x0b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */ | ||
1926 | 0x80, /* ACLINK: I2S */ | ||
1927 | 0xfc, /* I2S: vol, 96k, 24bit, 192k */ | ||
1928 | 0xc3, /* SPDUF: out-en, out-int */ | ||
1929 | 0x00, /* GPIO_DIR */ | ||
1930 | 0x07, /* GPIO_DIR1 */ | ||
1931 | 0x00, /* GPIO_DIR2 */ | ||
1932 | 0xff, /* GPIO_MASK */ | ||
1933 | 0xf8, /* GPIO_MASK1 */ | ||
1934 | 0xff, /* GPIO_MASK2 */ | ||
1935 | 0x00, /* GPIO_STATE */ | ||
1936 | 0x00, /* GPIO_STATE1 */ | ||
1937 | 0x00, /* GPIO_STATE2 */ | ||
1938 | }; | ||
1939 | |||
1940 | |||
1905 | /* entry point */ | 1941 | /* entry point */ |
1906 | struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { | 1942 | struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { |
1907 | { | 1943 | { |
@@ -1944,5 +1980,15 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { | |||
1944 | .eeprom_data = prodigy71_eeprom, | 1980 | .eeprom_data = prodigy71_eeprom, |
1945 | .driver = "Prodigy71", /* should be identical with Aureon71 */ | 1981 | .driver = "Prodigy71", /* should be identical with Aureon71 */ |
1946 | }, | 1982 | }, |
1983 | { | ||
1984 | .subvendor = VT1724_SUBDEVICE_PRODIGY71LT, | ||
1985 | .name = "Audiotrak Prodigy 7.1 LT", | ||
1986 | .model = "prodigy71lt", | ||
1987 | .chip_init = aureon_init, | ||
1988 | .build_controls = aureon_add_controls, | ||
1989 | .eeprom_size = sizeof(prodigy71lt_eeprom), | ||
1990 | .eeprom_data = prodigy71lt_eeprom, | ||
1991 | .driver = "Prodigy71LT", | ||
1992 | }, | ||
1947 | { } /* terminator */ | 1993 | { } /* terminator */ |
1948 | }; | 1994 | }; |
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h index 95d515f36f23..98a6752280f2 100644 --- a/sound/pci/ice1712/aureon.h +++ b/sound/pci/ice1712/aureon.h | |||
@@ -27,12 +27,14 @@ | |||
27 | #define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\ | 27 | #define AUREON_DEVICE_DESC "{Terratec,Aureon 5.1 Sky},"\ |
28 | "{Terratec,Aureon 7.1 Space},"\ | 28 | "{Terratec,Aureon 7.1 Space},"\ |
29 | "{Terratec,Aureon 7.1 Universe}," \ | 29 | "{Terratec,Aureon 7.1 Universe}," \ |
30 | "{AudioTrak,Prodigy 7.1}," | 30 | "{AudioTrak,Prodigy 7.1}," \ |
31 | "{AudioTrak,Prodigy 7.1 LT}," | ||
31 | 32 | ||
32 | #define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ | 33 | #define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ |
33 | #define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ | 34 | #define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ |
34 | #define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ | 35 | #define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ |
35 | #define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ | 36 | #define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ |
37 | #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ | ||
36 | 38 | ||
37 | extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; | 39 | extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; |
38 | 40 | ||
@@ -53,4 +55,8 @@ extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; | |||
53 | #define AUREON_AC97_DATA_HIGH (1 << 8) | 55 | #define AUREON_AC97_DATA_HIGH (1 << 8) |
54 | #define AUREON_AC97_DATA_MASK 0xFF | 56 | #define AUREON_AC97_DATA_MASK 0xFF |
55 | 57 | ||
58 | #define PRODIGY_WM_CS (1 << 8) | ||
59 | #define PRODIGY_SPI_MOSI (1 << 10) | ||
60 | #define PRODIGY_SPI_CLK (1 << 9) | ||
61 | |||
56 | #endif /* __SOUND_AUREON_H */ | 62 | #endif /* __SOUND_AUREON_H */ |
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 9a51d34e6817..af659800c9b0 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/mutex.h> | ||
32 | |||
31 | #include <sound/core.h> | 33 | #include <sound/core.h> |
32 | #include <sound/cs8427.h> | 34 | #include <sound/cs8427.h> |
33 | #include <sound/asoundef.h> | 35 | #include <sound/asoundef.h> |
@@ -130,13 +132,13 @@ static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *byt | |||
130 | int res = count; | 132 | int res = count; |
131 | unsigned char tmp; | 133 | unsigned char tmp; |
132 | 134 | ||
133 | down(&ice->gpio_mutex); | 135 | mutex_lock(&ice->gpio_mutex); |
134 | tmp = ap_cs8427_codec_select(ice); | 136 | tmp = ap_cs8427_codec_select(ice); |
135 | ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ | 137 | ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */ |
136 | while (count-- > 0) | 138 | while (count-- > 0) |
137 | ap_cs8427_write_byte(ice, *bytes++, tmp); | 139 | ap_cs8427_write_byte(ice, *bytes++, tmp); |
138 | ap_cs8427_codec_deassert(ice, tmp); | 140 | ap_cs8427_codec_deassert(ice, tmp); |
139 | up(&ice->gpio_mutex); | 141 | mutex_unlock(&ice->gpio_mutex); |
140 | return res; | 142 | return res; |
141 | } | 143 | } |
142 | 144 | ||
@@ -147,13 +149,13 @@ static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *byt | |||
147 | int res = count; | 149 | int res = count; |
148 | unsigned char tmp; | 150 | unsigned char tmp; |
149 | 151 | ||
150 | down(&ice->gpio_mutex); | 152 | mutex_lock(&ice->gpio_mutex); |
151 | tmp = ap_cs8427_codec_select(ice); | 153 | tmp = ap_cs8427_codec_select(ice); |
152 | ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ | 154 | ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */ |
153 | while (count-- > 0) | 155 | while (count-- > 0) |
154 | *bytes++ = ap_cs8427_read_byte(ice, tmp); | 156 | *bytes++ = ap_cs8427_read_byte(ice, tmp); |
155 | ap_cs8427_codec_deassert(ice, tmp); | 157 | ap_cs8427_codec_deassert(ice, tmp); |
156 | up(&ice->gpio_mutex); | 158 | mutex_unlock(&ice->gpio_mutex); |
157 | return res; | 159 | return res; |
158 | } | 160 | } |
159 | 161 | ||
@@ -180,7 +182,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign | |||
180 | /* send byte to transmitter */ | 182 | /* send byte to transmitter */ |
181 | mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; | 183 | mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK; |
182 | mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; | 184 | mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA; |
183 | down(&ice->gpio_mutex); | 185 | mutex_lock(&ice->gpio_mutex); |
184 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 186 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
185 | for (idx = 7; idx >= 0; idx--) { | 187 | for (idx = 7; idx >= 0; idx--) { |
186 | tmp &= ~(mask1 | mask2); | 188 | tmp &= ~(mask1 | mask2); |
@@ -194,7 +196,7 @@ static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsign | |||
194 | } | 196 | } |
195 | tmp &= ~mask1; | 197 | tmp &= ~mask1; |
196 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); | 198 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); |
197 | up(&ice->gpio_mutex); | 199 | mutex_unlock(&ice->gpio_mutex); |
198 | } | 200 | } |
199 | 201 | ||
200 | 202 | ||
@@ -296,14 +298,14 @@ static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate) | |||
296 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ | 298 | if (rate == 0) /* no hint - S/PDIF input is master, simply return */ |
297 | return; | 299 | return; |
298 | 300 | ||
299 | down(&ice->gpio_mutex); | 301 | mutex_lock(&ice->gpio_mutex); |
300 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 302 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
301 | tmp2 = tmp & ~ICE1712_DELTA_DFS; | 303 | tmp2 = tmp & ~ICE1712_DELTA_DFS; |
302 | if (rate > 48000) | 304 | if (rate > 48000) |
303 | tmp2 |= ICE1712_DELTA_DFS; | 305 | tmp2 |= ICE1712_DELTA_DFS; |
304 | if (tmp != tmp2) | 306 | if (tmp != tmp2) |
305 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); | 307 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp2); |
306 | up(&ice->gpio_mutex); | 308 | mutex_unlock(&ice->gpio_mutex); |
307 | } | 309 | } |
308 | 310 | ||
309 | /* | 311 | /* |
@@ -318,9 +320,9 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
318 | return; | 320 | return; |
319 | 321 | ||
320 | /* check before reset ak4524 to avoid unnecessary clicks */ | 322 | /* check before reset ak4524 to avoid unnecessary clicks */ |
321 | down(&ice->gpio_mutex); | 323 | mutex_lock(&ice->gpio_mutex); |
322 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); | 324 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA); |
323 | up(&ice->gpio_mutex); | 325 | mutex_unlock(&ice->gpio_mutex); |
324 | tmp2 = tmp & ~ICE1712_DELTA_DFS; | 326 | tmp2 = tmp & ~ICE1712_DELTA_DFS; |
325 | if (rate > 48000) | 327 | if (rate > 48000) |
326 | tmp2 |= ICE1712_DELTA_DFS; | 328 | tmp2 |= ICE1712_DELTA_DFS; |
@@ -329,12 +331,12 @@ static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) | |||
329 | 331 | ||
330 | /* do it again */ | 332 | /* do it again */ |
331 | snd_akm4xxx_reset(ak, 1); | 333 | snd_akm4xxx_reset(ak, 1); |
332 | down(&ice->gpio_mutex); | 334 | mutex_lock(&ice->gpio_mutex); |
333 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; | 335 | tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ~ICE1712_DELTA_DFS; |
334 | if (rate > 48000) | 336 | if (rate > 48000) |
335 | tmp |= ICE1712_DELTA_DFS; | 337 | tmp |= ICE1712_DELTA_DFS; |
336 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); | 338 | snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp); |
337 | up(&ice->gpio_mutex); | 339 | mutex_unlock(&ice->gpio_mutex); |
338 | snd_akm4xxx_reset(ak, 0); | 340 | snd_akm4xxx_reset(ak, 0); |
339 | } | 341 | } |
340 | 342 | ||
@@ -391,6 +393,37 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) | |||
391 | snd_ice1712_delta_cs8403_spdif_write(ice, tmp); | 393 | snd_ice1712_delta_cs8403_spdif_write(ice, tmp); |
392 | } | 394 | } |
393 | 395 | ||
396 | static int snd_ice1712_delta1010lt_wordclock_status_info(struct snd_kcontrol *kcontrol, | ||
397 | struct snd_ctl_elem_info *uinfo) | ||
398 | { | ||
399 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
400 | uinfo->count = 1; | ||
401 | uinfo->value.integer.min = 0; | ||
402 | uinfo->value.integer.max = 1; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, | ||
407 | struct snd_ctl_elem_value *ucontrol) | ||
408 | { | ||
409 | char reg = 0x10; // cs8427 receiver error register | ||
410 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | ||
411 | |||
412 | if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) | ||
413 | snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); | ||
414 | snd_i2c_readbytes(ice->cs8427, ®, 1); | ||
415 | ucontrol->value.integer.value[0] = (reg ? 1 : 0); | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = | ||
420 | { | ||
421 | .access = (SNDRV_CTL_ELEM_ACCESS_READ), | ||
422 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
423 | .name = "Word Clock Status", | ||
424 | .info = snd_ice1712_delta1010lt_wordclock_status_info, | ||
425 | .get = snd_ice1712_delta1010lt_wordclock_status_get, | ||
426 | }; | ||
394 | 427 | ||
395 | /* | 428 | /* |
396 | * initialize the chips on M-Audio cards | 429 | * initialize the chips on M-Audio cards |
@@ -620,7 +653,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) | |||
620 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = | 653 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = |
621 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); | 654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); |
622 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = | 655 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = |
623 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0); | 656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); |
624 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = | 657 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = |
625 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); | 658 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); |
626 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = | 659 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = |
@@ -653,6 +686,9 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) | |||
653 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); | 686 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_select, ice)); |
654 | if (err < 0) | 687 | if (err < 0) |
655 | return err; | 688 | return err; |
689 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010lt_wordclock_status, ice)); | ||
690 | if (err < 0) | ||
691 | return err; | ||
656 | break; | 692 | break; |
657 | } | 693 | } |
658 | 694 | ||
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 3f2f918536f5..3f27d04e7d3c 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | 33 | ||
32 | #include "ice1712.h" | 34 | #include "ice1712.h" |
@@ -48,31 +50,31 @@ static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, un | |||
48 | 50 | ||
49 | static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) | 51 | static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) |
50 | { | 52 | { |
51 | down(&ice->gpio_mutex); | 53 | mutex_lock(&ice->gpio_mutex); |
52 | ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate); | 54 | ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate); |
53 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); | 55 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); |
54 | up(&ice->gpio_mutex); | 56 | mutex_unlock(&ice->gpio_mutex); |
55 | } | 57 | } |
56 | 58 | ||
57 | static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) | 59 | static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) |
58 | { | 60 | { |
59 | down(&ice->gpio_mutex); | 61 | mutex_lock(&ice->gpio_mutex); |
60 | ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate); | 62 | ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate); |
61 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); | 63 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); |
62 | up(&ice->gpio_mutex); | 64 | mutex_unlock(&ice->gpio_mutex); |
63 | } | 65 | } |
64 | 66 | ||
65 | static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) | 67 | static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) |
66 | { | 68 | { |
67 | down(&ice->gpio_mutex); | 69 | mutex_lock(&ice->gpio_mutex); |
68 | ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate); | 70 | ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate); |
69 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); | 71 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); |
70 | up(&ice->gpio_mutex); | 72 | mutex_unlock(&ice->gpio_mutex); |
71 | } | 73 | } |
72 | 74 | ||
73 | static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) | 75 | static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) |
74 | { | 76 | { |
75 | down(&ice->gpio_mutex); | 77 | mutex_lock(&ice->gpio_mutex); |
76 | 78 | ||
77 | /* select box */ | 79 | /* select box */ |
78 | ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); | 80 | ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); |
@@ -115,12 +117,12 @@ static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, i | |||
115 | ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0); | 117 | ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0); |
116 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); | 118 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); |
117 | 119 | ||
118 | up(&ice->gpio_mutex); | 120 | mutex_unlock(&ice->gpio_mutex); |
119 | } | 121 | } |
120 | 122 | ||
121 | static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) | 123 | static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) |
122 | { | 124 | { |
123 | down(&ice->gpio_mutex); | 125 | mutex_lock(&ice->gpio_mutex); |
124 | 126 | ||
125 | /* select box */ | 127 | /* select box */ |
126 | ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); | 128 | ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); |
@@ -141,15 +143,15 @@ static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int | |||
141 | ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); | 143 | ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); |
142 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); | 144 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); |
143 | 145 | ||
144 | up(&ice->gpio_mutex); | 146 | mutex_unlock(&ice->gpio_mutex); |
145 | } | 147 | } |
146 | 148 | ||
147 | static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) | 149 | static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) |
148 | { | 150 | { |
149 | down(&ice->gpio_mutex); | 151 | mutex_lock(&ice->gpio_mutex); |
150 | ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate); | 152 | ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate); |
151 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); | 153 | snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); |
152 | up(&ice->gpio_mutex); | 154 | mutex_unlock(&ice->gpio_mutex); |
153 | } | 155 | } |
154 | 156 | ||
155 | static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) | 157 | static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index ef6f18558c95..672e198317e1 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -53,8 +53,10 @@ | |||
53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/pci.h> | 55 | #include <linux/pci.h> |
56 | #include <linux/dma-mapping.h> | ||
56 | #include <linux/slab.h> | 57 | #include <linux/slab.h> |
57 | #include <linux/moduleparam.h> | 58 | #include <linux/moduleparam.h> |
59 | #include <linux/mutex.h> | ||
58 | #include <sound/core.h> | 60 | #include <sound/core.h> |
59 | #include <sound/cs8427.h> | 61 | #include <sound/cs8427.h> |
60 | #include <sound/info.h> | 62 | #include <sound/info.h> |
@@ -82,10 +84,11 @@ MODULE_SUPPORTED_DEVICE("{" | |||
82 | 84 | ||
83 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 85 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
84 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 86 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
85 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 87 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ |
86 | static char *model[SNDRV_CARDS]; | 88 | static char *model[SNDRV_CARDS]; |
87 | static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ | 89 | static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ |
88 | static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */ | 90 | static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transciever reset timeout value in msec */ |
91 | static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */ | ||
89 | 92 | ||
90 | module_param_array(index, int, NULL, 0444); | 93 | module_param_array(index, int, NULL, 0444); |
91 | MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard."); | 94 | MODULE_PARM_DESC(index, "Index value for ICE1712 soundcard."); |
@@ -99,6 +102,8 @@ module_param_array(cs8427_timeout, int, NULL, 0444); | |||
99 | MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution."); | 102 | MODULE_PARM_DESC(cs8427_timeout, "Define reset timeout for cs8427 chip in msec resolution."); |
100 | module_param_array(model, charp, NULL, 0444); | 103 | module_param_array(model, charp, NULL, 0444); |
101 | MODULE_PARM_DESC(model, "Use the given board model."); | 104 | MODULE_PARM_DESC(model, "Use the given board model."); |
105 | module_param_array(dxr_enable, int, NULL, 0444); | ||
106 | MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); | ||
102 | 107 | ||
103 | 108 | ||
104 | static struct pci_device_id snd_ice1712_ids[] = { | 109 | static struct pci_device_id snd_ice1712_ids[] = { |
@@ -316,7 +321,6 @@ static void snd_ice1712_set_gpio_data(struct snd_ice1712 *ice, unsigned int val) | |||
316 | inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ | 321 | inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */ |
317 | } | 322 | } |
318 | 323 | ||
319 | |||
320 | /* | 324 | /* |
321 | * | 325 | * |
322 | * CS8427 interface | 326 | * CS8427 interface |
@@ -396,6 +400,20 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) | |||
396 | return 0; | 400 | return 0; |
397 | } | 401 | } |
398 | 402 | ||
403 | static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master) | ||
404 | { | ||
405 | /* change CS8427 clock source too */ | ||
406 | if (ice->cs8427) | ||
407 | snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); | ||
408 | /* notify ak4524 chip as well */ | ||
409 | if (spdif_is_master) { | ||
410 | unsigned int i; | ||
411 | for (i = 0; i < ice->akm_codecs; i++) { | ||
412 | if (ice->akm[i].ops.set_rate_val) | ||
413 | ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); | ||
414 | } | ||
415 | } | ||
416 | } | ||
399 | 417 | ||
400 | /* | 418 | /* |
401 | * Interrupt handler | 419 | * Interrupt handler |
@@ -1567,6 +1585,9 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry, | |||
1567 | snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE))); | 1585 | snd_iprintf(buffer, " CAPTURE : 0x%08x\n", inl(ICEMT(ice, ROUTE_CAPTURE))); |
1568 | snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); | 1586 | snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); |
1569 | snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); | 1587 | snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); |
1588 | snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice)); | ||
1589 | snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); | ||
1590 | snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION)); | ||
1570 | } | 1591 | } |
1571 | 1592 | ||
1572 | static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice) | 1593 | static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice) |
@@ -1856,20 +1877,8 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, | |||
1856 | spin_unlock_irq(&ice->reg_lock); | 1877 | spin_unlock_irq(&ice->reg_lock); |
1857 | 1878 | ||
1858 | if ((oval & ICE1712_SPDIF_MASTER) != | 1879 | if ((oval & ICE1712_SPDIF_MASTER) != |
1859 | (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) { | 1880 | (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) |
1860 | /* change CS8427 clock source too */ | 1881 | snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); |
1861 | if (ice->cs8427) { | ||
1862 | snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice)); | ||
1863 | } | ||
1864 | /* notify ak4524 chip as well */ | ||
1865 | if (is_spdif_master(ice)) { | ||
1866 | unsigned int i; | ||
1867 | for (i = 0; i < ice->akm_codecs; i++) { | ||
1868 | if (ice->akm[i].ops.set_rate_val) | ||
1869 | ice->akm[i].ops.set_rate_val(&ice->akm[i], 0); | ||
1870 | } | ||
1871 | } | ||
1872 | } | ||
1873 | 1882 | ||
1874 | return change; | 1883 | return change; |
1875 | } | 1884 | } |
@@ -2388,7 +2397,13 @@ static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice) | |||
2388 | udelay(200); | 2397 | udelay(200); |
2389 | outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); | 2398 | outb(ICE1712_NATIVE, ICEREG(ice, CONTROL)); |
2390 | udelay(200); | 2399 | udelay(200); |
2391 | pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); | 2400 | if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DMX6FIRE && !ice->dxr_enable) { |
2401 | /* Limit active ADCs and DACs to 6; */ | ||
2402 | /* Note: DXR extension not supported */ | ||
2403 | pci_write_config_byte(ice->pci, 0x60, 0x0a); | ||
2404 | } else { | ||
2405 | pci_write_config_byte(ice->pci, 0x60, ice->eeprom.data[ICE_EEP1_CODEC]); | ||
2406 | } | ||
2392 | pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); | 2407 | pci_write_config_byte(ice->pci, 0x61, ice->eeprom.data[ICE_EEP1_ACLINK]); |
2393 | pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); | 2408 | pci_write_config_byte(ice->pci, 0x62, ice->eeprom.data[ICE_EEP1_I2SID]); |
2394 | pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); | 2409 | pci_write_config_byte(ice->pci, 0x63, ice->eeprom.data[ICE_EEP1_SPDIF]); |
@@ -2524,6 +2539,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, | |||
2524 | const char *modelname, | 2539 | const char *modelname, |
2525 | int omni, | 2540 | int omni, |
2526 | int cs8427_timeout, | 2541 | int cs8427_timeout, |
2542 | int dxr_enable, | ||
2527 | struct snd_ice1712 ** r_ice1712) | 2543 | struct snd_ice1712 ** r_ice1712) |
2528 | { | 2544 | { |
2529 | struct snd_ice1712 *ice; | 2545 | struct snd_ice1712 *ice; |
@@ -2538,8 +2554,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card, | |||
2538 | if ((err = pci_enable_device(pci)) < 0) | 2554 | if ((err = pci_enable_device(pci)) < 0) |
2539 | return err; | 2555 | return err; |
2540 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2556 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2541 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 2557 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
2542 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 2558 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
2543 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2559 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2544 | pci_disable_device(pci); | 2560 | pci_disable_device(pci); |
2545 | return -ENXIO; | 2561 | return -ENXIO; |
@@ -2556,10 +2572,11 @@ static int __devinit snd_ice1712_create(struct snd_card *card, | |||
2556 | else if (cs8427_timeout > 1000) | 2572 | else if (cs8427_timeout > 1000) |
2557 | cs8427_timeout = 1000; | 2573 | cs8427_timeout = 1000; |
2558 | ice->cs8427_timeout = cs8427_timeout; | 2574 | ice->cs8427_timeout = cs8427_timeout; |
2575 | ice->dxr_enable = dxr_enable; | ||
2559 | spin_lock_init(&ice->reg_lock); | 2576 | spin_lock_init(&ice->reg_lock); |
2560 | init_MUTEX(&ice->gpio_mutex); | 2577 | mutex_init(&ice->gpio_mutex); |
2561 | init_MUTEX(&ice->i2c_mutex); | 2578 | mutex_init(&ice->i2c_mutex); |
2562 | init_MUTEX(&ice->open_mutex); | 2579 | mutex_init(&ice->open_mutex); |
2563 | ice->gpio.set_mask = snd_ice1712_set_gpio_mask; | 2580 | ice->gpio.set_mask = snd_ice1712_set_gpio_mask; |
2564 | ice->gpio.set_dir = snd_ice1712_set_gpio_dir; | 2581 | ice->gpio.set_dir = snd_ice1712_set_gpio_dir; |
2565 | ice->gpio.set_data = snd_ice1712_set_gpio_data; | 2582 | ice->gpio.set_data = snd_ice1712_set_gpio_data; |
@@ -2658,7 +2675,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
2658 | strcpy(card->shortname, "ICEnsemble ICE1712"); | 2675 | strcpy(card->shortname, "ICEnsemble ICE1712"); |
2659 | 2676 | ||
2660 | if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], | 2677 | if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], |
2661 | cs8427_timeout[dev], &ice)) < 0) { | 2678 | cs8427_timeout[dev], dxr_enable[dev], |
2679 | &ice)) < 0) { | ||
2662 | snd_card_free(card); | 2680 | snd_card_free(card); |
2663 | return err; | 2681 | return err; |
2664 | } | 2682 | } |
@@ -2735,6 +2753,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
2735 | } | 2753 | } |
2736 | } | 2754 | } |
2737 | 2755 | ||
2756 | snd_ice1712_set_input_clock_source(ice, 0); | ||
2757 | |||
2738 | sprintf(card->longname, "%s at 0x%lx, irq %i", | 2758 | sprintf(card->longname, "%s at 0x%lx, irq %i", |
2739 | card->shortname, ice->port, ice->irq); | 2759 | card->shortname, ice->port, ice->irq); |
2740 | 2760 | ||
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index ce96b3bb6531..f9b22d4a3932 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h | |||
@@ -325,6 +325,7 @@ struct snd_ice1712 { | |||
325 | 325 | ||
326 | unsigned int pro_volumes[20]; | 326 | unsigned int pro_volumes[20]; |
327 | unsigned int omni: 1; /* Delta Omni I/O */ | 327 | unsigned int omni: 1; /* Delta Omni I/O */ |
328 | unsigned int dxr_enable: 1; /* Terratec DXR enable for DMX6FIRE */ | ||
328 | unsigned int vt1724: 1; | 329 | unsigned int vt1724: 1; |
329 | unsigned int vt1720: 1; | 330 | unsigned int vt1720: 1; |
330 | unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ | 331 | unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ |
@@ -334,7 +335,7 @@ struct snd_ice1712 { | |||
334 | unsigned int num_total_adcs; /* total ADCs */ | 335 | unsigned int num_total_adcs; /* total ADCs */ |
335 | unsigned int cur_rate; /* current rate */ | 336 | unsigned int cur_rate; /* current rate */ |
336 | 337 | ||
337 | struct semaphore open_mutex; | 338 | struct mutex open_mutex; |
338 | struct snd_pcm_substream *pcm_reserved[4]; | 339 | struct snd_pcm_substream *pcm_reserved[4]; |
339 | struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ | 340 | struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */ |
340 | 341 | ||
@@ -342,7 +343,7 @@ struct snd_ice1712 { | |||
342 | struct snd_akm4xxx *akm; | 343 | struct snd_akm4xxx *akm; |
343 | struct snd_ice1712_spdif spdif; | 344 | struct snd_ice1712_spdif spdif; |
344 | 345 | ||
345 | struct semaphore i2c_mutex; /* I2C mutex for ICE1724 registers */ | 346 | struct mutex i2c_mutex; /* I2C mutex for ICE1724 registers */ |
346 | struct snd_i2c_bus *i2c; /* I2C bus */ | 347 | struct snd_i2c_bus *i2c; /* I2C bus */ |
347 | struct snd_i2c_device *cs8427; /* CS8427 I2C device */ | 348 | struct snd_i2c_device *cs8427; /* CS8427 I2C device */ |
348 | unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ | 349 | unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ |
@@ -360,7 +361,7 @@ struct snd_ice1712 { | |||
360 | void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate); | 361 | void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate); |
361 | void (*i2s_mclk_changed)(struct snd_ice1712 *ice); | 362 | void (*i2s_mclk_changed)(struct snd_ice1712 *ice); |
362 | } gpio; | 363 | } gpio; |
363 | struct semaphore gpio_mutex; | 364 | struct mutex gpio_mutex; |
364 | 365 | ||
365 | /* other board-specific data */ | 366 | /* other board-specific data */ |
366 | union { | 367 | union { |
@@ -423,7 +424,7 @@ static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice) | |||
423 | */ | 424 | */ |
424 | static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice) | 425 | static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice) |
425 | { | 426 | { |
426 | down(&ice->gpio_mutex); | 427 | mutex_lock(&ice->gpio_mutex); |
427 | ice->gpio.saved[0] = ice->gpio.direction; | 428 | ice->gpio.saved[0] = ice->gpio.direction; |
428 | ice->gpio.saved[1] = ice->gpio.write_mask; | 429 | ice->gpio.saved[1] = ice->gpio.write_mask; |
429 | } | 430 | } |
@@ -434,7 +435,7 @@ static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice) | |||
434 | ice->gpio.set_mask(ice, ice->gpio.saved[1]); | 435 | ice->gpio.set_mask(ice, ice->gpio.saved[1]); |
435 | ice->gpio.direction = ice->gpio.saved[0]; | 436 | ice->gpio.direction = ice->gpio.saved[0]; |
436 | ice->gpio.write_mask = ice->gpio.saved[1]; | 437 | ice->gpio.write_mask = ice->gpio.saved[1]; |
437 | up(&ice->gpio_mutex); | 438 | mutex_unlock(&ice->gpio_mutex); |
438 | } | 439 | } |
439 | 440 | ||
440 | /* for bit controls */ | 441 | /* for bit controls */ |
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 71f08c036019..fce616c2761f 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
33 | #include <linux/mutex.h> | ||
33 | #include <sound/core.h> | 34 | #include <sound/core.h> |
34 | #include <sound/info.h> | 35 | #include <sound/info.h> |
35 | #include <sound/mpu401.h> | 36 | #include <sound/mpu401.h> |
@@ -487,7 +488,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | |||
487 | int i, chs; | 488 | int i, chs; |
488 | 489 | ||
489 | chs = params_channels(hw_params); | 490 | chs = params_channels(hw_params); |
490 | down(&ice->open_mutex); | 491 | mutex_lock(&ice->open_mutex); |
491 | /* mark surround channels */ | 492 | /* mark surround channels */ |
492 | if (substream == ice->playback_pro_substream) { | 493 | if (substream == ice->playback_pro_substream) { |
493 | /* PDMA0 can be multi-channel up to 8 */ | 494 | /* PDMA0 can be multi-channel up to 8 */ |
@@ -495,7 +496,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | |||
495 | for (i = 0; i < chs; i++) { | 496 | for (i = 0; i < chs; i++) { |
496 | if (ice->pcm_reserved[i] && | 497 | if (ice->pcm_reserved[i] && |
497 | ice->pcm_reserved[i] != substream) { | 498 | ice->pcm_reserved[i] != substream) { |
498 | up(&ice->open_mutex); | 499 | mutex_unlock(&ice->open_mutex); |
499 | return -EBUSY; | 500 | return -EBUSY; |
500 | } | 501 | } |
501 | ice->pcm_reserved[i] = substream; | 502 | ice->pcm_reserved[i] = substream; |
@@ -510,7 +511,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | |||
510 | if (ice->playback_con_substream_ds[i] == substream) { | 511 | if (ice->playback_con_substream_ds[i] == substream) { |
511 | if (ice->pcm_reserved[i] && | 512 | if (ice->pcm_reserved[i] && |
512 | ice->pcm_reserved[i] != substream) { | 513 | ice->pcm_reserved[i] != substream) { |
513 | up(&ice->open_mutex); | 514 | mutex_unlock(&ice->open_mutex); |
514 | return -EBUSY; | 515 | return -EBUSY; |
515 | } | 516 | } |
516 | ice->pcm_reserved[i] = substream; | 517 | ice->pcm_reserved[i] = substream; |
@@ -518,7 +519,7 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | |||
518 | } | 519 | } |
519 | } | 520 | } |
520 | } | 521 | } |
521 | up(&ice->open_mutex); | 522 | mutex_unlock(&ice->open_mutex); |
522 | snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); | 523 | snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); |
523 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 524 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
524 | } | 525 | } |
@@ -528,12 +529,12 @@ static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream) | |||
528 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | 529 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); |
529 | int i; | 530 | int i; |
530 | 531 | ||
531 | down(&ice->open_mutex); | 532 | mutex_lock(&ice->open_mutex); |
532 | /* unmark surround channels */ | 533 | /* unmark surround channels */ |
533 | for (i = 0; i < 3; i++) | 534 | for (i = 0; i < 3; i++) |
534 | if (ice->pcm_reserved[i] == substream) | 535 | if (ice->pcm_reserved[i] == substream) |
535 | ice->pcm_reserved[i] = NULL; | 536 | ice->pcm_reserved[i] = NULL; |
536 | up(&ice->open_mutex); | 537 | mutex_unlock(&ice->open_mutex); |
537 | return snd_pcm_lib_free_pages(substream); | 538 | return snd_pcm_lib_free_pages(substream); |
538 | } | 539 | } |
539 | 540 | ||
@@ -778,7 +779,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) | |||
778 | snd_pcm_set_sync(substream); | 779 | snd_pcm_set_sync(substream); |
779 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 780 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
780 | set_rate_constraints(ice, substream); | 781 | set_rate_constraints(ice, substream); |
781 | down(&ice->open_mutex); | 782 | mutex_lock(&ice->open_mutex); |
782 | /* calculate the currently available channels */ | 783 | /* calculate the currently available channels */ |
783 | for (chs = 0; chs < 3; chs++) { | 784 | for (chs = 0; chs < 3; chs++) { |
784 | if (ice->pcm_reserved[chs]) | 785 | if (ice->pcm_reserved[chs]) |
@@ -788,7 +789,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) | |||
788 | runtime->hw.channels_max = chs; | 789 | runtime->hw.channels_max = chs; |
789 | if (chs > 2) /* channels must be even */ | 790 | if (chs > 2) /* channels must be even */ |
790 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); | 791 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); |
791 | up(&ice->open_mutex); | 792 | mutex_unlock(&ice->open_mutex); |
792 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 793 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
793 | VT1724_BUFFER_ALIGN); | 794 | VT1724_BUFFER_ALIGN); |
794 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 795 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
@@ -1128,13 +1129,13 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream) | |||
1128 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | 1129 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); |
1129 | struct snd_pcm_runtime *runtime = substream->runtime; | 1130 | struct snd_pcm_runtime *runtime = substream->runtime; |
1130 | 1131 | ||
1131 | down(&ice->open_mutex); | 1132 | mutex_lock(&ice->open_mutex); |
1132 | /* already used by PDMA0? */ | 1133 | /* already used by PDMA0? */ |
1133 | if (ice->pcm_reserved[substream->number]) { | 1134 | if (ice->pcm_reserved[substream->number]) { |
1134 | up(&ice->open_mutex); | 1135 | mutex_unlock(&ice->open_mutex); |
1135 | return -EBUSY; /* FIXME: should handle blocking mode properly */ | 1136 | return -EBUSY; /* FIXME: should handle blocking mode properly */ |
1136 | } | 1137 | } |
1137 | up(&ice->open_mutex); | 1138 | mutex_unlock(&ice->open_mutex); |
1138 | runtime->private_data = &vt1724_playback_dma_regs[substream->number]; | 1139 | runtime->private_data = &vt1724_playback_dma_regs[substream->number]; |
1139 | ice->playback_con_substream_ds[substream->number] = substream; | 1140 | ice->playback_con_substream_ds[substream->number] = substream; |
1140 | runtime->hw = snd_vt1724_2ch_stereo; | 1141 | runtime->hw = snd_vt1724_2ch_stereo; |
@@ -1978,12 +1979,12 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, | |||
1978 | { | 1979 | { |
1979 | unsigned char val; | 1980 | unsigned char val; |
1980 | 1981 | ||
1981 | down(&ice->i2c_mutex); | 1982 | mutex_lock(&ice->i2c_mutex); |
1982 | outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); | 1983 | outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); |
1983 | outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); | 1984 | outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); |
1984 | wait_i2c_busy(ice); | 1985 | wait_i2c_busy(ice); |
1985 | val = inb(ICEREG1724(ice, I2C_DATA)); | 1986 | val = inb(ICEREG1724(ice, I2C_DATA)); |
1986 | up(&ice->i2c_mutex); | 1987 | mutex_unlock(&ice->i2c_mutex); |
1987 | //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); | 1988 | //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); |
1988 | return val; | 1989 | return val; |
1989 | } | 1990 | } |
@@ -1991,14 +1992,14 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, | |||
1991 | void snd_vt1724_write_i2c(struct snd_ice1712 *ice, | 1992 | void snd_vt1724_write_i2c(struct snd_ice1712 *ice, |
1992 | unsigned char dev, unsigned char addr, unsigned char data) | 1993 | unsigned char dev, unsigned char addr, unsigned char data) |
1993 | { | 1994 | { |
1994 | down(&ice->i2c_mutex); | 1995 | mutex_lock(&ice->i2c_mutex); |
1995 | wait_i2c_busy(ice); | 1996 | wait_i2c_busy(ice); |
1996 | //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); | 1997 | //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); |
1997 | outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); | 1998 | outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); |
1998 | outb(data, ICEREG1724(ice, I2C_DATA)); | 1999 | outb(data, ICEREG1724(ice, I2C_DATA)); |
1999 | outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); | 2000 | outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); |
2000 | wait_i2c_busy(ice); | 2001 | wait_i2c_busy(ice); |
2001 | up(&ice->i2c_mutex); | 2002 | mutex_unlock(&ice->i2c_mutex); |
2002 | } | 2003 | } |
2003 | 2004 | ||
2004 | static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, | 2005 | static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, |
@@ -2229,9 +2230,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card, | |||
2229 | } | 2230 | } |
2230 | ice->vt1724 = 1; | 2231 | ice->vt1724 = 1; |
2231 | spin_lock_init(&ice->reg_lock); | 2232 | spin_lock_init(&ice->reg_lock); |
2232 | init_MUTEX(&ice->gpio_mutex); | 2233 | mutex_init(&ice->gpio_mutex); |
2233 | init_MUTEX(&ice->open_mutex); | 2234 | mutex_init(&ice->open_mutex); |
2234 | init_MUTEX(&ice->i2c_mutex); | 2235 | mutex_init(&ice->i2c_mutex); |
2235 | ice->gpio.set_mask = snd_vt1724_set_gpio_mask; | 2236 | ice->gpio.set_mask = snd_vt1724_set_gpio_mask; |
2236 | ice->gpio.set_dir = snd_vt1724_set_gpio_dir; | 2237 | ice->gpio.set_dir = snd_vt1724_set_gpio_dir; |
2237 | ice->gpio.set_data = snd_vt1724_set_gpio_data; | 2238 | ice->gpio.set_data = snd_vt1724_set_gpio_data; |
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index ec3757834b93..502da1c8b5f7 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/mutex.h> | ||
43 | |||
42 | #include <sound/core.h> | 44 | #include <sound/core.h> |
43 | 45 | ||
44 | #include "ice1712.h" | 46 | #include "ice1712.h" |
@@ -273,9 +275,9 @@ static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
273 | { | 275 | { |
274 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 276 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
275 | 277 | ||
276 | down(&ice->gpio_mutex); | 278 | mutex_lock(&ice->gpio_mutex); |
277 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; | 279 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; |
278 | up(&ice->gpio_mutex); | 280 | mutex_unlock(&ice->gpio_mutex); |
279 | return 0; | 281 | return 0; |
280 | } | 282 | } |
281 | 283 | ||
@@ -584,11 +586,11 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
584 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 586 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
585 | unsigned short val; | 587 | unsigned short val; |
586 | 588 | ||
587 | down(&ice->gpio_mutex); | 589 | mutex_lock(&ice->gpio_mutex); |
588 | val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; | 590 | val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; |
589 | val = val > PCM_MIN ? (val - PCM_MIN) : 0; | 591 | val = val > PCM_MIN ? (val - PCM_MIN) : 0; |
590 | ucontrol->value.integer.value[0] = val; | 592 | ucontrol->value.integer.value[0] = val; |
591 | up(&ice->gpio_mutex); | 593 | mutex_unlock(&ice->gpio_mutex); |
592 | return 0; | 594 | return 0; |
593 | } | 595 | } |
594 | 596 | ||
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 0dccd7707a4b..d23fb3fc2133 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/info.h> | 33 | #include <sound/info.h> |
32 | 34 | ||
@@ -124,13 +126,13 @@ static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
124 | unsigned short val; | 126 | unsigned short val; |
125 | int i; | 127 | int i; |
126 | 128 | ||
127 | down(&ice->gpio_mutex); | 129 | mutex_lock(&ice->gpio_mutex); |
128 | for (i = 0; i < 2; i++) { | 130 | for (i = 0; i < 2; i++) { |
129 | val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff; | 131 | val = wm_get(ice, WM_DAC_ATTEN_L + i) & 0xff; |
130 | val = val > DAC_MIN ? (val - DAC_MIN) : 0; | 132 | val = val > DAC_MIN ? (val - DAC_MIN) : 0; |
131 | ucontrol->value.integer.value[i] = val; | 133 | ucontrol->value.integer.value[i] = val; |
132 | } | 134 | } |
133 | up(&ice->gpio_mutex); | 135 | mutex_unlock(&ice->gpio_mutex); |
134 | return 0; | 136 | return 0; |
135 | } | 137 | } |
136 | 138 | ||
@@ -140,7 +142,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
140 | unsigned short oval, nval; | 142 | unsigned short oval, nval; |
141 | int i, idx, change = 0; | 143 | int i, idx, change = 0; |
142 | 144 | ||
143 | down(&ice->gpio_mutex); | 145 | mutex_lock(&ice->gpio_mutex); |
144 | for (i = 0; i < 2; i++) { | 146 | for (i = 0; i < 2; i++) { |
145 | nval = ucontrol->value.integer.value[i]; | 147 | nval = ucontrol->value.integer.value[i]; |
146 | nval = (nval ? (nval + DAC_MIN) : 0) & 0xff; | 148 | nval = (nval ? (nval + DAC_MIN) : 0) & 0xff; |
@@ -152,7 +154,7 @@ static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
152 | change = 1; | 154 | change = 1; |
153 | } | 155 | } |
154 | } | 156 | } |
155 | up(&ice->gpio_mutex); | 157 | mutex_unlock(&ice->gpio_mutex); |
156 | return change; | 158 | return change; |
157 | } | 159 | } |
158 | 160 | ||
@@ -179,13 +181,13 @@ static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
179 | unsigned short val; | 181 | unsigned short val; |
180 | int i; | 182 | int i; |
181 | 183 | ||
182 | down(&ice->gpio_mutex); | 184 | mutex_lock(&ice->gpio_mutex); |
183 | for (i = 0; i < 2; i++) { | 185 | for (i = 0; i < 2; i++) { |
184 | val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff; | 186 | val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff; |
185 | val = val > ADC_MIN ? (val - ADC_MIN) : 0; | 187 | val = val > ADC_MIN ? (val - ADC_MIN) : 0; |
186 | ucontrol->value.integer.value[i] = val; | 188 | ucontrol->value.integer.value[i] = val; |
187 | } | 189 | } |
188 | up(&ice->gpio_mutex); | 190 | mutex_unlock(&ice->gpio_mutex); |
189 | return 0; | 191 | return 0; |
190 | } | 192 | } |
191 | 193 | ||
@@ -195,7 +197,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
195 | unsigned short ovol, nvol; | 197 | unsigned short ovol, nvol; |
196 | int i, idx, change = 0; | 198 | int i, idx, change = 0; |
197 | 199 | ||
198 | down(&ice->gpio_mutex); | 200 | mutex_lock(&ice->gpio_mutex); |
199 | for (i = 0; i < 2; i++) { | 201 | for (i = 0; i < 2; i++) { |
200 | nvol = ucontrol->value.integer.value[i]; | 202 | nvol = ucontrol->value.integer.value[i]; |
201 | nvol = nvol ? (nvol + ADC_MIN) : 0; | 203 | nvol = nvol ? (nvol + ADC_MIN) : 0; |
@@ -206,7 +208,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
206 | change = 1; | 208 | change = 1; |
207 | } | 209 | } |
208 | } | 210 | } |
209 | up(&ice->gpio_mutex); | 211 | mutex_unlock(&ice->gpio_mutex); |
210 | return change; | 212 | return change; |
211 | } | 213 | } |
212 | 214 | ||
@@ -227,9 +229,9 @@ static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
227 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 229 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
228 | int bit = kcontrol->private_value; | 230 | int bit = kcontrol->private_value; |
229 | 231 | ||
230 | down(&ice->gpio_mutex); | 232 | mutex_lock(&ice->gpio_mutex); |
231 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0; | 233 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0; |
232 | up(&ice->gpio_mutex); | 234 | mutex_unlock(&ice->gpio_mutex); |
233 | return 0; | 235 | return 0; |
234 | } | 236 | } |
235 | 237 | ||
@@ -240,7 +242,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
240 | unsigned short oval, nval; | 242 | unsigned short oval, nval; |
241 | int change; | 243 | int change; |
242 | 244 | ||
243 | down(&ice->gpio_mutex); | 245 | mutex_lock(&ice->gpio_mutex); |
244 | nval = oval = wm_get(ice, WM_ADC_MUX); | 246 | nval = oval = wm_get(ice, WM_ADC_MUX); |
245 | if (ucontrol->value.integer.value[0]) | 247 | if (ucontrol->value.integer.value[0]) |
246 | nval |= (1 << bit); | 248 | nval |= (1 << bit); |
@@ -250,7 +252,7 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val | |||
250 | if (change) { | 252 | if (change) { |
251 | wm_put(ice, WM_ADC_MUX, nval); | 253 | wm_put(ice, WM_ADC_MUX, nval); |
252 | } | 254 | } |
253 | up(&ice->gpio_mutex); | 255 | mutex_unlock(&ice->gpio_mutex); |
254 | return 0; | 256 | return 0; |
255 | } | 257 | } |
256 | 258 | ||
@@ -270,9 +272,9 @@ static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
270 | { | 272 | { |
271 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 273 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
272 | 274 | ||
273 | down(&ice->gpio_mutex); | 275 | mutex_lock(&ice->gpio_mutex); |
274 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0; | 276 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0; |
275 | up(&ice->gpio_mutex); | 277 | mutex_unlock(&ice->gpio_mutex); |
276 | return 0; | 278 | return 0; |
277 | } | 279 | } |
278 | 280 | ||
@@ -282,7 +284,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
282 | unsigned short val, oval; | 284 | unsigned short val, oval; |
283 | int change = 0; | 285 | int change = 0; |
284 | 286 | ||
285 | down(&ice->gpio_mutex); | 287 | mutex_lock(&ice->gpio_mutex); |
286 | val = oval = wm_get(ice, WM_OUT_MUX); | 288 | val = oval = wm_get(ice, WM_OUT_MUX); |
287 | if (ucontrol->value.integer.value[0]) | 289 | if (ucontrol->value.integer.value[0]) |
288 | val |= 0x04; | 290 | val |= 0x04; |
@@ -292,7 +294,7 @@ static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
292 | wm_put(ice, WM_OUT_MUX, val); | 294 | wm_put(ice, WM_OUT_MUX, val); |
293 | change = 1; | 295 | change = 1; |
294 | } | 296 | } |
295 | up(&ice->gpio_mutex); | 297 | mutex_unlock(&ice->gpio_mutex); |
296 | return change; | 298 | return change; |
297 | } | 299 | } |
298 | 300 | ||
@@ -312,9 +314,9 @@ static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
312 | { | 314 | { |
313 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 315 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
314 | 316 | ||
315 | down(&ice->gpio_mutex); | 317 | mutex_lock(&ice->gpio_mutex); |
316 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90; | 318 | ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90; |
317 | up(&ice->gpio_mutex); | 319 | mutex_unlock(&ice->gpio_mutex); |
318 | return 0; | 320 | return 0; |
319 | } | 321 | } |
320 | 322 | ||
@@ -324,7 +326,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
324 | unsigned short val, oval; | 326 | unsigned short val, oval; |
325 | int change = 0; | 327 | int change = 0; |
326 | 328 | ||
327 | down(&ice->gpio_mutex); | 329 | mutex_lock(&ice->gpio_mutex); |
328 | oval = wm_get(ice, WM_DAC_CTRL1); | 330 | oval = wm_get(ice, WM_DAC_CTRL1); |
329 | val = oval & 0x0f; | 331 | val = oval & 0x0f; |
330 | if (ucontrol->value.integer.value[0]) | 332 | if (ucontrol->value.integer.value[0]) |
@@ -336,7 +338,7 @@ static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
336 | wm_put_nocache(ice, WM_DAC_CTRL1, val); | 338 | wm_put_nocache(ice, WM_DAC_CTRL1, val); |
337 | change = 1; | 339 | change = 1; |
338 | } | 340 | } |
339 | up(&ice->gpio_mutex); | 341 | mutex_unlock(&ice->gpio_mutex); |
340 | return change; | 342 | return change; |
341 | } | 343 | } |
342 | 344 | ||
@@ -449,9 +451,9 @@ static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
449 | { | 451 | { |
450 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 452 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
451 | 453 | ||
452 | down(&ice->gpio_mutex); | 454 | mutex_lock(&ice->gpio_mutex); |
453 | ucontrol->value.enumerated.item[0] = ice->gpio.saved[0]; | 455 | ucontrol->value.enumerated.item[0] = ice->gpio.saved[0]; |
454 | up(&ice->gpio_mutex); | 456 | mutex_unlock(&ice->gpio_mutex); |
455 | return 0; | 457 | return 0; |
456 | } | 458 | } |
457 | 459 | ||
@@ -461,14 +463,14 @@ static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu | |||
461 | unsigned char val; | 463 | unsigned char val; |
462 | int change = 0; | 464 | int change = 0; |
463 | 465 | ||
464 | down(&ice->gpio_mutex); | 466 | mutex_lock(&ice->gpio_mutex); |
465 | if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) { | 467 | if (ucontrol->value.enumerated.item[0] != ice->gpio.saved[0]) { |
466 | ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3; | 468 | ice->gpio.saved[0] = ucontrol->value.enumerated.item[0] & 3; |
467 | val = 0x80 | (ice->gpio.saved[0] << 3); | 469 | val = 0x80 | (ice->gpio.saved[0] << 3); |
468 | spi_write(ice, CS_DEV, 0x04, val); | 470 | spi_write(ice, CS_DEV, 0x04, val); |
469 | change = 1; | 471 | change = 1; |
470 | } | 472 | } |
471 | up(&ice->gpio_mutex); | 473 | mutex_unlock(&ice->gpio_mutex); |
472 | return 0; | 474 | return 0; |
473 | } | 475 | } |
474 | 476 | ||
@@ -488,10 +490,10 @@ static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
488 | static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 490 | static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
489 | { | 491 | { |
490 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 492 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
491 | down(&ice->gpio_mutex); | 493 | mutex_lock(&ice->gpio_mutex); |
492 | /* 4-7 reserved */ | 494 | /* 4-7 reserved */ |
493 | ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0; | 495 | ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0; |
494 | up(&ice->gpio_mutex); | 496 | mutex_unlock(&ice->gpio_mutex); |
495 | return 0; | 497 | return 0; |
496 | } | 498 | } |
497 | 499 | ||
@@ -500,22 +502,22 @@ static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
500 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 502 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
501 | unsigned int val; | 503 | unsigned int val; |
502 | int changed; | 504 | int changed; |
503 | down(&ice->gpio_mutex); | 505 | mutex_lock(&ice->gpio_mutex); |
504 | /* 4-7 reserved */ | 506 | /* 4-7 reserved */ |
505 | val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0; | 507 | val = (~ucontrol->value.integer.value[0] & 0xffff) | 0x00f0; |
506 | changed = val != ice->gpio.write_mask; | 508 | changed = val != ice->gpio.write_mask; |
507 | ice->gpio.write_mask = val; | 509 | ice->gpio.write_mask = val; |
508 | up(&ice->gpio_mutex); | 510 | mutex_unlock(&ice->gpio_mutex); |
509 | return changed; | 511 | return changed; |
510 | } | 512 | } |
511 | 513 | ||
512 | static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 514 | static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
513 | { | 515 | { |
514 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 516 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
515 | down(&ice->gpio_mutex); | 517 | mutex_lock(&ice->gpio_mutex); |
516 | /* 4-7 reserved */ | 518 | /* 4-7 reserved */ |
517 | ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f; | 519 | ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f; |
518 | up(&ice->gpio_mutex); | 520 | mutex_unlock(&ice->gpio_mutex); |
519 | return 0; | 521 | return 0; |
520 | } | 522 | } |
521 | 523 | ||
@@ -524,23 +526,23 @@ static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
524 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 526 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
525 | unsigned int val; | 527 | unsigned int val; |
526 | int changed; | 528 | int changed; |
527 | down(&ice->gpio_mutex); | 529 | mutex_lock(&ice->gpio_mutex); |
528 | /* 4-7 reserved */ | 530 | /* 4-7 reserved */ |
529 | val = ucontrol->value.integer.value[0] & 0xff0f; | 531 | val = ucontrol->value.integer.value[0] & 0xff0f; |
530 | changed = (val != ice->gpio.direction); | 532 | changed = (val != ice->gpio.direction); |
531 | ice->gpio.direction = val; | 533 | ice->gpio.direction = val; |
532 | up(&ice->gpio_mutex); | 534 | mutex_unlock(&ice->gpio_mutex); |
533 | return changed; | 535 | return changed; |
534 | } | 536 | } |
535 | 537 | ||
536 | static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 538 | static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
537 | { | 539 | { |
538 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 540 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
539 | down(&ice->gpio_mutex); | 541 | mutex_lock(&ice->gpio_mutex); |
540 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); | 542 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); |
541 | snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); | 543 | snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); |
542 | ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff; | 544 | ucontrol->value.integer.value[0] = snd_ice1712_gpio_read(ice) & 0xffff; |
543 | up(&ice->gpio_mutex); | 545 | mutex_unlock(&ice->gpio_mutex); |
544 | return 0; | 546 | return 0; |
545 | } | 547 | } |
546 | 548 | ||
@@ -549,7 +551,7 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
549 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 551 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
550 | unsigned int val, nval; | 552 | unsigned int val, nval; |
551 | int changed = 0; | 553 | int changed = 0; |
552 | down(&ice->gpio_mutex); | 554 | mutex_lock(&ice->gpio_mutex); |
553 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); | 555 | snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); |
554 | snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); | 556 | snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask); |
555 | val = snd_ice1712_gpio_read(ice) & 0xffff; | 557 | val = snd_ice1712_gpio_read(ice) & 0xffff; |
@@ -558,7 +560,7 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
558 | snd_ice1712_gpio_write(ice, nval); | 560 | snd_ice1712_gpio_write(ice, nval); |
559 | changed = 1; | 561 | changed = 1; |
560 | } | 562 | } |
561 | up(&ice->gpio_mutex); | 563 | mutex_unlock(&ice->gpio_mutex); |
562 | return changed; | 564 | return changed; |
563 | } | 565 | } |
564 | 566 | ||
@@ -651,14 +653,14 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf | |||
651 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 653 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; |
652 | char line[64]; | 654 | char line[64]; |
653 | unsigned int reg, val; | 655 | unsigned int reg, val; |
654 | down(&ice->gpio_mutex); | 656 | mutex_lock(&ice->gpio_mutex); |
655 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 657 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
656 | if (sscanf(line, "%x %x", ®, &val) != 2) | 658 | if (sscanf(line, "%x %x", ®, &val) != 2) |
657 | continue; | 659 | continue; |
658 | if (reg <= 0x17 && val <= 0xffff) | 660 | if (reg <= 0x17 && val <= 0xffff) |
659 | wm_put(ice, reg, val); | 661 | wm_put(ice, reg, val); |
660 | } | 662 | } |
661 | up(&ice->gpio_mutex); | 663 | mutex_unlock(&ice->gpio_mutex); |
662 | } | 664 | } |
663 | 665 | ||
664 | static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) | 666 | static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) |
@@ -666,12 +668,12 @@ static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff | |||
666 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 668 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; |
667 | int reg, val; | 669 | int reg, val; |
668 | 670 | ||
669 | down(&ice->gpio_mutex); | 671 | mutex_lock(&ice->gpio_mutex); |
670 | for (reg = 0; reg <= 0x17; reg++) { | 672 | for (reg = 0; reg <= 0x17; reg++) { |
671 | val = wm_get(ice, reg); | 673 | val = wm_get(ice, reg); |
672 | snd_iprintf(buffer, "%02x = %04x\n", reg, val); | 674 | snd_iprintf(buffer, "%02x = %04x\n", reg, val); |
673 | } | 675 | } |
674 | up(&ice->gpio_mutex); | 676 | mutex_unlock(&ice->gpio_mutex); |
675 | } | 677 | } |
676 | 678 | ||
677 | static void wm_proc_init(struct snd_ice1712 *ice) | 679 | static void wm_proc_init(struct snd_ice1712 *ice) |
@@ -690,14 +692,14 @@ static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buff | |||
690 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; | 692 | struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; |
691 | int reg, val; | 693 | int reg, val; |
692 | 694 | ||
693 | down(&ice->gpio_mutex); | 695 | mutex_lock(&ice->gpio_mutex); |
694 | for (reg = 0; reg <= 0x26; reg++) { | 696 | for (reg = 0; reg <= 0x26; reg++) { |
695 | val = spi_read(ice, CS_DEV, reg); | 697 | val = spi_read(ice, CS_DEV, reg); |
696 | snd_iprintf(buffer, "%02x = %02x\n", reg, val); | 698 | snd_iprintf(buffer, "%02x = %02x\n", reg, val); |
697 | } | 699 | } |
698 | val = spi_read(ice, CS_DEV, 0x7f); | 700 | val = spi_read(ice, CS_DEV, 0x7f); |
699 | snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val); | 701 | snd_iprintf(buffer, "%02x = %02x\n", 0x7f, val); |
700 | up(&ice->gpio_mutex); | 702 | mutex_unlock(&ice->gpio_mutex); |
701 | } | 703 | } |
702 | 704 | ||
703 | static void cs_proc_init(struct snd_ice1712 *ice) | 705 | static void cs_proc_init(struct snd_ice1712 *ice) |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 174237f4a22c..ebbf2cf4ca0f 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -178,6 +178,8 @@ DEFINE_REGSET(SP, 0x60); /* SPDIF out */ | |||
178 | #define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */ | 178 | #define ICH_SAMPLE_CAP 0x00c00000 /* ICH4: sample capability bits (RO) */ |
179 | #define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */ | 179 | #define ICH_SAMPLE_16_20 0x00400000 /* ICH4: 16- and 20-bit samples */ |
180 | #define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */ | 180 | #define ICH_MULTICHAN_CAP 0x00300000 /* ICH4: multi-channel capability bits (RO) */ |
181 | #define ICH_SIS_TRI 0x00080000 /* SIS: tertiary resume irq */ | ||
182 | #define ICH_SIS_TCR 0x00040000 /* SIS: tertiary codec ready */ | ||
181 | #define ICH_MD3 0x00020000 /* modem power down semaphore */ | 183 | #define ICH_MD3 0x00020000 /* modem power down semaphore */ |
182 | #define ICH_AD3 0x00010000 /* audio power down semaphore */ | 184 | #define ICH_AD3 0x00010000 /* audio power down semaphore */ |
183 | #define ICH_RCS 0x00008000 /* read completion status */ | 185 | #define ICH_RCS 0x00008000 /* read completion status */ |
@@ -398,6 +400,10 @@ struct intel8x0 { | |||
398 | struct snd_ac97_bus *ac97_bus; | 400 | struct snd_ac97_bus *ac97_bus; |
399 | struct snd_ac97 *ac97[3]; | 401 | struct snd_ac97 *ac97[3]; |
400 | unsigned int ac97_sdin[3]; | 402 | unsigned int ac97_sdin[3]; |
403 | unsigned int max_codecs, ncodecs; | ||
404 | unsigned int *codec_bit; | ||
405 | unsigned int codec_isr_bits; | ||
406 | unsigned int codec_ready_bits; | ||
401 | 407 | ||
402 | spinlock_t reg_lock; | 408 | spinlock_t reg_lock; |
403 | 409 | ||
@@ -516,18 +522,6 @@ static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) | |||
516 | * access to AC97 codec via normal i/o (for ICH and SIS7012) | 522 | * access to AC97 codec via normal i/o (for ICH and SIS7012) |
517 | */ | 523 | */ |
518 | 524 | ||
519 | /* return the GLOB_STA bit for the corresponding codec */ | ||
520 | static unsigned int get_ich_codec_bit(struct intel8x0 *chip, unsigned int codec) | ||
521 | { | ||
522 | static unsigned int codec_bit[3] = { | ||
523 | ICH_PCR, ICH_SCR, ICH_TCR | ||
524 | }; | ||
525 | snd_assert(codec < 3, return ICH_PCR); | ||
526 | if (chip->device_type == DEVICE_INTEL_ICH4) | ||
527 | codec = chip->ac97_sdin[codec]; | ||
528 | return codec_bit[codec]; | ||
529 | } | ||
530 | |||
531 | static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec) | 525 | static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec) |
532 | { | 526 | { |
533 | int time; | 527 | int time; |
@@ -537,9 +531,9 @@ static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int code | |||
537 | if (chip->in_sdin_init) { | 531 | if (chip->in_sdin_init) { |
538 | /* we don't know the ready bit assignment at the moment */ | 532 | /* we don't know the ready bit assignment at the moment */ |
539 | /* so we check any */ | 533 | /* so we check any */ |
540 | codec = ICH_PCR | ICH_SCR | ICH_TCR; | 534 | codec = chip->codec_isr_bits; |
541 | } else { | 535 | } else { |
542 | codec = get_ich_codec_bit(chip, codec); | 536 | codec = chip->codec_bit[chip->ac97_sdin[codec]]; |
543 | } | 537 | } |
544 | 538 | ||
545 | /* codec ready ? */ | 539 | /* codec ready ? */ |
@@ -596,7 +590,7 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, | |||
596 | if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { | 590 | if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { |
597 | /* reset RCS and preserve other R/WC bits */ | 591 | /* reset RCS and preserve other R/WC bits */ |
598 | iputdword(chip, ICHREG(GLOB_STA), tmp & | 592 | iputdword(chip, ICHREG(GLOB_STA), tmp & |
599 | ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI)); | 593 | ~(chip->codec_ready_bits | ICH_GSCI)); |
600 | if (! chip->in_ac97_init) | 594 | if (! chip->in_ac97_init) |
601 | snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg); | 595 | snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg); |
602 | res = 0xffff; | 596 | res = 0xffff; |
@@ -605,7 +599,8 @@ static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97, | |||
605 | return res; | 599 | return res; |
606 | } | 600 | } |
607 | 601 | ||
608 | static void snd_intel8x0_codec_read_test(struct intel8x0 *chip, unsigned int codec) | 602 | static void __devinit snd_intel8x0_codec_read_test(struct intel8x0 *chip, |
603 | unsigned int codec) | ||
609 | { | 604 | { |
610 | unsigned int tmp; | 605 | unsigned int tmp; |
611 | 606 | ||
@@ -614,7 +609,7 @@ static void snd_intel8x0_codec_read_test(struct intel8x0 *chip, unsigned int cod | |||
614 | if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { | 609 | if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) { |
615 | /* reset RCS and preserve other R/WC bits */ | 610 | /* reset RCS and preserve other R/WC bits */ |
616 | iputdword(chip, ICHREG(GLOB_STA), tmp & | 611 | iputdword(chip, ICHREG(GLOB_STA), tmp & |
617 | ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI)); | 612 | ~(chip->codec_ready_bits | ICH_GSCI)); |
618 | } | 613 | } |
619 | } | 614 | } |
620 | } | 615 | } |
@@ -2078,23 +2073,24 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, | |||
2078 | if (chip->device_type != DEVICE_ALI) { | 2073 | if (chip->device_type != DEVICE_ALI) { |
2079 | glob_sta = igetdword(chip, ICHREG(GLOB_STA)); | 2074 | glob_sta = igetdword(chip, ICHREG(GLOB_STA)); |
2080 | ops = &standard_bus_ops; | 2075 | ops = &standard_bus_ops; |
2081 | if (chip->device_type == DEVICE_INTEL_ICH4) { | 2076 | chip->in_sdin_init = 1; |
2082 | codecs = 0; | 2077 | codecs = 0; |
2083 | if (glob_sta & ICH_PCR) | 2078 | for (i = 0; i < chip->max_codecs; i++) { |
2084 | codecs++; | 2079 | if (! (glob_sta & chip->codec_bit[i])) |
2085 | if (glob_sta & ICH_SCR) | 2080 | continue; |
2086 | codecs++; | 2081 | if (chip->device_type == DEVICE_INTEL_ICH4) { |
2087 | if (glob_sta & ICH_TCR) | 2082 | snd_intel8x0_codec_read_test(chip, codecs); |
2088 | codecs++; | 2083 | chip->ac97_sdin[codecs] = |
2089 | chip->in_sdin_init = 1; | 2084 | igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; |
2090 | for (i = 0; i < codecs; i++) { | 2085 | snd_assert(chip->ac97_sdin[codecs] < 3, |
2091 | snd_intel8x0_codec_read_test(chip, i); | 2086 | chip->ac97_sdin[codecs] = 0); |
2092 | chip->ac97_sdin[i] = igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; | 2087 | } else |
2093 | } | 2088 | chip->ac97_sdin[codecs] = i; |
2094 | chip->in_sdin_init = 0; | 2089 | codecs++; |
2095 | } else { | ||
2096 | codecs = glob_sta & ICH_SCR ? 2 : 1; | ||
2097 | } | 2090 | } |
2091 | chip->in_sdin_init = 0; | ||
2092 | if (! codecs) | ||
2093 | codecs = 1; | ||
2098 | } else { | 2094 | } else { |
2099 | ops = &ali_bus_ops; | 2095 | ops = &ali_bus_ops; |
2100 | codecs = 1; | 2096 | codecs = 1; |
@@ -2120,6 +2116,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, | |||
2120 | else | 2116 | else |
2121 | pbus->dra = 1; | 2117 | pbus->dra = 1; |
2122 | chip->ac97_bus = pbus; | 2118 | chip->ac97_bus = pbus; |
2119 | chip->ncodecs = codecs; | ||
2123 | 2120 | ||
2124 | ac97.pci = chip->pci; | 2121 | ac97.pci = chip->pci; |
2125 | for (i = 0; i < codecs; i++) { | 2122 | for (i = 0; i < codecs; i++) { |
@@ -2264,7 +2261,7 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | |||
2264 | end_time = jiffies + HZ; | 2261 | end_time = jiffies + HZ; |
2265 | do { | 2262 | do { |
2266 | status = igetdword(chip, ICHREG(GLOB_STA)) & | 2263 | status = igetdword(chip, ICHREG(GLOB_STA)) & |
2267 | (ICH_PCR | ICH_SCR | ICH_TCR); | 2264 | chip->codec_isr_bits; |
2268 | if (status) | 2265 | if (status) |
2269 | break; | 2266 | break; |
2270 | schedule_timeout_uninterruptible(1); | 2267 | schedule_timeout_uninterruptible(1); |
@@ -2276,32 +2273,27 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing) | |||
2276 | return -EIO; | 2273 | return -EIO; |
2277 | } | 2274 | } |
2278 | 2275 | ||
2279 | if (chip->device_type == DEVICE_INTEL_ICH4) | ||
2280 | /* ICH4 can have three codecs */ | ||
2281 | nstatus = ICH_PCR | ICH_SCR | ICH_TCR; | ||
2282 | else | ||
2283 | /* others up to two codecs */ | ||
2284 | nstatus = ICH_PCR | ICH_SCR; | ||
2285 | |||
2286 | /* wait for other codecs ready status. */ | 2276 | /* wait for other codecs ready status. */ |
2287 | end_time = jiffies + HZ / 4; | 2277 | end_time = jiffies + HZ / 4; |
2288 | while (status != nstatus && time_after_eq(end_time, jiffies)) { | 2278 | while (status != chip->codec_isr_bits && |
2279 | time_after_eq(end_time, jiffies)) { | ||
2289 | schedule_timeout_uninterruptible(1); | 2280 | schedule_timeout_uninterruptible(1); |
2290 | status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus; | 2281 | status |= igetdword(chip, ICHREG(GLOB_STA)) & |
2282 | chip->codec_isr_bits; | ||
2291 | } | 2283 | } |
2292 | 2284 | ||
2293 | } else { | 2285 | } else { |
2294 | /* resume phase */ | 2286 | /* resume phase */ |
2295 | int i; | 2287 | int i; |
2296 | status = 0; | 2288 | status = 0; |
2297 | for (i = 0; i < 3; i++) | 2289 | for (i = 0; i < chip->ncodecs; i++) |
2298 | if (chip->ac97[i]) | 2290 | if (chip->ac97[i]) |
2299 | status |= get_ich_codec_bit(chip, i); | 2291 | status |= chip->codec_bit[chip->ac97_sdin[i]]; |
2300 | /* wait until all the probed codecs are ready */ | 2292 | /* wait until all the probed codecs are ready */ |
2301 | end_time = jiffies + HZ; | 2293 | end_time = jiffies + HZ; |
2302 | do { | 2294 | do { |
2303 | nstatus = igetdword(chip, ICHREG(GLOB_STA)) & | 2295 | nstatus = igetdword(chip, ICHREG(GLOB_STA)) & |
2304 | (ICH_PCR | ICH_SCR | ICH_TCR); | 2296 | chip->codec_isr_bits; |
2305 | if (status == nstatus) | 2297 | if (status == nstatus) |
2306 | break; | 2298 | break; |
2307 | schedule_timeout_uninterruptible(1); | 2299 | schedule_timeout_uninterruptible(1); |
@@ -2359,7 +2351,7 @@ static int snd_intel8x0_ali_chip_init(struct intel8x0 *chip, int probing) | |||
2359 | 2351 | ||
2360 | static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing) | 2352 | static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing) |
2361 | { | 2353 | { |
2362 | unsigned int i; | 2354 | unsigned int i, timeout; |
2363 | int err; | 2355 | int err; |
2364 | 2356 | ||
2365 | if (chip->device_type != DEVICE_ALI) { | 2357 | if (chip->device_type != DEVICE_ALI) { |
@@ -2377,6 +2369,15 @@ static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing) | |||
2377 | /* reset channels */ | 2369 | /* reset channels */ |
2378 | for (i = 0; i < chip->bdbars_count; i++) | 2370 | for (i = 0; i < chip->bdbars_count; i++) |
2379 | iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); | 2371 | iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); |
2372 | for (i = 0; i < chip->bdbars_count; i++) { | ||
2373 | timeout = 100000; | ||
2374 | while (--timeout != 0) { | ||
2375 | if ((igetbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset) & ICH_RESETREGS) == 0) | ||
2376 | break; | ||
2377 | } | ||
2378 | if (timeout == 0) | ||
2379 | printk(KERN_ERR "intel8x0: reset of registers failed?\n"); | ||
2380 | } | ||
2380 | /* initialize Buffer Descriptor Lists */ | 2381 | /* initialize Buffer Descriptor Lists */ |
2381 | for (i = 0; i < chip->bdbars_count; i++) | 2382 | for (i = 0; i < chip->bdbars_count; i++) |
2382 | iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, | 2383 | iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, |
@@ -2447,7 +2448,7 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) | |||
2447 | } | 2448 | } |
2448 | } | 2449 | } |
2449 | } | 2450 | } |
2450 | for (i = 0; i < 3; i++) | 2451 | for (i = 0; i < chip->ncodecs; i++) |
2451 | snd_ac97_suspend(chip->ac97[i]); | 2452 | snd_ac97_suspend(chip->ac97[i]); |
2452 | if (chip->device_type == DEVICE_INTEL_ICH4) | 2453 | if (chip->device_type == DEVICE_INTEL_ICH4) |
2453 | chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); | 2454 | chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); |
@@ -2488,7 +2489,7 @@ static int intel8x0_resume(struct pci_dev *pci) | |||
2488 | if (chip->fix_nocache) | 2489 | if (chip->fix_nocache) |
2489 | fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); | 2490 | fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1); |
2490 | 2491 | ||
2491 | for (i = 0; i < 3; i++) | 2492 | for (i = 0; i < chip->ncodecs; i++) |
2492 | snd_ac97_resume(chip->ac97[i]); | 2493 | snd_ac97_resume(chip->ac97[i]); |
2493 | 2494 | ||
2494 | /* refill nocache */ | 2495 | /* refill nocache */ |
@@ -2619,12 +2620,20 @@ static void snd_intel8x0_proc_read(struct snd_info_entry * entry, | |||
2619 | snd_iprintf(buffer, "Global status : 0x%08x\n", tmp); | 2620 | snd_iprintf(buffer, "Global status : 0x%08x\n", tmp); |
2620 | if (chip->device_type == DEVICE_INTEL_ICH4) | 2621 | if (chip->device_type == DEVICE_INTEL_ICH4) |
2621 | snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM))); | 2622 | snd_iprintf(buffer, "SDM : 0x%08x\n", igetdword(chip, ICHREG(SDM))); |
2622 | snd_iprintf(buffer, "AC'97 codecs ready :%s%s%s%s\n", | 2623 | snd_iprintf(buffer, "AC'97 codecs ready :"); |
2623 | tmp & ICH_PCR ? " primary" : "", | 2624 | if (tmp & chip->codec_isr_bits) { |
2624 | tmp & ICH_SCR ? " secondary" : "", | 2625 | int i; |
2625 | tmp & ICH_TCR ? " tertiary" : "", | 2626 | static const char *codecs[3] = { |
2626 | (tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : ""); | 2627 | "primary", "secondary", "tertiary" |
2627 | if (chip->device_type == DEVICE_INTEL_ICH4) | 2628 | }; |
2629 | for (i = 0; i < chip->max_codecs; i++) | ||
2630 | if (tmp & chip->codec_bit[i]) | ||
2631 | snd_iprintf(buffer, " %s", codecs[i]); | ||
2632 | } else | ||
2633 | snd_iprintf(buffer, " none"); | ||
2634 | snd_iprintf(buffer, "\n"); | ||
2635 | if (chip->device_type == DEVICE_INTEL_ICH4 || | ||
2636 | chip->device_type == DEVICE_SIS) | ||
2628 | snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n", | 2637 | snd_iprintf(buffer, "AC'97 codecs SDIN : %i %i %i\n", |
2629 | chip->ac97_sdin[0], | 2638 | chip->ac97_sdin[0], |
2630 | chip->ac97_sdin[1], | 2639 | chip->ac97_sdin[1], |
@@ -2653,6 +2662,13 @@ struct ich_reg_info { | |||
2653 | unsigned int offset; | 2662 | unsigned int offset; |
2654 | }; | 2663 | }; |
2655 | 2664 | ||
2665 | static unsigned int ich_codec_bits[3] = { | ||
2666 | ICH_PCR, ICH_SCR, ICH_TCR | ||
2667 | }; | ||
2668 | static unsigned int sis_codec_bits[3] = { | ||
2669 | ICH_PCR, ICH_SCR, ICH_SIS_TCR | ||
2670 | }; | ||
2671 | |||
2656 | static int __devinit snd_intel8x0_create(struct snd_card *card, | 2672 | static int __devinit snd_intel8x0_create(struct snd_card *card, |
2657 | struct pci_dev *pci, | 2673 | struct pci_dev *pci, |
2658 | unsigned long device_type, | 2674 | unsigned long device_type, |
@@ -2835,6 +2851,29 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, | |||
2835 | pci_set_master(pci); | 2851 | pci_set_master(pci); |
2836 | synchronize_irq(chip->irq); | 2852 | synchronize_irq(chip->irq); |
2837 | 2853 | ||
2854 | switch(chip->device_type) { | ||
2855 | case DEVICE_INTEL_ICH4: | ||
2856 | /* ICH4 can have three codecs */ | ||
2857 | chip->max_codecs = 3; | ||
2858 | chip->codec_bit = ich_codec_bits; | ||
2859 | chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_TRI; | ||
2860 | break; | ||
2861 | case DEVICE_SIS: | ||
2862 | /* recent SIS7012 can have three codecs */ | ||
2863 | chip->max_codecs = 3; | ||
2864 | chip->codec_bit = sis_codec_bits; | ||
2865 | chip->codec_ready_bits = ICH_PRI | ICH_SRI | ICH_SIS_TRI; | ||
2866 | break; | ||
2867 | default: | ||
2868 | /* others up to two codecs */ | ||
2869 | chip->max_codecs = 2; | ||
2870 | chip->codec_bit = ich_codec_bits; | ||
2871 | chip->codec_ready_bits = ICH_PRI | ICH_SRI; | ||
2872 | break; | ||
2873 | } | ||
2874 | for (i = 0; i < chip->max_codecs; i++) | ||
2875 | chip->codec_isr_bits |= chip->codec_bit[i]; | ||
2876 | |||
2838 | if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { | 2877 | if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) { |
2839 | snd_intel8x0_free(chip); | 2878 | snd_intel8x0_free(chip); |
2840 | return err; | 2879 | return err; |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 4eddb512c12f..4721c096335e 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/mutex.h> | ||
30 | 31 | ||
31 | #include <sound/core.h> | 32 | #include <sound/core.h> |
32 | #include <sound/info.h> | 33 | #include <sound/info.h> |
@@ -325,7 +326,7 @@ struct snd_korg1212 { | |||
325 | int irq; | 326 | int irq; |
326 | 327 | ||
327 | spinlock_t lock; | 328 | spinlock_t lock; |
328 | struct semaphore open_mutex; | 329 | struct mutex open_mutex; |
329 | 330 | ||
330 | struct timer_list timer; /* timer callback for checking ack of stop request */ | 331 | struct timer_list timer; /* timer callback for checking ack of stop request */ |
331 | int stop_pending_cnt; /* counter for stop pending check */ | 332 | int stop_pending_cnt; /* counter for stop pending check */ |
@@ -667,13 +668,13 @@ static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212) | |||
667 | { | 668 | { |
668 | K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", | 669 | K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", |
669 | stateName[korg1212->cardState], korg1212->opencnt); | 670 | stateName[korg1212->cardState], korg1212->opencnt); |
670 | down(&korg1212->open_mutex); | 671 | mutex_lock(&korg1212->open_mutex); |
671 | if (korg1212->opencnt++ == 0) { | 672 | if (korg1212->opencnt++ == 0) { |
672 | snd_korg1212_TurnOffIdleMonitor(korg1212); | 673 | snd_korg1212_TurnOffIdleMonitor(korg1212); |
673 | snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN); | 674 | snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN); |
674 | } | 675 | } |
675 | 676 | ||
676 | up(&korg1212->open_mutex); | 677 | mutex_unlock(&korg1212->open_mutex); |
677 | return 1; | 678 | return 1; |
678 | } | 679 | } |
679 | 680 | ||
@@ -682,9 +683,9 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) | |||
682 | K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", | 683 | K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", |
683 | stateName[korg1212->cardState], korg1212->opencnt); | 684 | stateName[korg1212->cardState], korg1212->opencnt); |
684 | 685 | ||
685 | down(&korg1212->open_mutex); | 686 | mutex_lock(&korg1212->open_mutex); |
686 | if (--(korg1212->opencnt)) { | 687 | if (--(korg1212->opencnt)) { |
687 | up(&korg1212->open_mutex); | 688 | mutex_unlock(&korg1212->open_mutex); |
688 | return 0; | 689 | return 0; |
689 | } | 690 | } |
690 | 691 | ||
@@ -695,7 +696,7 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) | |||
695 | K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n", | 696 | K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n", |
696 | rc, stateName[korg1212->cardState]); | 697 | rc, stateName[korg1212->cardState]); |
697 | if (rc != K1212_CMDRET_Success) { | 698 | if (rc != K1212_CMDRET_Success) { |
698 | up(&korg1212->open_mutex); | 699 | mutex_unlock(&korg1212->open_mutex); |
699 | return 0; | 700 | return 0; |
700 | } | 701 | } |
701 | } else if (korg1212->cardState > K1212_STATE_SETUP) { | 702 | } else if (korg1212->cardState > K1212_STATE_SETUP) { |
@@ -707,7 +708,7 @@ static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212) | |||
707 | snd_korg1212_setCardState(korg1212, K1212_STATE_READY); | 708 | snd_korg1212_setCardState(korg1212, K1212_STATE_READY); |
708 | } | 709 | } |
709 | 710 | ||
710 | up(&korg1212->open_mutex); | 711 | mutex_unlock(&korg1212->open_mutex); |
711 | return 0; | 712 | return 0; |
712 | } | 713 | } |
713 | 714 | ||
@@ -2179,7 +2180,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * | |||
2179 | 2180 | ||
2180 | init_waitqueue_head(&korg1212->wait); | 2181 | init_waitqueue_head(&korg1212->wait); |
2181 | spin_lock_init(&korg1212->lock); | 2182 | spin_lock_init(&korg1212->lock); |
2182 | init_MUTEX(&korg1212->open_mutex); | 2183 | mutex_init(&korg1212->open_mutex); |
2183 | init_timer(&korg1212->timer); | 2184 | init_timer(&korg1212->timer); |
2184 | korg1212->timer.function = snd_korg1212_timer_func; | 2185 | korg1212->timer.function = snd_korg1212_timer_func; |
2185 | korg1212->timer.data = (unsigned long)korg1212; | 2186 | korg1212->timer.data = (unsigned long)korg1212; |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index d3ef0cc6c4f9..8bc084956c28 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/dma-mapping.h> | ||
40 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
41 | #include <linux/vmalloc.h> | 42 | #include <linux/vmalloc.h> |
42 | #include <linux/moduleparam.h> | 43 | #include <linux/moduleparam.h> |
@@ -2657,8 +2658,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2657 | return -EIO; | 2658 | return -EIO; |
2658 | 2659 | ||
2659 | /* check, if we can restrict PCI DMA transfers to 28 bits */ | 2660 | /* check, if we can restrict PCI DMA transfers to 28 bits */ |
2660 | if (pci_set_dma_mask(pci, 0x0fffffff) < 0 || | 2661 | if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || |
2661 | pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) { | 2662 | pci_set_consistent_dma_mask(pci, DMA_28BIT_MASK) < 0) { |
2662 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); | 2663 | snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n"); |
2663 | pci_disable_device(pci); | 2664 | pci_disable_device(pci); |
2664 | return -ENXIO; | 2665 | return -ENXIO; |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index b218e1d20c78..43ee3b2b948f 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -25,7 +25,9 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/mutex.h> | ||
29 | #include <sound/core.h> | 31 | #include <sound/core.h> |
30 | #include <sound/initval.h> | 32 | #include <sound/initval.h> |
31 | #include <sound/info.h> | 33 | #include <sound/info.h> |
@@ -589,7 +591,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, | |||
589 | /* set up format for the stream */ | 591 | /* set up format for the stream */ |
590 | format = params_format(hw); | 592 | format = params_format(hw); |
591 | 593 | ||
592 | down(&mgr->setup_mutex); | 594 | mutex_lock(&mgr->setup_mutex); |
593 | 595 | ||
594 | /* update the stream levels */ | 596 | /* update the stream levels */ |
595 | if( stream->pcm_number <= MIXART_PCM_DIGITAL ) { | 597 | if( stream->pcm_number <= MIXART_PCM_DIGITAL ) { |
@@ -628,7 +630,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, | |||
628 | bufferinfo[i].available_length, | 630 | bufferinfo[i].available_length, |
629 | subs->number); | 631 | subs->number); |
630 | } | 632 | } |
631 | up(&mgr->setup_mutex); | 633 | mutex_unlock(&mgr->setup_mutex); |
632 | 634 | ||
633 | return err; | 635 | return err; |
634 | } | 636 | } |
@@ -700,7 +702,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs) | |||
700 | int err = 0; | 702 | int err = 0; |
701 | int pcm_number; | 703 | int pcm_number; |
702 | 704 | ||
703 | down(&mgr->setup_mutex); | 705 | mutex_lock(&mgr->setup_mutex); |
704 | 706 | ||
705 | if ( pcm == chip->pcm ) { | 707 | if ( pcm == chip->pcm ) { |
706 | pcm_number = MIXART_PCM_ANALOG; | 708 | pcm_number = MIXART_PCM_ANALOG; |
@@ -758,7 +760,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs) | |||
758 | } | 760 | } |
759 | 761 | ||
760 | _exit_open: | 762 | _exit_open: |
761 | up(&mgr->setup_mutex); | 763 | mutex_unlock(&mgr->setup_mutex); |
762 | 764 | ||
763 | return err; | 765 | return err; |
764 | } | 766 | } |
@@ -775,7 +777,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs) | |||
775 | int err = 0; | 777 | int err = 0; |
776 | int pcm_number; | 778 | int pcm_number; |
777 | 779 | ||
778 | down(&mgr->setup_mutex); | 780 | mutex_lock(&mgr->setup_mutex); |
779 | 781 | ||
780 | if ( pcm == chip->pcm ) { | 782 | if ( pcm == chip->pcm ) { |
781 | pcm_number = MIXART_PCM_ANALOG; | 783 | pcm_number = MIXART_PCM_ANALOG; |
@@ -836,7 +838,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs) | |||
836 | } | 838 | } |
837 | 839 | ||
838 | _exit_open: | 840 | _exit_open: |
839 | up(&mgr->setup_mutex); | 841 | mutex_unlock(&mgr->setup_mutex); |
840 | 842 | ||
841 | return err; | 843 | return err; |
842 | } | 844 | } |
@@ -849,7 +851,7 @@ static int snd_mixart_close(struct snd_pcm_substream *subs) | |||
849 | struct mixart_mgr *mgr = chip->mgr; | 851 | struct mixart_mgr *mgr = chip->mgr; |
850 | struct mixart_stream *stream = subs->runtime->private_data; | 852 | struct mixart_stream *stream = subs->runtime->private_data; |
851 | 853 | ||
852 | down(&mgr->setup_mutex); | 854 | mutex_lock(&mgr->setup_mutex); |
853 | 855 | ||
854 | snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number); | 856 | snd_printdd("snd_mixart_close C%d/P%d/Sub%d\n", chip->chip_idx, stream->pcm_number, subs->number); |
855 | 857 | ||
@@ -868,7 +870,7 @@ static int snd_mixart_close(struct snd_pcm_substream *subs) | |||
868 | stream->status = MIXART_STREAM_STATUS_FREE; | 870 | stream->status = MIXART_STREAM_STATUS_FREE; |
869 | stream->substream = NULL; | 871 | stream->substream = NULL; |
870 | 872 | ||
871 | up(&mgr->setup_mutex); | 873 | mutex_unlock(&mgr->setup_mutex); |
872 | return 0; | 874 | return 0; |
873 | } | 875 | } |
874 | 876 | ||
@@ -1288,7 +1290,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, | |||
1288 | pci_set_master(pci); | 1290 | pci_set_master(pci); |
1289 | 1291 | ||
1290 | /* check if we can restrict PCI DMA transfers to 32 bits */ | 1292 | /* check if we can restrict PCI DMA transfers to 32 bits */ |
1291 | if (pci_set_dma_mask(pci, 0xffffffff) < 0) { | 1293 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { |
1292 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); | 1294 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); |
1293 | pci_disable_device(pci); | 1295 | pci_disable_device(pci); |
1294 | return -ENXIO; | 1296 | return -ENXIO; |
@@ -1335,12 +1337,12 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, | |||
1335 | mgr->msg_fifo_writeptr = 0; | 1337 | mgr->msg_fifo_writeptr = 0; |
1336 | 1338 | ||
1337 | spin_lock_init(&mgr->msg_lock); | 1339 | spin_lock_init(&mgr->msg_lock); |
1338 | init_MUTEX(&mgr->msg_mutex); | 1340 | mutex_init(&mgr->msg_mutex); |
1339 | init_waitqueue_head(&mgr->msg_sleep); | 1341 | init_waitqueue_head(&mgr->msg_sleep); |
1340 | atomic_set(&mgr->msg_processed, 0); | 1342 | atomic_set(&mgr->msg_processed, 0); |
1341 | 1343 | ||
1342 | /* init setup mutex*/ | 1344 | /* init setup mutex*/ |
1343 | init_MUTEX(&mgr->setup_mutex); | 1345 | mutex_init(&mgr->setup_mutex); |
1344 | 1346 | ||
1345 | /* init message taslket */ | 1347 | /* init message taslket */ |
1346 | tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr); | 1348 | tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr); |
diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h index 3e84863ca02c..561634d5c007 100644 --- a/sound/pci/mixart/mixart.h +++ b/sound/pci/mixart/mixart.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __SOUND_MIXART_H | 24 | #define __SOUND_MIXART_H |
25 | 25 | ||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
28 | 29 | ||
29 | #define MIXART_DRIVER_VERSION 0x000100 /* 0.1.0 */ | 30 | #define MIXART_DRIVER_VERSION 0x000100 /* 0.1.0 */ |
@@ -92,9 +93,9 @@ struct mixart_mgr { | |||
92 | 93 | ||
93 | spinlock_t lock; /* interrupt spinlock */ | 94 | spinlock_t lock; /* interrupt spinlock */ |
94 | spinlock_t msg_lock; /* mailbox spinlock */ | 95 | spinlock_t msg_lock; /* mailbox spinlock */ |
95 | struct semaphore msg_mutex; /* mutex for blocking_requests */ | 96 | struct mutex msg_mutex; /* mutex for blocking_requests */ |
96 | 97 | ||
97 | struct semaphore setup_mutex; /* mutex used in hw_params, open and close */ | 98 | struct mutex setup_mutex; /* mutex used in hw_params, open and close */ |
98 | 99 | ||
99 | /* hardware interface */ | 100 | /* hardware interface */ |
100 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ | 101 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ |
@@ -107,7 +108,7 @@ struct mixart_mgr { | |||
107 | int sample_rate; | 108 | int sample_rate; |
108 | int ref_count_rate; | 109 | int ref_count_rate; |
109 | 110 | ||
110 | struct semaphore mixer_mutex; /* mutex for mixer */ | 111 | struct mutex mixer_mutex; /* mutex for mixer */ |
111 | 112 | ||
112 | }; | 113 | }; |
113 | 114 | ||
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index 07c707d7ebbf..406ac3a9d42a 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c | |||
@@ -22,6 +22,8 @@ | |||
22 | 22 | ||
23 | #include <sound/driver.h> | 23 | #include <sound/driver.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/mutex.h> | ||
26 | |||
25 | #include <asm/io.h> | 27 | #include <asm/io.h> |
26 | #include <sound/core.h> | 28 | #include <sound/core.h> |
27 | #include "mixart.h" | 29 | #include "mixart.h" |
@@ -239,7 +241,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int | |||
239 | wait_queue_t wait; | 241 | wait_queue_t wait; |
240 | long timeout; | 242 | long timeout; |
241 | 243 | ||
242 | down(&mgr->msg_mutex); | 244 | mutex_lock(&mgr->msg_mutex); |
243 | 245 | ||
244 | init_waitqueue_entry(&wait, current); | 246 | init_waitqueue_entry(&wait, current); |
245 | 247 | ||
@@ -248,7 +250,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int | |||
248 | err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */ | 250 | err = send_msg(mgr, request, max_resp_size, 1, &msg_frame); /* send and mark the answer pending */ |
249 | if (err) { | 251 | if (err) { |
250 | spin_unlock_irq(&mgr->msg_lock); | 252 | spin_unlock_irq(&mgr->msg_lock); |
251 | up(&mgr->msg_mutex); | 253 | mutex_unlock(&mgr->msg_mutex); |
252 | return err; | 254 | return err; |
253 | } | 255 | } |
254 | 256 | ||
@@ -260,7 +262,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int | |||
260 | 262 | ||
261 | if (! timeout) { | 263 | if (! timeout) { |
262 | /* error - no ack */ | 264 | /* error - no ack */ |
263 | up(&mgr->msg_mutex); | 265 | mutex_unlock(&mgr->msg_mutex); |
264 | snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame); | 266 | snd_printk(KERN_ERR "error: no reponse on msg %x\n", msg_frame); |
265 | return -EIO; | 267 | return -EIO; |
266 | } | 268 | } |
@@ -276,7 +278,7 @@ int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int | |||
276 | if( request->message_id != resp.message_id ) | 278 | if( request->message_id != resp.message_id ) |
277 | snd_printk(KERN_ERR "REPONSE ERROR!\n"); | 279 | snd_printk(KERN_ERR "REPONSE ERROR!\n"); |
278 | 280 | ||
279 | up(&mgr->msg_mutex); | 281 | mutex_unlock(&mgr->msg_mutex); |
280 | return err; | 282 | return err; |
281 | } | 283 | } |
282 | 284 | ||
@@ -292,7 +294,7 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, | |||
292 | snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL); | 294 | snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL); |
293 | snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL); | 295 | snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL); |
294 | 296 | ||
295 | down(&mgr->msg_mutex); | 297 | mutex_lock(&mgr->msg_mutex); |
296 | 298 | ||
297 | init_waitqueue_entry(&wait, current); | 299 | init_waitqueue_entry(&wait, current); |
298 | 300 | ||
@@ -301,7 +303,7 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, | |||
301 | err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, ¬if_event); /* send and mark the notification event pending */ | 303 | err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, ¬if_event); /* send and mark the notification event pending */ |
302 | if(err) { | 304 | if(err) { |
303 | spin_unlock_irq(&mgr->msg_lock); | 305 | spin_unlock_irq(&mgr->msg_lock); |
304 | up(&mgr->msg_mutex); | 306 | mutex_unlock(&mgr->msg_mutex); |
305 | return err; | 307 | return err; |
306 | } | 308 | } |
307 | 309 | ||
@@ -313,12 +315,12 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, | |||
313 | 315 | ||
314 | if (! timeout) { | 316 | if (! timeout) { |
315 | /* error - no ack */ | 317 | /* error - no ack */ |
316 | up(&mgr->msg_mutex); | 318 | mutex_unlock(&mgr->msg_mutex); |
317 | snd_printk(KERN_ERR "error: notification %x not received\n", notif_event); | 319 | snd_printk(KERN_ERR "error: notification %x not received\n", notif_event); |
318 | return -EIO; | 320 | return -EIO; |
319 | } | 321 | } |
320 | 322 | ||
321 | up(&mgr->msg_mutex); | 323 | mutex_unlock(&mgr->msg_mutex); |
322 | return 0; | 324 | return 0; |
323 | } | 325 | } |
324 | 326 | ||
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c index 36a7e9ddfb15..ed47b732c103 100644 --- a/sound/pci/mixart/mixart_mixer.c +++ b/sound/pci/mixart/mixart_mixer.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/time.h> | 24 | #include <linux/time.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/mutex.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include "mixart.h" | 30 | #include "mixart.h" |
29 | #include "mixart_core.h" | 31 | #include "mixart_core.h" |
@@ -353,7 +355,7 @@ static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
353 | static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 355 | static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
354 | { | 356 | { |
355 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 357 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
356 | down(&chip->mgr->mixer_mutex); | 358 | mutex_lock(&chip->mgr->mixer_mutex); |
357 | if(kcontrol->private_value == 0) { /* playback */ | 359 | if(kcontrol->private_value == 0) { /* playback */ |
358 | ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; | 360 | ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; |
359 | ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; | 361 | ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; |
@@ -361,7 +363,7 @@ static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
361 | ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; | 363 | ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; |
362 | ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; | 364 | ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; |
363 | } | 365 | } |
364 | up(&chip->mgr->mixer_mutex); | 366 | mutex_unlock(&chip->mgr->mixer_mutex); |
365 | return 0; | 367 | return 0; |
366 | } | 368 | } |
367 | 369 | ||
@@ -371,7 +373,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
371 | int changed = 0; | 373 | int changed = 0; |
372 | int is_capture, i; | 374 | int is_capture, i; |
373 | 375 | ||
374 | down(&chip->mgr->mixer_mutex); | 376 | mutex_lock(&chip->mgr->mixer_mutex); |
375 | is_capture = (kcontrol->private_value != 0); | 377 | is_capture = (kcontrol->private_value != 0); |
376 | for(i=0; i<2; i++) { | 378 | for(i=0; i<2; i++) { |
377 | int new_volume = ucontrol->value.integer.value[i]; | 379 | int new_volume = ucontrol->value.integer.value[i]; |
@@ -382,7 +384,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
382 | } | 384 | } |
383 | } | 385 | } |
384 | if(changed) mixart_update_analog_audio_level(chip, is_capture); | 386 | if(changed) mixart_update_analog_audio_level(chip, is_capture); |
385 | up(&chip->mgr->mixer_mutex); | 387 | mutex_unlock(&chip->mgr->mixer_mutex); |
386 | return changed; | 388 | return changed; |
387 | } | 389 | } |
388 | 390 | ||
@@ -408,10 +410,10 @@ static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
408 | { | 410 | { |
409 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 411 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
410 | 412 | ||
411 | down(&chip->mgr->mixer_mutex); | 413 | mutex_lock(&chip->mgr->mixer_mutex); |
412 | ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; | 414 | ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; |
413 | ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; | 415 | ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; |
414 | up(&chip->mgr->mixer_mutex); | 416 | mutex_unlock(&chip->mgr->mixer_mutex); |
415 | return 0; | 417 | return 0; |
416 | } | 418 | } |
417 | 419 | ||
@@ -419,7 +421,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
419 | { | 421 | { |
420 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 422 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
421 | int i, changed = 0; | 423 | int i, changed = 0; |
422 | down(&chip->mgr->mixer_mutex); | 424 | mutex_lock(&chip->mgr->mixer_mutex); |
423 | for(i=0; i<2; i++) { | 425 | for(i=0; i<2; i++) { |
424 | if(chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { | 426 | if(chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { |
425 | chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; | 427 | chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; |
@@ -427,7 +429,7 @@ static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
427 | } | 429 | } |
428 | } | 430 | } |
429 | if(changed) mixart_update_analog_audio_level(chip, 0); /* update playback levels */ | 431 | if(changed) mixart_update_analog_audio_level(chip, 0); /* update playback levels */ |
430 | up(&chip->mgr->mixer_mutex); | 432 | mutex_unlock(&chip->mgr->mixer_mutex); |
431 | return changed; | 433 | return changed; |
432 | } | 434 | } |
433 | 435 | ||
@@ -817,7 +819,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
817 | int *stored_volume; | 819 | int *stored_volume; |
818 | int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK; | 820 | int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK; |
819 | int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; | 821 | int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; |
820 | down(&chip->mgr->mixer_mutex); | 822 | mutex_lock(&chip->mgr->mixer_mutex); |
821 | if(is_capture) { | 823 | if(is_capture) { |
822 | if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ | 824 | if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ |
823 | else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ | 825 | else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ |
@@ -828,7 +830,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
828 | } | 830 | } |
829 | ucontrol->value.integer.value[0] = stored_volume[0]; | 831 | ucontrol->value.integer.value[0] = stored_volume[0]; |
830 | ucontrol->value.integer.value[1] = stored_volume[1]; | 832 | ucontrol->value.integer.value[1] = stored_volume[1]; |
831 | up(&chip->mgr->mixer_mutex); | 833 | mutex_unlock(&chip->mgr->mixer_mutex); |
832 | return 0; | 834 | return 0; |
833 | } | 835 | } |
834 | 836 | ||
@@ -841,7 +843,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
841 | int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; | 843 | int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; |
842 | int* stored_volume; | 844 | int* stored_volume; |
843 | int i; | 845 | int i; |
844 | down(&chip->mgr->mixer_mutex); | 846 | mutex_lock(&chip->mgr->mixer_mutex); |
845 | if(is_capture) { | 847 | if(is_capture) { |
846 | if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ | 848 | if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ |
847 | else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ | 849 | else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ |
@@ -860,7 +862,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
860 | if(is_capture) mixart_update_capture_stream_level(chip, is_aes); | 862 | if(is_capture) mixart_update_capture_stream_level(chip, is_aes); |
861 | else mixart_update_playback_stream_level(chip, is_aes, idx); | 863 | else mixart_update_playback_stream_level(chip, is_aes, idx); |
862 | } | 864 | } |
863 | up(&chip->mgr->mixer_mutex); | 865 | mutex_unlock(&chip->mgr->mixer_mutex); |
864 | return changed; | 866 | return changed; |
865 | } | 867 | } |
866 | 868 | ||
@@ -880,12 +882,12 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
880 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 882 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
881 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ | 883 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ |
882 | snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); | 884 | snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); |
883 | down(&chip->mgr->mixer_mutex); | 885 | mutex_lock(&chip->mgr->mixer_mutex); |
884 | if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ | 886 | if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ |
885 | idx += MIXART_PLAYBACK_STREAMS; | 887 | idx += MIXART_PLAYBACK_STREAMS; |
886 | ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; | 888 | ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; |
887 | ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; | 889 | ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; |
888 | up(&chip->mgr->mixer_mutex); | 890 | mutex_unlock(&chip->mgr->mixer_mutex); |
889 | return 0; | 891 | return 0; |
890 | } | 892 | } |
891 | 893 | ||
@@ -897,7 +899,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
897 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ | 899 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ |
898 | int i, j; | 900 | int i, j; |
899 | snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); | 901 | snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); |
900 | down(&chip->mgr->mixer_mutex); | 902 | mutex_lock(&chip->mgr->mixer_mutex); |
901 | j = idx; | 903 | j = idx; |
902 | if(is_aes) j += MIXART_PLAYBACK_STREAMS; | 904 | if(is_aes) j += MIXART_PLAYBACK_STREAMS; |
903 | for(i=0; i<2; i++) { | 905 | for(i=0; i<2; i++) { |
@@ -907,7 +909,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ | |||
907 | } | 909 | } |
908 | } | 910 | } |
909 | if(changed) mixart_update_playback_stream_level(chip, is_aes, idx); | 911 | if(changed) mixart_update_playback_stream_level(chip, is_aes, idx); |
910 | up(&chip->mgr->mixer_mutex); | 912 | mutex_unlock(&chip->mgr->mixer_mutex); |
911 | return changed; | 913 | return changed; |
912 | } | 914 | } |
913 | 915 | ||
@@ -956,10 +958,10 @@ static int mixart_update_monitoring(struct snd_mixart* chip, int channel) | |||
956 | static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 958 | static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
957 | { | 959 | { |
958 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 960 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
959 | down(&chip->mgr->mixer_mutex); | 961 | mutex_lock(&chip->mgr->mixer_mutex); |
960 | ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; | 962 | ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; |
961 | ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; | 963 | ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; |
962 | up(&chip->mgr->mixer_mutex); | 964 | mutex_unlock(&chip->mgr->mixer_mutex); |
963 | return 0; | 965 | return 0; |
964 | } | 966 | } |
965 | 967 | ||
@@ -968,7 +970,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
968 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 970 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
969 | int changed = 0; | 971 | int changed = 0; |
970 | int i; | 972 | int i; |
971 | down(&chip->mgr->mixer_mutex); | 973 | mutex_lock(&chip->mgr->mixer_mutex); |
972 | for(i=0; i<2; i++) { | 974 | for(i=0; i<2; i++) { |
973 | if(chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { | 975 | if(chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { |
974 | chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; | 976 | chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; |
@@ -976,7 +978,7 @@ static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
976 | changed = 1; | 978 | changed = 1; |
977 | } | 979 | } |
978 | } | 980 | } |
979 | up(&chip->mgr->mixer_mutex); | 981 | mutex_unlock(&chip->mgr->mixer_mutex); |
980 | return changed; | 982 | return changed; |
981 | } | 983 | } |
982 | 984 | ||
@@ -995,10 +997,10 @@ static struct snd_kcontrol_new mixart_control_monitor_vol = { | |||
995 | static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 997 | static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
996 | { | 998 | { |
997 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 999 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
998 | down(&chip->mgr->mixer_mutex); | 1000 | mutex_lock(&chip->mgr->mixer_mutex); |
999 | ucontrol->value.integer.value[0] = chip->monitoring_active[0]; | 1001 | ucontrol->value.integer.value[0] = chip->monitoring_active[0]; |
1000 | ucontrol->value.integer.value[1] = chip->monitoring_active[1]; | 1002 | ucontrol->value.integer.value[1] = chip->monitoring_active[1]; |
1001 | up(&chip->mgr->mixer_mutex); | 1003 | mutex_unlock(&chip->mgr->mixer_mutex); |
1002 | return 0; | 1004 | return 0; |
1003 | } | 1005 | } |
1004 | 1006 | ||
@@ -1007,7 +1009,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1007 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); | 1009 | struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); |
1008 | int changed = 0; | 1010 | int changed = 0; |
1009 | int i; | 1011 | int i; |
1010 | down(&chip->mgr->mixer_mutex); | 1012 | mutex_lock(&chip->mgr->mixer_mutex); |
1011 | for(i=0; i<2; i++) { | 1013 | for(i=0; i<2; i++) { |
1012 | if(chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { | 1014 | if(chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { |
1013 | chip->monitoring_active[i] = ucontrol->value.integer.value[i]; | 1015 | chip->monitoring_active[i] = ucontrol->value.integer.value[i]; |
@@ -1029,7 +1031,7 @@ static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1029 | } | 1031 | } |
1030 | } | 1032 | } |
1031 | 1033 | ||
1032 | up(&chip->mgr->mixer_mutex); | 1034 | mutex_unlock(&chip->mgr->mixer_mutex); |
1033 | return (changed != 0); | 1035 | return (changed != 0); |
1034 | } | 1036 | } |
1035 | 1037 | ||
@@ -1059,7 +1061,7 @@ int snd_mixart_create_mixer(struct mixart_mgr *mgr) | |||
1059 | struct snd_mixart *chip; | 1061 | struct snd_mixart *chip; |
1060 | int err, i; | 1062 | int err, i; |
1061 | 1063 | ||
1062 | init_MUTEX(&mgr->mixer_mutex); /* can be in another place */ | 1064 | mutex_init(&mgr->mixer_mutex); /* can be in another place */ |
1063 | 1065 | ||
1064 | for(i=0; i<mgr->num_cards; i++) { | 1066 | for(i=0; i<mgr->num_cards; i++) { |
1065 | struct snd_kcontrol_new temp; | 1067 | struct snd_kcontrol_new temp; |
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 0d0ff54f0fc6..cc297abc9d11 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
35 | #include <linux/mutex.h> | ||
36 | |||
35 | #include <sound/core.h> | 37 | #include <sound/core.h> |
36 | #include <sound/info.h> | 38 | #include <sound/info.h> |
37 | #include <sound/control.h> | 39 | #include <sound/control.h> |
@@ -226,6 +228,7 @@ struct nm256 { | |||
226 | unsigned int use_cache: 1; /* use one big coef. table */ | 228 | unsigned int use_cache: 1; /* use one big coef. table */ |
227 | unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ | 229 | unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */ |
228 | unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */ | 230 | unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */ |
231 | unsigned int in_resume: 1; | ||
229 | 232 | ||
230 | int mixer_base; /* register offset of ac97 mixer */ | 233 | int mixer_base; /* register offset of ac97 mixer */ |
231 | int mixer_status_offset; /* offset of mixer status reg. */ | 234 | int mixer_status_offset; /* offset of mixer status reg. */ |
@@ -235,11 +238,12 @@ struct nm256 { | |||
235 | int irq_acks; | 238 | int irq_acks; |
236 | irqreturn_t (*interrupt)(int, void *, struct pt_regs *); | 239 | irqreturn_t (*interrupt)(int, void *, struct pt_regs *); |
237 | int badintrcount; /* counter to check bogus interrupts */ | 240 | int badintrcount; /* counter to check bogus interrupts */ |
238 | struct semaphore irq_mutex; | 241 | struct mutex irq_mutex; |
239 | 242 | ||
240 | struct nm256_stream streams[2]; | 243 | struct nm256_stream streams[2]; |
241 | 244 | ||
242 | struct snd_ac97 *ac97; | 245 | struct snd_ac97 *ac97; |
246 | unsigned short *ac97_regs; /* register caches, only for valid regs */ | ||
243 | 247 | ||
244 | struct snd_pcm *pcm; | 248 | struct snd_pcm *pcm; |
245 | 249 | ||
@@ -459,32 +463,32 @@ snd_nm256_set_format(struct nm256 *chip, struct nm256_stream *s, | |||
459 | /* acquire interrupt */ | 463 | /* acquire interrupt */ |
460 | static int snd_nm256_acquire_irq(struct nm256 *chip) | 464 | static int snd_nm256_acquire_irq(struct nm256 *chip) |
461 | { | 465 | { |
462 | down(&chip->irq_mutex); | 466 | mutex_lock(&chip->irq_mutex); |
463 | if (chip->irq < 0) { | 467 | if (chip->irq < 0) { |
464 | if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, | 468 | if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ, |
465 | chip->card->driver, chip)) { | 469 | chip->card->driver, chip)) { |
466 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq); | 470 | snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq); |
467 | up(&chip->irq_mutex); | 471 | mutex_unlock(&chip->irq_mutex); |
468 | return -EBUSY; | 472 | return -EBUSY; |
469 | } | 473 | } |
470 | chip->irq = chip->pci->irq; | 474 | chip->irq = chip->pci->irq; |
471 | } | 475 | } |
472 | chip->irq_acks++; | 476 | chip->irq_acks++; |
473 | up(&chip->irq_mutex); | 477 | mutex_unlock(&chip->irq_mutex); |
474 | return 0; | 478 | return 0; |
475 | } | 479 | } |
476 | 480 | ||
477 | /* release interrupt */ | 481 | /* release interrupt */ |
478 | static void snd_nm256_release_irq(struct nm256 *chip) | 482 | static void snd_nm256_release_irq(struct nm256 *chip) |
479 | { | 483 | { |
480 | down(&chip->irq_mutex); | 484 | mutex_lock(&chip->irq_mutex); |
481 | if (chip->irq_acks > 0) | 485 | if (chip->irq_acks > 0) |
482 | chip->irq_acks--; | 486 | chip->irq_acks--; |
483 | if (chip->irq_acks == 0 && chip->irq >= 0) { | 487 | if (chip->irq_acks == 0 && chip->irq >= 0) { |
484 | free_irq(chip->irq, chip); | 488 | free_irq(chip->irq, chip); |
485 | chip->irq = -1; | 489 | chip->irq = -1; |
486 | } | 490 | } |
487 | up(&chip->irq_mutex); | 491 | mutex_unlock(&chip->irq_mutex); |
488 | } | 492 | } |
489 | 493 | ||
490 | /* | 494 | /* |
@@ -1151,23 +1155,63 @@ snd_nm256_ac97_ready(struct nm256 *chip) | |||
1151 | return 0; | 1155 | return 0; |
1152 | } | 1156 | } |
1153 | 1157 | ||
1158 | /* | ||
1159 | * Initial register values to be written to the AC97 mixer. | ||
1160 | * While most of these are identical to the reset values, we do this | ||
1161 | * so that we have most of the register contents cached--this avoids | ||
1162 | * reading from the mixer directly (which seems to be problematic, | ||
1163 | * probably due to ignorance). | ||
1164 | */ | ||
1165 | |||
1166 | struct initialValues { | ||
1167 | unsigned short reg; | ||
1168 | unsigned short value; | ||
1169 | }; | ||
1170 | |||
1171 | static struct initialValues nm256_ac97_init_val[] = | ||
1172 | { | ||
1173 | { AC97_MASTER, 0x8000 }, | ||
1174 | { AC97_HEADPHONE, 0x8000 }, | ||
1175 | { AC97_MASTER_MONO, 0x8000 }, | ||
1176 | { AC97_PC_BEEP, 0x8000 }, | ||
1177 | { AC97_PHONE, 0x8008 }, | ||
1178 | { AC97_MIC, 0x8000 }, | ||
1179 | { AC97_LINE, 0x8808 }, | ||
1180 | { AC97_CD, 0x8808 }, | ||
1181 | { AC97_VIDEO, 0x8808 }, | ||
1182 | { AC97_AUX, 0x8808 }, | ||
1183 | { AC97_PCM, 0x8808 }, | ||
1184 | { AC97_REC_SEL, 0x0000 }, | ||
1185 | { AC97_REC_GAIN, 0x0B0B }, | ||
1186 | { AC97_GENERAL_PURPOSE, 0x0000 }, | ||
1187 | { AC97_3D_CONTROL, 0x8000 }, | ||
1188 | { AC97_VENDOR_ID1, 0x8384 }, | ||
1189 | { AC97_VENDOR_ID2, 0x7609 }, | ||
1190 | }; | ||
1191 | |||
1192 | static int nm256_ac97_idx(unsigned short reg) | ||
1193 | { | ||
1194 | int i; | ||
1195 | for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++) | ||
1196 | if (nm256_ac97_init_val[i].reg == reg) | ||
1197 | return i; | ||
1198 | return -1; | ||
1199 | } | ||
1200 | |||
1154 | /* | 1201 | /* |
1202 | * some nm256 easily crash when reading from mixer registers | ||
1203 | * thus we're treating it as a write-only mixer and cache the | ||
1204 | * written values | ||
1155 | */ | 1205 | */ |
1156 | static unsigned short | 1206 | static unsigned short |
1157 | snd_nm256_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 1207 | snd_nm256_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
1158 | { | 1208 | { |
1159 | struct nm256 *chip = ac97->private_data; | 1209 | struct nm256 *chip = ac97->private_data; |
1160 | int res; | 1210 | int idx = nm256_ac97_idx(reg); |
1161 | 1211 | ||
1162 | if (reg >= 128) | 1212 | if (idx < 0) |
1163 | return 0; | 1213 | return 0; |
1164 | 1214 | return chip->ac97_regs[idx]; | |
1165 | if (! snd_nm256_ac97_ready(chip)) | ||
1166 | return 0; | ||
1167 | res = snd_nm256_readw(chip, chip->mixer_base + reg); | ||
1168 | /* Magic delay. Bleah yucky. */ | ||
1169 | msleep(1); | ||
1170 | return res; | ||
1171 | } | 1215 | } |
1172 | 1216 | ||
1173 | /* | 1217 | /* |
@@ -1178,8 +1222,12 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, | |||
1178 | { | 1222 | { |
1179 | struct nm256 *chip = ac97->private_data; | 1223 | struct nm256 *chip = ac97->private_data; |
1180 | int tries = 2; | 1224 | int tries = 2; |
1225 | int idx = nm256_ac97_idx(reg); | ||
1181 | u32 base; | 1226 | u32 base; |
1182 | 1227 | ||
1228 | if (idx < 0) | ||
1229 | return; | ||
1230 | |||
1183 | base = chip->mixer_base; | 1231 | base = chip->mixer_base; |
1184 | 1232 | ||
1185 | snd_nm256_ac97_ready(chip); | 1233 | snd_nm256_ac97_ready(chip); |
@@ -1188,12 +1236,32 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, | |||
1188 | while (tries-- > 0) { | 1236 | while (tries-- > 0) { |
1189 | snd_nm256_writew(chip, base + reg, val); | 1237 | snd_nm256_writew(chip, base + reg, val); |
1190 | msleep(1); /* a little delay here seems better.. */ | 1238 | msleep(1); /* a little delay here seems better.. */ |
1191 | if (snd_nm256_ac97_ready(chip)) | 1239 | if (snd_nm256_ac97_ready(chip)) { |
1240 | /* successful write: set cache */ | ||
1241 | chip->ac97_regs[idx] = val; | ||
1192 | return; | 1242 | return; |
1243 | } | ||
1193 | } | 1244 | } |
1194 | snd_printd("nm256: ac97 codec not ready..\n"); | 1245 | snd_printd("nm256: ac97 codec not ready..\n"); |
1195 | } | 1246 | } |
1196 | 1247 | ||
1248 | /* static resolution table */ | ||
1249 | static struct snd_ac97_res_table nm256_res_table[] = { | ||
1250 | { AC97_MASTER, 0x1f1f }, | ||
1251 | { AC97_HEADPHONE, 0x1f1f }, | ||
1252 | { AC97_MASTER_MONO, 0x001f }, | ||
1253 | { AC97_PC_BEEP, 0x001f }, | ||
1254 | { AC97_PHONE, 0x001f }, | ||
1255 | { AC97_MIC, 0x001f }, | ||
1256 | { AC97_LINE, 0x1f1f }, | ||
1257 | { AC97_CD, 0x1f1f }, | ||
1258 | { AC97_VIDEO, 0x1f1f }, | ||
1259 | { AC97_AUX, 0x1f1f }, | ||
1260 | { AC97_PCM, 0x1f1f }, | ||
1261 | { AC97_REC_GAIN, 0x0f0f }, | ||
1262 | { } /* terminator */ | ||
1263 | }; | ||
1264 | |||
1197 | /* initialize the ac97 into a known state */ | 1265 | /* initialize the ac97 into a known state */ |
1198 | static void | 1266 | static void |
1199 | snd_nm256_ac97_reset(struct snd_ac97 *ac97) | 1267 | snd_nm256_ac97_reset(struct snd_ac97 *ac97) |
@@ -1211,6 +1279,16 @@ snd_nm256_ac97_reset(struct snd_ac97 *ac97) | |||
1211 | snd_nm256_writeb(chip, 0x6cc, 0x80); | 1279 | snd_nm256_writeb(chip, 0x6cc, 0x80); |
1212 | snd_nm256_writeb(chip, 0x6cc, 0x0); | 1280 | snd_nm256_writeb(chip, 0x6cc, 0x0); |
1213 | } | 1281 | } |
1282 | if (! chip->in_resume) { | ||
1283 | int i; | ||
1284 | for (i = 0; i < ARRAY_SIZE(nm256_ac97_init_val); i++) { | ||
1285 | /* preload the cache, so as to avoid even a single | ||
1286 | * read of the mixer regs | ||
1287 | */ | ||
1288 | snd_nm256_ac97_write(ac97, nm256_ac97_init_val[i].reg, | ||
1289 | nm256_ac97_init_val[i].value); | ||
1290 | } | ||
1291 | } | ||
1214 | } | 1292 | } |
1215 | 1293 | ||
1216 | /* create an ac97 mixer interface */ | 1294 | /* create an ac97 mixer interface */ |
@@ -1219,32 +1297,25 @@ snd_nm256_mixer(struct nm256 *chip) | |||
1219 | { | 1297 | { |
1220 | struct snd_ac97_bus *pbus; | 1298 | struct snd_ac97_bus *pbus; |
1221 | struct snd_ac97_template ac97; | 1299 | struct snd_ac97_template ac97; |
1222 | int i, err; | 1300 | int err; |
1223 | static struct snd_ac97_bus_ops ops = { | 1301 | static struct snd_ac97_bus_ops ops = { |
1224 | .reset = snd_nm256_ac97_reset, | 1302 | .reset = snd_nm256_ac97_reset, |
1225 | .write = snd_nm256_ac97_write, | 1303 | .write = snd_nm256_ac97_write, |
1226 | .read = snd_nm256_ac97_read, | 1304 | .read = snd_nm256_ac97_read, |
1227 | }; | 1305 | }; |
1228 | /* looks like nm256 hangs up when unexpected registers are touched... */ | 1306 | |
1229 | static int mixer_regs[] = { | 1307 | chip->ac97_regs = kcalloc(sizeof(short), |
1230 | AC97_MASTER, AC97_HEADPHONE, AC97_MASTER_MONO, | 1308 | ARRAY_SIZE(nm256_ac97_init_val), GFP_KERNEL); |
1231 | AC97_PC_BEEP, AC97_PHONE, AC97_MIC, AC97_LINE, AC97_CD, | 1309 | if (! chip->ac97_regs) |
1232 | AC97_VIDEO, AC97_AUX, AC97_PCM, AC97_REC_SEL, | 1310 | return -ENOMEM; |
1233 | AC97_REC_GAIN, AC97_GENERAL_PURPOSE, AC97_3D_CONTROL, | ||
1234 | /*AC97_EXTENDED_ID,*/ | ||
1235 | AC97_VENDOR_ID1, AC97_VENDOR_ID2, | ||
1236 | -1 | ||
1237 | }; | ||
1238 | 1311 | ||
1239 | if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0) | 1312 | if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0) |
1240 | return err; | 1313 | return err; |
1241 | 1314 | ||
1242 | memset(&ac97, 0, sizeof(ac97)); | 1315 | memset(&ac97, 0, sizeof(ac97)); |
1243 | ac97.scaps = AC97_SCAP_AUDIO; /* we support audio! */ | 1316 | ac97.scaps = AC97_SCAP_AUDIO; /* we support audio! */ |
1244 | ac97.limited_regs = 1; | ||
1245 | for (i = 0; mixer_regs[i] >= 0; i++) | ||
1246 | set_bit(mixer_regs[i], ac97.reg_accessed); | ||
1247 | ac97.private_data = chip; | 1317 | ac97.private_data = chip; |
1318 | ac97.res_table = nm256_res_table; | ||
1248 | pbus->no_vra = 1; | 1319 | pbus->no_vra = 1; |
1249 | err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); | 1320 | err = snd_ac97_mixer(pbus, &ac97, &chip->ac97); |
1250 | if (err < 0) | 1321 | if (err < 0) |
@@ -1329,6 +1400,7 @@ static int nm256_resume(struct pci_dev *pci) | |||
1329 | int i; | 1400 | int i; |
1330 | 1401 | ||
1331 | /* Perform a full reset on the hardware */ | 1402 | /* Perform a full reset on the hardware */ |
1403 | chip->in_resume = 1; | ||
1332 | pci_restore_state(pci); | 1404 | pci_restore_state(pci); |
1333 | pci_enable_device(pci); | 1405 | pci_enable_device(pci); |
1334 | snd_nm256_init_chip(chip); | 1406 | snd_nm256_init_chip(chip); |
@@ -1346,6 +1418,7 @@ static int nm256_resume(struct pci_dev *pci) | |||
1346 | } | 1418 | } |
1347 | 1419 | ||
1348 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 1420 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
1421 | chip->in_resume = 0; | ||
1349 | return 0; | 1422 | return 0; |
1350 | } | 1423 | } |
1351 | #endif /* CONFIG_PM */ | 1424 | #endif /* CONFIG_PM */ |
@@ -1370,6 +1443,7 @@ static int snd_nm256_free(struct nm256 *chip) | |||
1370 | free_irq(chip->irq, chip); | 1443 | free_irq(chip->irq, chip); |
1371 | 1444 | ||
1372 | pci_disable_device(chip->pci); | 1445 | pci_disable_device(chip->pci); |
1446 | kfree(chip->ac97_regs); | ||
1373 | kfree(chip); | 1447 | kfree(chip); |
1374 | return 0; | 1448 | return 0; |
1375 | } | 1449 | } |
@@ -1407,7 +1481,7 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, | |||
1407 | chip->use_cache = use_cache; | 1481 | chip->use_cache = use_cache; |
1408 | spin_lock_init(&chip->reg_lock); | 1482 | spin_lock_init(&chip->reg_lock); |
1409 | chip->irq = -1; | 1483 | chip->irq = -1; |
1410 | init_MUTEX(&chip->irq_mutex); | 1484 | mutex_init(&chip->irq_mutex); |
1411 | 1485 | ||
1412 | /* store buffer sizes in bytes */ | 1486 | /* store buffer sizes in bytes */ |
1413 | chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024; | 1487 | chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024; |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index b2cba75b6b16..f679779d96e3 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -26,8 +26,11 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/dma-mapping.h> | ||
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/moduleparam.h> | 31 | #include <linux/moduleparam.h> |
32 | #include <linux/mutex.h> | ||
33 | |||
31 | #include <sound/core.h> | 34 | #include <sound/core.h> |
32 | #include <sound/initval.h> | 35 | #include <sound/initval.h> |
33 | #include <sound/info.h> | 36 | #include <sound/info.h> |
@@ -518,7 +521,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
518 | struct timeval my_tv1, my_tv2; | 521 | struct timeval my_tv1, my_tv2; |
519 | do_gettimeofday(&my_tv1); | 522 | do_gettimeofday(&my_tv1); |
520 | #endif | 523 | #endif |
521 | down(&mgr->setup_mutex); | 524 | mutex_lock(&mgr->setup_mutex); |
522 | 525 | ||
523 | /* check the pipes concerned and build pipe_array */ | 526 | /* check the pipes concerned and build pipe_array */ |
524 | for (i = 0; i < mgr->num_cards; i++) { | 527 | for (i = 0; i < mgr->num_cards; i++) { |
@@ -537,7 +540,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
537 | } | 540 | } |
538 | } | 541 | } |
539 | if (capture_mask == 0 && playback_mask == 0) { | 542 | if (capture_mask == 0 && playback_mask == 0) { |
540 | up(&mgr->setup_mutex); | 543 | mutex_unlock(&mgr->setup_mutex); |
541 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : no pipes\n"); | 544 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : no pipes\n"); |
542 | return; | 545 | return; |
543 | } | 546 | } |
@@ -548,7 +551,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
548 | /* synchronous stop of all the pipes concerned */ | 551 | /* synchronous stop of all the pipes concerned */ |
549 | err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); | 552 | err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); |
550 | if (err) { | 553 | if (err) { |
551 | up(&mgr->setup_mutex); | 554 | mutex_unlock(&mgr->setup_mutex); |
552 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", | 555 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", |
553 | playback_mask, capture_mask); | 556 | playback_mask, capture_mask); |
554 | return; | 557 | return; |
@@ -592,7 +595,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
592 | /* synchronous start of all the pipes concerned */ | 595 | /* synchronous start of all the pipes concerned */ |
593 | err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); | 596 | err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); |
594 | if (err) { | 597 | if (err) { |
595 | up(&mgr->setup_mutex); | 598 | mutex_unlock(&mgr->setup_mutex); |
596 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", | 599 | snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", |
597 | playback_mask, capture_mask); | 600 | playback_mask, capture_mask); |
598 | return; | 601 | return; |
@@ -619,7 +622,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg) | |||
619 | } | 622 | } |
620 | spin_unlock_irqrestore(&mgr->lock, flags); | 623 | spin_unlock_irqrestore(&mgr->lock, flags); |
621 | 624 | ||
622 | up(&mgr->setup_mutex); | 625 | mutex_unlock(&mgr->setup_mutex); |
623 | 626 | ||
624 | #ifdef CONFIG_SND_DEBUG_DETECT | 627 | #ifdef CONFIG_SND_DEBUG_DETECT |
625 | do_gettimeofday(&my_tv2); | 628 | do_gettimeofday(&my_tv2); |
@@ -728,7 +731,7 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs) | |||
728 | } | 731 | } |
729 | */ | 732 | */ |
730 | 733 | ||
731 | down(&mgr->setup_mutex); | 734 | mutex_lock(&mgr->setup_mutex); |
732 | 735 | ||
733 | do { | 736 | do { |
734 | /* if the stream was stopped before, format and buffer were reset */ | 737 | /* if the stream was stopped before, format and buffer were reset */ |
@@ -755,7 +758,7 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs) | |||
755 | } | 758 | } |
756 | } while(0); /* do only once (so we can use break instead of goto) */ | 759 | } while(0); /* do only once (so we can use break instead of goto) */ |
757 | 760 | ||
758 | up(&mgr->setup_mutex); | 761 | mutex_unlock(&mgr->setup_mutex); |
759 | 762 | ||
760 | return err; | 763 | return err; |
761 | } | 764 | } |
@@ -780,7 +783,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, | |||
780 | /* set up format for the stream */ | 783 | /* set up format for the stream */ |
781 | format = params_format(hw); | 784 | format = params_format(hw); |
782 | 785 | ||
783 | down(&mgr->setup_mutex); | 786 | mutex_lock(&mgr->setup_mutex); |
784 | 787 | ||
785 | stream->channels = channels; | 788 | stream->channels = channels; |
786 | stream->format = format; | 789 | stream->format = format; |
@@ -789,7 +792,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, | |||
789 | /* | 792 | /* |
790 | err = pcxhr_set_format(stream); | 793 | err = pcxhr_set_format(stream); |
791 | if(err) { | 794 | if(err) { |
792 | up(&mgr->setup_mutex); | 795 | mutex_unlock(&mgr->setup_mutex); |
793 | return err; | 796 | return err; |
794 | } | 797 | } |
795 | */ | 798 | */ |
@@ -801,7 +804,7 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs, | |||
801 | err = pcxhr_update_r_buffer(stream); | 804 | err = pcxhr_update_r_buffer(stream); |
802 | } | 805 | } |
803 | */ | 806 | */ |
804 | up(&mgr->setup_mutex); | 807 | mutex_unlock(&mgr->setup_mutex); |
805 | 808 | ||
806 | return err; | 809 | return err; |
807 | } | 810 | } |
@@ -847,7 +850,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) | |||
847 | struct pcxhr_stream *stream; | 850 | struct pcxhr_stream *stream; |
848 | int is_capture; | 851 | int is_capture; |
849 | 852 | ||
850 | down(&mgr->setup_mutex); | 853 | mutex_lock(&mgr->setup_mutex); |
851 | 854 | ||
852 | /* copy the struct snd_pcm_hardware struct */ | 855 | /* copy the struct snd_pcm_hardware struct */ |
853 | runtime->hw = pcxhr_caps; | 856 | runtime->hw = pcxhr_caps; |
@@ -871,7 +874,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) | |||
871 | /* streams in use */ | 874 | /* streams in use */ |
872 | snd_printk(KERN_ERR "pcxhr_open chip%d subs%d in use\n", | 875 | snd_printk(KERN_ERR "pcxhr_open chip%d subs%d in use\n", |
873 | chip->chip_idx, subs->number); | 876 | chip->chip_idx, subs->number); |
874 | up(&mgr->setup_mutex); | 877 | mutex_unlock(&mgr->setup_mutex); |
875 | return -EBUSY; | 878 | return -EBUSY; |
876 | } | 879 | } |
877 | 880 | ||
@@ -887,7 +890,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) | |||
887 | &external_rate) || | 890 | &external_rate) || |
888 | external_rate == 0) { | 891 | external_rate == 0) { |
889 | /* cannot detect the external clock rate */ | 892 | /* cannot detect the external clock rate */ |
890 | up(&mgr->setup_mutex); | 893 | mutex_unlock(&mgr->setup_mutex); |
891 | return -EBUSY; | 894 | return -EBUSY; |
892 | } | 895 | } |
893 | runtime->hw.rate_min = runtime->hw.rate_max = external_rate; | 896 | runtime->hw.rate_min = runtime->hw.rate_max = external_rate; |
@@ -905,7 +908,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs) | |||
905 | 908 | ||
906 | mgr->ref_count_rate++; | 909 | mgr->ref_count_rate++; |
907 | 910 | ||
908 | up(&mgr->setup_mutex); | 911 | mutex_unlock(&mgr->setup_mutex); |
909 | return 0; | 912 | return 0; |
910 | } | 913 | } |
911 | 914 | ||
@@ -916,7 +919,7 @@ static int pcxhr_close(struct snd_pcm_substream *subs) | |||
916 | struct pcxhr_mgr *mgr = chip->mgr; | 919 | struct pcxhr_mgr *mgr = chip->mgr; |
917 | struct pcxhr_stream *stream = subs->runtime->private_data; | 920 | struct pcxhr_stream *stream = subs->runtime->private_data; |
918 | 921 | ||
919 | down(&mgr->setup_mutex); | 922 | mutex_lock(&mgr->setup_mutex); |
920 | 923 | ||
921 | snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); | 924 | snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); |
922 | 925 | ||
@@ -929,7 +932,7 @@ static int pcxhr_close(struct snd_pcm_substream *subs) | |||
929 | stream->status = PCXHR_STREAM_STATUS_FREE; | 932 | stream->status = PCXHR_STREAM_STATUS_FREE; |
930 | stream->substream = NULL; | 933 | stream->substream = NULL; |
931 | 934 | ||
932 | up(&mgr->setup_mutex); | 935 | mutex_unlock(&mgr->setup_mutex); |
933 | 936 | ||
934 | return 0; | 937 | return 0; |
935 | } | 938 | } |
@@ -1215,7 +1218,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id | |||
1215 | pci_set_master(pci); | 1218 | pci_set_master(pci); |
1216 | 1219 | ||
1217 | /* check if we can restrict PCI DMA transfers to 32 bits */ | 1220 | /* check if we can restrict PCI DMA transfers to 32 bits */ |
1218 | if (pci_set_dma_mask(pci, 0xffffffff) < 0) { | 1221 | if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { |
1219 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); | 1222 | snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); |
1220 | pci_disable_device(pci); | 1223 | pci_disable_device(pci); |
1221 | return -ENXIO; | 1224 | return -ENXIO; |
@@ -1264,7 +1267,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id | |||
1264 | spin_lock_init(&mgr->msg_lock); | 1267 | spin_lock_init(&mgr->msg_lock); |
1265 | 1268 | ||
1266 | /* init setup mutex*/ | 1269 | /* init setup mutex*/ |
1267 | init_MUTEX(&mgr->setup_mutex); | 1270 | mutex_init(&mgr->setup_mutex); |
1268 | 1271 | ||
1269 | /* init taslket */ | 1272 | /* init taslket */ |
1270 | tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); | 1273 | tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); |
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index 049f2b3f2867..652064787a55 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __SOUND_PCXHR_H | 24 | #define __SOUND_PCXHR_H |
25 | 25 | ||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
28 | 29 | ||
29 | #define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ | 30 | #define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ |
@@ -76,8 +77,8 @@ struct pcxhr_mgr { | |||
76 | spinlock_t lock; /* interrupt spinlock */ | 77 | spinlock_t lock; /* interrupt spinlock */ |
77 | spinlock_t msg_lock; /* message spinlock */ | 78 | spinlock_t msg_lock; /* message spinlock */ |
78 | 79 | ||
79 | struct semaphore setup_mutex; /* mutex used in hw_params, open and close */ | 80 | struct mutex setup_mutex; /* mutex used in hw_params, open and close */ |
80 | struct semaphore mixer_mutex; /* mutex for mixer */ | 81 | struct mutex mixer_mutex; /* mutex for mixer */ |
81 | 82 | ||
82 | /* hardware interface */ | 83 | /* hardware interface */ |
83 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ | 84 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ |
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index fa0d27e2c79b..fdc652c6992d 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c | |||
@@ -1176,7 +1176,7 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
1176 | mgr->dsp_time_last = dsp_time_new; | 1176 | mgr->dsp_time_last = dsp_time_new; |
1177 | 1177 | ||
1178 | if (timer_toggle == mgr->timer_toggle) | 1178 | if (timer_toggle == mgr->timer_toggle) |
1179 | snd_printk(KERN_ERR "ERROR TIMER TOGGLE\n"); | 1179 | snd_printdd("ERROR TIMER TOGGLE\n"); |
1180 | mgr->timer_toggle = timer_toggle; | 1180 | mgr->timer_toggle = timer_toggle; |
1181 | 1181 | ||
1182 | reg &= ~PCXHR_IRQ_TIMER; | 1182 | reg &= ~PCXHR_IRQ_TIMER; |
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 760e733ac25e..94e63a1e90d9 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include "pcxhr.h" | 30 | #include "pcxhr.h" |
30 | #include "pcxhr_hwdep.h" | 31 | #include "pcxhr_hwdep.h" |
@@ -92,7 +93,7 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol, | |||
92 | struct snd_ctl_elem_value *ucontrol) | 93 | struct snd_ctl_elem_value *ucontrol) |
93 | { | 94 | { |
94 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 95 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
95 | down(&chip->mgr->mixer_mutex); | 96 | mutex_lock(&chip->mgr->mixer_mutex); |
96 | if (kcontrol->private_value == 0) { /* playback */ | 97 | if (kcontrol->private_value == 0) { /* playback */ |
97 | ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; | 98 | ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; |
98 | ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; | 99 | ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; |
@@ -100,7 +101,7 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol, | |||
100 | ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; | 101 | ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; |
101 | ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; | 102 | ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; |
102 | } | 103 | } |
103 | up(&chip->mgr->mixer_mutex); | 104 | mutex_unlock(&chip->mgr->mixer_mutex); |
104 | return 0; | 105 | return 0; |
105 | } | 106 | } |
106 | 107 | ||
@@ -111,7 +112,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, | |||
111 | int changed = 0; | 112 | int changed = 0; |
112 | int is_capture, i; | 113 | int is_capture, i; |
113 | 114 | ||
114 | down(&chip->mgr->mixer_mutex); | 115 | mutex_lock(&chip->mgr->mixer_mutex); |
115 | is_capture = (kcontrol->private_value != 0); | 116 | is_capture = (kcontrol->private_value != 0); |
116 | for (i = 0; i < 2; i++) { | 117 | for (i = 0; i < 2; i++) { |
117 | int new_volume = ucontrol->value.integer.value[i]; | 118 | int new_volume = ucontrol->value.integer.value[i]; |
@@ -123,7 +124,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, | |||
123 | pcxhr_update_analog_audio_level(chip, is_capture, i); | 124 | pcxhr_update_analog_audio_level(chip, is_capture, i); |
124 | } | 125 | } |
125 | } | 126 | } |
126 | up(&chip->mgr->mixer_mutex); | 127 | mutex_unlock(&chip->mgr->mixer_mutex); |
127 | return changed; | 128 | return changed; |
128 | } | 129 | } |
129 | 130 | ||
@@ -150,10 +151,10 @@ static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, | |||
150 | { | 151 | { |
151 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 152 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
152 | 153 | ||
153 | down(&chip->mgr->mixer_mutex); | 154 | mutex_lock(&chip->mgr->mixer_mutex); |
154 | ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; | 155 | ucontrol->value.integer.value[0] = chip->analog_playback_active[0]; |
155 | ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; | 156 | ucontrol->value.integer.value[1] = chip->analog_playback_active[1]; |
156 | up(&chip->mgr->mixer_mutex); | 157 | mutex_unlock(&chip->mgr->mixer_mutex); |
157 | return 0; | 158 | return 0; |
158 | } | 159 | } |
159 | 160 | ||
@@ -162,7 +163,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol, | |||
162 | { | 163 | { |
163 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 164 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
164 | int i, changed = 0; | 165 | int i, changed = 0; |
165 | down(&chip->mgr->mixer_mutex); | 166 | mutex_lock(&chip->mgr->mixer_mutex); |
166 | for(i = 0; i < 2; i++) { | 167 | for(i = 0; i < 2; i++) { |
167 | if (chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { | 168 | if (chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) { |
168 | chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; | 169 | chip->analog_playback_active[i] = ucontrol->value.integer.value[i]; |
@@ -170,7 +171,7 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol, | |||
170 | pcxhr_update_analog_audio_level(chip, 0, i); /* update playback levels */ | 171 | pcxhr_update_analog_audio_level(chip, 0, i); /* update playback levels */ |
171 | } | 172 | } |
172 | } | 173 | } |
173 | up(&chip->mgr->mixer_mutex); | 174 | mutex_unlock(&chip->mgr->mixer_mutex); |
174 | return changed; | 175 | return changed; |
175 | } | 176 | } |
176 | 177 | ||
@@ -299,14 +300,14 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol, | |||
299 | int *stored_volume; | 300 | int *stored_volume; |
300 | int is_capture = kcontrol->private_value; | 301 | int is_capture = kcontrol->private_value; |
301 | 302 | ||
302 | down(&chip->mgr->mixer_mutex); | 303 | mutex_lock(&chip->mgr->mixer_mutex); |
303 | if (is_capture) | 304 | if (is_capture) |
304 | stored_volume = chip->digital_capture_volume; /* digital capture */ | 305 | stored_volume = chip->digital_capture_volume; /* digital capture */ |
305 | else | 306 | else |
306 | stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ | 307 | stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ |
307 | ucontrol->value.integer.value[0] = stored_volume[0]; | 308 | ucontrol->value.integer.value[0] = stored_volume[0]; |
308 | ucontrol->value.integer.value[1] = stored_volume[1]; | 309 | ucontrol->value.integer.value[1] = stored_volume[1]; |
309 | up(&chip->mgr->mixer_mutex); | 310 | mutex_unlock(&chip->mgr->mixer_mutex); |
310 | return 0; | 311 | return 0; |
311 | } | 312 | } |
312 | 313 | ||
@@ -320,7 +321,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, | |||
320 | int *stored_volume; | 321 | int *stored_volume; |
321 | int i; | 322 | int i; |
322 | 323 | ||
323 | down(&chip->mgr->mixer_mutex); | 324 | mutex_lock(&chip->mgr->mixer_mutex); |
324 | if (is_capture) | 325 | if (is_capture) |
325 | stored_volume = chip->digital_capture_volume; /* digital capture */ | 326 | stored_volume = chip->digital_capture_volume; /* digital capture */ |
326 | else | 327 | else |
@@ -335,7 +336,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, | |||
335 | } | 336 | } |
336 | if (! is_capture && changed) | 337 | if (! is_capture && changed) |
337 | pcxhr_update_playback_stream_level(chip, idx); /* update playback volume */ | 338 | pcxhr_update_playback_stream_level(chip, idx); /* update playback volume */ |
338 | up(&chip->mgr->mixer_mutex); | 339 | mutex_unlock(&chip->mgr->mixer_mutex); |
339 | return changed; | 340 | return changed; |
340 | } | 341 | } |
341 | 342 | ||
@@ -356,10 +357,10 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol, | |||
356 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 357 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
357 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ | 358 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ |
358 | 359 | ||
359 | down(&chip->mgr->mixer_mutex); | 360 | mutex_lock(&chip->mgr->mixer_mutex); |
360 | ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; | 361 | ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0]; |
361 | ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; | 362 | ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1]; |
362 | up(&chip->mgr->mixer_mutex); | 363 | mutex_unlock(&chip->mgr->mixer_mutex); |
363 | return 0; | 364 | return 0; |
364 | } | 365 | } |
365 | 366 | ||
@@ -370,7 +371,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
370 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ | 371 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ |
371 | int i, j; | 372 | int i, j; |
372 | 373 | ||
373 | down(&chip->mgr->mixer_mutex); | 374 | mutex_lock(&chip->mgr->mixer_mutex); |
374 | j = idx; | 375 | j = idx; |
375 | for (i = 0; i < 2; i++) { | 376 | for (i = 0; i < 2; i++) { |
376 | if (chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) { | 377 | if (chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) { |
@@ -380,7 +381,7 @@ static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
380 | } | 381 | } |
381 | if (changed) | 382 | if (changed) |
382 | pcxhr_update_playback_stream_level(chip, idx); | 383 | pcxhr_update_playback_stream_level(chip, idx); |
383 | up(&chip->mgr->mixer_mutex); | 384 | mutex_unlock(&chip->mgr->mixer_mutex); |
384 | return changed; | 385 | return changed; |
385 | } | 386 | } |
386 | 387 | ||
@@ -402,10 +403,10 @@ static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol, | |||
402 | struct snd_ctl_elem_value *ucontrol) | 403 | struct snd_ctl_elem_value *ucontrol) |
403 | { | 404 | { |
404 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 405 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
405 | down(&chip->mgr->mixer_mutex); | 406 | mutex_lock(&chip->mgr->mixer_mutex); |
406 | ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; | 407 | ucontrol->value.integer.value[0] = chip->monitoring_volume[0]; |
407 | ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; | 408 | ucontrol->value.integer.value[1] = chip->monitoring_volume[1]; |
408 | up(&chip->mgr->mixer_mutex); | 409 | mutex_unlock(&chip->mgr->mixer_mutex); |
409 | return 0; | 410 | return 0; |
410 | } | 411 | } |
411 | 412 | ||
@@ -416,7 +417,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol, | |||
416 | int changed = 0; | 417 | int changed = 0; |
417 | int i; | 418 | int i; |
418 | 419 | ||
419 | down(&chip->mgr->mixer_mutex); | 420 | mutex_lock(&chip->mgr->mixer_mutex); |
420 | for (i = 0; i < 2; i++) { | 421 | for (i = 0; i < 2; i++) { |
421 | if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { | 422 | if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) { |
422 | chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; | 423 | chip->monitoring_volume[i] = ucontrol->value.integer.value[i]; |
@@ -426,7 +427,7 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol, | |||
426 | changed = 1; | 427 | changed = 1; |
427 | } | 428 | } |
428 | } | 429 | } |
429 | up(&chip->mgr->mixer_mutex); | 430 | mutex_unlock(&chip->mgr->mixer_mutex); |
430 | return changed; | 431 | return changed; |
431 | } | 432 | } |
432 | 433 | ||
@@ -446,10 +447,10 @@ static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol, | |||
446 | struct snd_ctl_elem_value *ucontrol) | 447 | struct snd_ctl_elem_value *ucontrol) |
447 | { | 448 | { |
448 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 449 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
449 | down(&chip->mgr->mixer_mutex); | 450 | mutex_lock(&chip->mgr->mixer_mutex); |
450 | ucontrol->value.integer.value[0] = chip->monitoring_active[0]; | 451 | ucontrol->value.integer.value[0] = chip->monitoring_active[0]; |
451 | ucontrol->value.integer.value[1] = chip->monitoring_active[1]; | 452 | ucontrol->value.integer.value[1] = chip->monitoring_active[1]; |
452 | up(&chip->mgr->mixer_mutex); | 453 | mutex_unlock(&chip->mgr->mixer_mutex); |
453 | return 0; | 454 | return 0; |
454 | } | 455 | } |
455 | 456 | ||
@@ -460,7 +461,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol, | |||
460 | int changed = 0; | 461 | int changed = 0; |
461 | int i; | 462 | int i; |
462 | 463 | ||
463 | down(&chip->mgr->mixer_mutex); | 464 | mutex_lock(&chip->mgr->mixer_mutex); |
464 | for (i = 0; i < 2; i++) { | 465 | for (i = 0; i < 2; i++) { |
465 | if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { | 466 | if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { |
466 | chip->monitoring_active[i] = ucontrol->value.integer.value[i]; | 467 | chip->monitoring_active[i] = ucontrol->value.integer.value[i]; |
@@ -474,7 +475,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol, | |||
474 | /* update right monitoring volume and mute */ | 475 | /* update right monitoring volume and mute */ |
475 | pcxhr_update_audio_pipe_level(chip, 0, 1); | 476 | pcxhr_update_audio_pipe_level(chip, 0, 1); |
476 | 477 | ||
477 | up(&chip->mgr->mixer_mutex); | 478 | mutex_unlock(&chip->mgr->mixer_mutex); |
478 | return (changed != 0); | 479 | return (changed != 0); |
479 | } | 480 | } |
480 | 481 | ||
@@ -571,13 +572,13 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol, | |||
571 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); | 572 | struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); |
572 | int ret = 0; | 573 | int ret = 0; |
573 | 574 | ||
574 | down(&chip->mgr->mixer_mutex); | 575 | mutex_lock(&chip->mgr->mixer_mutex); |
575 | if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { | 576 | if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { |
576 | chip->audio_capture_source = ucontrol->value.enumerated.item[0]; | 577 | chip->audio_capture_source = ucontrol->value.enumerated.item[0]; |
577 | pcxhr_set_audio_source(chip); | 578 | pcxhr_set_audio_source(chip); |
578 | ret = 1; | 579 | ret = 1; |
579 | } | 580 | } |
580 | up(&chip->mgr->mixer_mutex); | 581 | mutex_unlock(&chip->mgr->mixer_mutex); |
581 | return ret; | 582 | return ret; |
582 | } | 583 | } |
583 | 584 | ||
@@ -636,9 +637,9 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol, | |||
636 | struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); | 637 | struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); |
637 | int rate, ret = 0; | 638 | int rate, ret = 0; |
638 | 639 | ||
639 | down(&mgr->mixer_mutex); | 640 | mutex_lock(&mgr->mixer_mutex); |
640 | if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) { | 641 | if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) { |
641 | down(&mgr->setup_mutex); | 642 | mutex_lock(&mgr->setup_mutex); |
642 | mgr->use_clock_type = ucontrol->value.enumerated.item[0]; | 643 | mgr->use_clock_type = ucontrol->value.enumerated.item[0]; |
643 | if (mgr->use_clock_type) | 644 | if (mgr->use_clock_type) |
644 | pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); | 645 | pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); |
@@ -649,10 +650,10 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol, | |||
649 | if (mgr->sample_rate) | 650 | if (mgr->sample_rate) |
650 | mgr->sample_rate = rate; | 651 | mgr->sample_rate = rate; |
651 | } | 652 | } |
652 | up(&mgr->setup_mutex); | 653 | mutex_unlock(&mgr->setup_mutex); |
653 | ret = 1; /* return 1 even if the set was not done. ok ? */ | 654 | ret = 1; /* return 1 even if the set was not done. ok ? */ |
654 | } | 655 | } |
655 | up(&mgr->mixer_mutex); | 656 | mutex_unlock(&mgr->mixer_mutex); |
656 | return ret; | 657 | return ret; |
657 | } | 658 | } |
658 | 659 | ||
@@ -685,7 +686,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol, | |||
685 | struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); | 686 | struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); |
686 | int i, err, rate; | 687 | int i, err, rate; |
687 | 688 | ||
688 | down(&mgr->mixer_mutex); | 689 | mutex_lock(&mgr->mixer_mutex); |
689 | for(i = 0; i < 3 + mgr->capture_chips; i++) { | 690 | for(i = 0; i < 3 + mgr->capture_chips; i++) { |
690 | if (i == PCXHR_CLOCK_TYPE_INTERNAL) | 691 | if (i == PCXHR_CLOCK_TYPE_INTERNAL) |
691 | rate = mgr->sample_rate_real; | 692 | rate = mgr->sample_rate_real; |
@@ -696,7 +697,7 @@ static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol, | |||
696 | } | 697 | } |
697 | ucontrol->value.integer.value[i] = rate; | 698 | ucontrol->value.integer.value[i] = rate; |
698 | } | 699 | } |
699 | up(&mgr->mixer_mutex); | 700 | mutex_unlock(&mgr->mixer_mutex); |
700 | return 0; | 701 | return 0; |
701 | } | 702 | } |
702 | 703 | ||
@@ -765,7 +766,7 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
765 | unsigned char aes_bits; | 766 | unsigned char aes_bits; |
766 | int i, err; | 767 | int i, err; |
767 | 768 | ||
768 | down(&chip->mgr->mixer_mutex); | 769 | mutex_lock(&chip->mgr->mixer_mutex); |
769 | for(i = 0; i < 5; i++) { | 770 | for(i = 0; i < 5; i++) { |
770 | if (kcontrol->private_value == 0) /* playback */ | 771 | if (kcontrol->private_value == 0) /* playback */ |
771 | aes_bits = chip->aes_bits[i]; | 772 | aes_bits = chip->aes_bits[i]; |
@@ -776,7 +777,7 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
776 | } | 777 | } |
777 | ucontrol->value.iec958.status[i] = aes_bits; | 778 | ucontrol->value.iec958.status[i] = aes_bits; |
778 | } | 779 | } |
779 | up(&chip->mgr->mixer_mutex); | 780 | mutex_unlock(&chip->mgr->mixer_mutex); |
780 | return 0; | 781 | return 0; |
781 | } | 782 | } |
782 | 783 | ||
@@ -828,14 +829,14 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol, | |||
828 | int i, changed = 0; | 829 | int i, changed = 0; |
829 | 830 | ||
830 | /* playback */ | 831 | /* playback */ |
831 | down(&chip->mgr->mixer_mutex); | 832 | mutex_lock(&chip->mgr->mixer_mutex); |
832 | for (i = 0; i < 5; i++) { | 833 | for (i = 0; i < 5; i++) { |
833 | if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { | 834 | if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { |
834 | pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); | 835 | pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); |
835 | changed = 1; | 836 | changed = 1; |
836 | } | 837 | } |
837 | } | 838 | } |
838 | up(&chip->mgr->mixer_mutex); | 839 | mutex_unlock(&chip->mgr->mixer_mutex); |
839 | return changed; | 840 | return changed; |
840 | } | 841 | } |
841 | 842 | ||
@@ -916,7 +917,7 @@ int pcxhr_create_mixer(struct pcxhr_mgr *mgr) | |||
916 | struct snd_pcxhr *chip; | 917 | struct snd_pcxhr *chip; |
917 | int err, i; | 918 | int err, i; |
918 | 919 | ||
919 | init_MUTEX(&mgr->mixer_mutex); /* can be in another place */ | 920 | mutex_init(&mgr->mixer_mutex); /* can be in another place */ |
920 | 921 | ||
921 | for (i = 0; i < mgr->num_cards; i++) { | 922 | for (i = 0; i < mgr->num_cards; i++) { |
922 | struct snd_kcontrol_new temp; | 923 | struct snd_kcontrol_new temp; |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 103b4d715ff4..980b9cd689dd 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -474,7 +474,7 @@ static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg) | |||
474 | static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, | 474 | static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, |
475 | unsigned int in) | 475 | unsigned int in) |
476 | { | 476 | { |
477 | if (chan > HDSPM_MIXER_CHANNELS || in > HDSPM_MIXER_CHANNELS) | 477 | if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS) |
478 | return 0; | 478 | return 0; |
479 | 479 | ||
480 | return hdspm->mixer->ch[chan].in[in]; | 480 | return hdspm->mixer->ch[chan].in[in]; |
@@ -483,7 +483,7 @@ static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan, | |||
483 | static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan, | 483 | static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan, |
484 | unsigned int pb) | 484 | unsigned int pb) |
485 | { | 485 | { |
486 | if (chan > HDSPM_MIXER_CHANNELS || pb > HDSPM_MIXER_CHANNELS) | 486 | if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS) |
487 | return 0; | 487 | return 0; |
488 | return hdspm->mixer->ch[chan].pb[pb]; | 488 | return hdspm->mixer->ch[chan].pb[pb]; |
489 | } | 489 | } |
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index cf09ea99755c..46c6982c9e88 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/time.h> | 29 | #include <linux/time.h> |
30 | #include <linux/mutex.h> | ||
31 | |||
30 | #include <sound/core.h> | 32 | #include <sound/core.h> |
31 | #include <sound/trident.h> | 33 | #include <sound/trident.h> |
32 | 34 | ||
@@ -201,16 +203,16 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, | |||
201 | 203 | ||
202 | 204 | ||
203 | 205 | ||
204 | down(&hdr->block_mutex); | 206 | mutex_lock(&hdr->block_mutex); |
205 | blk = search_empty(hdr, runtime->dma_bytes); | 207 | blk = search_empty(hdr, runtime->dma_bytes); |
206 | if (blk == NULL) { | 208 | if (blk == NULL) { |
207 | up(&hdr->block_mutex); | 209 | mutex_unlock(&hdr->block_mutex); |
208 | return NULL; | 210 | return NULL; |
209 | } | 211 | } |
210 | if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) { | 212 | if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) { |
211 | snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk)); | 213 | snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk)); |
212 | __snd_util_mem_free(hdr, blk); | 214 | __snd_util_mem_free(hdr, blk); |
213 | up(&hdr->block_mutex); | 215 | mutex_unlock(&hdr->block_mutex); |
214 | return NULL; | 216 | return NULL; |
215 | } | 217 | } |
216 | 218 | ||
@@ -221,12 +223,12 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, | |||
221 | unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; | 223 | unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; |
222 | if (! is_valid_page(addr)) { | 224 | if (! is_valid_page(addr)) { |
223 | __snd_util_mem_free(hdr, blk); | 225 | __snd_util_mem_free(hdr, blk); |
224 | up(&hdr->block_mutex); | 226 | mutex_unlock(&hdr->block_mutex); |
225 | return NULL; | 227 | return NULL; |
226 | } | 228 | } |
227 | set_tlb_bus(trident, page, ptr, addr); | 229 | set_tlb_bus(trident, page, ptr, addr); |
228 | } | 230 | } |
229 | up(&hdr->block_mutex); | 231 | mutex_unlock(&hdr->block_mutex); |
230 | return blk; | 232 | return blk; |
231 | } | 233 | } |
232 | 234 | ||
@@ -248,10 +250,10 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, | |||
248 | hdr = trident->tlb.memhdr; | 250 | hdr = trident->tlb.memhdr; |
249 | snd_assert(hdr != NULL, return NULL); | 251 | snd_assert(hdr != NULL, return NULL); |
250 | 252 | ||
251 | down(&hdr->block_mutex); | 253 | mutex_lock(&hdr->block_mutex); |
252 | blk = search_empty(hdr, runtime->dma_bytes); | 254 | blk = search_empty(hdr, runtime->dma_bytes); |
253 | if (blk == NULL) { | 255 | if (blk == NULL) { |
254 | up(&hdr->block_mutex); | 256 | mutex_unlock(&hdr->block_mutex); |
255 | return NULL; | 257 | return NULL; |
256 | } | 258 | } |
257 | 259 | ||
@@ -262,12 +264,12 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, | |||
262 | ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) { | 264 | ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) { |
263 | if (! is_valid_page(addr)) { | 265 | if (! is_valid_page(addr)) { |
264 | __snd_util_mem_free(hdr, blk); | 266 | __snd_util_mem_free(hdr, blk); |
265 | up(&hdr->block_mutex); | 267 | mutex_unlock(&hdr->block_mutex); |
266 | return NULL; | 268 | return NULL; |
267 | } | 269 | } |
268 | set_tlb_bus(trident, page, ptr, addr); | 270 | set_tlb_bus(trident, page, ptr, addr); |
269 | } | 271 | } |
270 | up(&hdr->block_mutex); | 272 | mutex_unlock(&hdr->block_mutex); |
271 | return blk; | 273 | return blk; |
272 | } | 274 | } |
273 | 275 | ||
@@ -300,13 +302,13 @@ int snd_trident_free_pages(struct snd_trident *trident, | |||
300 | snd_assert(blk != NULL, return -EINVAL); | 302 | snd_assert(blk != NULL, return -EINVAL); |
301 | 303 | ||
302 | hdr = trident->tlb.memhdr; | 304 | hdr = trident->tlb.memhdr; |
303 | down(&hdr->block_mutex); | 305 | mutex_lock(&hdr->block_mutex); |
304 | /* reset TLB entries */ | 306 | /* reset TLB entries */ |
305 | for (page = firstpg(blk); page <= lastpg(blk); page++) | 307 | for (page = firstpg(blk); page <= lastpg(blk); page++) |
306 | set_silent_tlb(trident, page); | 308 | set_silent_tlb(trident, page); |
307 | /* free memory block */ | 309 | /* free memory block */ |
308 | __snd_util_mem_free(hdr, blk); | 310 | __snd_util_mem_free(hdr, blk); |
309 | up(&hdr->block_mutex); | 311 | mutex_unlock(&hdr->block_mutex); |
310 | return 0; | 312 | return 0; |
311 | } | 313 | } |
312 | 314 | ||
@@ -332,18 +334,18 @@ snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size) | |||
332 | struct snd_util_memblk *blk; | 334 | struct snd_util_memblk *blk; |
333 | struct snd_util_memhdr *hdr = hw->tlb.memhdr; | 335 | struct snd_util_memhdr *hdr = hw->tlb.memhdr; |
334 | 336 | ||
335 | down(&hdr->block_mutex); | 337 | mutex_lock(&hdr->block_mutex); |
336 | blk = __snd_util_mem_alloc(hdr, size); | 338 | blk = __snd_util_mem_alloc(hdr, size); |
337 | if (blk == NULL) { | 339 | if (blk == NULL) { |
338 | up(&hdr->block_mutex); | 340 | mutex_unlock(&hdr->block_mutex); |
339 | return NULL; | 341 | return NULL; |
340 | } | 342 | } |
341 | if (synth_alloc_pages(hw, blk)) { | 343 | if (synth_alloc_pages(hw, blk)) { |
342 | __snd_util_mem_free(hdr, blk); | 344 | __snd_util_mem_free(hdr, blk); |
343 | up(&hdr->block_mutex); | 345 | mutex_unlock(&hdr->block_mutex); |
344 | return NULL; | 346 | return NULL; |
345 | } | 347 | } |
346 | up(&hdr->block_mutex); | 348 | mutex_unlock(&hdr->block_mutex); |
347 | return blk; | 349 | return blk; |
348 | } | 350 | } |
349 | 351 | ||
@@ -356,10 +358,10 @@ snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk) | |||
356 | { | 358 | { |
357 | struct snd_util_memhdr *hdr = hw->tlb.memhdr; | 359 | struct snd_util_memhdr *hdr = hw->tlb.memhdr; |
358 | 360 | ||
359 | down(&hdr->block_mutex); | 361 | mutex_lock(&hdr->block_mutex); |
360 | synth_free_pages(hw, blk); | 362 | synth_free_pages(hw, blk); |
361 | __snd_util_mem_free(hdr, blk); | 363 | __snd_util_mem_free(hdr, blk); |
362 | up(&hdr->block_mutex); | 364 | mutex_unlock(&hdr->block_mutex); |
363 | return 0; | 365 | return 0; |
364 | } | 366 | } |
365 | 367 | ||
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 423741371191..1957d29c119e 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -2375,8 +2375,10 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
2375 | { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ | 2375 | { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ |
2376 | { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ | 2376 | { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */ |
2377 | { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ | 2377 | { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */ |
2378 | { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */ | ||
2378 | { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */ | 2379 | { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */ |
2379 | { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ | 2380 | { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ |
2381 | { .subvendor = 0x1849, .subdevice = 0x9739, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ | ||
2380 | { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ | 2382 | { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */ |
2381 | { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ | 2383 | { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ |
2382 | { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ | 2384 | { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ |
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index c705af409b0f..9b6d345b83a6 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/firmware.h> | 26 | #include <linux/firmware.h> |
27 | #include <linux/mutex.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include <sound/control.h> | 30 | #include <sound/control.h> |
29 | #include <asm/io.h> | 31 | #include <asm/io.h> |
@@ -861,10 +863,10 @@ static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
861 | { | 863 | { |
862 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 864 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
863 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 865 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; |
864 | down(&_chip->mixer_mutex); | 866 | mutex_lock(&_chip->mixer_mutex); |
865 | ucontrol->value.integer.value[0] = chip->input_level[0]; | 867 | ucontrol->value.integer.value[0] = chip->input_level[0]; |
866 | ucontrol->value.integer.value[1] = chip->input_level[1]; | 868 | ucontrol->value.integer.value[1] = chip->input_level[1]; |
867 | up(&_chip->mixer_mutex); | 869 | mutex_unlock(&_chip->mixer_mutex); |
868 | return 0; | 870 | return 0; |
869 | } | 871 | } |
870 | 872 | ||
@@ -872,16 +874,16 @@ static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem | |||
872 | { | 874 | { |
873 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 875 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
874 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 876 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; |
875 | down(&_chip->mixer_mutex); | 877 | mutex_lock(&_chip->mixer_mutex); |
876 | if (chip->input_level[0] != ucontrol->value.integer.value[0] || | 878 | if (chip->input_level[0] != ucontrol->value.integer.value[0] || |
877 | chip->input_level[1] != ucontrol->value.integer.value[1]) { | 879 | chip->input_level[1] != ucontrol->value.integer.value[1]) { |
878 | chip->input_level[0] = ucontrol->value.integer.value[0]; | 880 | chip->input_level[0] = ucontrol->value.integer.value[0]; |
879 | chip->input_level[1] = ucontrol->value.integer.value[1]; | 881 | chip->input_level[1] = ucontrol->value.integer.value[1]; |
880 | vx2_set_input_level(chip); | 882 | vx2_set_input_level(chip); |
881 | up(&_chip->mixer_mutex); | 883 | mutex_unlock(&_chip->mixer_mutex); |
882 | return 1; | 884 | return 1; |
883 | } | 885 | } |
884 | up(&_chip->mixer_mutex); | 886 | mutex_unlock(&_chip->mixer_mutex); |
885 | return 0; | 887 | return 0; |
886 | } | 888 | } |
887 | 889 | ||
@@ -907,14 +909,14 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
907 | { | 909 | { |
908 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 910 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
909 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; | 911 | struct snd_vx222 *chip = (struct snd_vx222 *)_chip; |
910 | down(&_chip->mixer_mutex); | 912 | mutex_lock(&_chip->mixer_mutex); |
911 | if (chip->mic_level != ucontrol->value.integer.value[0]) { | 913 | if (chip->mic_level != ucontrol->value.integer.value[0]) { |
912 | chip->mic_level = ucontrol->value.integer.value[0]; | 914 | chip->mic_level = ucontrol->value.integer.value[0]; |
913 | vx2_set_input_level(chip); | 915 | vx2_set_input_level(chip); |
914 | up(&_chip->mixer_mutex); | 916 | mutex_unlock(&_chip->mixer_mutex); |
915 | return 1; | 917 | return 1; |
916 | } | 918 | } |
917 | up(&_chip->mixer_mutex); | 919 | mutex_unlock(&_chip->mixer_mutex); |
918 | return 0; | 920 | return 0; |
919 | } | 921 | } |
920 | 922 | ||
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index dab9b8310341..db57ce939fa8 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -49,6 +49,7 @@ static long mpu_port[SNDRV_CARDS]; | |||
49 | static long joystick_port[SNDRV_CARDS]; | 49 | static long joystick_port[SNDRV_CARDS]; |
50 | #endif | 50 | #endif |
51 | static int rear_switch[SNDRV_CARDS]; | 51 | static int rear_switch[SNDRV_CARDS]; |
52 | static int rear_swap[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 }; | ||
52 | 53 | ||
53 | module_param_array(index, int, NULL, 0444); | 54 | module_param_array(index, int, NULL, 0444); |
54 | MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); | 55 | MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); |
@@ -66,6 +67,8 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address"); | |||
66 | #endif | 67 | #endif |
67 | module_param_array(rear_switch, bool, NULL, 0444); | 68 | module_param_array(rear_switch, bool, NULL, 0444); |
68 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); | 69 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); |
70 | module_param_array(rear_swap, bool, NULL, 0444); | ||
71 | MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output"); | ||
69 | 72 | ||
70 | static struct pci_device_id snd_ymfpci_ids[] = { | 73 | static struct pci_device_id snd_ymfpci_ids[] = { |
71 | { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ | 74 | { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ |
@@ -295,7 +298,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, | |||
295 | snd_card_free(card); | 298 | snd_card_free(card); |
296 | return err; | 299 | return err; |
297 | } | 300 | } |
298 | if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { | 301 | if ((err = snd_ymfpci_mixer(chip, rear_switch[dev], rear_swap[dev])) < 0) { |
299 | snd_card_free(card); | 302 | snd_card_free(card); |
300 | return err; | 303 | return err; |
301 | } | 304 | } |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index a1aa74b79b3d..8ac5ab50b5c7 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -536,15 +536,30 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int | |||
536 | } | 536 | } |
537 | } | 537 | } |
538 | if (ypcm->output_rear) { | 538 | if (ypcm->output_rear) { |
539 | if (use_left) { | 539 | if (!ypcm->swap_rear) { |
540 | bank->eff2_gain = | 540 | if (use_left) { |
541 | bank->eff2_gain_end = vol_left; | 541 | bank->eff2_gain = |
542 | } | 542 | bank->eff2_gain_end = vol_left; |
543 | if (use_right) { | 543 | } |
544 | bank->eff3_gain = | 544 | if (use_right) { |
545 | bank->eff3_gain_end = vol_right; | 545 | bank->eff3_gain = |
546 | } | 546 | bank->eff3_gain_end = vol_right; |
547 | } | 547 | } |
548 | } else { | ||
549 | /* The SPDIF out channels seem to be swapped, so we have | ||
550 | * to swap them here, too. The rear analog out channels | ||
551 | * will be wrong, but otherwise AC3 would not work. | ||
552 | */ | ||
553 | if (use_left) { | ||
554 | bank->eff3_gain = | ||
555 | bank->eff3_gain_end = vol_left; | ||
556 | } | ||
557 | if (use_right) { | ||
558 | bank->eff2_gain = | ||
559 | bank->eff2_gain_end = vol_right; | ||
560 | } | ||
561 | } | ||
562 | } | ||
548 | } | 563 | } |
549 | } | 564 | } |
550 | 565 | ||
@@ -894,6 +909,7 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) | |||
894 | ypcm = runtime->private_data; | 909 | ypcm = runtime->private_data; |
895 | ypcm->output_front = 1; | 910 | ypcm->output_front = 1; |
896 | ypcm->output_rear = chip->mode_dup4ch ? 1 : 0; | 911 | ypcm->output_rear = chip->mode_dup4ch ? 1 : 0; |
912 | ypcm->swap_rear = chip->rear_swap; | ||
897 | spin_lock_irq(&chip->reg_lock); | 913 | spin_lock_irq(&chip->reg_lock); |
898 | if (ypcm->output_rear) { | 914 | if (ypcm->output_rear) { |
899 | ymfpci_open_extension(chip); | 915 | ymfpci_open_extension(chip); |
@@ -1734,7 +1750,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97) | |||
1734 | chip->ac97 = NULL; | 1750 | chip->ac97 = NULL; |
1735 | } | 1751 | } |
1736 | 1752 | ||
1737 | int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) | 1753 | int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap) |
1738 | { | 1754 | { |
1739 | struct snd_ac97_template ac97; | 1755 | struct snd_ac97_template ac97; |
1740 | struct snd_kcontrol *kctl; | 1756 | struct snd_kcontrol *kctl; |
@@ -1746,6 +1762,7 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) | |||
1746 | .read = snd_ymfpci_codec_read, | 1762 | .read = snd_ymfpci_codec_read, |
1747 | }; | 1763 | }; |
1748 | 1764 | ||
1765 | chip->rear_swap = rear_swap; | ||
1749 | if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0) | 1766 | if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &chip->ac97_bus)) < 0) |
1750 | return err; | 1767 | return err; |
1751 | chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus; | 1768 | chip->ac97_bus->private_free = snd_ymfpci_mixer_free_ac97_bus; |
@@ -2293,6 +2310,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card, | |||
2293 | return -EIO; | 2310 | return -EIO; |
2294 | } | 2311 | } |
2295 | 2312 | ||
2313 | chip->rear_swap = 1; | ||
2296 | if ((err = snd_ymfpci_ac3_init(chip)) < 0) { | 2314 | if ((err = snd_ymfpci_ac3_init(chip)) < 0) { |
2297 | snd_ymfpci_free(chip); | 2315 | snd_ymfpci_free(chip); |
2298 | return err; | 2316 | return err; |
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index 962e6d525564..7f2a4de1d35d 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c | |||
@@ -66,10 +66,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s | |||
66 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) | 66 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) |
67 | { | 67 | { |
68 | struct snd_pcm_runtime *runtime = subs->runtime; | 68 | struct snd_pcm_runtime *runtime = subs->runtime; |
69 | if (runtime->dma_area) { | 69 | |
70 | vfree(runtime->dma_area); | 70 | vfree(runtime->dma_area); |
71 | runtime->dma_area = NULL; | 71 | runtime->dma_area = NULL; |
72 | } | ||
73 | return 0; | 72 | return 0; |
74 | } | 73 | } |
75 | 74 | ||
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c index 9450149b931c..e237f6c2018f 100644 --- a/sound/pcmcia/vx/vxp_mixer.c +++ b/sound/pcmcia/vx/vxp_mixer.c | |||
@@ -52,14 +52,14 @@ static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
52 | { | 52 | { |
53 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 53 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
54 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 54 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; |
55 | down(&_chip->mixer_mutex); | 55 | mutex_lock(&_chip->mixer_mutex); |
56 | if (chip->mic_level != ucontrol->value.integer.value[0]) { | 56 | if (chip->mic_level != ucontrol->value.integer.value[0]) { |
57 | vx_set_mic_level(_chip, ucontrol->value.integer.value[0]); | 57 | vx_set_mic_level(_chip, ucontrol->value.integer.value[0]); |
58 | chip->mic_level = ucontrol->value.integer.value[0]; | 58 | chip->mic_level = ucontrol->value.integer.value[0]; |
59 | up(&_chip->mixer_mutex); | 59 | mutex_unlock(&_chip->mixer_mutex); |
60 | return 1; | 60 | return 1; |
61 | } | 61 | } |
62 | up(&_chip->mixer_mutex); | 62 | mutex_unlock(&_chip->mixer_mutex); |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
@@ -95,14 +95,14 @@ static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
95 | { | 95 | { |
96 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); | 96 | struct vx_core *_chip = snd_kcontrol_chip(kcontrol); |
97 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; | 97 | struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip; |
98 | down(&_chip->mixer_mutex); | 98 | mutex_lock(&_chip->mixer_mutex); |
99 | if (chip->mic_level != ucontrol->value.integer.value[0]) { | 99 | if (chip->mic_level != ucontrol->value.integer.value[0]) { |
100 | vx_set_mic_boost(_chip, ucontrol->value.integer.value[0]); | 100 | vx_set_mic_boost(_chip, ucontrol->value.integer.value[0]); |
101 | chip->mic_level = ucontrol->value.integer.value[0]; | 101 | chip->mic_level = ucontrol->value.integer.value[0]; |
102 | up(&_chip->mixer_mutex); | 102 | mutex_unlock(&_chip->mixer_mutex); |
103 | return 1; | 103 | return 1; |
104 | } | 104 | } |
105 | up(&_chip->mixer_mutex); | 105 | mutex_unlock(&_chip->mixer_mutex); |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index fd6543998788..53a148b01b6b 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -115,8 +115,8 @@ struct snd_cs4231 { | |||
115 | unsigned char image[32]; /* registers image */ | 115 | unsigned char image[32]; /* registers image */ |
116 | int mce_bit; | 116 | int mce_bit; |
117 | int calibrate_mute; | 117 | int calibrate_mute; |
118 | struct semaphore mce_mutex; | 118 | struct mutex mce_mutex; |
119 | struct semaphore open_mutex; | 119 | struct mutex open_mutex; |
120 | 120 | ||
121 | union { | 121 | union { |
122 | #ifdef SBUS_SUPPORT | 122 | #ifdef SBUS_SUPPORT |
@@ -775,7 +775,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h | |||
775 | { | 775 | { |
776 | unsigned long flags; | 776 | unsigned long flags; |
777 | 777 | ||
778 | down(&chip->mce_mutex); | 778 | mutex_lock(&chip->mce_mutex); |
779 | snd_cs4231_calibrate_mute(chip, 1); | 779 | snd_cs4231_calibrate_mute(chip, 1); |
780 | 780 | ||
781 | snd_cs4231_mce_up(chip); | 781 | snd_cs4231_mce_up(chip); |
@@ -790,7 +790,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_h | |||
790 | snd_cs4231_mce_down(chip); | 790 | snd_cs4231_mce_down(chip); |
791 | 791 | ||
792 | snd_cs4231_calibrate_mute(chip, 0); | 792 | snd_cs4231_calibrate_mute(chip, 0); |
793 | up(&chip->mce_mutex); | 793 | mutex_unlock(&chip->mce_mutex); |
794 | } | 794 | } |
795 | 795 | ||
796 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, | 796 | static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, |
@@ -798,7 +798,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw | |||
798 | { | 798 | { |
799 | unsigned long flags; | 799 | unsigned long flags; |
800 | 800 | ||
801 | down(&chip->mce_mutex); | 801 | mutex_lock(&chip->mce_mutex); |
802 | snd_cs4231_calibrate_mute(chip, 1); | 802 | snd_cs4231_calibrate_mute(chip, 1); |
803 | 803 | ||
804 | snd_cs4231_mce_up(chip); | 804 | snd_cs4231_mce_up(chip); |
@@ -819,7 +819,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw | |||
819 | snd_cs4231_mce_down(chip); | 819 | snd_cs4231_mce_down(chip); |
820 | 820 | ||
821 | snd_cs4231_calibrate_mute(chip, 0); | 821 | snd_cs4231_calibrate_mute(chip, 0); |
822 | up(&chip->mce_mutex); | 822 | mutex_unlock(&chip->mce_mutex); |
823 | } | 823 | } |
824 | 824 | ||
825 | /* | 825 | /* |
@@ -933,14 +933,14 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) | |||
933 | { | 933 | { |
934 | unsigned long flags; | 934 | unsigned long flags; |
935 | 935 | ||
936 | down(&chip->open_mutex); | 936 | mutex_lock(&chip->open_mutex); |
937 | if ((chip->mode & mode)) { | 937 | if ((chip->mode & mode)) { |
938 | up(&chip->open_mutex); | 938 | mutex_unlock(&chip->open_mutex); |
939 | return -EAGAIN; | 939 | return -EAGAIN; |
940 | } | 940 | } |
941 | if (chip->mode & CS4231_MODE_OPEN) { | 941 | if (chip->mode & CS4231_MODE_OPEN) { |
942 | chip->mode |= mode; | 942 | chip->mode |= mode; |
943 | up(&chip->open_mutex); | 943 | mutex_unlock(&chip->open_mutex); |
944 | return 0; | 944 | return 0; |
945 | } | 945 | } |
946 | /* ok. now enable and ack CODEC IRQ */ | 946 | /* ok. now enable and ack CODEC IRQ */ |
@@ -960,7 +960,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode) | |||
960 | spin_unlock_irqrestore(&chip->lock, flags); | 960 | spin_unlock_irqrestore(&chip->lock, flags); |
961 | 961 | ||
962 | chip->mode = mode; | 962 | chip->mode = mode; |
963 | up(&chip->open_mutex); | 963 | mutex_unlock(&chip->open_mutex); |
964 | return 0; | 964 | return 0; |
965 | } | 965 | } |
966 | 966 | ||
@@ -968,10 +968,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
968 | { | 968 | { |
969 | unsigned long flags; | 969 | unsigned long flags; |
970 | 970 | ||
971 | down(&chip->open_mutex); | 971 | mutex_lock(&chip->open_mutex); |
972 | chip->mode &= ~mode; | 972 | chip->mode &= ~mode; |
973 | if (chip->mode & CS4231_MODE_OPEN) { | 973 | if (chip->mode & CS4231_MODE_OPEN) { |
974 | up(&chip->open_mutex); | 974 | mutex_unlock(&chip->open_mutex); |
975 | return; | 975 | return; |
976 | } | 976 | } |
977 | snd_cs4231_calibrate_mute(chip, 1); | 977 | snd_cs4231_calibrate_mute(chip, 1); |
@@ -1008,7 +1008,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode) | |||
1008 | snd_cs4231_calibrate_mute(chip, 0); | 1008 | snd_cs4231_calibrate_mute(chip, 0); |
1009 | 1009 | ||
1010 | chip->mode = 0; | 1010 | chip->mode = 0; |
1011 | up(&chip->open_mutex); | 1011 | mutex_unlock(&chip->open_mutex); |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | /* | 1014 | /* |
@@ -1969,8 +1969,8 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, | |||
1969 | spin_lock_init(&chip->lock); | 1969 | spin_lock_init(&chip->lock); |
1970 | spin_lock_init(&chip->c_dma.sbus_info.lock); | 1970 | spin_lock_init(&chip->c_dma.sbus_info.lock); |
1971 | spin_lock_init(&chip->p_dma.sbus_info.lock); | 1971 | spin_lock_init(&chip->p_dma.sbus_info.lock); |
1972 | init_MUTEX(&chip->mce_mutex); | 1972 | mutex_init(&chip->mce_mutex); |
1973 | init_MUTEX(&chip->open_mutex); | 1973 | mutex_init(&chip->open_mutex); |
1974 | chip->card = card; | 1974 | chip->card = card; |
1975 | chip->dev_u.sdev = sdev; | 1975 | chip->dev_u.sdev = sdev; |
1976 | chip->regs_size = sdev->reg_addrs[0].reg_size; | 1976 | chip->regs_size = sdev->reg_addrs[0].reg_size; |
@@ -2157,8 +2157,8 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, | |||
2157 | spin_lock_init(&chip->lock); | 2157 | spin_lock_init(&chip->lock); |
2158 | spin_lock_init(&chip->c_dma.ebus_info.lock); | 2158 | spin_lock_init(&chip->c_dma.ebus_info.lock); |
2159 | spin_lock_init(&chip->p_dma.ebus_info.lock); | 2159 | spin_lock_init(&chip->p_dma.ebus_info.lock); |
2160 | init_MUTEX(&chip->mce_mutex); | 2160 | mutex_init(&chip->mce_mutex); |
2161 | init_MUTEX(&chip->open_mutex); | 2161 | mutex_init(&chip->open_mutex); |
2162 | chip->flags |= CS4231_FLAG_EBUS; | 2162 | chip->flags |= CS4231_FLAG_EBUS; |
2163 | chip->card = card; | 2163 | chip->card = card; |
2164 | chip->dev_u.pdev = edev->bus->self; | 2164 | chip->dev_u.pdev = edev->bus->self; |
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c index 7c8e328fae62..fc733bbf4487 100644 --- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c | |||
@@ -45,7 +45,7 @@ int snd_emux_new(struct snd_emux **remu) | |||
45 | return -ENOMEM; | 45 | return -ENOMEM; |
46 | 46 | ||
47 | spin_lock_init(&emu->voice_lock); | 47 | spin_lock_init(&emu->voice_lock); |
48 | init_MUTEX(&emu->register_mutex); | 48 | mutex_init(&emu->register_mutex); |
49 | 49 | ||
50 | emu->client = -1; | 50 | emu->client = -1; |
51 | #ifdef CONFIG_SND_SEQUENCER_OSS | 51 | #ifdef CONFIG_SND_SEQUENCER_OSS |
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c index dfbfcfbe5dd2..3436816727c8 100644 --- a/sound/synth/emux/emux_oss.c +++ b/sound/synth/emux/emux_oss.c | |||
@@ -117,10 +117,10 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) | |||
117 | emu = closure; | 117 | emu = closure; |
118 | snd_assert(arg != NULL && emu != NULL, return -ENXIO); | 118 | snd_assert(arg != NULL && emu != NULL, return -ENXIO); |
119 | 119 | ||
120 | down(&emu->register_mutex); | 120 | mutex_lock(&emu->register_mutex); |
121 | 121 | ||
122 | if (!snd_emux_inc_count(emu)) { | 122 | if (!snd_emux_inc_count(emu)) { |
123 | up(&emu->register_mutex); | 123 | mutex_unlock(&emu->register_mutex); |
124 | return -EFAULT; | 124 | return -EFAULT; |
125 | } | 125 | } |
126 | 126 | ||
@@ -134,7 +134,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) | |||
134 | if (p == NULL) { | 134 | if (p == NULL) { |
135 | snd_printk("can't create port\n"); | 135 | snd_printk("can't create port\n"); |
136 | snd_emux_dec_count(emu); | 136 | snd_emux_dec_count(emu); |
137 | up(&emu->register_mutex); | 137 | mutex_unlock(&emu->register_mutex); |
138 | return -ENOMEM; | 138 | return -ENOMEM; |
139 | } | 139 | } |
140 | 140 | ||
@@ -148,7 +148,7 @@ snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure) | |||
148 | 148 | ||
149 | snd_emux_reset_port(p); | 149 | snd_emux_reset_port(p); |
150 | 150 | ||
151 | up(&emu->register_mutex); | 151 | mutex_unlock(&emu->register_mutex); |
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
@@ -191,13 +191,13 @@ snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg) | |||
191 | emu = p->emu; | 191 | emu = p->emu; |
192 | snd_assert(emu != NULL, return -ENXIO); | 192 | snd_assert(emu != NULL, return -ENXIO); |
193 | 193 | ||
194 | down(&emu->register_mutex); | 194 | mutex_lock(&emu->register_mutex); |
195 | snd_emux_sounds_off_all(p); | 195 | snd_emux_sounds_off_all(p); |
196 | snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port)); | 196 | snd_soundfont_close_check(emu->sflist, SF_CLIENT_NO(p->chset.port)); |
197 | snd_seq_event_port_detach(p->chset.client, p->chset.port); | 197 | snd_seq_event_port_detach(p->chset.client, p->chset.port); |
198 | snd_emux_dec_count(emu); | 198 | snd_emux_dec_count(emu); |
199 | 199 | ||
200 | up(&emu->register_mutex); | 200 | mutex_unlock(&emu->register_mutex); |
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c index a70a179f6947..1ba68ce30279 100644 --- a/sound/synth/emux/emux_proc.c +++ b/sound/synth/emux/emux_proc.c | |||
@@ -37,7 +37,7 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, | |||
37 | int i; | 37 | int i; |
38 | 38 | ||
39 | emu = entry->private_data; | 39 | emu = entry->private_data; |
40 | down(&emu->register_mutex); | 40 | mutex_lock(&emu->register_mutex); |
41 | if (emu->name) | 41 | if (emu->name) |
42 | snd_iprintf(buf, "Device: %s\n", emu->name); | 42 | snd_iprintf(buf, "Device: %s\n", emu->name); |
43 | snd_iprintf(buf, "Ports: %d\n", emu->num_ports); | 43 | snd_iprintf(buf, "Ports: %d\n", emu->num_ports); |
@@ -56,13 +56,13 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, | |||
56 | snd_iprintf(buf, "Memory Size: 0\n"); | 56 | snd_iprintf(buf, "Memory Size: 0\n"); |
57 | } | 57 | } |
58 | if (emu->sflist) { | 58 | if (emu->sflist) { |
59 | down(&emu->sflist->presets_mutex); | 59 | mutex_lock(&emu->sflist->presets_mutex); |
60 | snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size); | 60 | snd_iprintf(buf, "SoundFonts: %d\n", emu->sflist->fonts_size); |
61 | snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter); | 61 | snd_iprintf(buf, "Instruments: %d\n", emu->sflist->zone_counter); |
62 | snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter); | 62 | snd_iprintf(buf, "Samples: %d\n", emu->sflist->sample_counter); |
63 | snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked); | 63 | snd_iprintf(buf, "Locked Instruments: %d\n", emu->sflist->zone_locked); |
64 | snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked); | 64 | snd_iprintf(buf, "Locked Samples: %d\n", emu->sflist->sample_locked); |
65 | up(&emu->sflist->presets_mutex); | 65 | mutex_unlock(&emu->sflist->presets_mutex); |
66 | } | 66 | } |
67 | #if 0 /* debug */ | 67 | #if 0 /* debug */ |
68 | if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) { | 68 | if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) { |
@@ -103,7 +103,7 @@ snd_emux_proc_info_read(struct snd_info_entry *entry, | |||
103 | snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset); | 103 | snd_iprintf(buf, "sample_mode=%x, rate=%x\n", vp->reg.sample_mode, vp->reg.rate_offset); |
104 | } | 104 | } |
105 | #endif | 105 | #endif |
106 | up(&emu->register_mutex); | 106 | mutex_unlock(&emu->register_mutex); |
107 | } | 107 | } |
108 | 108 | ||
109 | 109 | ||
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 1a973d7a90f8..8f00f07701c4 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c | |||
@@ -123,12 +123,12 @@ snd_emux_detach_seq(struct snd_emux *emu) | |||
123 | if (emu->voices) | 123 | if (emu->voices) |
124 | snd_emux_terminate_all(emu); | 124 | snd_emux_terminate_all(emu); |
125 | 125 | ||
126 | down(&emu->register_mutex); | 126 | mutex_lock(&emu->register_mutex); |
127 | if (emu->client >= 0) { | 127 | if (emu->client >= 0) { |
128 | snd_seq_delete_kernel_client(emu->client); | 128 | snd_seq_delete_kernel_client(emu->client); |
129 | emu->client = -1; | 129 | emu->client = -1; |
130 | } | 130 | } |
131 | up(&emu->register_mutex); | 131 | mutex_unlock(&emu->register_mutex); |
132 | } | 132 | } |
133 | 133 | ||
134 | 134 | ||
@@ -311,10 +311,10 @@ snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info) | |||
311 | emu = p->emu; | 311 | emu = p->emu; |
312 | snd_assert(emu != NULL, return -EINVAL); | 312 | snd_assert(emu != NULL, return -EINVAL); |
313 | 313 | ||
314 | down(&emu->register_mutex); | 314 | mutex_lock(&emu->register_mutex); |
315 | snd_emux_init_port(p); | 315 | snd_emux_init_port(p); |
316 | snd_emux_inc_count(emu); | 316 | snd_emux_inc_count(emu); |
317 | up(&emu->register_mutex); | 317 | mutex_unlock(&emu->register_mutex); |
318 | return 0; | 318 | return 0; |
319 | } | 319 | } |
320 | 320 | ||
@@ -332,10 +332,10 @@ snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info) | |||
332 | emu = p->emu; | 332 | emu = p->emu; |
333 | snd_assert(emu != NULL, return -EINVAL); | 333 | snd_assert(emu != NULL, return -EINVAL); |
334 | 334 | ||
335 | down(&emu->register_mutex); | 335 | mutex_lock(&emu->register_mutex); |
336 | snd_emux_sounds_off_all(p); | 336 | snd_emux_sounds_off_all(p); |
337 | snd_emux_dec_count(emu); | 337 | snd_emux_dec_count(emu); |
338 | up(&emu->register_mutex); | 338 | mutex_unlock(&emu->register_mutex); |
339 | return 0; | 339 | return 0; |
340 | } | 340 | } |
341 | 341 | ||
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c index 4c5754d4a2e8..32c27162dfb6 100644 --- a/sound/synth/emux/soundfont.c +++ b/sound/synth/emux/soundfont.c | |||
@@ -79,7 +79,7 @@ static void | |||
79 | lock_preset(struct snd_sf_list *sflist) | 79 | lock_preset(struct snd_sf_list *sflist) |
80 | { | 80 | { |
81 | unsigned long flags; | 81 | unsigned long flags; |
82 | down(&sflist->presets_mutex); | 82 | mutex_lock(&sflist->presets_mutex); |
83 | spin_lock_irqsave(&sflist->lock, flags); | 83 | spin_lock_irqsave(&sflist->lock, flags); |
84 | sflist->presets_locked = 1; | 84 | sflist->presets_locked = 1; |
85 | spin_unlock_irqrestore(&sflist->lock, flags); | 85 | spin_unlock_irqrestore(&sflist->lock, flags); |
@@ -96,7 +96,7 @@ unlock_preset(struct snd_sf_list *sflist) | |||
96 | spin_lock_irqsave(&sflist->lock, flags); | 96 | spin_lock_irqsave(&sflist->lock, flags); |
97 | sflist->presets_locked = 0; | 97 | sflist->presets_locked = 0; |
98 | spin_unlock_irqrestore(&sflist->lock, flags); | 98 | spin_unlock_irqrestore(&sflist->lock, flags); |
99 | up(&sflist->presets_mutex); | 99 | mutex_unlock(&sflist->presets_mutex); |
100 | } | 100 | } |
101 | 101 | ||
102 | 102 | ||
@@ -1390,7 +1390,7 @@ snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr) | |||
1390 | if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL) | 1390 | if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL) |
1391 | return NULL; | 1391 | return NULL; |
1392 | 1392 | ||
1393 | init_MUTEX(&sflist->presets_mutex); | 1393 | mutex_init(&sflist->presets_mutex); |
1394 | spin_lock_init(&sflist->lock); | 1394 | spin_lock_init(&sflist->lock); |
1395 | sflist->memhdr = hdr; | 1395 | sflist->memhdr = hdr; |
1396 | 1396 | ||
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c index 217e8e552a42..1d9b11f345f8 100644 --- a/sound/synth/util_mem.c +++ b/sound/synth/util_mem.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/mutex.h> | ||
21 | #include <sound/driver.h> | 22 | #include <sound/driver.h> |
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
@@ -42,7 +43,7 @@ snd_util_memhdr_new(int memsize) | |||
42 | if (hdr == NULL) | 43 | if (hdr == NULL) |
43 | return NULL; | 44 | return NULL; |
44 | hdr->size = memsize; | 45 | hdr->size = memsize; |
45 | init_MUTEX(&hdr->block_mutex); | 46 | mutex_init(&hdr->block_mutex); |
46 | INIT_LIST_HEAD(&hdr->block); | 47 | INIT_LIST_HEAD(&hdr->block); |
47 | 48 | ||
48 | return hdr; | 49 | return hdr; |
@@ -136,9 +137,9 @@ struct snd_util_memblk * | |||
136 | snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size) | 137 | snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size) |
137 | { | 138 | { |
138 | struct snd_util_memblk *blk; | 139 | struct snd_util_memblk *blk; |
139 | down(&hdr->block_mutex); | 140 | mutex_lock(&hdr->block_mutex); |
140 | blk = __snd_util_mem_alloc(hdr, size); | 141 | blk = __snd_util_mem_alloc(hdr, size); |
141 | up(&hdr->block_mutex); | 142 | mutex_unlock(&hdr->block_mutex); |
142 | return blk; | 143 | return blk; |
143 | } | 144 | } |
144 | 145 | ||
@@ -163,9 +164,9 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) | |||
163 | { | 164 | { |
164 | snd_assert(hdr && blk, return -EINVAL); | 165 | snd_assert(hdr && blk, return -EINVAL); |
165 | 166 | ||
166 | down(&hdr->block_mutex); | 167 | mutex_lock(&hdr->block_mutex); |
167 | __snd_util_mem_free(hdr, blk); | 168 | __snd_util_mem_free(hdr, blk); |
168 | up(&hdr->block_mutex); | 169 | mutex_unlock(&hdr->block_mutex); |
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
171 | 172 | ||
@@ -175,9 +176,9 @@ int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk) | |||
175 | int snd_util_mem_avail(struct snd_util_memhdr *hdr) | 176 | int snd_util_mem_avail(struct snd_util_memhdr *hdr) |
176 | { | 177 | { |
177 | unsigned int size; | 178 | unsigned int size; |
178 | down(&hdr->block_mutex); | 179 | mutex_lock(&hdr->block_mutex); |
179 | size = hdr->size - hdr->used; | 180 | size = hdr->size - hdr->used; |
180 | up(&hdr->block_mutex); | 181 | mutex_unlock(&hdr->block_mutex); |
181 | return size; | 182 | return size; |
182 | } | 183 | } |
183 | 184 | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index d5013383fad7..4e614ac39f21 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
49 | #include <linux/moduleparam.h> | 49 | #include <linux/moduleparam.h> |
50 | #include <linux/mutex.h> | ||
50 | #include <sound/core.h> | 51 | #include <sound/core.h> |
51 | #include <sound/info.h> | 52 | #include <sound/info.h> |
52 | #include <sound/pcm.h> | 53 | #include <sound/pcm.h> |
@@ -69,6 +70,7 @@ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Vendor ID for | |||
69 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ | 70 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; /* Product ID for this card */ |
70 | static int nrpacks = 4; /* max. number of packets per urb */ | 71 | static int nrpacks = 4; /* max. number of packets per urb */ |
71 | static int async_unlink = 1; | 72 | static int async_unlink = 1; |
73 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card*/ | ||
72 | 74 | ||
73 | module_param_array(index, int, NULL, 0444); | 75 | module_param_array(index, int, NULL, 0444); |
74 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 76 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
@@ -84,6 +86,8 @@ module_param(nrpacks, int, 0644); | |||
84 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); | 86 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); |
85 | module_param(async_unlink, bool, 0444); | 87 | module_param(async_unlink, bool, 0444); |
86 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | 88 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); |
89 | module_param_array(device_setup, int, NULL, 0444); | ||
90 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); | ||
87 | 91 | ||
88 | 92 | ||
89 | /* | 93 | /* |
@@ -202,7 +206,7 @@ struct snd_usb_stream { | |||
202 | * the all interfaces on the same card as one sound device. | 206 | * the all interfaces on the same card as one sound device. |
203 | */ | 207 | */ |
204 | 208 | ||
205 | static DECLARE_MUTEX(register_mutex); | 209 | static DEFINE_MUTEX(register_mutex); |
206 | static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; | 210 | static struct snd_usb_audio *usb_chip[SNDRV_CARDS]; |
207 | 211 | ||
208 | 212 | ||
@@ -475,6 +479,18 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, | |||
475 | return 0; | 479 | return 0; |
476 | } | 480 | } |
477 | 481 | ||
482 | /* determine the number of frames in the next packet */ | ||
483 | static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) | ||
484 | { | ||
485 | if (subs->fill_max) | ||
486 | return subs->maxframesize; | ||
487 | else { | ||
488 | subs->phase = (subs->phase & 0xffff) | ||
489 | + (subs->freqm << subs->datainterval); | ||
490 | return min(subs->phase >> 16, subs->maxframesize); | ||
491 | } | ||
492 | } | ||
493 | |||
478 | /* | 494 | /* |
479 | * Prepare urb for streaming before playback starts. | 495 | * Prepare urb for streaming before playback starts. |
480 | * | 496 | * |
@@ -492,16 +508,7 @@ static int prepare_startup_playback_urb(struct snd_usb_substream *subs, | |||
492 | urb->dev = ctx->subs->dev; | 508 | urb->dev = ctx->subs->dev; |
493 | urb->number_of_packets = subs->packs_per_ms; | 509 | urb->number_of_packets = subs->packs_per_ms; |
494 | for (i = 0; i < subs->packs_per_ms; ++i) { | 510 | for (i = 0; i < subs->packs_per_ms; ++i) { |
495 | /* calculate the size of a packet */ | 511 | counts = snd_usb_audio_next_packet_size(subs); |
496 | if (subs->fill_max) | ||
497 | counts = subs->maxframesize; /* fixed */ | ||
498 | else { | ||
499 | subs->phase = (subs->phase & 0xffff) | ||
500 | + (subs->freqm << subs->datainterval); | ||
501 | counts = subs->phase >> 16; | ||
502 | if (counts > subs->maxframesize) | ||
503 | counts = subs->maxframesize; | ||
504 | } | ||
505 | urb->iso_frame_desc[i].offset = offs * stride; | 512 | urb->iso_frame_desc[i].offset = offs * stride; |
506 | urb->iso_frame_desc[i].length = counts * stride; | 513 | urb->iso_frame_desc[i].length = counts * stride; |
507 | offs += counts; | 514 | offs += counts; |
@@ -538,16 +545,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs, | |||
538 | urb->number_of_packets = 0; | 545 | urb->number_of_packets = 0; |
539 | spin_lock_irqsave(&subs->lock, flags); | 546 | spin_lock_irqsave(&subs->lock, flags); |
540 | for (i = 0; i < ctx->packets; i++) { | 547 | for (i = 0; i < ctx->packets; i++) { |
541 | /* calculate the size of a packet */ | 548 | counts = snd_usb_audio_next_packet_size(subs); |
542 | if (subs->fill_max) | ||
543 | counts = subs->maxframesize; /* fixed */ | ||
544 | else { | ||
545 | subs->phase = (subs->phase & 0xffff) | ||
546 | + (subs->freqm << subs->datainterval); | ||
547 | counts = subs->phase >> 16; | ||
548 | if (counts > subs->maxframesize) | ||
549 | counts = subs->maxframesize; | ||
550 | } | ||
551 | /* set up descriptor */ | 549 | /* set up descriptor */ |
552 | urb->iso_frame_desc[i].offset = offs * stride; | 550 | urb->iso_frame_desc[i].offset = offs * stride; |
553 | urb->iso_frame_desc[i].length = counts * stride; | 551 | urb->iso_frame_desc[i].length = counts * stride; |
@@ -725,10 +723,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s | |||
725 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) | 723 | static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) |
726 | { | 724 | { |
727 | struct snd_pcm_runtime *runtime = subs->runtime; | 725 | struct snd_pcm_runtime *runtime = subs->runtime; |
728 | if (runtime->dma_area) { | 726 | |
729 | vfree(runtime->dma_area); | 727 | vfree(runtime->dma_area); |
730 | runtime->dma_area = NULL; | 728 | runtime->dma_area = NULL; |
731 | } | ||
732 | return 0; | 729 | return 0; |
733 | } | 730 | } |
734 | 731 | ||
@@ -779,6 +776,35 @@ static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sl | |||
779 | } | 776 | } |
780 | 777 | ||
781 | 778 | ||
779 | static const char *usb_error_string(int err) | ||
780 | { | ||
781 | switch (err) { | ||
782 | case -ENODEV: | ||
783 | return "no device"; | ||
784 | case -ENOENT: | ||
785 | return "endpoint not enabled"; | ||
786 | case -EPIPE: | ||
787 | return "endpoint stalled"; | ||
788 | case -ENOSPC: | ||
789 | return "not enough bandwidth"; | ||
790 | case -ESHUTDOWN: | ||
791 | return "device disabled"; | ||
792 | case -EHOSTUNREACH: | ||
793 | return "device suspended"; | ||
794 | #ifndef CONFIG_USB_EHCI_SPLIT_ISO | ||
795 | case -ENOSYS: | ||
796 | return "enable CONFIG_USB_EHCI_SPLIT_ISO to play through a hub"; | ||
797 | #endif | ||
798 | case -EINVAL: | ||
799 | case -EAGAIN: | ||
800 | case -EFBIG: | ||
801 | case -EMSGSIZE: | ||
802 | return "internal error"; | ||
803 | default: | ||
804 | return "unknown error"; | ||
805 | } | ||
806 | } | ||
807 | |||
782 | /* | 808 | /* |
783 | * set up and start data/sync urbs | 809 | * set up and start data/sync urbs |
784 | */ | 810 | */ |
@@ -811,16 +837,22 @@ static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *ru | |||
811 | subs->unlink_mask = 0; | 837 | subs->unlink_mask = 0; |
812 | subs->running = 1; | 838 | subs->running = 1; |
813 | for (i = 0; i < subs->nurbs; i++) { | 839 | for (i = 0; i < subs->nurbs; i++) { |
814 | if ((err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC)) < 0) { | 840 | err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); |
815 | snd_printk(KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err); | 841 | if (err < 0) { |
842 | snd_printk(KERN_ERR "cannot submit datapipe " | ||
843 | "for urb %d, error %d: %s\n", | ||
844 | i, err, usb_error_string(err)); | ||
816 | goto __error; | 845 | goto __error; |
817 | } | 846 | } |
818 | set_bit(i, &subs->active_mask); | 847 | set_bit(i, &subs->active_mask); |
819 | } | 848 | } |
820 | if (subs->syncpipe) { | 849 | if (subs->syncpipe) { |
821 | for (i = 0; i < SYNC_URBS; i++) { | 850 | for (i = 0; i < SYNC_URBS; i++) { |
822 | if ((err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC)) < 0) { | 851 | err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); |
823 | snd_printk(KERN_ERR "cannot submit syncpipe for urb %d, err = %d\n", i, err); | 852 | if (err < 0) { |
853 | snd_printk(KERN_ERR "cannot submit syncpipe " | ||
854 | "for urb %d, error %d: %s\n", | ||
855 | i, err, usb_error_string(err)); | ||
824 | goto __error; | 856 | goto __error; |
825 | } | 857 | } |
826 | set_bit(i + 16, &subs->active_mask); | 858 | set_bit(i + 16, &subs->active_mask); |
@@ -1390,8 +1422,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
1390 | channels = params_channels(hw_params); | 1422 | channels = params_channels(hw_params); |
1391 | fmt = find_format(subs, format, rate, channels); | 1423 | fmt = find_format(subs, format, rate, channels); |
1392 | if (! fmt) { | 1424 | if (! fmt) { |
1393 | snd_printd(KERN_DEBUG "cannot set format: format = %s, rate = %d, channels = %d\n", | 1425 | snd_printd(KERN_DEBUG "cannot set format: format = 0x%x, rate = %d, channels = %d\n", |
1394 | snd_pcm_format_name(format), rate, channels); | 1426 | format, rate, channels); |
1395 | return -EINVAL; | 1427 | return -EINVAL; |
1396 | } | 1428 | } |
1397 | 1429 | ||
@@ -2017,6 +2049,8 @@ static struct usb_driver usb_audio_driver = { | |||
2017 | }; | 2049 | }; |
2018 | 2050 | ||
2019 | 2051 | ||
2052 | #if defined(CONFIG_PROCFS) && defined(CONFIG_SND_VERBOSE_PROCFS) | ||
2053 | |||
2020 | /* | 2054 | /* |
2021 | * proc interface for list the supported pcm formats | 2055 | * proc interface for list the supported pcm formats |
2022 | */ | 2056 | */ |
@@ -2032,7 +2066,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
2032 | fp = list_entry(p, struct audioformat, list); | 2066 | fp = list_entry(p, struct audioformat, list); |
2033 | snd_iprintf(buffer, " Interface %d\n", fp->iface); | 2067 | snd_iprintf(buffer, " Interface %d\n", fp->iface); |
2034 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); | 2068 | snd_iprintf(buffer, " Altset %d\n", fp->altsetting); |
2035 | snd_iprintf(buffer, " Format: %s\n", snd_pcm_format_name(fp->format)); | 2069 | snd_iprintf(buffer, " Format: 0x%x\n", fp->format); |
2036 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); | 2070 | snd_iprintf(buffer, " Channels: %d\n", fp->channels); |
2037 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", | 2071 | snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", |
2038 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, | 2072 | fp->endpoint & USB_ENDPOINT_NUMBER_MASK, |
@@ -2107,6 +2141,13 @@ static void proc_pcm_format_add(struct snd_usb_stream *stream) | |||
2107 | snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); | 2141 | snd_info_set_text_ops(entry, stream, 1024, proc_pcm_format_read); |
2108 | } | 2142 | } |
2109 | 2143 | ||
2144 | #else | ||
2145 | |||
2146 | static inline void proc_pcm_format_add(struct snd_usb_stream *stream) | ||
2147 | { | ||
2148 | } | ||
2149 | |||
2150 | #endif | ||
2110 | 2151 | ||
2111 | /* | 2152 | /* |
2112 | * initialize the substream instance. | 2153 | * initialize the substream instance. |
@@ -2509,6 +2550,8 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp | |||
2509 | return 0; | 2550 | return 0; |
2510 | } | 2551 | } |
2511 | 2552 | ||
2553 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | ||
2554 | int iface, int altno); | ||
2512 | static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 2555 | static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
2513 | { | 2556 | { |
2514 | struct usb_device *dev; | 2557 | struct usb_device *dev; |
@@ -2543,6 +2586,12 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2543 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | 2586 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? |
2544 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 2587 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
2545 | altno = altsd->bAlternateSetting; | 2588 | altno = altsd->bAlternateSetting; |
2589 | |||
2590 | /* audiophile usb: skip altsets incompatible with device_setup | ||
2591 | */ | ||
2592 | if (chip->usb_id == USB_ID(0x0763, 0x2003) && | ||
2593 | audiophile_skip_setting_quirk(chip, iface_no, altno)) | ||
2594 | continue; | ||
2546 | 2595 | ||
2547 | /* get audio formats */ | 2596 | /* get audio formats */ |
2548 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); | 2597 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, AS_GENERAL); |
@@ -2637,7 +2686,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2637 | continue; | 2686 | continue; |
2638 | } | 2687 | } |
2639 | 2688 | ||
2640 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, i, fp->endpoint); | 2689 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint 0x%x\n", dev->devnum, iface_no, altno, fp->endpoint); |
2641 | err = add_audio_endpoint(chip, stream, fp); | 2690 | err = add_audio_endpoint(chip, stream, fp); |
2642 | if (err < 0) { | 2691 | if (err < 0) { |
2643 | kfree(fp->rate_table); | 2692 | kfree(fp->rate_table); |
@@ -3045,6 +3094,45 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
3045 | return 0; | 3094 | return 0; |
3046 | } | 3095 | } |
3047 | 3096 | ||
3097 | /* | ||
3098 | * Setup quirks | ||
3099 | */ | ||
3100 | #define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */ | ||
3101 | #define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */ | ||
3102 | #define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */ | ||
3103 | #define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */ | ||
3104 | #define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */ | ||
3105 | #define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */ | ||
3106 | #define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */ | ||
3107 | #define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */ | ||
3108 | #define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */ | ||
3109 | #define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */ | ||
3110 | |||
3111 | static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | ||
3112 | int iface, int altno) | ||
3113 | { | ||
3114 | if (device_setup[chip->index] & AUDIOPHILE_SET) { | ||
3115 | if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) | ||
3116 | && altno != 6) | ||
3117 | return 1; /* skip this altsetting */ | ||
3118 | if ((device_setup[chip->index] & AUDIOPHILE_SET_96K) | ||
3119 | && altno != 1) | ||
3120 | return 1; /* skip this altsetting */ | ||
3121 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
3122 | AUDIOPHILE_SET_24B_48K_DI && altno != 2) | ||
3123 | return 1; /* skip this altsetting */ | ||
3124 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
3125 | AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3) | ||
3126 | return 1; /* skip this altsetting */ | ||
3127 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
3128 | AUDIOPHILE_SET_16B_48K_DI && altno != 4) | ||
3129 | return 1; /* skip this altsetting */ | ||
3130 | if ((device_setup[chip->index] & AUDIOPHILE_SET_MASK) == | ||
3131 | AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5) | ||
3132 | return 1; /* skip this altsetting */ | ||
3133 | } | ||
3134 | return 0; /* keep this altsetting */ | ||
3135 | } | ||
3048 | 3136 | ||
3049 | /* | 3137 | /* |
3050 | * audio-interface quirks | 3138 | * audio-interface quirks |
@@ -3070,7 +3158,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
3070 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, | 3158 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, |
3071 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, | 3159 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, |
3072 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, | 3160 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, |
3073 | [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, | 3161 | [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, |
3074 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 3162 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
3075 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 3163 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
3076 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, | 3164 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, |
@@ -3282,7 +3370,7 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3282 | 3370 | ||
3283 | /* check whether it's already registered */ | 3371 | /* check whether it's already registered */ |
3284 | chip = NULL; | 3372 | chip = NULL; |
3285 | down(®ister_mutex); | 3373 | mutex_lock(®ister_mutex); |
3286 | for (i = 0; i < SNDRV_CARDS; i++) { | 3374 | for (i = 0; i < SNDRV_CARDS; i++) { |
3287 | if (usb_chip[i] && usb_chip[i]->dev == dev) { | 3375 | if (usb_chip[i] && usb_chip[i]->dev == dev) { |
3288 | if (usb_chip[i]->shutdown) { | 3376 | if (usb_chip[i]->shutdown) { |
@@ -3335,13 +3423,13 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
3335 | 3423 | ||
3336 | usb_chip[chip->index] = chip; | 3424 | usb_chip[chip->index] = chip; |
3337 | chip->num_interfaces++; | 3425 | chip->num_interfaces++; |
3338 | up(®ister_mutex); | 3426 | mutex_unlock(®ister_mutex); |
3339 | return chip; | 3427 | return chip; |
3340 | 3428 | ||
3341 | __error: | 3429 | __error: |
3342 | if (chip && !chip->num_interfaces) | 3430 | if (chip && !chip->num_interfaces) |
3343 | snd_card_free(chip->card); | 3431 | snd_card_free(chip->card); |
3344 | up(®ister_mutex); | 3432 | mutex_unlock(®ister_mutex); |
3345 | __err_val: | 3433 | __err_val: |
3346 | return NULL; | 3434 | return NULL; |
3347 | } | 3435 | } |
@@ -3361,7 +3449,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
3361 | 3449 | ||
3362 | chip = ptr; | 3450 | chip = ptr; |
3363 | card = chip->card; | 3451 | card = chip->card; |
3364 | down(®ister_mutex); | 3452 | mutex_lock(®ister_mutex); |
3365 | chip->shutdown = 1; | 3453 | chip->shutdown = 1; |
3366 | chip->num_interfaces--; | 3454 | chip->num_interfaces--; |
3367 | if (chip->num_interfaces <= 0) { | 3455 | if (chip->num_interfaces <= 0) { |
@@ -3379,10 +3467,10 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) | |||
3379 | snd_usb_mixer_disconnect(p); | 3467 | snd_usb_mixer_disconnect(p); |
3380 | } | 3468 | } |
3381 | usb_chip[chip->index] = NULL; | 3469 | usb_chip[chip->index] = NULL; |
3382 | up(®ister_mutex); | 3470 | mutex_unlock(®ister_mutex); |
3383 | snd_card_free(card); | 3471 | snd_card_free(card); |
3384 | } else { | 3472 | } else { |
3385 | up(®ister_mutex); | 3473 | mutex_unlock(®ister_mutex); |
3386 | } | 3474 | } |
3387 | } | 3475 | } |
3388 | 3476 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index ecd724bfe5a5..88733524d0fb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -161,7 +161,7 @@ enum quirk_type { | |||
161 | QUIRK_MIDI_NOVATION, | 161 | QUIRK_MIDI_NOVATION, |
162 | QUIRK_MIDI_RAW, | 162 | QUIRK_MIDI_RAW, |
163 | QUIRK_MIDI_EMAGIC, | 163 | QUIRK_MIDI_EMAGIC, |
164 | QUIRK_MIDI_MIDITECH, | 164 | QUIRK_MIDI_CME, |
165 | QUIRK_AUDIO_STANDARD_INTERFACE, | 165 | QUIRK_AUDIO_STANDARD_INTERFACE, |
166 | QUIRK_AUDIO_FIXED_ENDPOINT, | 166 | QUIRK_AUDIO_FIXED_ENDPOINT, |
167 | QUIRK_AUDIO_EDIROL_UA700_UA25, | 167 | QUIRK_AUDIO_EDIROL_UA700_UA25, |
@@ -209,7 +209,7 @@ struct snd_usb_midi_endpoint_info { | |||
209 | /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info | 209 | /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info |
210 | * structure (out_cables and in_cables only) */ | 210 | * structure (out_cables and in_cables only) */ |
211 | 211 | ||
212 | /* for QUIRK_MIDI_MIDITECH, data is NULL */ | 212 | /* for QUIRK_MIDI_CME, data is NULL */ |
213 | 213 | ||
214 | /* | 214 | /* |
215 | */ | 215 | */ |
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index f15b021c3ce8..2b9d940c8064 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -871,10 +871,10 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
871 | 871 | ||
872 | static unsigned int snd_usbmidi_count_bits(unsigned int x) | 872 | static unsigned int snd_usbmidi_count_bits(unsigned int x) |
873 | { | 873 | { |
874 | unsigned int bits = 0; | 874 | unsigned int bits; |
875 | 875 | ||
876 | for (; x; x >>= 1) | 876 | for (bits = 0; x; ++bits) |
877 | bits += x & 1; | 877 | x &= x - 1; |
878 | return bits; | 878 | return bits; |
879 | } | 879 | } |
880 | 880 | ||
@@ -1082,6 +1082,8 @@ static struct { | |||
1082 | { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, | 1082 | { USB_ID(0x0582, 0x004d), 0, "%s MIDI" }, |
1083 | { USB_ID(0x0582, 0x004d), 1, "%s 1" }, | 1083 | { USB_ID(0x0582, 0x004d), 1, "%s 1" }, |
1084 | { USB_ID(0x0582, 0x004d), 2, "%s 2" }, | 1084 | { USB_ID(0x0582, 0x004d), 2, "%s 2" }, |
1085 | /* Edirol UM-3EX */ | ||
1086 | { USB_ID(0x0582, 0x009a), 3, "%s Control" }, | ||
1085 | /* M-Audio MidiSport 8x8 */ | 1087 | /* M-Audio MidiSport 8x8 */ |
1086 | { USB_ID(0x0763, 0x1031), 8, "%s Control" }, | 1088 | { USB_ID(0x0763, 0x1031), 8, "%s Control" }, |
1087 | { USB_ID(0x0763, 0x1033), 8, "%s Control" }, | 1089 | { USB_ID(0x0763, 0x1033), 8, "%s Control" }, |
@@ -1574,7 +1576,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1574 | sizeof(struct snd_usb_midi_endpoint_info)); | 1576 | sizeof(struct snd_usb_midi_endpoint_info)); |
1575 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); | 1577 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); |
1576 | break; | 1578 | break; |
1577 | case QUIRK_MIDI_MIDITECH: | 1579 | case QUIRK_MIDI_CME: |
1578 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1580 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1579 | break; | 1581 | break; |
1580 | default: | 1582 | default: |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 678dac2d4dba..8d08b34a1cb5 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -434,7 +434,6 @@ static int add_control_to_empty(struct mixer_build *state, struct snd_kcontrol * | |||
434 | kctl->id.index++; | 434 | kctl->id.index++; |
435 | if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) { | 435 | if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) { |
436 | snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); | 436 | snd_printd(KERN_ERR "cannot add control (err = %d)\n", err); |
437 | snd_ctl_free_one(kctl); | ||
438 | return err; | 437 | return err; |
439 | } | 438 | } |
440 | cval->elem_id = &kctl->id; | 439 | cval->elem_id = &kctl->id; |
@@ -1469,6 +1468,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi | |||
1469 | kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval); | 1468 | kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval); |
1470 | if (! kctl) { | 1469 | if (! kctl) { |
1471 | snd_printk(KERN_ERR "cannot malloc kcontrol\n"); | 1470 | snd_printk(KERN_ERR "cannot malloc kcontrol\n"); |
1471 | kfree(namelist); | ||
1472 | kfree(cval); | 1472 | kfree(cval); |
1473 | return -ENOMEM; | 1473 | return -ENOMEM; |
1474 | } | 1474 | } |
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c index c1264434e50a..37accb68652d 100644 --- a/sound/usb/usbmixer_maps.c +++ b/sound/usb/usbmixer_maps.c | |||
@@ -195,6 +195,22 @@ static struct usbmix_name_map linex_map[] = { | |||
195 | { 0 } /* terminator */ | 195 | { 0 } /* terminator */ |
196 | }; | 196 | }; |
197 | 197 | ||
198 | static struct usbmix_name_map maya44_map[] = { | ||
199 | /* 1: IT line */ | ||
200 | { 2, "Line Playback" }, /* FU */ | ||
201 | /* 3: IT line */ | ||
202 | { 4, "Line Playback" }, /* FU */ | ||
203 | /* 5: IT pcm playback */ | ||
204 | /* 6: MU */ | ||
205 | { 7, "Master Playback" }, /* FU */ | ||
206 | /* 8: OT speaker */ | ||
207 | /* 9: IT line */ | ||
208 | { 10, "Line Capture" }, /* FU */ | ||
209 | /* 11: MU */ | ||
210 | /* 12: OT pcm capture */ | ||
211 | { } | ||
212 | }; | ||
213 | |||
198 | /* Section "justlink_map" below added by James Courtier-Dutton <James@superbug.demon.co.uk> | 214 | /* Section "justlink_map" below added by James Courtier-Dutton <James@superbug.demon.co.uk> |
199 | * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK | 215 | * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK |
200 | * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.) | 216 | * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.) |
@@ -253,6 +269,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
253 | .ignore_ctl_error = 1, | 269 | .ignore_ctl_error = 1, |
254 | }, | 270 | }, |
255 | { | 271 | { |
272 | .id = USB_ID(0x0a92, 0x0091), | ||
273 | .map = maya44_map, | ||
274 | }, | ||
275 | { | ||
256 | .id = USB_ID(0x0c45, 0x1158), | 276 | .id = USB_ID(0x0c45, 0x1158), |
257 | .map = justlink_map, | 277 | .map = justlink_map, |
258 | }, | 278 | }, |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 6190ada00e38..0992a0923f1a 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -82,6 +82,7 @@ YAMAHA_DEVICE(0x1012, "TYROS"), | |||
82 | YAMAHA_DEVICE(0x1013, "PF-500"), | 82 | YAMAHA_DEVICE(0x1013, "PF-500"), |
83 | YAMAHA_DEVICE(0x1014, "S90"), | 83 | YAMAHA_DEVICE(0x1014, "S90"), |
84 | YAMAHA_DEVICE(0x1015, "MOTIF-R"), | 84 | YAMAHA_DEVICE(0x1015, "MOTIF-R"), |
85 | YAMAHA_DEVICE(0x1016, "MDP-5"), | ||
85 | YAMAHA_DEVICE(0x1017, "CVP-204"), | 86 | YAMAHA_DEVICE(0x1017, "CVP-204"), |
86 | YAMAHA_DEVICE(0x1018, "CVP-206"), | 87 | YAMAHA_DEVICE(0x1018, "CVP-206"), |
87 | YAMAHA_DEVICE(0x1019, "CVP-208"), | 88 | YAMAHA_DEVICE(0x1019, "CVP-208"), |
@@ -90,6 +91,7 @@ YAMAHA_DEVICE(0x101b, "PSR-1100"), | |||
90 | YAMAHA_DEVICE(0x101c, "PSR-2100"), | 91 | YAMAHA_DEVICE(0x101c, "PSR-2100"), |
91 | YAMAHA_DEVICE(0x101d, "CLP-175"), | 92 | YAMAHA_DEVICE(0x101d, "CLP-175"), |
92 | YAMAHA_DEVICE(0x101e, "PSR-K1"), | 93 | YAMAHA_DEVICE(0x101e, "PSR-K1"), |
94 | YAMAHA_DEVICE(0x101f, "EZ-J24"), | ||
93 | YAMAHA_DEVICE(0x1020, "EZ-250i"), | 95 | YAMAHA_DEVICE(0x1020, "EZ-250i"), |
94 | YAMAHA_DEVICE(0x1021, "MOTIF ES 6"), | 96 | YAMAHA_DEVICE(0x1021, "MOTIF ES 6"), |
95 | YAMAHA_DEVICE(0x1022, "MOTIF ES 7"), | 97 | YAMAHA_DEVICE(0x1022, "MOTIF ES 7"), |
@@ -294,7 +296,8 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
294 | } | 296 | } |
295 | }, | 297 | }, |
296 | { | 298 | { |
297 | /* a later revision uses ID 0x0099 */ | 299 | /* Has ID 0x0099 when not in "Advanced Driver" mode. |
300 | * The UM-2EX has only one input, but we cannot detect this. */ | ||
298 | USB_DEVICE(0x0582, 0x0005), | 301 | USB_DEVICE(0x0582, 0x0005), |
299 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 302 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
300 | .vendor_name = "EDIROL", | 303 | .vendor_name = "EDIROL", |
@@ -385,7 +388,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
385 | } | 388 | } |
386 | }, | 389 | }, |
387 | { | 390 | { |
388 | /* a later revision uses ID 0x009d */ | 391 | /* has ID 0x009d when not in "Advanced Driver" mode */ |
389 | USB_DEVICE(0x0582, 0x0009), | 392 | USB_DEVICE(0x0582, 0x0009), |
390 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 393 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
391 | .vendor_name = "EDIROL", | 394 | .vendor_name = "EDIROL", |
@@ -1090,6 +1093,53 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1090 | } | 1093 | } |
1091 | } | 1094 | } |
1092 | }, | 1095 | }, |
1096 | /* TODO: add Edirol UA-101 support */ | ||
1097 | { | ||
1098 | /* has ID 0x0081 when not in "Advanced Driver" mode */ | ||
1099 | USB_DEVICE(0x0582, 0x0080), | ||
1100 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1101 | .vendor_name = "Roland", | ||
1102 | .product_name = "G-70", | ||
1103 | .ifnum = 0, | ||
1104 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1105 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1106 | .out_cables = 0x0001, | ||
1107 | .in_cables = 0x0001 | ||
1108 | } | ||
1109 | } | ||
1110 | }, | ||
1111 | /* TODO: add Roland V-SYNTH XT support */ | ||
1112 | /* TODO: add BOSS GT-PRO support */ | ||
1113 | { | ||
1114 | /* has ID 0x008c when not in "Advanced Driver" mode */ | ||
1115 | USB_DEVICE(0x0582, 0x008b), | ||
1116 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1117 | .vendor_name = "EDIROL", | ||
1118 | .product_name = "PC-50", | ||
1119 | .ifnum = 0, | ||
1120 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1121 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1122 | .out_cables = 0x0001, | ||
1123 | .in_cables = 0x0001 | ||
1124 | } | ||
1125 | } | ||
1126 | }, | ||
1127 | /* TODO: add Edirol PC-80 support */ | ||
1128 | /* TODO: add Edirol UA-1EX support */ | ||
1129 | { | ||
1130 | USB_DEVICE(0x0582, 0x009a), | ||
1131 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1132 | .vendor_name = "EDIROL", | ||
1133 | .product_name = "UM-3EX", | ||
1134 | .ifnum = 0, | ||
1135 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1136 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1137 | .out_cables = 0x000f, | ||
1138 | .in_cables = 0x000f | ||
1139 | } | ||
1140 | } | ||
1141 | }, | ||
1142 | /* TODO: add Edirol MD-P1 support */ | ||
1093 | 1143 | ||
1094 | /* Guillemot devices */ | 1144 | /* Guillemot devices */ |
1095 | { | 1145 | { |
@@ -1111,15 +1161,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1111 | } | 1161 | } |
1112 | } | 1162 | } |
1113 | }, | 1163 | }, |
1114 | /* TODO: add Edirol UA-101 support */ | ||
1115 | /* TODO: add Roland G-70 support */ | ||
1116 | /* TODO: add Roland V-SYNTH XT support */ | ||
1117 | /* TODO: add BOSS GT-PRO support */ | ||
1118 | /* TODO: add Edirol PC-50 support */ | ||
1119 | /* TODO: add Edirol PC-80 support */ | ||
1120 | /* TODO: add Edirol UA-1EX support */ | ||
1121 | /* TODO: add Edirol UM-3 support */ | ||
1122 | /* TODO: add Edirol MD-P1 support */ | ||
1123 | 1164 | ||
1124 | /* Midiman/M-Audio devices */ | 1165 | /* Midiman/M-Audio devices */ |
1125 | { | 1166 | { |
@@ -1367,6 +1408,27 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1367 | } | 1408 | } |
1368 | }, | 1409 | }, |
1369 | 1410 | ||
1411 | /* Casio devices */ | ||
1412 | { | ||
1413 | USB_DEVICE(0x07cf, 0x6801), | ||
1414 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1415 | .vendor_name = "Casio", | ||
1416 | .product_name = "PL-40R", | ||
1417 | .ifnum = 0, | ||
1418 | .type = QUIRK_MIDI_YAMAHA | ||
1419 | } | ||
1420 | }, | ||
1421 | { | ||
1422 | /* this ID is used by several devices without a product ID */ | ||
1423 | USB_DEVICE(0x07cf, 0x6802), | ||
1424 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1425 | .vendor_name = "Casio", | ||
1426 | .product_name = "Keyboard", | ||
1427 | .ifnum = 0, | ||
1428 | .type = QUIRK_MIDI_YAMAHA | ||
1429 | } | ||
1430 | }, | ||
1431 | |||
1370 | /* Mark of the Unicorn devices */ | 1432 | /* Mark of the Unicorn devices */ |
1371 | { | 1433 | { |
1372 | /* thanks to Robert A. Lerche <ral 'at' msbit.com> */ | 1434 | /* thanks to Robert A. Lerche <ral 'at' msbit.com> */ |
@@ -1468,6 +1530,15 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1468 | .type = QUIRK_MIDI_STANDARD_INTERFACE | 1530 | .type = QUIRK_MIDI_STANDARD_INTERFACE |
1469 | } | 1531 | } |
1470 | }, | 1532 | }, |
1533 | { | ||
1534 | USB_DEVICE(0x0ccd, 0x0035), | ||
1535 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1536 | .vendor_name = "Miditech", | ||
1537 | .product_name = "Play'n Roll", | ||
1538 | .ifnum = 0, | ||
1539 | .type = QUIRK_MIDI_CME | ||
1540 | } | ||
1541 | }, | ||
1471 | 1542 | ||
1472 | /* Novation EMS devices */ | 1543 | /* Novation EMS devices */ |
1473 | { | 1544 | { |
@@ -1498,22 +1569,24 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1498 | } | 1569 | } |
1499 | }, | 1570 | }, |
1500 | 1571 | ||
1572 | /* Miditech devices */ | ||
1501 | { | 1573 | { |
1502 | USB_DEVICE(0x4752, 0x0011), | 1574 | USB_DEVICE(0x4752, 0x0011), |
1503 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1575 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1504 | .vendor_name = "Miditech", | 1576 | .vendor_name = "Miditech", |
1505 | .product_name = "Midistart-2", | 1577 | .product_name = "Midistart-2", |
1506 | .ifnum = 0, | 1578 | .ifnum = 0, |
1507 | .type = QUIRK_MIDI_MIDITECH | 1579 | .type = QUIRK_MIDI_CME |
1508 | } | 1580 | } |
1509 | }, | 1581 | }, |
1582 | |||
1583 | /* Central Music devices */ | ||
1510 | { | 1584 | { |
1585 | /* this ID used by both Miditech MidiStudio-2 and CME UF-x */ | ||
1511 | USB_DEVICE(0x7104, 0x2202), | 1586 | USB_DEVICE(0x7104, 0x2202), |
1512 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1587 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1513 | .vendor_name = "Miditech", | ||
1514 | .product_name = "MidiStudio-2", | ||
1515 | .ifnum = 0, | 1588 | .ifnum = 0, |
1516 | .type = QUIRK_MIDI_MIDITECH | 1589 | .type = QUIRK_MIDI_CME |
1517 | } | 1590 | } |
1518 | }, | 1591 | }, |
1519 | 1592 | ||
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index e0abb56bbe49..cfec38d7839b 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c | |||
@@ -351,7 +351,7 @@ static struct snd_card *usX2Y_create_card(struct usb_device *device) | |||
351 | usX2Y(card)->chip.dev = device; | 351 | usX2Y(card)->chip.dev = device; |
352 | usX2Y(card)->chip.card = card; | 352 | usX2Y(card)->chip.card = card; |
353 | init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); | 353 | init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); |
354 | init_MUTEX (&usX2Y(card)->prepare_mutex); | 354 | mutex_init(&usX2Y(card)->prepare_mutex); |
355 | INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); | 355 | INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); |
356 | strcpy(card->driver, "USB "NAME_ALLCAPS""); | 356 | strcpy(card->driver, "USB "NAME_ALLCAPS""); |
357 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); | 357 | sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); |
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h index 435c1feda9df..456b5fdbc339 100644 --- a/sound/usb/usx2y/usbusx2y.h +++ b/sound/usb/usx2y/usbusx2y.h | |||
@@ -34,7 +34,7 @@ struct usX2Ydev { | |||
34 | unsigned int rate, | 34 | unsigned int rate, |
35 | format; | 35 | format; |
36 | int chip_status; | 36 | int chip_status; |
37 | struct semaphore prepare_mutex; | 37 | struct mutex prepare_mutex; |
38 | struct us428ctls_sharedmem *us428ctls_sharedmem; | 38 | struct us428ctls_sharedmem *us428ctls_sharedmem; |
39 | int wait_iso_frame; | 39 | int wait_iso_frame; |
40 | wait_queue_head_t us428ctls_wait_queue_head; | 40 | wait_queue_head_t us428ctls_wait_queue_head; |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index a6bbc7a6348f..f6bd0dee563c 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -811,7 +811,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream) | |||
811 | { | 811 | { |
812 | struct snd_pcm_runtime *runtime = substream->runtime; | 812 | struct snd_pcm_runtime *runtime = substream->runtime; |
813 | struct snd_usX2Y_substream *subs = runtime->private_data; | 813 | struct snd_usX2Y_substream *subs = runtime->private_data; |
814 | down(&subs->usX2Y->prepare_mutex); | 814 | mutex_lock(&subs->usX2Y->prepare_mutex); |
815 | snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); | 815 | snd_printdd("snd_usX2Y_hw_free(%p)\n", substream); |
816 | 816 | ||
817 | if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { | 817 | if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { |
@@ -832,7 +832,7 @@ static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream) | |||
832 | usX2Y_urbs_release(subs); | 832 | usX2Y_urbs_release(subs); |
833 | } | 833 | } |
834 | } | 834 | } |
835 | up(&subs->usX2Y->prepare_mutex); | 835 | mutex_unlock(&subs->usX2Y->prepare_mutex); |
836 | return snd_pcm_lib_free_pages(substream); | 836 | return snd_pcm_lib_free_pages(substream); |
837 | } | 837 | } |
838 | /* | 838 | /* |
@@ -849,7 +849,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream) | |||
849 | int err = 0; | 849 | int err = 0; |
850 | snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); | 850 | snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream); |
851 | 851 | ||
852 | down(&usX2Y->prepare_mutex); | 852 | mutex_lock(&usX2Y->prepare_mutex); |
853 | usX2Y_subs_prepare(subs); | 853 | usX2Y_subs_prepare(subs); |
854 | // Start hardware streams | 854 | // Start hardware streams |
855 | // SyncStream first.... | 855 | // SyncStream first.... |
@@ -869,7 +869,7 @@ static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream) | |||
869 | err = usX2Y_urbs_start(subs); | 869 | err = usX2Y_urbs_start(subs); |
870 | 870 | ||
871 | up_prepare_mutex: | 871 | up_prepare_mutex: |
872 | up(&usX2Y->prepare_mutex); | 872 | mutex_unlock(&usX2Y->prepare_mutex); |
873 | return err; | 873 | return err; |
874 | } | 874 | } |
875 | 875 | ||
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 796a7dcef09d..315855082fe1 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
@@ -366,7 +366,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream) | |||
366 | struct snd_pcm_runtime *runtime = substream->runtime; | 366 | struct snd_pcm_runtime *runtime = substream->runtime; |
367 | struct snd_usX2Y_substream *subs = runtime->private_data, | 367 | struct snd_usX2Y_substream *subs = runtime->private_data, |
368 | *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; | 368 | *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2]; |
369 | down(&subs->usX2Y->prepare_mutex); | 369 | mutex_lock(&subs->usX2Y->prepare_mutex); |
370 | snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream); | 370 | snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream); |
371 | 371 | ||
372 | if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { | 372 | if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) { |
@@ -395,7 +395,7 @@ static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream) | |||
395 | usX2Y_usbpcm_urbs_release(cap_subs2); | 395 | usX2Y_usbpcm_urbs_release(cap_subs2); |
396 | } | 396 | } |
397 | } | 397 | } |
398 | up(&subs->usX2Y->prepare_mutex); | 398 | mutex_unlock(&subs->usX2Y->prepare_mutex); |
399 | return snd_pcm_lib_free_pages(substream); | 399 | return snd_pcm_lib_free_pages(substream); |
400 | } | 400 | } |
401 | 401 | ||
@@ -503,7 +503,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream) | |||
503 | memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm)); | 503 | memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm)); |
504 | } | 504 | } |
505 | 505 | ||
506 | down(&usX2Y->prepare_mutex); | 506 | mutex_lock(&usX2Y->prepare_mutex); |
507 | usX2Y_subs_prepare(subs); | 507 | usX2Y_subs_prepare(subs); |
508 | // Start hardware streams | 508 | // Start hardware streams |
509 | // SyncStream first.... | 509 | // SyncStream first.... |
@@ -544,7 +544,7 @@ static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream) | |||
544 | usX2Y->hwdep_pcm_shm->capture_iso_start = -1; | 544 | usX2Y->hwdep_pcm_shm->capture_iso_start = -1; |
545 | 545 | ||
546 | up_prepare_mutex: | 546 | up_prepare_mutex: |
547 | up(&usX2Y->prepare_mutex); | 547 | mutex_unlock(&usX2Y->prepare_mutex); |
548 | return err; | 548 | return err; |
549 | } | 549 | } |
550 | 550 | ||
@@ -621,7 +621,7 @@ static int usX2Y_pcms_lock_check(struct snd_card *card) | |||
621 | if (dev->type != SNDRV_DEV_PCM) | 621 | if (dev->type != SNDRV_DEV_PCM) |
622 | continue; | 622 | continue; |
623 | pcm = dev->device_data; | 623 | pcm = dev->device_data; |
624 | down(&pcm->open_mutex); | 624 | mutex_lock(&pcm->open_mutex); |
625 | } | 625 | } |
626 | list_for_each(list, &card->devices) { | 626 | list_for_each(list, &card->devices) { |
627 | int s; | 627 | int s; |
@@ -650,7 +650,7 @@ static void usX2Y_pcms_unlock(struct snd_card *card) | |||
650 | if (dev->type != SNDRV_DEV_PCM) | 650 | if (dev->type != SNDRV_DEV_PCM) |
651 | continue; | 651 | continue; |
652 | pcm = dev->device_data; | 652 | pcm = dev->device_data; |
653 | up(&pcm->open_mutex); | 653 | mutex_unlock(&pcm->open_mutex); |
654 | } | 654 | } |
655 | } | 655 | } |
656 | 656 | ||