diff --git a/[refs] b/[refs] index 7d50c0ad0dcf..8859add795b5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7f46e6ca0183568a688e6bfe40e3ab9adb305d03 +refs/heads/master: e6c972f21828f16d12704e5cf67d6f79c26cb53b diff --git a/trunk/CREDITS b/trunk/CREDITS index 10c214dc95e7..79fd13dbb8e4 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -2212,13 +2212,13 @@ S: 2300 Copenhagen S S: Denmark N: Claudio S. Matsuoka -E: cmatsuoka@gmail.com -E: claudio@mandriva.com +E: claudio@conectiva.com +E: claudio@helllabs.org W: http://helllabs.org/~claudio -D: V4L, OV511 and HDA-codec hacks +D: V4L, OV511 driver hacks S: Conectiva S.A. -S: Souza Naves 1250 -S: 80050-040 Curitiba PR +S: R. Tocantins 89 +S: 80050-430 Curitiba PR S: Brazil N: Heinz Mauelshagen diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 241e26c4ff92..355ff0a2bb7c 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -467,12 +467,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. above explicitly. The power-management is supported. - - Module snd-cs5530 - _________________ - - Module for Cyrix/NatSemi Geode 5530 chip. - + Module snd-cs5535audio ---------------------- @@ -764,7 +759,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. model - force the model name position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) - probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) single_cmd - Use single immediate commands to communicate with codecs (for debugging only) enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) @@ -809,8 +803,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. hp-3013 HP machines (3013-variant) fujitsu Fujitsu S7020 acer Acer TravelMate - will Will laptops (PB V7900) - replacer Replacer 672V basic fixed pin assignment (old default model) auto auto-config reading BIOS (default) @@ -819,31 +811,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. hp-bpc HP xw4400/6400/8400/9400 laptops hp-bpc-d7000 HP BPC D7000 benq Benq ED8 - benq-t31 Benq T31 hippo Hippo (ATI) with jack detection, Sony UX-90s hippo_1 Hippo (Benq) with jack detection - sony-assamd Sony ASSAMD basic fixed pin assignment w/o SPDIF auto auto-config reading BIOS (default) - ALC268 - 3stack 3-stack model - auto auto-config reading BIOS (default) - - ALC662 - 3stack-dig 3-stack (2-channel) with SPDIF - 3stack-6ch 3-stack (6-channel) - 3stack-6ch-dig 3-stack (6-channel) with SPDIF - 6stack-dig 6-stack with SPDIF - lenovo-101e Lenovo laptop - auto auto-config reading BIOS (default) - ALC882/885 3stack-dig 3-jack with SPDIF I/O 6stack-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 macpro MacPro support - imac24 iMac 24'' with jack detection w2jc ASUS W2JC auto auto-config reading BIOS (default) @@ -855,15 +832,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig-demo 6-jack digital for Intel demo board acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) medion Medion Laptops - medion-md2 Medion MD2 targa-dig Targa/MSI targa-2ch-dig Targs/MSI with 2-channel laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) - lenovo-101e Lenovo 101E - lenovo-nb0763 Lenovo NB0763 - lenovo-ms7195-dig Lenovo MS7195 - 6stack-hp HP machines with 6stack (Nettle boards) - 3stack-hp HP machines with 3stack (Lucknow, Samba boards) auto auto-config reading BIOS (default) ALC861/660 @@ -882,9 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig 3-jack with SPDIF OUT 6stack-dig 6-jack with SPDIF OUT 3stack-660 3-jack (for ALC660VD) - 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD) lenovo Lenovo 3000 C200 - dallas Dallas laptops auto auto-config reading BIOS (default) CMI9880 @@ -895,26 +864,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. allout 5-jack in back, 2-jack in front, SPDIF out auto auto-config reading BIOS (default) - AD1882 - 3stack 3-stack mode (default) - 6stack 6-stack mode - - AD1884 - N/A - AD1981 basic 3-jack (default) hp HP nx6320 thinkpad Lenovo Thinkpad T60/X60/Z60 toshiba Toshiba U205 - AD1983 - N/A - - AD1984 - basic default configuration - thinkpad Lenovo Thinkpad T61/X61 - AD1986A 6stack 6-jack, separate surrounds (default) 3stack 3-stack, shared surrounds @@ -952,18 +907,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. ref Reference board 3stack D945 3stack 5stack D945 5stack + SPDIF - dell Dell XPS M1210 - intel-mac-v1 Intel Mac Type 1 - intel-mac-v2 Intel Mac Type 2 - intel-mac-v3 Intel Mac Type 3 - intel-mac-v4 Intel Mac Type 4 - intel-mac-v5 Intel Mac Type 5 - macmini Intel Mac Mini (equivalent with type 3) - macbook Intel Mac Book (eq. type 5) - macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) - macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) - imac-intel Intel iMac (eq. type 2) - imac-intel-20 Intel iMac (newer version) (eq. type 3) + macmini Intel Mac Mini + macbook Intel Mac Book + macbook-pro-v1 Intel Mac Book Pro 1st generation + macbook-pro Intel Mac Book Pro 2nd generation + imac-intel Intel iMac STAC9202/9250/9251 ref Reference board, base config @@ -1008,17 +956,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. from the irq. Remember this is a last resort, and should be avoided as much as possible... - MORE NOTES ON "azx_get_response timeout" PROBLEMS: - On some hardwares, you may need to add a proper probe_mask option - to avoid the "azx_get_response timeout" problem above, instead. - This occurs when the access to non-existing or non-working codec slot - (likely a modem one) causes a stall of the communication via HD-audio - bus. You can see which codec slots are probed by enabling - CONFIG_SND_DEBUG_DETECT, or simply from the file name of the codec - proc files. Then limit the slots to probe by probe_mask option. - For example, probe_mask=1 means to probe only the first slot, and - probe_mask=4 means only the third slot. - The power-management is supported. Module snd-hdsp diff --git a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt index 2ad5e6306c44..e40cce83327c 100644 --- a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt @@ -1,4 +1,4 @@ - Guide to using M-Audio Audiophile USB with ALSA and Jack v1.5 + Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3 ======================================================== Thibault Le Meur @@ -6,19 +6,8 @@ This document is a guide to using the M-Audio Audiophile USB (tm) device with ALSA and JACK. -History -======= -* v1.4 - Thibault Le Meur (2007-07-11) - - Added Low Endianness nature of 16bits-modes - found by Hakan Lennestal - - Modifying document structure -* v1.5 - Thibault Le Meur (2007-07-12) - - Added AC3/DTS passthru info - - 1 - Audiophile USB Specs and correct usage ========================================== - This part is a reminder of important facts about the functions and limitations of the device. @@ -36,18 +25,18 @@ The device has 4 audio interfaces, and 2 MIDI ports: The internal DAC/ADC has the following characteristics: * sample depth of 16 or 24 bits * sample rate from 8kHz to 96kHz -* Two interfaces can't use different sample depths at the same time. -Moreover, the Audiophile USB documentation gives the following Warning: -"Please exit any audio application running before switching between bit depths" +* Two ports can't use different sample depths at the same time. Moreover, the +Audiophile USB documentation gives the following Warning: "Please exit any +audio application running before switching between bit depths" Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be activated at the same time depending on the audio mode selected: - * 16-bit/48kHz ==> 4 channels in + 4 channels out + * 16-bit/48kHz ==> 4 channels in/4 channels out - Ai+Ao+Di+Do - * 24-bit/48kHz ==> 4 channels in + 2 channels out, - or 2 channels in + 4 channels out + * 24-bit/48kHz ==> 4 channels in/2 channels out, + or 2 channels in/4 channels out - Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do - * 24-bit/96kHz ==> 2 channels in _or_ 2 channels out (half duplex only) + * 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only) - Ai or Ao or Di or Do Important facts about the Digital interface: @@ -63,56 +52,44 @@ source is connected synchronization error (for instance sound played at an odd sample rate) -2 - Audiophile USB MIDI support in ALSA -======================================= +2 - Audiophile USB support in ALSA +================================== -The Audiophile USB MIDI ports will be automatically supported once the +2.1 - MIDI ports +---------------- +The Audiophile USB MIDI ports will be automatically supported once the following modules have been loaded: * snd-usb-audio * snd-seq-midi No additional setting is required. - -3 - Audiophile USB Audio support in ALSA -======================================== +2.2 - Audio ports +----------------- Audio functions of the Audiophile USB device are handled by the snd-usb-audio module. This module can work in a default mode (without any device-specific parameter), or in an "advanced" mode with the device-specific parameter called "device_setup". -3.1 - Default Alsa driver mode ------------------------------- - -The default behavior of the snd-usb-audio driver is to list the device -capabilities at startup and activate the required mode when required -by the applications: for instance if the user is recording in a -24bit-depth-mode and immediately after wants to switch to a 16bit-depth mode, -the snd-usb-audio module will reconfigure the device on the fly. - -This approach has the advantage to let the driver automatically switch from sample -rates/depths automatically according to the user's needs. However, those who -are using the device under windows know that this is not how the device is meant to -work: under windows applications must be closed before using the m-audio control -panel to switch the device working mode. Thus as we'll see in next section, this -Default Alsa driver mode can lead to device misconfigurations. - -Let's get back to the Default Alsa driver mode for now. In this case the -Audiophile interfaces are mapped to alsa pcm devices in the following -way (I suppose the device's index is 1): +2.2.1 - Default Alsa driver mode + +The default behavior of the snd-usb-audio driver is to parse the device +capabilities at startup and enable all functions inside the device (including +all ports at any supported sample rates and sample depths). This approach +has the advantage to let the driver easily switch from sample rates/depths +automatically according to the need of the application claiming the device. + +In this case the Audiophile ports are mapped to alsa pcm devices in the +following way (I suppose the device's index is 1): * hw:1,0 is Ao in playback and Di in capture * hw:1,1 is Do in playback and Ai in capture * hw:1,2 is Do in AC3/DTS passthrough mode -In this mode, the device uses Big Endian byte-encoding so that -supported audio format are S16_BE for 16-bit depth modes and S24_3BE for -24-bits depth mode. - -One exception is the hw:1,2 port which was reported to be Little Endian -compliant (supposedly supporting S16_LE) but processes in fact only S16_BE streams. -This has been fixed in kernel 2.6.23 and above and now the hw:1,2 interface -is reported to be big endian in this default driver mode. +You must note as well that the device uses Big Endian byte encoding so that +supported audio format are S16_BE for 16-bit depth modes and S24_3BE for +24-bits depth mode. One exception is the hw:1,2 port which is Little Endian +compliant and thus uses S16_LE. Examples: * playing a S24_3BE encoded raw file to the Ao port @@ -121,26 +98,22 @@ Examples: % arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw * playing a S16_BE encoded raw file to the Do port % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw - * playing an ac3 sample file to the Do port - % aplay -D hw:1,2 --channels=6 ac3_S16_BE_encoded_file.raw -If you're happy with the default Alsa driver mode and don't experience any +If you're happy with the default Alsa driver setup and don't experience any issue with this mode, then you can skip the following chapter. -3.2 - Advanced module setup ---------------------------- +2.2.2 - Advanced module setup Due to the hardware constraints described above, the device initialization made by the Alsa driver in default mode may result in a corrupted state of the device. For instance, a particularly annoying issue is that the sound captured -from the Ai interface sounds distorted (as if boosted with an excessive high -volume gain). +from the Ai port sounds distorted (as if boosted with an excessive high volume +gain). For people having this problem, the snd-usb-audio module has a new module -parameter called "device_setup" (this parameter was introduced in kernel -release 2.6.17) +parameter called "device_setup". -3.2.1 - Initializing the working mode of the Audiophile USB +2.2.2.1 - Initializing the working mode of the Audiophile USB As far as the Audiophile USB device is concerned, this value let the user specify: @@ -148,57 +121,33 @@ specify: * the sample rate * whether the Di port is used or not -When initialized with "device_setup=0x00", the snd-usb-audio module has -the same behaviour as when the parameter is omitted (see paragraph "Default -Alsa driver mode" above) - -Others modes are described in the following subsections. - -3.2.1.1 - 16-bit modes - -The two supported modes are: - +Here is a list of supported device_setup values for this device: + * device_setup=0x00 (or omitted) + - Alsa driver default mode + - maintains backward compatibility with setups that do not use this + parameter by not introducing any change + - results sometimes in corrupted sound as described earlier * device_setup=0x01 - 16bits 48kHz mode with Di disabled - Ai,Ao,Do can be used at the same time - hw:1,0 is not available in capture mode - hw:1,2 is not available - * device_setup=0x11 - 16bits 48kHz mode with Di enabled - Ai,Ao,Di,Do can be used at the same time - hw:1,0 is available in capture mode - hw:1,2 is not available - -In this modes the device operates only at 16bits-modes. Before kernel 2.6.23, -the devices where reported to be Big-Endian when in fact they were Little-Endian -so that playing a file was a matter of using: - % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test_S16_LE.raw -where "test_S16_LE.raw" was in fact a little-endian sample file. - -Thanks to Hakan Lennestal (who discovered the Little-Endiannes of the device in -these modes) a fix has been committed (expected in kernel 2.6.23) and -Alsa now reports Little-Endian interfaces. Thus playing a file now is as simple as -using: - % aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_LE test_S16_LE.raw - -3.2.1.2 - 24-bit modes - -The three supported modes are: - * device_setup=0x09 - 24bits 48kHz mode with Di disabled - Ai,Ao,Do can be used at the same time - hw:1,0 is not available in capture mode - hw:1,2 is not available - * device_setup=0x19 - 24bits 48kHz mode with Di enabled - 3 ports from {Ai,Ao,Di,Do} can be used at the same time - hw:1,0 is available in capture mode and an active digital source must be connected to Di - hw:1,2 is not available - * device_setup=0x0D or 0x10 - 24bits 96kHz mode - Di is enabled by default for this mode but does not need to be connected @@ -206,64 +155,34 @@ The three supported modes are: - Only 1 port from {Ai,Ao,Di,Do} can be used at the same time - hw:1,0 is available in captured mode - hw:1,2 is not available - -In these modes the device is only Big-Endian compliant (see "Default Alsa driver -mode" above for an aplay command example) - -3.2.1.3 - AC3 w/ DTS passthru mode - -Thanks to Hakan Lennestal, I now have a report saying that this mode works. - * device_setup=0x03 - 16bits 48kHz mode with only the Do port enabled - - AC3 with DTS passthru + - AC3 with DTS passthru (not tested) - Caution with this setup the Do port is mapped to the pcm device hw:1,0 -The command line used to playback the AC3/DTS encoded .wav-files in this mode: - % aplay -D hw:1,0 --channels=6 ac3_S16_LE_encoded_file.raw - -3.2.2 - How to use the device_setup parameter ----------------------------------------------- +2.2.2.2 - Setting and switching configurations with the device_setup parameter The parameter can be given: - * By manually probing the device (as root): # modprobe -r snd-usb-audio # modprobe snd-usb-audio index=1 device_setup=0x09 - * Or while configuring the modules options in your modules configuration file - For Fedora distributions, edit the /etc/modprobe.conf file: alias snd-card-1 snd-usb-audio options snd-usb-audio index=1 device_setup=0x09 -CAUTION when initializaing the device -------------------------------------- - - * Correct initialization on the device requires that device_setup is given to - the module BEFORE the device is turned on. So, if you use the "manual probing" - method described above, take care to power-on the device AFTER this initialization. - - * Failing to respect this will lead in a misconfiguration of the device. In this case - turn off the device, unproble the snd-usb-audio module, then probe it again with - correct device_setup parameter and then (and only then) turn on the device again. - - * If you've correctly initialized the device in a valid mode and then want to switch - to another mode (possibly with another sample-depth), please use also the following - procedure: +IMPORTANT NOTE WHEN SWITCHING CONFIGURATION: +------------------------------------------- + * You may need to _first_ initialize the module with the correct device_setup + parameter and _only_after_ turn on the Audiophile USB device + * This is especially true when switching the sample depth: - first turn off the device - de-register the snd-usb-audio module (modprobe -r) - change the device_setup parameter by changing the device_setup option in /etc/modprobe.conf - turn on the device - * A workaround for this last issue has been applied to kernel 2.6.23, but it may not - be enough to ensure the 'stability' of the device initialization. -3.2.3 - Technical details for hackers -------------------------------------- -This section is for hackers, wanting to understand details about the device -internals and how Alsa supports it. - -3.2.3.1 - Audiophile USB's device_setup structure +2.2.2.3 - Audiophile USB's device_setup structure If you want to understand the device_setup magic numbers for the Audiophile USB, you need some very basic understanding of binary computation. However, @@ -309,12 +228,12 @@ Caution: - choosing b2 will prepare all interfaces for 24bits/96kHz but you'll only be able to use one at the same time -3.2.3.2 - USB implementation details for this device +2.2.3 - USB implementation details for this device You may safely skip this section if you're not interested in driver -hacking. +development. -This section describes some internal aspects of the device and summarizes the +This section describes some internal aspects of the device and summarize the data I got by usb-snooping the windows and Linux drivers. The M-Audio Audiophile USB has 7 USB Interfaces: @@ -374,45 +293,43 @@ parse_audio_endpoints function uses a quirk called "audiophile_skip_setting_quirk" in order to prevent AltSettings not corresponding to device_setup from being registered in the driver. -4 - Audiophile USB and Jack support +3 - Audiophile USB and Jack support =================================== This section deals with support of the Audiophile USB device in Jack. +The main issue regarding this support is that the device is Big Endian +compliant. -There are 2 main potential issues when using Jackd with the device: -* support for Big-Endian devices in 24-bit modes -* support for 4-in / 4-out channels - -4.1 - Direct support in Jackd ------------------------------ +3.1 - Using the plug alsa plugin +-------------------------------- -Jack supports big endian devices only in recent versions (thanks to -Andreas Steinmetz for his first big-endian patch). I can't remember -extacly when this support was released into jackd, let's just say that -with jackd version 0.103.0 it's almost ok (just a small bug is affecting -16bits Big-Endian devices, but since you've read carefully the above -paragraphs, you're now using kernel >= 2.6.23 and your 16bits devices -are now Little Endians ;-) ). - -You can run jackd with the following command for playback with Ao and -record with Ai: - % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 - -4.2 - Using Alsa plughw ------------------------ -If you don't have a recent Jackd installed, you can downgrade to using -the Alsa "plug" converter. +Jack doesn't directly support big endian devices. Thus, one way to have support +for this device with Alsa is to use the Alsa "plug" converter. For instance here is one way to run Jack with 2 playback channels on Ao and 2 capture channels from Ai: % jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1 + However you may see the following warning message: "You appear to be using the ALSA software "plug" layer, probably a result of using the "default" ALSA device. This is less efficient than it could be. Consider using a hardware device instead rather than using the plug layer." -4.3 - Getting 2 input and/or output interfaces in Jack +3.2 - Patching alsa to use direct pcm device +-------------------------------------------- +A patch for Jack by Andreas Steinmetz adds support for Big Endian devices. +However it has not been included in the CVS tree. + +You can find it at the following URL: +http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687& +atid=425939 + +After having applied the patch you can run jackd with the following command +line: + % jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1 + +3.2 - Getting 2 input and/or output interfaces in Jack ------------------------------------------------------ As you can see, starting the Jack server this way will only enable 1 stereo @@ -422,7 +339,6 @@ This is due to the following restrictions: * Jack can only open one capture device and one playback device at a time * The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1 (and optionally hw:1,2) - If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to combine the Alsa devices into one logical "complex" device. @@ -432,11 +348,13 @@ It is related to another device (ice1712) but can be adapted to suit the Audiophile USB. Enabling multiple Audiophile USB interfaces for Jackd will certainly require: -* Making sure your Jackd version has the MMAP_COMPLEX patch (see the ice1712 page) -* (maybe) patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) +* patching Jack with the previously mentioned "Big Endian" patch +* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page) +* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page) * define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc file * start jackd with this device -I had no success in testing this for now, if you have any success with this kind -of setup, please drop me an email. +I had no success in testing this for now, but this may be due to my OS +configuration. If you have any success with this kind of setup, please +drop me an email. diff --git a/trunk/Documentation/sound/alsa/OSS-Emulation.txt b/trunk/Documentation/sound/alsa/OSS-Emulation.txt index bfa0c9aacb4b..ec2a02541d5b 100644 --- a/trunk/Documentation/sound/alsa/OSS-Emulation.txt +++ b/trunk/Documentation/sound/alsa/OSS-Emulation.txt @@ -278,21 +278,6 @@ current mixer configuration by reading and writing the whole file image. -Duplex Streams -============== - -Note that when attempting to use a single device file for playback and -capture, the OSS API provides no way to set the format, sample rate or -number of channels different in each direction. Thus - io_handle = open("device", O_RDWR) -will only function correctly if the values are the same in each direction. - -To use different values in the two directions, use both - input_handle = open("device", O_RDONLY) - output_handle = open("device", O_WRONLY) -and set the values for the corresponding handle. - - Unsupported Features ==================== diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f49c5563f060..fbe0dca1c0ed 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -329,12 +329,6 @@ P: Ivan Kokshaysky M: ink@jurassic.park.msu.ru S: Maintained for 2.4; PCI support for 2.6. -AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER -P: Thomas Dahlmann -M: thomas.dahlmann@amd.com -L: info-linux@geode.amd.com -S: Supported - AMD GEODE PROCESSOR/CHIPSET SUPPORT P: Jordan Crouse M: info-linux@geode.amd.com diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 846cce48e2b7..c04124a095cf 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -145,8 +145,8 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) __do_kernel_fault(mm, addr, fsr, regs); } -#define VM_FAULT_BADMAP 0x010000 -#define VM_FAULT_BADACCESS 0x020000 +#define VM_FAULT_BADMAP (-20) +#define VM_FAULT_BADACCESS (-21) static int __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, @@ -249,7 +249,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR */ - if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) + if (likely(!(fault & VM_FAULT_ERROR))) return 0; /* diff --git a/trunk/arch/i386/boot/compressed/relocs.c b/trunk/arch/i386/boot/compressed/relocs.c index 2d77ee728f92..b0e21c3cee5c 100644 --- a/trunk/arch/i386/boot/compressed/relocs.c +++ b/trunk/arch/i386/boot/compressed/relocs.c @@ -31,7 +31,6 @@ static const char* safe_abs_relocs[] = { "__kernel_rt_sigreturn", "__kernel_sigreturn", "SYSENTER_RETURN", - "VDSO_NOTE_MASK", "xen_irq_disable_direct_reloc", "xen_save_fl_direct_reloc", }; diff --git a/trunk/arch/i386/kernel/vsyscall-note.S b/trunk/arch/i386/kernel/vsyscall-note.S index 07c0daf78237..271f16a8ca01 100644 --- a/trunk/arch/i386/kernel/vsyscall-note.S +++ b/trunk/arch/i386/kernel/vsyscall-note.S @@ -14,6 +14,7 @@ ELFNOTE_START(Linux, 0, "a") ELFNOTE_END #ifdef CONFIG_XEN + /* * Add a special note telling glibc's dynamic linker a fake hardware * flavor that it will use to choose the search path for libraries in the @@ -27,19 +28,15 @@ ELFNOTE_END * It should contain: * hwcap 1 nosegneg * to match the mapping of bit to name that we give here. - * - * At runtime, the fake hardware feature will be considered to be present - * if its bit is set in the mask word. So, we start with the mask 0, and - * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen. */ -#include "../xen/vdso.h" /* Defines VDSO_NOTE_NONEGSEG_BIT. */ +/* Bit used for the pseudo-hwcap for non-negative segments. We use + bit 1 to avoid bugs in some versions of glibc when bit 0 is + used; the choice is otherwise arbitrary. */ +#define VDSO_NOTE_NONEGSEG_BIT 1 - .globl VDSO_NOTE_MASK ELFNOTE_START(GNU, 2, "a") - .long 1 /* ncaps */ -VDSO_NOTE_MASK: - .long 0 /* mask */ + .long 1, 1< #include #include -#include #include #include diff --git a/trunk/arch/i386/xen/setup.c b/trunk/arch/i386/xen/setup.c index f84e77226646..2fe6eac510f0 100644 --- a/trunk/arch/i386/xen/setup.c +++ b/trunk/arch/i386/xen/setup.c @@ -19,7 +19,6 @@ #include #include "xen-ops.h" -#include "vdso.h" /* These are code, but not functions. Defined in entry.S */ extern const char xen_hypervisor_callback[]; @@ -56,18 +55,6 @@ static void xen_idle(void) } } -/* - * Set the bit indicating "nosegneg" library variants should be used. - */ -static void fiddle_vdso(void) -{ - extern u32 VDSO_NOTE_MASK; /* See ../kernel/vsyscall-note.S. */ - extern char vsyscall_int80_start; - u32 *mask = (u32 *) ((unsigned long) &VDSO_NOTE_MASK - VDSO_PRELINK + - &vsyscall_int80_start); - *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT; -} - void __init xen_arch_setup(void) { struct physdev_set_iopl set_iopl; @@ -106,6 +93,4 @@ void __init xen_arch_setup(void) #endif paravirt_disable_iospace(); - - fiddle_vdso(); } diff --git a/trunk/arch/i386/xen/vdso.h b/trunk/arch/i386/xen/vdso.h deleted file mode 100644 index 861fedfe5230..000000000000 --- a/trunk/arch/i386/xen/vdso.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Bit used for the pseudo-hwcap for non-negative segments. We use - bit 1 to avoid bugs in some versions of glibc when bit 0 is - used; the choice is otherwise arbitrary. */ -#define VDSO_NOTE_NONEGSEG_BIT 1 diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 20a9c08e59c3..a86e2e9a639f 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -37,10 +37,6 @@ config TIME_LOW_RES bool default y -config GENERIC_IOMAP - bool - default y - config ARCH_MAY_HAVE_PC_FDC bool depends on Q40 || (BROKEN && SUN3X) @@ -49,9 +45,6 @@ config ARCH_MAY_HAVE_PC_FDC config NO_IOPORT def_bool y -config NO_DMA - def_bool SUN3 - mainmenu "Linux/68k Kernel Configuration" source "init/Kconfig" diff --git a/trunk/arch/m68k/apollo/config.c b/trunk/arch/m68k/apollo/config.c index 78df98f2029a..cb8e7609df4c 100644 --- a/trunk/arch/m68k/apollo/config.c +++ b/trunk/arch/m68k/apollo/config.c @@ -148,8 +148,8 @@ void dn_serial_print (const char *str) } } -void __init config_apollo(void) -{ +void config_apollo(void) { + int i; dn_setup_model(); diff --git a/trunk/arch/m68k/apollo/dn_ints.c b/trunk/arch/m68k/apollo/dn_ints.c index 5d47f3aa3810..13bd41bed28e 100644 --- a/trunk/arch/m68k/apollo/dn_ints.c +++ b/trunk/arch/m68k/apollo/dn_ints.c @@ -37,7 +37,7 @@ static struct irq_controller apollo_irq_controller = { }; -void __init dn_init_IRQ(void) +void dn_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); diff --git a/trunk/arch/m68k/atari/atakeyb.c b/trunk/arch/m68k/atari/atakeyb.c index 2b5f64726a2e..1c29603b16b3 100644 --- a/trunk/arch/m68k/atari/atakeyb.c +++ b/trunk/arch/m68k/atari/atakeyb.c @@ -13,7 +13,6 @@ * enhanced by Bjoern Brauel and Roman Hodek */ -#include #include #include #include @@ -43,9 +42,6 @@ void (*atari_mouse_interrupt_hook) (char *); void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); /* Hook for mouse inputdev driver */ void (*atari_input_mouse_interrupt_hook) (char *); -EXPORT_SYMBOL(atari_mouse_interrupt_hook); -EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook); -EXPORT_SYMBOL(atari_input_mouse_interrupt_hook); /* variables for IKBD self test: */ @@ -433,7 +429,6 @@ void ikbd_mouse_rel_pos(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_rel_pos); /* Set absolute mouse position reporting */ void ikbd_mouse_abs_pos(int xmax, int ymax) @@ -458,7 +453,6 @@ void ikbd_mouse_thresh(int x, int y) ikbd_write(cmd, 3); } -EXPORT_SYMBOL(ikbd_mouse_thresh); /* Set mouse scale */ void ikbd_mouse_scale(int x, int y) @@ -501,7 +495,6 @@ void ikbd_mouse_y0_top(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_y0_top); /* Resume */ void ikbd_resume(void) @@ -518,7 +511,6 @@ void ikbd_mouse_disable(void) ikbd_write(cmd, 1); } -EXPORT_SYMBOL(ikbd_mouse_disable); /* Pause output */ void ikbd_pause(void) @@ -704,6 +696,7 @@ int __init atari_keyb_init(void) return 0; } + int atari_kbdrate(struct kbd_repeat *k) { if (k->delay > 0) { diff --git a/trunk/arch/m68k/bvme6000/config.c b/trunk/arch/m68k/bvme6000/config.c index 9433a88a33c4..896ae3d3d919 100644 --- a/trunk/arch/m68k/bvme6000/config.c +++ b/trunk/arch/m68k/bvme6000/config.c @@ -97,7 +97,7 @@ static int bvme6000_get_hardware_list(char *buffer) * This function is called during kernel startup to initialize * the bvme6000 IRQ handling routines. */ -static void __init bvme6000_init_IRQ(void) +static void bvme6000_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/kernel/head.S b/trunk/arch/m68k/kernel/head.S index faa6764f1d13..05741f233567 100644 --- a/trunk/arch/m68k/kernel/head.S +++ b/trunk/arch/m68k/kernel/head.S @@ -577,7 +577,7 @@ func_define putn,1 #endif .endm -.section ".text.head","ax" +.text ENTRY(_stext) /* * Version numbers of the bootinfo interface diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 7e6d5fb75390..215c7bd43924 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -58,7 +58,6 @@ extern int end; extern unsigned long availmem; int m68k_num_memory; -EXPORT_SYMBOL(m68k_num_memory); int m68k_realnum_memory; EXPORT_SYMBOL(m68k_realnum_memory); unsigned long m68k_memoffset; diff --git a/trunk/arch/m68k/kernel/sun3-head.S b/trunk/arch/m68k/kernel/sun3-head.S index aad01592dbbc..4b5f050204e8 100644 --- a/trunk/arch/m68k/kernel/sun3-head.S +++ b/trunk/arch/m68k/kernel/sun3-head.S @@ -29,7 +29,7 @@ kernel_pmd_table: .skip 0x2000 .globl kernel_pg_dir .equ kernel_pg_dir,kernel_pmd_table - .section .text.head + .section .head ENTRY(_stext) ENTRY(_start) diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 7db41594d7b6..4c065f9ceffc 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -72,7 +72,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy) return IRQ_HANDLED; } -void __init time_init(void) +void time_init(void) { struct rtc_time time; diff --git a/trunk/arch/m68k/kernel/vmlinux-std.lds b/trunk/arch/m68k/kernel/vmlinux-std.lds index c42245775a4d..40f02b128f22 100644 --- a/trunk/arch/m68k/kernel/vmlinux-std.lds +++ b/trunk/arch/m68k/kernel/vmlinux-std.lds @@ -11,7 +11,6 @@ SECTIONS . = 0x1000; _text = .; /* Text and read-only data */ .text : { - *(.text.head) TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/m68k/kernel/vmlinux-sun3.lds b/trunk/arch/m68k/kernel/vmlinux-sun3.lds index 4adffefb5c48..f06425b6d206 100644 --- a/trunk/arch/m68k/kernel/vmlinux-sun3.lds +++ b/trunk/arch/m68k/kernel/vmlinux-sun3.lds @@ -11,7 +11,7 @@ SECTIONS . = 0xE002000; _text = .; /* Text and read-only data */ .text : { - *(.text.head) + *(.head) TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 8547dbc5e8d7..5fd413246f89 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -49,7 +49,6 @@ struct mac_booter_data mac_bi_data; int mac_bisize = sizeof mac_bi_data; struct mac_hw_present mac_hw_present; -EXPORT_SYMBOL(mac_hw_present); /* New m68k bootinfo stuff and videobase */ @@ -85,7 +84,7 @@ extern void nubus_sweep_video(void); static void mac_get_model(char *str); -static void __init mac_sched_init(irq_handler_t vector) +static void mac_sched_init(irq_handler_t vector) { via_init_clock(vector); } @@ -770,7 +769,7 @@ static struct mac_model mac_data_table[] = { } }; -void __init mac_identify(void) +void mac_identify(void) { struct mac_model *m; @@ -847,7 +846,7 @@ void __init mac_identify(void) baboon_init(); } -void __init mac_report_hardware(void) +void mac_report_hardware(void) { printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name); } diff --git a/trunk/arch/m68k/mac/macints.c b/trunk/arch/m68k/mac/macints.c index ecddac4a02b9..0fc72d8f786e 100644 --- a/trunk/arch/m68k/mac/macints.c +++ b/trunk/arch/m68k/mac/macints.c @@ -114,7 +114,6 @@ * */ -#include #include #include #include @@ -225,7 +224,7 @@ static struct irq_controller mac_irq_controller = { .disable = mac_disable_irq, }; -void __init mac_init_IRQ(void) +void mac_init_IRQ(void) { #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); @@ -392,7 +391,6 @@ int mac_irq_pending(unsigned int irq) } return 0; } -EXPORT_SYMBOL(mac_irq_pending); static int num_debug[8]; diff --git a/trunk/arch/m68k/mm/init.c b/trunk/arch/m68k/mm/init.c index f42caa79e4e8..f1de19e1dde6 100644 --- a/trunk/arch/m68k/mm/init.c +++ b/trunk/arch/m68k/mm/init.c @@ -44,7 +44,7 @@ pg_data_t *pg_data_table[65]; EXPORT_SYMBOL(pg_data_table); #endif -void __init m68k_setup_node(int node) +void m68k_setup_node(int node) { #ifndef CONFIG_SINGLE_MEMORY_CHUNK struct mem_info *info = m68k_memory + node; diff --git a/trunk/arch/m68k/mm/sun3kmap.c b/trunk/arch/m68k/mm/sun3kmap.c index 3dc41158c05e..1af24cb5bfe1 100644 --- a/trunk/arch/m68k/mm/sun3kmap.c +++ b/trunk/arch/m68k/mm/sun3kmap.c @@ -105,7 +105,6 @@ void __iomem *sun3_ioremap(unsigned long phys, unsigned long size, return (void __iomem *)ret; } -EXPORT_SYMBOL(sun3_ioremap); void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache) @@ -158,4 +157,3 @@ int sun3_map_test(unsigned long addr, char *val) return ret; } -EXPORT_SYMBOL(sun3_map_test); diff --git a/trunk/arch/m68k/mvme147/config.c b/trunk/arch/m68k/mvme147/config.c index 92fe50714112..4a7df9c3f85a 100644 --- a/trunk/arch/m68k/mvme147/config.c +++ b/trunk/arch/m68k/mvme147/config.c @@ -89,7 +89,7 @@ static int mvme147_get_hardware_list(char *buffer) * the mvme147 IRQ handling routines. */ -void __init mvme147_init_IRQ(void) +void mvme147_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/mvme16x/config.c b/trunk/arch/m68k/mvme16x/config.c index daa785161401..c829ebb6b1af 100644 --- a/trunk/arch/m68k/mvme16x/config.c +++ b/trunk/arch/m68k/mvme16x/config.c @@ -119,7 +119,7 @@ static int mvme16x_get_hardware_list(char *buffer) * that the base vectors for the VMEChip2 and PCCChip2 are valid. */ -static void __init mvme16x_init_IRQ (void) +static void mvme16x_init_IRQ (void) { m68k_setup_user_interrupt(VEC_USER, 192, NULL); } diff --git a/trunk/arch/m68k/q40/q40ints.c b/trunk/arch/m68k/q40/q40ints.c index ad3ed1fb8879..2fb25ae46a8a 100644 --- a/trunk/arch/m68k/q40/q40ints.c +++ b/trunk/arch/m68k/q40/q40ints.c @@ -79,7 +79,7 @@ static struct irq_controller q40_irq_controller = { static int disabled; -void __init q40_init_IRQ(void) +void q40_init_IRQ(void) { m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index cf93481adb1d..50df34bf80e3 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -97,7 +97,7 @@ static struct irq_controller sun3_irq_controller = { .disable = sun3_disable_irq, }; -void __init sun3_init_IRQ(void) +void sun3_init_IRQ(void) { *sun3_intreg = 1; diff --git a/trunk/arch/m68k/sun3x/prom.c b/trunk/arch/m68k/sun3x/prom.c index a7b7e818d627..48f8eb7b1565 100644 --- a/trunk/arch/m68k/sun3x/prom.c +++ b/trunk/arch/m68k/sun3x/prom.c @@ -92,7 +92,7 @@ static struct console sun3x_debug = { .index = -1, }; -void __init sun3x_prom_init(void) +void sun3x_prom_init(void) { /* Read the vector table */ diff --git a/trunk/arch/m68knommu/kernel/setup.c b/trunk/arch/m68knommu/kernel/setup.c index 2203f694f26b..80f4e9d74ac1 100644 --- a/trunk/arch/m68knommu/kernel/setup.c +++ b/trunk/arch/m68knommu/kernel/setup.c @@ -231,33 +231,32 @@ void setup_arch(char **cmdline_p) /* * Get CPU information for use by the procfs. */ + static int show_cpuinfo(struct seq_file *m, void *v) { - char *cpu, *mmu, *fpu; - u_long clockfreq; + char *cpu, *mmu, *fpu; + u_long clockfreq; - cpu = CPU; - mmu = "none"; - fpu = "none"; + cpu = CPU; + mmu = "none"; + fpu = "none"; #ifdef CONFIG_COLDFIRE - clockfreq = (loops_per_jiffy * HZ) * 3; + clockfreq = (loops_per_jiffy*HZ)*3; #else - clockfreq = (loops_per_jiffy * HZ) * 16; -#endif - - seq_printf(m, "CPU:\t\t%s\n" - "MMU:\t\t%s\n" - "FPU:\t\t%s\n" - "Clocking:\t%lu.%1luMHz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpu, mmu, fpu, - clockfreq / 1000000, - (clockfreq / 100000) % 10, - (loops_per_jiffy * HZ) / 500000, - ((loops_per_jiffy * HZ) / 5000) % 100, - (loops_per_jiffy * HZ)); + clockfreq = (loops_per_jiffy*HZ)*16; +#endif + + seq_printf(m, "CPU:\t\t%s\n" + "MMU:\t\t%s\n" + "FPU:\t\t%s\n" + "Clocking:\t%lu.%1luMHz\n" + "BogoMips:\t%lu.%02lu\n" + "Calibration:\t%lu loops\n", + cpu, mmu, fpu, + clockfreq/1000000,(clockfreq/100000)%10, + (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100, + (loops_per_jiffy*HZ)); return 0; } diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index 5afb864a1ec5..adb529d01bae 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -21,6 +21,58 @@ #include #include +static struct resource r8a66597_usb_host_resources[] = { + [0] = { + .name = "r8a66597_hcd", + .start = 0xA4200000, + .end = 0xA42000FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "r8a66597_hcd", + .start = 11, /* irq number */ + .end = 11, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device r8a66597_usb_host_device = { + .name = "r8a66597_hcd", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(r8a66597_usb_host_resources), + .resource = r8a66597_usb_host_resources, +}; + +static struct resource m66592_usb_peripheral_resources[] = { + [0] = { + .name = "m66592_udc", + .start = 0xb0000000, + .end = 0xb00000FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "m66592_udc", + .start = 9, /* irq number */ + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m66592_usb_peripheral_device = { + .name = "m66592_udc", + .id = -1, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(m66592_usb_peripheral_resources), + .resource = m66592_usb_peripheral_resources, +}; + static struct resource cf_ide_resources[] = { [0] = { .start = PA_AREA5_IO + 0x1000, @@ -81,6 +133,8 @@ static struct platform_device heartbeat_device = { }; static struct platform_device *r7780rp_devices[] __initdata = { + &r8a66597_usb_host_device, + &m66592_usb_peripheral_device, &cf_ide_device, &heartbeat_device, }; diff --git a/trunk/arch/sh64/configs/cayman_defconfig b/trunk/arch/sh64/configs/cayman_defconfig index 784434143343..ed035084b053 100644 --- a/trunk/arch/sh64/configs/cayman_defconfig +++ b/trunk/arch/sh64/configs/cayman_defconfig @@ -1,12 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22 -# Fri Jul 20 12:28:34 2007 +# Linux kernel version: 2.6.22-rc1 +# Mon May 14 08:43:31 2007 # CONFIG_SUPERH=y CONFIG_SUPERH64=y CONFIG_MMU=y -CONFIG_QUICKLIST=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -33,7 +32,7 @@ CONFIG_SWAP=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 @@ -67,12 +66,19 @@ CONFIG_SLAB=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# # CONFIG_MODULES is not set + +# +# Block layer +# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -150,8 +156,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=1 -CONFIG_VIRT_TO_BUS=y # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -171,6 +175,7 @@ CONFIG_SH_PCIDMA_NONCOHERENT=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # @@ -220,8 +225,20 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# # CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# # CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -257,7 +274,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set # # Device Drivers @@ -272,10 +288,26 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -291,11 +323,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y + +# +# Misc devices +# # CONFIG_PHANTOM is not set -# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_BLINK is not set + +# +# ATA/ATAPI/MFM/RLL support +# # CONFIG_IDE is not set # @@ -303,7 +342,6 @@ CONFIG_MISC_DEVICES=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_DMA=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -372,8 +410,13 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set # @@ -389,16 +432,30 @@ CONFIG_SCSI_SYM53C8XX_MMIO=y # # CONFIG_FIREWIRE is not set # CONFIG_IEEE1394 is not set + +# +# I2O device support +# # CONFIG_I2O is not set + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set + +# +# ARCnet devices +# # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y # CONFIG_MII is not set # CONFIG_STNIC is not set @@ -407,6 +464,10 @@ CONFIG_NET_ETHERNET=y # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set + +# +# Tulip family network device support +# CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set CONFIG_TULIP=y @@ -449,6 +510,7 @@ CONFIG_NETDEV_1000=y # CONFIG_SIS190 is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set @@ -462,6 +524,11 @@ CONFIG_NETDEV_10000=y # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_MLX4_CORE is not set +CONFIG_MLX4_DEBUG=y + +# +# Token Ring devices +# # CONFIG_TR is not set # @@ -479,7 +546,15 @@ CONFIG_NETDEV_10000=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# # CONFIG_ISDN is not set + +# +# Telephony Support +# # CONFIG_PHONE is not set # @@ -487,7 +562,6 @@ CONFIG_NETDEV_10000=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -564,6 +638,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -580,10 +658,15 @@ CONFIG_WATCHDOG=y # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set CONFIG_DEVPORT=y # CONFIG_I2C is not set @@ -593,24 +676,20 @@ CONFIG_DEVPORT=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# # CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -660,6 +739,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_EPSON1355 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set @@ -685,7 +765,6 @@ CONFIG_FB_KYRO=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -710,10 +789,16 @@ CONFIG_LOGO_SUPERH_CLUT224=y # Sound # # CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y + +# +# HID Devices +# CONFIG_HID=y # CONFIG_HID_DEBUG is not set -CONFIG_USB_SUPPORT=y + +# +# USB support +# CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y @@ -741,8 +826,16 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # LED Triggers # + +# +# InfiniBand support +# # CONFIG_INFINIBAND is not set +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + # # Real Time Clock # @@ -761,11 +854,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Userspace I/O -# -# CONFIG_UIO is not set - # # File systems # @@ -862,6 +950,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -912,7 +1001,6 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set @@ -929,6 +1017,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_KERNEL_WITH_GDB_STUB is not set @@ -944,6 +1033,10 @@ CONFIG_SH64_SR_WATCH=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set + +# +# Cryptographic options +# # CONFIG_CRYPTO is not set # @@ -954,7 +1047,6 @@ CONFIG_BITREVERSE=y # CONFIG_CRC16 is not set # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y diff --git a/trunk/arch/sh64/kernel/head.S b/trunk/arch/sh64/kernel/head.S index 186406d3ad9c..f3740ddbc471 100644 --- a/trunk/arch/sh64/kernel/head.S +++ b/trunk/arch/sh64/kernel/head.S @@ -124,7 +124,7 @@ empty_bad_pte_table: fpu_in_use: .quad 0 - .section .text.head, "ax" + .section .text, "ax" .balign L1_CACHE_BYTES /* * Condition at the entry of __stext: diff --git a/trunk/arch/sh64/kernel/pci_sh5.c b/trunk/arch/sh64/kernel/pci_sh5.c index 388bb711f1b0..3334f99b5835 100644 --- a/trunk/arch/sh64/kernel/pci_sh5.c +++ b/trunk/arch/sh64/kernel/pci_sh5.c @@ -48,7 +48,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -char * __devinit pcibios_setup(char *str) +char * __init pcibios_setup(char *str) { return str; } @@ -497,7 +497,7 @@ static int __init pcibios_init(void) subsys_initcall(pcibios_init); -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void __init pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; int i; diff --git a/trunk/arch/sh64/kernel/syscalls.S b/trunk/arch/sh64/kernel/syscalls.S index abb94c05d07a..a5c680d29384 100644 --- a/trunk/arch/sh64/kernel/syscalls.S +++ b/trunk/arch/sh64/kernel/syscalls.S @@ -378,4 +378,3 @@ sys_call_table: .long sys_signalfd .long sys_timerfd /* 350 */ .long sys_eventfd - .long sys_fallocate diff --git a/trunk/arch/sh64/kernel/vmlinux.lds.S b/trunk/arch/sh64/kernel/vmlinux.lds.S index 267b4f9af2e1..8ac9c7c5f848 100644 --- a/trunk/arch/sh64/kernel/vmlinux.lds.S +++ b/trunk/arch/sh64/kernel/vmlinux.lds.S @@ -54,7 +54,6 @@ SECTIONS } = 0 .text : C_PHYS(.text) { - *(.text.head) TEXT_TEXT *(.text64) *(.text..SHmedia32) diff --git a/trunk/arch/sh64/mm/ioremap.c b/trunk/arch/sh64/mm/ioremap.c index 990857756d44..ff26c02511aa 100644 --- a/trunk/arch/sh64/mm/ioremap.c +++ b/trunk/arch/sh64/mm/ioremap.c @@ -242,7 +242,7 @@ static void shmedia_free_io(struct resource *res) release_resource(res); } -static __init_refok void *sh64_get_page(void) +static void *sh64_get_page(void) { extern int after_bootmem; void *page; diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S index 55722840859c..90b52d4dab9a 100644 --- a/trunk/arch/sparc/kernel/systbls.S +++ b/trunk/arch/sparc/kernel/systbls.S @@ -1,7 +1,8 @@ -/* systbls.S: System call entry point tables for OS compatibility. +/* $Id: systbls.S,v 1.103 2002/02/08 03:57:14 davem Exp $ + * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * Based upon preliminary work which is: * @@ -79,7 +80,7 @@ sys_call_table: /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate +/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -197,6 +198,6 @@ sunos_sys_table: .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 10e301970a44..45ebf91a280c 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.22 -# Thu Jul 19 21:30:37 2007 +# Tue Jul 17 01:19:52 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -16,7 +16,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_AUDIT_ARCH=y -CONFIG_ARCH_NO_VIRT_TO_BUS=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set @@ -149,6 +148,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_NR_QUICK=1 +CONFIG_VIRT_TO_BUS=y CONFIG_SBUS=y CONFIG_SBUSCHAR=y CONFIG_SUN_AUXIO=y @@ -317,6 +317,7 @@ CONFIG_CONNECTOR=m # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set @@ -469,6 +470,10 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_SUNESP is not set # CONFIG_SCSI_SRP is not set # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# CONFIG_MD=y CONFIG_BLK_DEV_MD=m CONFIG_MD_LINEAR=m @@ -605,6 +610,10 @@ CONFIG_SLHC=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# # CONFIG_ISDN is not set # CONFIG_PHONE is not set @@ -773,7 +782,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set @@ -800,13 +808,11 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -900,7 +906,6 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_PROM_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set @@ -1190,11 +1195,6 @@ CONFIG_USB_STORAGE=m # DMA Devices # -# -# Userspace I/O -# -# CONFIG_UIO is not set - # # Misc Linux/SPARC drivers # @@ -1385,7 +1385,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1462,7 +1461,6 @@ CONFIG_CRC_CCITT=m CONFIG_CRC16=m # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -# CONFIG_CRC7 is not set CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/sparc64/kernel/ds.c b/trunk/arch/sparc64/kernel/ds.c index 1a2062ecb0bc..fa1f04d756a2 100644 --- a/trunk/arch/sparc64/kernel/ds.c +++ b/trunk/arch/sparc64/kernel/ds.c @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -328,7 +328,7 @@ static void domain_shutdown_data(struct ldc_channel *lp, ds_send(lp, &pkt, sizeof(pkt)); - orderly_poweroff(true); + wake_up_powerd(); } struct ds_panic_req { @@ -1133,6 +1133,8 @@ static int __devinit ds_probe(struct vio_dev *vdev, ds_info = dp; + start_powerd(); + return err; out_free_ldc: diff --git a/trunk/arch/sparc64/kernel/head.S b/trunk/arch/sparc64/kernel/head.S index 35feacb6b8ec..77259526cb15 100644 --- a/trunk/arch/sparc64/kernel/head.S +++ b/trunk/arch/sparc64/kernel/head.S @@ -458,6 +458,7 @@ tlb_fixup_done: or %g6, %lo(init_thread_union), %g6 ldx [%g6 + TI_TASK], %g4 mov %sp, %l6 + mov %o4, %l7 wr %g0, ASI_P, %asi mov 1, %g1 diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index c72795666a62..8cb3358674f5 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -701,10 +701,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { unsigned long sysino, hv_err; - BUG_ON(devhandle & devino); + BUG_ON(devhandle & ~IMAP_IGN); + BUG_ON(devino & ~IMAP_INO); sysino = devhandle | devino; - BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO)); hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); if (hv_err) { diff --git a/trunk/arch/sparc64/kernel/mdesc.c b/trunk/arch/sparc64/kernel/mdesc.c index 13a79fe5115b..302ba5e5a0bb 100644 --- a/trunk/arch/sparc64/kernel/mdesc.c +++ b/trunk/arch/sparc64/kernel/mdesc.c @@ -231,25 +231,6 @@ void mdesc_register_notifier(struct mdesc_notifier_client *client) mutex_unlock(&mdesc_mutex); } -static const u64 *parent_cfg_handle(struct mdesc_handle *hp, u64 node) -{ - const u64 *id; - u64 a; - - id = NULL; - mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { - u64 target; - - target = mdesc_arc_target(hp, a); - id = mdesc_get_property(hp, target, - "cfg-handle", NULL); - if (id) - break; - } - - return id; -} - /* Run 'func' on nodes which are in A but not in B. */ static void invoke_on_missing(const char *name, struct mdesc_handle *a, @@ -259,42 +240,13 @@ static void invoke_on_missing(const char *name, u64 node; mdesc_for_each_node_by_name(a, node, name) { - int found = 0, is_vdc_port = 0; - const char *name_prop; - const u64 *id; + const u64 *id = mdesc_get_property(a, node, "id", NULL); + int found = 0; u64 fnode; - name_prop = mdesc_get_property(a, node, "name", NULL); - if (name_prop && !strcmp(name_prop, "vdc-port")) { - is_vdc_port = 1; - id = parent_cfg_handle(a, node); - } else - id = mdesc_get_property(a, node, "id", NULL); - - if (!id) { - printk(KERN_ERR "MD: Cannot find ID for %s node.\n", - (name_prop ? name_prop : name)); - continue; - } - mdesc_for_each_node_by_name(b, fnode, name) { - const u64 *fid; - - if (is_vdc_port) { - name_prop = mdesc_get_property(b, fnode, - "name", NULL); - if (!name_prop || - strcmp(name_prop, "vdc-port")) - continue; - fid = parent_cfg_handle(b, fnode); - if (!fid) { - printk(KERN_ERR "MD: Cannot find ID " - "for vdc-port node.\n"); - continue; - } - } else - fid = mdesc_get_property(b, fnode, - "id", NULL); + const u64 *fid = mdesc_get_property(b, fnode, + "id", NULL); if (*id == *fid) { found = 1; diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 39f9f6494d4c..8dd4294ad21e 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -12,13 +12,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -31,9 +31,20 @@ int scons_pwroff = 1; static void __iomem *power_reg; +static DECLARE_WAIT_QUEUE_HEAD(powerd_wait); +static int button_pressed; + +void wake_up_powerd(void) +{ + if (button_pressed == 0) { + button_pressed = 1; + wake_up(&powerd_wait); + } +} + static irqreturn_t power_handler(int irq, void *dev_id) { - orderly_poweroff(true); + wake_up_powerd(); /* FIXME: Check registers for status... */ return IRQ_HANDLED; @@ -66,6 +77,48 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL(pm_power_off); +static int powerd(void *__unused) +{ + static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; + DECLARE_WAITQUEUE(wait, current); + + daemonize("powerd"); + + add_wait_queue(&powerd_wait, &wait); + + for (;;) { + set_task_state(current, TASK_INTERRUPTIBLE); + if (button_pressed) + break; + flush_signals(current); + schedule(); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&powerd_wait, &wait); + + /* Ok, down we go... */ + button_pressed = 0; + if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { + printk(KERN_ERR "powerd: shutdown execution failed\n"); + machine_power_off(); + } + return 0; +} + +int start_powerd(void) +{ + int err; + + err = kernel_thread(powerd, NULL, CLONE_FS); + if (err < 0) + printk(KERN_ERR "power: Failed to start power daemon.\n"); + else + printk(KERN_INFO "power: powerd running.\n"); + + return err; +} + static int __init has_button_interrupt(unsigned int irq, struct device_node *dp) { if (irq == 0xffffffff) @@ -83,15 +136,20 @@ static int __devinit power_probe(struct of_device *op, const struct of_device_id power_reg = of_ioremap(res, 0, 0x4, "power"); - printk(KERN_INFO "%s: Control reg at %lx\n", + printk("%s: Control reg at %lx ... ", op->node->name, res->start); poweroff_method = machine_halt; /* able to use the standard halt */ if (has_button_interrupt(irq, op->node)) { + if (start_powerd() < 0) + return 0; + if (request_irq(irq, power_handler, 0, "power", NULL) < 0) printk(KERN_ERR "power: Cannot setup IRQ handler.\n"); + } else { + printk(KERN_INFO "power: Not using powerd.\n"); } return 0; diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index e8dce90d05d4..abd83129b2e7 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -1,7 +1,8 @@ -/* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. +/* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $ + * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) * * These routines maintain argument size conversion between 32bit and 64bit * environment. @@ -1027,10 +1028,3 @@ long compat_sync_file_range(int fd, unsigned long off_high, unsigned long off_lo (nb_high << 32) | nb_low, flags); } - -asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo, - u32 lenhi, u32 lenlo) -{ - return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo, - ((loff_t)lenhi << 32) | lenlo); -} diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 06d10907d8ce..8765e32155a0 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -1,7 +1,8 @@ -/* systbls.S: System call entry point tables for OS compatibility. +/* $Id: systbls.S,v 1.81 2002/02/08 03:57:14 davem Exp $ + * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * - * Copyright (C) 1995, 1996, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * * Based upon preliminary work which is: @@ -80,7 +81,7 @@ sys_call_table32: .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait -/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd, compat_sys_fallocate +/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd #endif /* CONFIG_COMPAT */ @@ -152,7 +153,7 @@ sys_call_table: .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate +/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -271,6 +272,6 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys + .word sunos_nosys #endif diff --git a/trunk/arch/sparc64/kernel/vio.c b/trunk/arch/sparc64/kernel/vio.c index 491223a6628f..8d3cc4fdb557 100644 --- a/trunk/arch/sparc64/kernel/vio.c +++ b/trunk/arch/sparc64/kernel/vio.c @@ -103,9 +103,9 @@ static ssize_t devspec_show(struct device *dev, struct vio_dev *vdev = to_vio_dev(dev); const char *str = "none"; - if (!strcmp(vdev->type, "vnet-port")) + if (!strcmp(vdev->type, "network")) str = "vnet"; - else if (!strcmp(vdev->type, "vdc-port")) + else if (!strcmp(vdev->type, "block")) str = "vdisk"; return sprintf(buf, "%s\n", str); @@ -221,27 +221,6 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, return NULL; } - if (!strcmp(type, "vdc-port")) { - u64 a; - - id = NULL; - mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) { - u64 target; - - target = mdesc_arc_target(hp, a); - id = mdesc_get_property(hp, target, - "cfg-handle", NULL); - if (id) - break; - } - if (!id) { - printk(KERN_ERR "VIO: vdc-port lacks parent " - "cfg-handle.\n"); - return NULL; - } - } else - id = mdesc_get_property(hp, mp, "id", NULL); - bus_id_name = type; if (!strcmp(type, "domain-services-port")) bus_id_name = "ds"; @@ -281,15 +260,13 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, vio_fill_channel_info(hp, mp, vdev); - if (!id) { + id = mdesc_get_property(hp, mp, "id", NULL); + if (!id) snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s", bus_id_name); - vdev->dev_no = ~(u64)0; - } else { + else snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu", bus_id_name, *id); - vdev->dev_no = *id; - } vdev->dev.parent = parent; vdev->dev.bus = &vio_bus_type; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index d148ccbc36d1..9755a3cfad26 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -92,11 +92,7 @@ struct cfq_data { struct cfq_queue *active_queue; struct cfq_io_context *active_cic; - /* - * async queue for each priority case - */ - struct cfq_queue *async_cfqq[2][IOPRIO_BE_NR]; - struct cfq_queue *async_idle_cfqq; + struct cfq_queue *async_cfqq[IOPRIO_BE_NR]; struct timer_list idle_class_timer; @@ -115,6 +111,9 @@ struct cfq_data { unsigned int cfq_slice_idle; struct list_head cic_list; + + sector_t new_seek_mean; + u64 new_seek_total; }; /* @@ -154,6 +153,8 @@ struct cfq_queue { /* various state flags, see below */ unsigned int flags; + + sector_t last_request_pos; }; enum cfqq_state_flags { @@ -1413,44 +1414,24 @@ cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, return cfqq; } -static struct cfq_queue ** -cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio) -{ - switch(ioprio_class) { - case IOPRIO_CLASS_RT: - return &cfqd->async_cfqq[0][ioprio]; - case IOPRIO_CLASS_BE: - return &cfqd->async_cfqq[1][ioprio]; - case IOPRIO_CLASS_IDLE: - return &cfqd->async_idle_cfqq; - default: - BUG(); - } -} - static struct cfq_queue * cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk, gfp_t gfp_mask) { const int ioprio = task_ioprio(tsk); - const int ioprio_class = task_ioprio_class(tsk); - struct cfq_queue **async_cfqq = NULL; struct cfq_queue *cfqq = NULL; - if (!is_sync) { - async_cfqq = cfq_async_queue_prio(cfqd, ioprio_class, ioprio); - cfqq = *async_cfqq; - } - + if (!is_sync) + cfqq = cfqd->async_cfqq[ioprio]; if (!cfqq) cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask); /* * pin the queue now that it's allocated, scheduler exit will prune it */ - if (!is_sync && !(*async_cfqq)) { + if (!is_sync && !cfqd->async_cfqq[ioprio]) { atomic_inc(&cfqq->ref); - *async_cfqq = cfqq; + cfqd->async_cfqq[ioprio] = cfqq; } atomic_inc(&cfqq->ref); @@ -1616,6 +1597,11 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, else sdist = cic->last_request_pos - rq->sector; + if (!cic->seek_samples) { + cfqd->new_seek_total = (7*cic->seek_total + (u64)256*sdist) / 8; + cfqd->new_seek_mean = cfqd->new_seek_total / 256; + } + /* * Don't allow the seek distance to get too large from the * odd fragment, pagein, etc @@ -1751,6 +1737,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_update_idle_window(cfqd, cfqq, cic); cic->last_request_pos = rq->sector + rq->nr_sectors; + cfqq->last_request_pos = cic->last_request_pos; if (cfqq == cfqd->active_queue) { /* @@ -2055,24 +2042,11 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd) blk_sync_queue(cfqd->queue); } -static void cfq_put_async_queues(struct cfq_data *cfqd) -{ - int i; - - for (i = 0; i < IOPRIO_BE_NR; i++) { - if (cfqd->async_cfqq[0][i]) - cfq_put_queue(cfqd->async_cfqq[0][i]); - if (cfqd->async_cfqq[1][i]) - cfq_put_queue(cfqd->async_cfqq[1][i]); - if (cfqd->async_idle_cfqq) - cfq_put_queue(cfqd->async_idle_cfqq); - } -} - static void cfq_exit_queue(elevator_t *e) { struct cfq_data *cfqd = e->elevator_data; request_queue_t *q = cfqd->queue; + int i; cfq_shutdown_timer_wq(cfqd); @@ -2089,7 +2063,12 @@ static void cfq_exit_queue(elevator_t *e) __cfq_exit_single_io_context(cfqd, cic); } - cfq_put_async_queues(cfqd); + /* + * Put the async queues + */ + for (i = 0; i < IOPRIO_BE_NR; i++) + if (cfqd->async_cfqq[i]) + cfq_put_queue(cfqd->async_cfqq[i]); spin_unlock_irq(q->queue_lock); diff --git a/trunk/crypto/async_tx/async_memcpy.c b/trunk/crypto/async_tx/async_memcpy.c index 047e533fcc5b..a973f4ef897d 100644 --- a/trunk/crypto/async_tx/async_memcpy.c +++ b/trunk/crypto/async_tx/async_memcpy.c @@ -36,6 +36,7 @@ * @offset: offset in pages to start transaction * @len: length in bytes * @flags: ASYNC_TX_ASSUME_COHERENT, ASYNC_TX_ACK, ASYNC_TX_DEP_ACK, + * ASYNC_TX_KMAP_SRC, ASYNC_TX_KMAP_DST * @depend_tx: memcpy depends on the result of this transaction * @cb_fn: function to call when the memcpy completes * @cb_param: parameter to pass to the callback routine @@ -87,13 +88,23 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, __FUNCTION__); } - dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; - src_buf = kmap_atomic(src, KM_USER1) + src_offset; + if (flags & ASYNC_TX_KMAP_DST) + dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; + else + dest_buf = page_address(dest) + dest_offset; + + if (flags & ASYNC_TX_KMAP_SRC) + src_buf = kmap_atomic(src, KM_USER0) + src_offset; + else + src_buf = page_address(src) + src_offset; memcpy(dest_buf, src_buf, len); - kunmap_atomic(dest_buf, KM_USER0); - kunmap_atomic(src_buf, KM_USER1); + if (flags & ASYNC_TX_KMAP_DST) + kunmap_atomic(dest_buf, KM_USER0); + + if (flags & ASYNC_TX_KMAP_SRC) + kunmap_atomic(src_buf, KM_USER0); async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); } diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 06f212ff2b4f..11e4eb9f304e 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -99,7 +99,6 @@ enum { HOST_CAP_SSC = (1 << 14), /* Slumber capable */ HOST_CAP_CLO = (1 << 24), /* Command List Override support */ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_CAP_SNTF = (1 << 29), /* SNotification register */ HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ @@ -114,11 +113,11 @@ enum { PORT_TFDATA = 0x20, /* taskfile data */ PORT_SIG = 0x24, /* device TF signature */ PORT_CMD_ISSUE = 0x38, /* command issue */ + PORT_SCR = 0x28, /* SATA phy register block */ PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */ PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */ PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ - PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ /* PORT_IRQ_{STAT,MASK} bits */ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ @@ -217,8 +216,8 @@ struct ahci_port_priv { unsigned int ncq_saw_sdb:1; }; -static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); static void ahci_irq_clear(struct ata_port *ap); @@ -418,10 +417,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* ATI */ { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ - { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 IDE */ - { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb600 }, /* ATI SB700 AHCI */ - { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb600 }, /* ATI SB700 nraid5 */ - { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb600 }, /* ATI SB700 raid5 */ + { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 */ /* VIA */ { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */ @@ -549,19 +545,13 @@ static void ahci_save_initial_config(struct pci_dev *pdev, hpriv->saved_cap = cap = readl(mmio + HOST_CAP); hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); - /* some chips have errata preventing 64bit use */ + /* some chips lie about 64bit support */ if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) { dev_printk(KERN_INFO, &pdev->dev, "controller can't do 64bit DMA, forcing 32bit\n"); cap &= ~HOST_CAP_64; } - if ((cap & HOST_CAP_NCQ) && (pi->flags & AHCI_FLAG_NO_NCQ)) { - dev_printk(KERN_INFO, &pdev->dev, - "controller can't do NCQ, turning off CAP_NCQ\n"); - cap &= ~HOST_CAP_NCQ; - } - /* fixup zero port_map */ if (!port_map) { port_map = (1 << ahci_nr_ports(cap)) - 1; @@ -635,45 +625,38 @@ static void ahci_restore_initial_config(struct ata_host *host) (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ } -static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg) +static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) { - static const int offset[] = { - [SCR_STATUS] = PORT_SCR_STAT, - [SCR_CONTROL] = PORT_SCR_CTL, - [SCR_ERROR] = PORT_SCR_ERR, - [SCR_ACTIVE] = PORT_SCR_ACT, - [SCR_NOTIFICATION] = PORT_SCR_NTF, - }; - struct ahci_host_priv *hpriv = ap->host->private_data; + unsigned int sc_reg; + + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return 0xffffffffU; + } - if (sc_reg < ARRAY_SIZE(offset) && - (sc_reg != SCR_NOTIFICATION || (hpriv->cap & HOST_CAP_SNTF))) - return offset[sc_reg]; - return 0; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) -{ - void __iomem *port_mmio = ahci_port_base(ap); - int offset = ahci_scr_offset(ap, sc_reg); - - if (offset) { - *val = readl(port_mmio + offset); - return 0; - } - return -EINVAL; -} -static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, + u32 val) { - void __iomem *port_mmio = ahci_port_base(ap); - int offset = ahci_scr_offset(ap, sc_reg); - - if (offset) { - writel(val, port_mmio + offset); - return 0; + unsigned int sc_reg; + + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return; } - return -EINVAL; + + writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); } static void ahci_start_engine(struct ata_port *ap) @@ -965,87 +948,37 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); } -static int ahci_kick_engine(struct ata_port *ap, int force_restart) +static int ahci_clo(struct ata_port *ap) { void __iomem *port_mmio = ap->ioaddr.cmd_addr; struct ahci_host_priv *hpriv = ap->host->private_data; u32 tmp; - int busy, rc; - - /* do we need to kick the port? */ - busy = ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ); - if (!busy && !force_restart) - return 0; - - /* stop engine */ - rc = ahci_stop_engine(ap); - if (rc) - goto out_restart; - /* need to do CLO? */ - if (!busy) { - rc = 0; - goto out_restart; - } + if (!(hpriv->cap & HOST_CAP_CLO)) + return -EOPNOTSUPP; - if (!(hpriv->cap & HOST_CAP_CLO)) { - rc = -EOPNOTSUPP; - goto out_restart; - } - - /* perform CLO */ tmp = readl(port_mmio + PORT_CMD); tmp |= PORT_CMD_CLO; writel(tmp, port_mmio + PORT_CMD); - rc = 0; tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); if (tmp & PORT_CMD_CLO) - rc = -EIO; + return -EIO; - /* restart engine */ - out_restart: - ahci_start_engine(ap); - return rc; + return 0; } -static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, - struct ata_taskfile *tf, int is_cmd, u16 flags, - unsigned long timeout_msec) +static int ahci_softreset(struct ata_port *ap, unsigned int *class, + unsigned long deadline) { - const u32 cmd_fis_len = 5; /* five dwords */ struct ahci_port_priv *pp = ap->private_data; void __iomem *port_mmio = ahci_port_base(ap); - u8 *fis = pp->cmd_tbl; - u32 tmp; - - /* prep the command */ - ata_tf_to_fis(tf, pmp, is_cmd, fis); - ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12)); - - /* issue & wait */ - writel(1, port_mmio + PORT_CMD_ISSUE); - - if (timeout_msec) { - tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, - 1, timeout_msec); - if (tmp & 0x1) { - ahci_kick_engine(ap, 1); - return -EBUSY; - } - } else - readl(port_mmio + PORT_CMD_ISSUE); /* flush */ - - return 0; -} - -static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, - int pmp, unsigned long deadline) -{ + const u32 cmd_fis_len = 5; /* five dwords */ const char *reason = NULL; - unsigned long now, msecs; struct ata_taskfile tf; + u32 tmp; + u8 *fis; int rc; DPRINTK("ENTER\n"); @@ -1057,22 +990,43 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, } /* prepare for SRST (AHCI-1.1 10.4.1) */ - rc = ahci_kick_engine(ap, 1); - if (rc) - ata_port_printk(ap, KERN_WARNING, - "failed to reset engine (errno=%d)", rc); + rc = ahci_stop_engine(ap); + if (rc) { + reason = "failed to stop engine"; + goto fail_restart; + } + + /* check BUSY/DRQ, perform Command List Override if necessary */ + if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) { + rc = ahci_clo(ap); + + if (rc == -EOPNOTSUPP) { + reason = "port busy but CLO unavailable"; + goto fail_restart; + } else if (rc) { + reason = "port busy but CLO failed"; + goto fail_restart; + } + } + + /* restart engine */ + ahci_start_engine(ap); ata_tf_init(ap->device, &tf); + fis = pp->cmd_tbl; /* issue the first D2H Register FIS */ - msecs = 0; - now = jiffies; - if (time_after(now, deadline)) - msecs = jiffies_to_msecs(deadline - now); + ahci_fill_cmd_slot(pp, 0, + cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); tf.ctl |= ATA_SRST; - if (ahci_exec_polled_cmd(ap, pmp, &tf, 0, - AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY, msecs)) { + ata_tf_to_fis(&tf, fis, 0); + fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ + + writel(1, port_mmio + PORT_CMD_ISSUE); + + tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500); + if (tmp & 0x1) { rc = -EIO; reason = "1st FIS failed"; goto fail; @@ -1082,8 +1036,14 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, msleep(1); /* issue the second D2H Register FIS */ + ahci_fill_cmd_slot(pp, 0, cmd_fis_len); + tf.ctl &= ~ATA_SRST; - ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); + ata_tf_to_fis(&tf, fis, 0); + fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ + + writel(1, port_mmio + PORT_CMD_ISSUE); + readl(port_mmio + PORT_CMD_ISSUE); /* flush */ /* spec mandates ">= 2ms" before checking status. * We wait 150ms, because that was the magic delay used for @@ -1106,17 +1066,13 @@ static int ahci_do_softreset(struct ata_port *ap, unsigned int *class, DPRINTK("EXIT, class=%u\n", *class); return 0; + fail_restart: + ahci_start_engine(ap); fail: ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); return rc; } -static int ahci_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - return ahci_do_softreset(ap, class, 0, deadline); -} - static int ahci_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { @@ -1132,7 +1088,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); tf.command = 0x80; - ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ata_tf_to_fis(&tf, d2h_fis, 0); rc = sata_std_hardreset(ap, class, deadline); @@ -1150,7 +1106,6 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { - u32 serror; int rc; DPRINTK("ENTER\n"); @@ -1161,8 +1116,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, deadline); /* vt8251 needs SError cleared for the port to operate */ - ahci_scr_read(ap, SCR_ERROR, &serror); - ahci_scr_write(ap, SCR_ERROR, serror); + ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); ahci_start_engine(ap); @@ -1251,7 +1205,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) */ cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; - ata_tf_to_fis(&qc->tf, 0, 1, cmd_tbl); + ata_tf_to_fis(&qc->tf, cmd_tbl, 0); if (is_atapi) { memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); @@ -1284,7 +1238,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ata_ehi_clear_desc(ehi); /* AHCI needs SError cleared; otherwise, it might lock up */ - ahci_scr_read(ap, SCR_ERROR, &serror); + serror = ahci_scr_read(ap, SCR_ERROR); ahci_scr_write(ap, SCR_ERROR, serror); /* analyze @irq_stat */ @@ -1308,12 +1262,12 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) if (irq_stat & PORT_IRQ_IF_ERR) { err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "interface fatal error"); + ata_ehi_push_desc(ehi, ", interface fatal error"); } if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "%s", irq_stat & PORT_IRQ_CONNECT ? + ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? "connection status changed" : "PHY RDY changed"); } @@ -1322,7 +1276,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) err_mask |= AC_ERR_HSM; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown FIS %08x %08x %08x %08x", + ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", unk[0], unk[1], unk[2], unk[3]); } @@ -1558,17 +1512,11 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - /* make DMA engine forget about the failed command */ - if (qc->flags & ATA_QCFLAG_FAILED) - ahci_kick_engine(ap, 1); -} - -static int ahci_port_resume(struct ata_port *ap) -{ - ahci_power_up(ap); - ahci_start_port(ap); - - return 0; + if (qc->flags & ATA_QCFLAG_FAILED) { + /* make DMA engine forget about the failed command */ + ahci_stop_engine(ap); + ahci_start_engine(ap); + } } #ifdef CONFIG_PM @@ -1588,6 +1536,14 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) return rc; } +static int ahci_port_resume(struct ata_port *ap) +{ + ahci_power_up(ap); + ahci_start_port(ap); + + return 0; +} + static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = dev_get_drvdata(&pdev->dev); @@ -1778,13 +1734,12 @@ static void ahci_print_info(struct ata_host *host) dev_printk(KERN_INFO, &pdev->dev, "flags: " - "%s%s%s%s%s%s%s" - "%s%s%s%s%s%s%s\n" + "%s%s%s%s%s%s" + "%s%s%s%s%s%s%s\n" , cap & (1 << 31) ? "64bit " : "", cap & (1 << 30) ? "ncq " : "", - cap & (1 << 29) ? "sntf " : "", cap & (1 << 28) ? "ilck " : "", cap & (1 << 27) ? "stag " : "", cap & (1 << 26) ? "pm " : "", @@ -1839,7 +1794,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ahci_save_initial_config(pdev, &pi, hpriv); /* prepare host */ - if (hpriv->cap & HOST_CAP_NCQ) + if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ)) pi.flags |= ATA_FLAG_NCQ; host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map)); @@ -1853,8 +1808,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *port_mmio = ahci_port_base(ap); /* standard SATA port setup */ - if (hpriv->port_map & (1 << i)) + if (hpriv->port_map & (1 << i)) { ap->ioaddr.cmd_addr = port_mmio; + ap->ioaddr.scr_addr = port_mmio + PORT_SCR; + } /* disabled/not-implemented port */ else diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 6001aae0b884..88e2dd0983b5 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -111,9 +111,8 @@ MODULE_VERSION(DRV_VERSION); /** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert - * @pmp: Port multiplier port - * @is_cmd: This FIS is for command * @fis: Buffer into which data will output + * @pmp: Port multiplier port * * Converts a standard ATA taskfile to a Serial ATA * FIS structure (Register - Host to Device). @@ -121,13 +120,12 @@ MODULE_VERSION(DRV_VERSION); * LOCKING: * Inherited from caller. */ -void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis) -{ - fis[0] = 0x27; /* Register - Host to Device FIS */ - fis[1] = pmp & 0xf; /* Port multiplier number*/ - if (is_cmd) - fis[1] |= (1 << 7); /* bit 7 indicates Command FIS */ +void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) +{ + fis[0] = 0x27; /* Register - Host to Device FIS */ + fis[1] = (pmp & 0xf) | (1 << 7); /* Port multiplier number, + bit 7 indicates Command FIS */ fis[2] = tf->command; fis[3] = tf->feature; @@ -2389,35 +2387,21 @@ int sata_down_spd_limit(struct ata_port *ap) u32 sstatus, spd, mask; int rc, highbit; - if (!sata_scr_valid(ap)) - return -EOPNOTSUPP; - - /* If SCR can be read, use it to determine the current SPD. - * If not, use cached value in ap->sata_spd. - */ rc = sata_scr_read(ap, SCR_STATUS, &sstatus); - if (rc == 0) - spd = (sstatus >> 4) & 0xf; - else - spd = ap->sata_spd; + if (rc) + return rc; mask = ap->sata_spd_limit; if (mask <= 1) return -EINVAL; - - /* unconditionally mask off the highest bit */ highbit = fls(mask) - 1; mask &= ~(1 << highbit); - /* Mask off all speeds higher than or equal to the current - * one. Force 1.5Gbps if current SPD is not available. - */ - if (spd > 1) - mask &= (1 << (spd - 1)) - 1; - else - mask &= 1; - - /* were we already at the bottom? */ + spd = (sstatus >> 4) & 0xf; + if (spd <= 1) + return -EINVAL; + spd--; + mask &= (1 << spd) - 1; if (!mask) return -EINVAL; @@ -3267,11 +3251,9 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, last = cur; last_jiffies = jiffies; - /* Check deadline. If debouncing failed, return - * -EPIPE to tell upper layer to lower link speed. - */ + /* check deadline */ if (time_after(jiffies, deadline)) - return -EPIPE; + return -EBUSY; } } @@ -3787,7 +3769,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, }, - { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ @@ -5748,8 +5729,10 @@ int sata_scr_valid(struct ata_port *ap) */ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) { - if (sata_scr_valid(ap)) - return ap->ops->scr_read(ap, reg, val); + if (sata_scr_valid(ap)) { + *val = ap->ops->scr_read(ap, reg); + return 0; + } return -EOPNOTSUPP; } @@ -5771,8 +5754,10 @@ int sata_scr_read(struct ata_port *ap, int reg, u32 *val) */ int sata_scr_write(struct ata_port *ap, int reg, u32 val) { - if (sata_scr_valid(ap)) - return ap->ops->scr_write(ap, reg, val); + if (sata_scr_valid(ap)) { + ap->ops->scr_write(ap, reg, val); + return 0; + } return -EOPNOTSUPP; } @@ -5793,13 +5778,10 @@ int sata_scr_write(struct ata_port *ap, int reg, u32 val) */ int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val) { - int rc; - if (sata_scr_valid(ap)) { - rc = ap->ops->scr_write(ap, reg, val); - if (rc == 0) - rc = ap->ops->scr_read(ap, reg, &val); - return rc; + ap->ops->scr_write(ap, reg, val); + ap->ops->scr_read(ap, reg); + return 0; } return -EOPNOTSUPP; } @@ -6011,7 +5993,6 @@ void ata_dev_init(struct ata_device *dev) /* SATA spd limit is bound to the first device */ ap->sata_spd_limit = ap->hw_sata_spd_limit; - ap->sata_spd = 0; /* High bits of dev->flags are used to record warm plug * requests which occur asynchronously. Synchronize using @@ -6077,9 +6058,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host) INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); - init_timer_deferrable(&ap->fastdrain_timer); - ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn; - ap->fastdrain_timer.data = (unsigned long)ap; ap->cbl = ATA_CBL_NONE; @@ -6456,7 +6434,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - ata_scsi_scan_host(ap, 1); + ata_scsi_scan_host(ap); } return 0; @@ -6964,9 +6942,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter); EXPORT_SYMBOL_GPL(ata_pci_clear_simplex); #endif /* CONFIG_PCI */ -EXPORT_SYMBOL_GPL(__ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_push_desc); -EXPORT_SYMBOL_GPL(ata_ehi_clear_desc); EXPORT_SYMBOL_GPL(ata_eng_timeout); EXPORT_SYMBOL_GPL(ata_port_schedule_eh); EXPORT_SYMBOL_GPL(ata_port_abort); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index ac6ceed4bb60..9aa62a0754f6 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -56,7 +56,6 @@ enum { */ enum { ATA_EH_PRERESET_TIMEOUT = 10 * HZ, - ATA_EH_FASTDRAIN_INTERVAL = 3 * HZ, }; /* The following table determines how we sequence resets. Each entry @@ -86,71 +85,6 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) { } #endif /* CONFIG_PM */ -static void __ata_ehi_pushv_desc(struct ata_eh_info *ehi, const char *fmt, - va_list args) -{ - ehi->desc_len += vscnprintf(ehi->desc + ehi->desc_len, - ATA_EH_DESC_LEN - ehi->desc_len, - fmt, args); -} - -/** - * __ata_ehi_push_desc - push error description without adding separator - * @ehi: target EHI - * @fmt: printf format string - * - * Format string according to @fmt and append it to @ehi->desc. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - __ata_ehi_pushv_desc(ehi, fmt, args); - va_end(args); -} - -/** - * ata_ehi_push_desc - push error description with separator - * @ehi: target EHI - * @fmt: printf format string - * - * Format string according to @fmt and append it to @ehi->desc. - * If @ehi->desc is not empty, ", " is added in-between. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) -{ - va_list args; - - if (ehi->desc_len) - __ata_ehi_push_desc(ehi, ", "); - - va_start(args, fmt); - __ata_ehi_pushv_desc(ehi, fmt, args); - va_end(args); -} - -/** - * ata_ehi_clear_desc - clean error description - * @ehi: target EHI - * - * Clear @ehi->desc. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -void ata_ehi_clear_desc(struct ata_eh_info *ehi) -{ - ehi->desc[0] = '\0'; - ehi->desc_len = 0; -} - static void ata_ering_record(struct ata_ering *ering, int is_io, unsigned int err_mask) { @@ -362,9 +296,6 @@ void ata_scsi_error(struct Scsi_Host *host) repeat: /* invoke error handler */ if (ap->ops->error_handler) { - /* kill fast drain timer */ - del_timer_sync(&ap->fastdrain_timer); - /* process port resume request */ ata_eh_handle_port_resume(ap); @@ -580,94 +511,6 @@ void ata_eng_timeout(struct ata_port *ap) DPRINTK("EXIT\n"); } -static int ata_eh_nr_in_flight(struct ata_port *ap) -{ - unsigned int tag; - int nr = 0; - - /* count only non-internal commands */ - for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) - if (ata_qc_from_tag(ap, tag)) - nr++; - - return nr; -} - -void ata_eh_fastdrain_timerfn(unsigned long arg) -{ - struct ata_port *ap = (void *)arg; - unsigned long flags; - int cnt; - - spin_lock_irqsave(ap->lock, flags); - - cnt = ata_eh_nr_in_flight(ap); - - /* are we done? */ - if (!cnt) - goto out_unlock; - - if (cnt == ap->fastdrain_cnt) { - unsigned int tag; - - /* No progress during the last interval, tag all - * in-flight qcs as timed out and freeze the port. - */ - for (tag = 0; tag < ATA_MAX_QUEUE - 1; tag++) { - struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); - if (qc) - qc->err_mask |= AC_ERR_TIMEOUT; - } - - ata_port_freeze(ap); - } else { - /* some qcs have finished, give it another chance */ - ap->fastdrain_cnt = cnt; - ap->fastdrain_timer.expires = - jiffies + ATA_EH_FASTDRAIN_INTERVAL; - add_timer(&ap->fastdrain_timer); - } - - out_unlock: - spin_unlock_irqrestore(ap->lock, flags); -} - -/** - * ata_eh_set_pending - set ATA_PFLAG_EH_PENDING and activate fast drain - * @ap: target ATA port - * @fastdrain: activate fast drain - * - * Set ATA_PFLAG_EH_PENDING and activate fast drain if @fastdrain - * is non-zero and EH wasn't pending before. Fast drain ensures - * that EH kicks in in timely manner. - * - * LOCKING: - * spin_lock_irqsave(host lock) - */ -static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) -{ - int cnt; - - /* already scheduled? */ - if (ap->pflags & ATA_PFLAG_EH_PENDING) - return; - - ap->pflags |= ATA_PFLAG_EH_PENDING; - - if (!fastdrain) - return; - - /* do we have in-flight qcs? */ - cnt = ata_eh_nr_in_flight(ap); - if (!cnt) - return; - - /* activate fast drain */ - ap->fastdrain_cnt = cnt; - ap->fastdrain_timer.expires = jiffies + ATA_EH_FASTDRAIN_INTERVAL; - add_timer(&ap->fastdrain_timer); -} - /** * ata_qc_schedule_eh - schedule qc for error handling * @qc: command to schedule error handling for @@ -685,7 +528,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) WARN_ON(!ap->ops->error_handler); qc->flags |= ATA_QCFLAG_FAILED; - ata_eh_set_pending(ap, 1); + qc->ap->pflags |= ATA_PFLAG_EH_PENDING; /* The following will fail if timeout has already expired. * ata_scsi_error() takes care of such scmds on EH entry. @@ -712,7 +555,7 @@ void ata_port_schedule_eh(struct ata_port *ap) if (ap->pflags & ATA_PFLAG_INITIALIZING) return; - ata_eh_set_pending(ap, 1); + ap->pflags |= ATA_PFLAG_EH_PENDING; scsi_schedule_eh(ap->scsi_host); DPRINTK("port EH scheduled\n"); @@ -736,9 +579,6 @@ int ata_port_abort(struct ata_port *ap) WARN_ON(!ap->ops->error_handler); - /* we're gonna abort all commands, no need for fast drain */ - ata_eh_set_pending(ap, 0); - for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, tag); @@ -1290,7 +1130,7 @@ static void ata_eh_analyze_ncq_error(struct ata_port *ap) /* we've got the perpetrator, condemn it */ qc = __ata_qc_from_tag(ap, tag); memcpy(&qc->result_tf, &tf, sizeof(tf)); - qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; + qc->err_mask |= AC_ERR_DEV; ehc->i.err_mask &= ~AC_ERR_DEV; } @@ -1573,12 +1413,8 @@ static void ata_eh_autopsy(struct ata_port *ap) if (rc == 0) { ehc->i.serror |= serror; ata_eh_analyze_serror(ap); - } else if (rc != -EOPNOTSUPP) { - /* SError read failed, force hardreset and probing */ - ata_ehi_schedule_probe(&ehc->i); + } else if (rc != -EOPNOTSUPP) ehc->i.action |= ATA_EH_HARDRESET; - ehc->i.err_mask |= AC_ERR_OTHER; - } /* analyze NCQ failure */ ata_eh_analyze_ncq_error(ap); @@ -1688,14 +1524,14 @@ static void ata_eh_report(struct ata_port *ap) ehc->i.err_mask, ap->sactive, ehc->i.serror, ehc->i.action, frozen); if (desc) - ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); + ata_dev_printk(ehc->i.dev, KERN_ERR, "(%s)\n", desc); } else { ata_port_printk(ap, KERN_ERR, "exception Emask 0x%x " "SAct 0x%x SErr 0x%x action 0x%x%s\n", ehc->i.err_mask, ap->sactive, ehc->i.serror, ehc->i.action, frozen); if (desc) - ata_port_printk(ap, KERN_ERR, "%s\n", desc); + ata_port_printk(ap, KERN_ERR, "(%s)\n", desc); } for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { @@ -1715,7 +1551,7 @@ static void ata_eh_report(struct ata_port *ap) "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " "tag %d cdb 0x%x data %u %s\n " "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " - "Emask 0x%x (%s)%s\n", + "Emask 0x%x (%s)\n", cmd->command, cmd->feature, cmd->nsect, cmd->lbal, cmd->lbam, cmd->lbah, cmd->hob_feature, cmd->hob_nsect, @@ -1726,8 +1562,7 @@ static void ata_eh_report(struct ata_port *ap) res->lbal, res->lbam, res->lbah, res->hob_feature, res->hob_nsect, res->hob_lbal, res->hob_lbam, res->hob_lbah, - res->device, qc->err_mask, ata_err_string(qc->err_mask), - qc->err_mask & AC_ERR_NCQ ? " " : ""); + res->device, qc->err_mask, ata_err_string(qc->err_mask)); } } @@ -1813,7 +1648,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } else ata_port_printk(ap, KERN_ERR, "prereset failed (errno=%d)\n", rc); - goto out; + return rc; } } @@ -1826,8 +1661,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, /* prereset told us not to reset, bang classes and return */ for (i = 0; i < ATA_MAX_DEVICES; i++) classes[i] = ATA_DEV_NONE; - rc = 0; - goto out; + return 0; } /* did prereset() screw up? if so, fix up to avoid oopsing */ @@ -1863,8 +1697,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_port_printk(ap, KERN_ERR, "follow-up softreset required " "but no softreset avaliable\n"); - rc = -EINVAL; - goto out; + return -EINVAL; } ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); @@ -1874,8 +1707,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, classes[0] == ATA_DEV_UNKNOWN) { ata_port_printk(ap, KERN_ERR, "classification failed\n"); - rc = -EINVAL; - goto out; + return -EINVAL; } } @@ -1892,7 +1724,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, schedule_timeout_uninterruptible(delta); } - if (rc == -EPIPE || + if (reset == hardreset && try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) sata_down_spd_limit(ap); if (hardreset) @@ -1901,18 +1733,12 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } if (rc == 0) { - u32 sstatus; - /* After the reset, the device state is PIO 0 and the * controller state is undefined. Record the mode. */ for (i = 0; i < ATA_MAX_DEVICES; i++) ap->device[i].pio_mode = XFER_PIO_0; - /* record current link speed */ - if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0) - ap->sata_spd = (sstatus >> 4) & 0xf; - if (postreset) postreset(ap, classes); @@ -1920,9 +1746,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); ehc->i.action |= ATA_EH_REVALIDATE; } - out: - /* clear hotplug flag */ - ehc->i.flags &= ~ATA_EHI_HOTPLUGGED; + return rc; } diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 12ac0b511f79..cfde22da07ac 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -2947,22 +2947,17 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) return rc; } -void ata_scsi_scan_host(struct ata_port *ap, int sync) +void ata_scsi_scan_host(struct ata_port *ap) { - int tries = 5; - struct ata_device *last_failed_dev = NULL; - struct ata_device *dev; unsigned int i; if (ap->flags & ATA_FLAG_DISABLED) return; - repeat: for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; struct scsi_device *sdev; - dev = &ap->device[i]; - if (!ata_dev_enabled(dev) || dev->sdev) continue; @@ -2972,45 +2967,6 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync) scsi_device_put(sdev); } } - - /* If we scanned while EH was in progress or allocation - * failure occurred, scan would have failed silently. Check - * whether all devices are attached. - */ - for (i = 0; i < ATA_MAX_DEVICES; i++) { - dev = &ap->device[i]; - if (ata_dev_enabled(dev) && !dev->sdev) - break; - } - if (i == ATA_MAX_DEVICES) - return; - - /* we're missing some SCSI devices */ - if (sync) { - /* If caller requested synchrnous scan && we've made - * any progress, sleep briefly and repeat. - */ - if (dev != last_failed_dev) { - msleep(100); - last_failed_dev = dev; - goto repeat; - } - - /* We might be failing to detect boot device, give it - * a few more chances. - */ - if (--tries) { - msleep(100); - goto repeat; - } - - ata_port_printk(ap, KERN_ERR, "WARNING: synchronous SCSI scan " - "failed without making any progress,\n" - " switching to async\n"); - } - - queue_delayed_work(ata_aux_wq, &ap->hotplug_task, - round_jiffies_relative(HZ)); } /** @@ -3137,7 +3093,20 @@ void ata_scsi_hotplug(struct work_struct *work) } /* scan for new ones */ - ata_scsi_scan_host(ap, 0); + ata_scsi_scan_host(ap); + + /* If we scanned while EH was in progress, scan would have + * failed silently. Requeue if there are enabled but + * unattached devices. + */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *dev = &ap->device[i]; + if (ata_dev_enabled(dev) && !dev->sdev) { + queue_delayed_work(ata_aux_wq, &ap->hotplug_task, + round_jiffies_relative(HZ)); + break; + } + } DPRINTK("EXIT\n"); } diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 6c289c7b1322..ca7d2245d684 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -1,5 +1,5 @@ /* - * libata-sff.c - helper library for PCI IDE BMDMA + * libata-bmdma.c - helper library for PCI IDE BMDMA * * Maintained by: Jeff Garzik * Please ALWAYS copy linux-ide@vger.kernel.org @@ -211,8 +211,6 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) tf->hob_lbal = ioread8(ioaddr->lbal_addr); tf->hob_lbam = ioread8(ioaddr->lbam_addr); tf->hob_lbah = ioread8(ioaddr->lbah_addr); - iowrite8(tf->ctl, ioaddr->ctl_addr); - ap->last_ctl = tf->ctl; } } diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 564cd234c805..ba17fc5f2e99 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -112,7 +112,7 @@ static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; } /* libata-scsi.c */ extern int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht); -extern void ata_scsi_scan_host(struct ata_port *ap, int sync); +extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_offline_dev(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, @@ -151,7 +151,6 @@ extern int ata_bus_probe(struct ata_port *ap); extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); extern void ata_scsi_error(struct Scsi_Host *host); extern void ata_port_wait_eh(struct ata_port *ap); -extern void ata_eh_fastdrain_timerfn(unsigned long arg); extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); /* libata-sff.c */ diff --git a/trunk/drivers/ata/pata_platform.c b/trunk/drivers/ata/pata_platform.c index a909f793ffc1..79f841bca593 100644 --- a/trunk/drivers/ata/pata_platform.c +++ b/trunk/drivers/ata/pata_platform.c @@ -213,9 +213,8 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) pata_platform_setup_port(&ap->ioaddr, pp_info); /* activate */ - return ata_host_activate(host, platform_get_irq(pdev, 0), - ata_interrupt, pp_info ? pp_info->irq_flags - : 0, &pata_platform_sht); + return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt, + pp_info->irq_flags, &pata_platform_sht); } /** diff --git a/trunk/drivers/ata/pata_scc.c b/trunk/drivers/ata/pata_scc.c index 36cdbd2b0bd5..c55667e0eb65 100644 --- a/trunk/drivers/ata/pata_scc.c +++ b/trunk/drivers/ata/pata_scc.c @@ -238,6 +238,12 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) else offset = 0; /* 100MHz */ + /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ + if (adev->class == ATA_DEV_ATAPI && speed > XFER_UDMA_4) { + printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); + speed = XFER_UDMA_4; + } + if (speed >= XFER_UDMA_0) idx = speed - XFER_UDMA_0; else @@ -258,17 +264,6 @@ static void scc_set_dmamode (struct ata_port *ap, struct ata_device *adev) JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]); } -unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask) -{ - /* errata A308 workaround: limit ATAPI UDMA mode to UDMA4 */ - if (adev->class == ATA_DEV_ATAPI && - (mask & (0xE0 << ATA_SHIFT_UDMA))) { - printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME); - mask &= ~(0xE0 << ATA_SHIFT_UDMA); - } - return ata_pci_default_filter(adev, mask); -} - /** * scc_tf_load - send taskfile registers to host controller * @ap: Port to which output is sent @@ -363,8 +358,6 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf) tf->hob_lbal = in_be32(ioaddr->lbal_addr); tf->hob_lbam = in_be32(ioaddr->lbam_addr); tf->hob_lbah = in_be32(ioaddr->lbah_addr); - out_be32(ioaddr->ctl_addr, tf->ctl); - ap->last_ctl = tf->ctl; } } @@ -748,7 +741,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) return host_stat; /* errata A252,A308 workaround: Step4 */ - if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) + if (ata_altstatus(ap) & ATA_ERR && int_status & INTSTS_INTRQ) return (host_stat | ATA_DMA_INTR); /* errata A308 workaround Step5 */ @@ -759,11 +752,11 @@ static u8 scc_bmdma_status (struct ata_port *ap) if ((qc->tf.protocol == ATA_PROT_DMA && qc->dev->xfer_mode > XFER_UDMA_4)) { if (!(int_status & INTSTS_ACTEINT)) { - printk(KERN_WARNING "ata%u: operation failed (transfer data loss)\n", - ap->print_id); + printk(KERN_WARNING "ata%u: data lost occurred. (ACTEINT==0, retry:%d)\n", + ap->print_id, retry); host_stat |= ATA_DMA_ERR; if (retry++) - ap->udma_mask &= ~(1 << qc->dev->xfer_mode); + ap->udma_mask >>= 1; } else retry = 0; } @@ -1023,7 +1016,7 @@ static const struct ata_port_operations scc_pata_ops = { .port_disable = ata_port_disable, .set_piomode = scc_set_piomode, .set_dmamode = scc_set_dmamode, - .mode_filter = scc_mode_filter, + .mode_filter = ata_pci_default_filter, .tf_load = scc_tf_load, .tf_read = scc_tf_read, diff --git a/trunk/drivers/ata/sata_inic162x.c b/trunk/drivers/ata/sata_inic162x.c index a9c948d7604a..3de183461c3c 100644 --- a/trunk/drivers/ata/sata_inic162x.c +++ b/trunk/drivers/ata/sata_inic162x.c @@ -190,34 +190,34 @@ static void inic_reset_port(void __iomem *port_base) writew(ctl, idma_ctl); } -static int inic_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) +static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg) { void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; + u32 val; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) - return -EINVAL; + return 0xffffffffU; addr = scr_addr + scr_map[sc_reg] * 4; - *val = readl(scr_addr + scr_map[sc_reg] * 4); + val = readl(scr_addr + scr_map[sc_reg] * 4); /* this controller has stuck DIAG.N, ignore it */ if (sc_reg == SCR_ERROR) - *val &= ~SERR_PHYRDY_CHG; - return 0; + val &= ~SERR_PHYRDY_CHG; + return val; } -static int inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) +static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { void __iomem *scr_addr = ap->ioaddr.scr_addr; void __iomem *addr; if (unlikely(sc_reg >= ARRAY_SIZE(scr_map))) - return -EINVAL; + return; addr = scr_addr + scr_map[sc_reg] * 4; writel(val, scr_addr + scr_map[sc_reg] * 4); - return 0; } /* diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 8ec520885b95..fb8a749423ca 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -35,6 +35,8 @@ 6) Add port multiplier support (intermediate) + 7) Test and verify 3.0 Gbps support + 8) Develop a low-power-consumption strategy, and implement it. 9) [Experiment, low priority] See if ATAPI can be supported using @@ -225,26 +227,26 @@ enum { EDMA_ERR_IRQ_CAUSE_OFS = 0x8, EDMA_ERR_IRQ_MASK_OFS = 0xc, - EDMA_ERR_D_PAR = (1 << 0), /* UDMA data parity err */ - EDMA_ERR_PRD_PAR = (1 << 1), /* UDMA PRD parity err */ - EDMA_ERR_DEV = (1 << 2), /* device error */ - EDMA_ERR_DEV_DCON = (1 << 3), /* device disconnect */ - EDMA_ERR_DEV_CON = (1 << 4), /* device connected */ - EDMA_ERR_SERR = (1 << 5), /* SError bits [WBDST] raised */ + EDMA_ERR_D_PAR = (1 << 0), + EDMA_ERR_PRD_PAR = (1 << 1), + EDMA_ERR_DEV = (1 << 2), + EDMA_ERR_DEV_DCON = (1 << 3), + EDMA_ERR_DEV_CON = (1 << 4), + EDMA_ERR_SERR = (1 << 5), EDMA_ERR_SELF_DIS = (1 << 7), /* Gen II/IIE self-disable */ EDMA_ERR_SELF_DIS_5 = (1 << 8), /* Gen I self-disable */ - EDMA_ERR_BIST_ASYNC = (1 << 8), /* BIST FIS or Async Notify */ + EDMA_ERR_BIST_ASYNC = (1 << 8), EDMA_ERR_TRANS_IRQ_7 = (1 << 8), /* Gen IIE transprt layer irq */ - EDMA_ERR_CRQB_PAR = (1 << 9), /* CRQB parity error */ - EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */ - EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */ - EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */ - EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */ + EDMA_ERR_CRBQ_PAR = (1 << 9), + EDMA_ERR_CRPB_PAR = (1 << 10), + EDMA_ERR_INTRL_PAR = (1 << 11), + EDMA_ERR_IORDY = (1 << 12), + EDMA_ERR_LNK_CTRL_RX = (0xf << 13), EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), - EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */ - EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */ - EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */ - EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */ + EDMA_ERR_LNK_DATA_RX = (0xf << 17), + EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), + EDMA_ERR_LNK_DATA_TX = (0x1f << 26), + EDMA_ERR_TRANS_PROTO = (1 << 31), EDMA_ERR_OVERRUN_5 = (1 << 5), EDMA_ERR_UNDERRUN_5 = (1 << 6), EDMA_EH_FREEZE = EDMA_ERR_D_PAR | @@ -253,7 +255,7 @@ enum { EDMA_ERR_DEV_CON | EDMA_ERR_SERR | EDMA_ERR_SELF_DIS | - EDMA_ERR_CRQB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | EDMA_ERR_IORDY | @@ -268,7 +270,7 @@ enum { EDMA_ERR_OVERRUN_5 | EDMA_ERR_UNDERRUN_5 | EDMA_ERR_SELF_DIS_5 | - EDMA_ERR_CRQB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | EDMA_ERR_IORDY, @@ -284,10 +286,10 @@ enum { EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ EDMA_RSP_Q_PTR_SHIFT = 3, - EDMA_CMD_OFS = 0x28, /* EDMA command register */ - EDMA_EN = (1 << 0), /* enable EDMA */ - EDMA_DS = (1 << 1), /* disable EDMA; self-negated */ - ATA_RST = (1 << 2), /* reset trans/link/phy */ + EDMA_CMD_OFS = 0x28, + EDMA_EN = (1 << 0), + EDMA_DS = (1 << 1), + ATA_RST = (1 << 2), EDMA_IORDY_TMOUT = 0x34, EDMA_ARB_CFG = 0x38, @@ -299,13 +301,14 @@ enum { MV_HP_ERRATA_60X1B2 = (1 << 3), MV_HP_ERRATA_60X1C0 = (1 << 4), MV_HP_ERRATA_XX42A0 = (1 << 5), - MV_HP_GEN_I = (1 << 6), /* Generation I: 50xx */ - MV_HP_GEN_II = (1 << 7), /* Generation II: 60xx */ - MV_HP_GEN_IIE = (1 << 8), /* Generation IIE: 6042/7042 */ + MV_HP_GEN_I = (1 << 6), + MV_HP_GEN_II = (1 << 7), + MV_HP_GEN_IIE = (1 << 8), /* Port private flags (pp_flags) */ - MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */ - MV_PP_FLAG_HAD_A_RESET = (1 << 2), /* 1st hard reset complete? */ + MV_PP_FLAG_EDMA_EN = (1 << 0), + MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), + MV_PP_FLAG_HAD_A_RESET = (1 << 2), }; #define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I) @@ -315,12 +318,8 @@ enum { enum { MV_DMA_BOUNDARY = 0xffffffffU, - /* mask of register bits containing lower 32 bits - * of EDMA request queue DMA address - */ EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, - /* ditto, for response queue */ EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, }; @@ -404,10 +403,10 @@ struct mv_host_priv { }; static void mv_irq_clear(struct ata_port *ap); -static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); -static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); -static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val); -static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); +static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); static void mv_qc_prep(struct ata_queued_cmd *qc); @@ -824,7 +823,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, } /** - * __mv_stop_dma - Disable eDMA engine + * mv_stop_dma - Disable eDMA engine * @ap: ATA channel to manipulate * * Verify the local cache of the eDMA state is accurate with a @@ -833,7 +832,7 @@ static void mv_start_dma(void __iomem *base, struct mv_host_priv *hpriv, * LOCKING: * Inherited from caller. */ -static int __mv_stop_dma(struct ata_port *ap) +static int mv_stop_dma(struct ata_port *ap) { void __iomem *port_mmio = mv_ap_base(ap); struct mv_port_priv *pp = ap->private_data; @@ -866,18 +865,6 @@ static int __mv_stop_dma(struct ata_port *ap) return err; } -static int mv_stop_dma(struct ata_port *ap) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&ap->host->lock, flags); - rc = __mv_stop_dma(ap); - spin_unlock_irqrestore(&ap->host->lock, flags); - - return rc; -} - #ifdef ATA_DEBUG static void mv_dump_mem(void __iomem *start, unsigned bytes) { @@ -974,26 +961,22 @@ static unsigned int mv_scr_offset(unsigned int sc_reg_in) return ofs; } -static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) +static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { - *val = readl(mv_ap_base(ap) + ofs); - return 0; - } else - return -EINVAL; + if (0xffffffffU != ofs) + return readl(mv_ap_base(ap) + ofs); + else + return (u32) ofs; } -static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) +static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { unsigned int ofs = mv_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { + if (0xffffffffU != ofs) writelfl(val, mv_ap_base(ap) + ofs); - return 0; - } else - return -EINVAL; } static void mv_edma_cfg(struct ata_port *ap, struct mv_host_priv *hpriv, @@ -1046,7 +1029,6 @@ static int mv_port_start(struct ata_port *ap) void __iomem *port_mmio = mv_ap_base(ap); void *mem; dma_addr_t mem_dma; - unsigned long flags; int rc; pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); @@ -1085,14 +1067,10 @@ static int mv_port_start(struct ata_port *ap) pp->sg_tbl = mem; pp->sg_tbl_dma = mem_dma; - spin_lock_irqsave(&ap->host->lock, flags); - mv_edma_cfg(ap, hpriv, port_mmio); mv_set_edma_ptrs(port_mmio, hpriv, pp); - spin_unlock_irqrestore(&ap->host->lock, flags); - /* Don't turn on EDMA here...do it before DMA commands only. Else * we'll be unable to send non-data, PIO, etc due to restricted access * to shadow regs. @@ -1112,7 +1090,11 @@ static int mv_port_start(struct ata_port *ap) */ static void mv_port_stop(struct ata_port *ap) { + unsigned long flags; + + spin_lock_irqsave(&ap->host->lock, flags); mv_stop_dma(ap); + spin_unlock_irqrestore(&ap->host->lock, flags); } /** @@ -1343,7 +1325,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) * port. Turn off EDMA so there won't be problems accessing * shadow block, etc registers. */ - __mv_stop_dma(ap); + mv_stop_dma(ap); return ata_qc_issue_prot(qc); } @@ -1411,16 +1393,16 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_DEV) err_mask |= AC_ERR_DEV; if (edma_err_cause & (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | - EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR | + EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR)) { err_mask |= AC_ERR_ATA_BUS; action |= ATA_EH_HARDRESET; - ata_ehi_push_desc(ehi, "parity error"); + ata_ehi_push_desc(ehi, ", parity error"); } if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) { ata_ehi_hotplugged(ehi); ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ? - "dev disconnect" : "dev connect"); + ", dev disconnect" : ", dev connect"); } if (IS_GEN_I(hpriv)) { @@ -1429,7 +1411,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_SELF_DIS_5) { struct mv_port_priv *pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; - ata_ehi_push_desc(ehi, "EDMA self-disable"); + ata_ehi_push_desc(ehi, ", EDMA self-disable"); } } else { eh_freeze_mask = EDMA_EH_FREEZE; @@ -1437,7 +1419,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc) if (edma_err_cause & EDMA_ERR_SELF_DIS) { struct mv_port_priv *pp = ap->private_data; pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; - ata_ehi_push_desc(ehi, "EDMA self-disable"); + ata_ehi_push_desc(ehi, ", EDMA self-disable"); } if (edma_err_cause & EDMA_ERR_SERR) { @@ -1507,30 +1489,33 @@ static void mv_intr_edma(struct ata_port *ap) while (1) { u16 status; - unsigned int tag; /* get s/w response queue last-read pointer, and compare */ out_index = pp->resp_idx & MV_MAX_Q_DEPTH_MASK; if (in_index == out_index) break; + /* 50xx: get active ATA command */ - if (IS_GEN_I(hpriv)) - tag = ap->active_tag; + if (IS_GEN_I(hpriv)) + qc = ata_qc_from_tag(ap, ap->active_tag); - /* Gen II/IIE: get active ATA command via tag, to enable - * support for queueing. this works transparently for - * queued and non-queued modes. + /* 60xx: get active ATA command via tag, to enable support + * for queueing. this works transparently for queued and + * non-queued modes. */ - else if (IS_GEN_II(hpriv)) - tag = (le16_to_cpu(pp->crpb[out_index].id) - >> CRPB_IOID_SHIFT_6) & 0x3f; + else { + unsigned int tag; - else /* IS_GEN_IIE */ - tag = (le16_to_cpu(pp->crpb[out_index].id) - >> CRPB_IOID_SHIFT_7) & 0x3f; + if (IS_GEN_II(hpriv)) + tag = (le16_to_cpu(pp->crpb[out_index].id) + >> CRPB_IOID_SHIFT_6) & 0x3f; + else + tag = (le16_to_cpu(pp->crpb[out_index].id) + >> CRPB_IOID_SHIFT_7) & 0x3f; - qc = ata_qc_from_tag(ap, tag); + qc = ata_qc_from_tag(ap, tag); + } /* lower 8 bits of status are EDMA_ERR_IRQ_CAUSE_OFS * bits (WARNING: might not necessarily be associated @@ -1550,7 +1535,7 @@ static void mv_intr_edma(struct ata_port *ap) ata_qc_complete(qc); } - /* advance software response queue pointer, to + /* advance software response queue pointer, to * indicate (after the loop completes) to hardware * that we have consumed a response queue entry. */ @@ -1756,30 +1741,26 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in) return ofs; } -static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val) +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) { void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *addr = mv5_phy_base(mmio, ap->port_no); unsigned int ofs = mv5_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { - *val = readl(addr + ofs); - return 0; - } else - return -EINVAL; + if (ofs != 0xffffffffU) + return readl(addr + ofs); + else + return (u32) ofs; } -static int mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR]; void __iomem *addr = mv5_phy_base(mmio, ap->port_no); unsigned int ofs = mv5_scr_offset(sc_reg_in); - if (ofs != 0xffffffffU) { + if (ofs != 0xffffffffU) writelfl(val, addr + ofs); - return 0; - } else - return -EINVAL; } static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) @@ -2157,17 +2138,9 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); -#ifdef DEBUG - { - u32 sstatus, serror, scontrol; - - mv_scr_read(ap, SCR_STATUS, &sstatus); - mv_scr_read(ap, SCR_ERROR, &serror); - mv_scr_read(ap, SCR_CONTROL, &scontrol); - DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " - "SCtrl 0x%08x\n", status, serror, scontrol); - } -#endif + DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " + "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), + mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); /* Issue COMRESET via SControl */ comreset_retry: @@ -2191,17 +2164,9 @@ static void mv_phy_reset(struct ata_port *ap, unsigned int *class, (retry-- > 0)) goto comreset_retry; -#ifdef DEBUG - { - u32 sstatus, serror, scontrol; - - mv_scr_read(ap, SCR_STATUS, &sstatus); - mv_scr_read(ap, SCR_ERROR, &serror); - mv_scr_read(ap, SCR_CONTROL, &scontrol); - DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " - "SCtrl 0x%08x\n", sstatus, serror, scontrol); - } -#endif + DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " + "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), + mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); if (ata_port_offline(ap)) { *class = ATA_DEV_NONE; @@ -2244,7 +2209,7 @@ static int mv_prereset(struct ata_port *ap, unsigned long deadline) struct mv_port_priv *pp = ap->private_data; struct ata_eh_context *ehc = &ap->eh_context; int rc; - + rc = mv_stop_dma(ap); if (rc) ehc->i.action |= ATA_EH_HARDRESET; diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index 0b58c4df6fd2..db81e3efa5ec 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -236,8 +236,8 @@ static void nv_ck804_host_stop(struct ata_host *host); static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance); static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); -static int nv_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); @@ -715,20 +715,19 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) int freeze = 0; ata_ehi_clear_desc(ehi); - __ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x: ", flags ); + ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags ); if (flags & NV_CPB_RESP_ATA_ERR) { - ata_ehi_push_desc(ehi, "ATA error"); + ata_ehi_push_desc(ehi, ": ATA error"); ehi->err_mask |= AC_ERR_DEV; } else if (flags & NV_CPB_RESP_CMD_ERR) { - ata_ehi_push_desc(ehi, "CMD error"); + ata_ehi_push_desc(ehi, ": CMD error"); ehi->err_mask |= AC_ERR_DEV; } else if (flags & NV_CPB_RESP_CPB_ERR) { - ata_ehi_push_desc(ehi, "CPB error"); + ata_ehi_push_desc(ehi, ": CPB error"); ehi->err_mask |= AC_ERR_SYSTEM; freeze = 1; } else { /* notifier error, but no error in CPB flags? */ - ata_ehi_push_desc(ehi, "unknown"); ehi->err_mask |= AC_ERR_OTHER; freeze = 1; } @@ -855,21 +854,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) struct ata_eh_info *ehi = &ap->eh_info; ata_ehi_clear_desc(ehi); - __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status ); + ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status ); if (status & NV_ADMA_STAT_TIMEOUT) { ehi->err_mask |= AC_ERR_SYSTEM; - ata_ehi_push_desc(ehi, "timeout"); + ata_ehi_push_desc(ehi, ": timeout"); } else if (status & NV_ADMA_STAT_HOTPLUG) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "hotplug"); + ata_ehi_push_desc(ehi, ": hotplug"); } else if (status & NV_ADMA_STAT_HOTUNPLUG) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "hot unplug"); + ata_ehi_push_desc(ehi, ": hot unplug"); } else if (status & NV_ADMA_STAT_SERROR) { /* let libata analyze SError and figure out the cause */ - ata_ehi_push_desc(ehi, "SError"); - } else - ata_ehi_push_desc(ehi, "unknown"); + ata_ehi_push_desc(ehi, ": SError"); + } ata_port_freeze(ap); continue; } @@ -1393,22 +1391,20 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance) return ret; } -static int nv_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; - *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int nv_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } static void nv_nf2_freeze(struct ata_port *ap) diff --git a/trunk/drivers/ata/sata_promise.c b/trunk/drivers/ata/sata_promise.c index d39ebc23c4a9..d2fcb9a6bec2 100644 --- a/trunk/drivers/ata/sata_promise.c +++ b/trunk/drivers/ata/sata_promise.c @@ -128,8 +128,8 @@ struct pdc_port_priv { dma_addr_t pkt_dma; }; -static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_common_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap); @@ -427,20 +427,19 @@ static int pdc_sata_cable_detect(struct ata_port *ap) return ATA_CBL_SATA; } -static int pdc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int pdc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } static void pdc_atapi_pkt(struct ata_queued_cmd *qc) @@ -643,12 +642,8 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) ac_err_mask |= AC_ERR_HOST_BUS; - if (sata_scr_valid(ap)) { - u32 serror; - - pdc_sata_scr_read(ap, SCR_ERROR, &serror); - ehi->serror |= serror; - } + if (sata_scr_valid(ap)) + ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR); qc->err_mask |= ac_err_mask; diff --git a/trunk/drivers/ata/sata_qstor.c b/trunk/drivers/ata/sata_qstor.c index c8f9242e7f44..9ab554da89bf 100644 --- a/trunk/drivers/ata/sata_qstor.c +++ b/trunk/drivers/ata/sata_qstor.c @@ -111,8 +111,8 @@ struct qs_port_priv { qs_state_t state; }; -static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); @@ -255,20 +255,18 @@ static void qs_eng_timeout(struct ata_port *ap) ata_eng_timeout(ap); } -static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 8)); - return 0; + return ~0U; + return readl(ap->ioaddr.scr_addr + (sc_reg * 8)); } -static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 8)); - return 0; } static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) @@ -339,7 +337,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) buf[28] = dflags; /* frame information structure (FIS) */ - ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); + ata_tf_to_fis(&qc->tf, &buf[32], 0); } static inline void qs_packet_start(struct ata_queued_cmd *qc) diff --git a/trunk/drivers/ata/sata_sil.c b/trunk/drivers/ata/sata_sil.c index db6763758952..2a86dc4598d0 100644 --- a/trunk/drivers/ata/sata_sil.c +++ b/trunk/drivers/ata/sata_sil.c @@ -115,8 +115,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int sil_pci_device_resume(struct pci_dev *pdev); #endif static void sil_dev_config(struct ata_device *dev); -static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed); static void sil_freeze(struct ata_port *ap); static void sil_thaw(struct ata_port *ap); @@ -350,26 +350,19 @@ static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_re return NULL; } -static int sil_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg) { void __iomem *mmio = sil_scr_addr(ap, sc_reg); - - if (mmio) { - *val = readl(mmio); - return 0; - } - return -EINVAL; + if (mmio) + return readl(mmio); + return 0xffffffffU; } -static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { void __iomem *mmio = sil_scr_addr(ap, sc_reg); - - if (mmio) { + if (mmio) writel(val, mmio); - return 0; - } - return -EINVAL; } static void sil_host_intr(struct ata_port *ap, u32 bmdma2) @@ -385,7 +378,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) * controllers continue to assert IRQ as long as * SError bits are pending. Clear SError immediately. */ - sil_scr_read(ap, SCR_ERROR, &serror); + serror = sil_scr_read(ap, SCR_ERROR); sil_scr_write(ap, SCR_ERROR, serror); /* Trigger hotplug and accumulate SError only if the diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index 46fbbe7f121c..ac43a30ebe29 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -326,8 +326,8 @@ struct sil24_port_priv { static void sil24_dev_config(struct ata_device *dev); static u8 sil24_check_status(struct ata_port *ap); -static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val); -static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); +static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); +static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); static void sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); @@ -464,15 +464,15 @@ static void sil24_dev_config(struct ata_device *dev) writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); } -static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf) +static inline void sil24_update_tf(struct ata_port *ap) { + struct sil24_port_priv *pp = ap->private_data; void __iomem *port = ap->ioaddr.cmd_addr; - struct sil24_prb __iomem *prb; + struct sil24_prb __iomem *prb = port; u8 fis[6 * 4]; - prb = port + PORT_LRAM + sil24_tag(tag) * PORT_LRAM_SLOT_SZ; - memcpy_fromio(fis, prb->fis, sizeof(fis)); - ata_tf_from_fis(fis, tf); + memcpy_fromio(fis, prb->fis, 6 * 4); + ata_tf_from_fis(fis, &pp->tf); } static u8 sil24_check_status(struct ata_port *ap) @@ -488,30 +488,25 @@ static int sil24_scr_map[] = { [SCR_ACTIVE] = 3, }; -static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val) +static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg) { void __iomem *scr_addr = ap->ioaddr.scr_addr; - if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; - *val = readl(scr_addr + sil24_scr_map[sc_reg] * 4); - return 0; + return readl(scr_addr + sil24_scr_map[sc_reg] * 4); } - return -EINVAL; + return 0xffffffffU; } -static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) +static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val) { void __iomem *scr_addr = ap->ioaddr.scr_addr; - if (sc_reg < ARRAY_SIZE(sil24_scr_map)) { void __iomem *addr; addr = scr_addr + sil24_scr_map[sc_reg] * 4; writel(val, scr_addr + sil24_scr_map[sc_reg] * 4); - return 0; } - return -EINVAL; } static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) @@ -536,60 +531,15 @@ static int sil24_init_port(struct ata_port *ap) return 0; } -static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp, - const struct ata_taskfile *tf, - int is_cmd, u32 ctrl, - unsigned long timeout_msec) +static int sil24_softreset(struct ata_port *ap, unsigned int *class, + unsigned long deadline) { void __iomem *port = ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; dma_addr_t paddr = pp->cmd_block_dma; - u32 irq_enabled, irq_mask, irq_stat; - int rc; - - prb->ctrl = cpu_to_le16(ctrl); - ata_tf_to_fis(tf, pmp, is_cmd, prb->fis); - - /* temporarily plug completion and error interrupts */ - irq_enabled = readl(port + PORT_IRQ_ENABLE_SET); - writel(PORT_IRQ_COMPLETE | PORT_IRQ_ERROR, port + PORT_IRQ_ENABLE_CLR); - - writel((u32)paddr, port + PORT_CMD_ACTIVATE); - writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); - - irq_mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; - irq_stat = ata_wait_register(port + PORT_IRQ_STAT, irq_mask, 0x0, - 10, timeout_msec); - - writel(irq_mask, port + PORT_IRQ_STAT); /* clear IRQs */ - irq_stat >>= PORT_IRQ_RAW_SHIFT; - - if (irq_stat & PORT_IRQ_COMPLETE) - rc = 0; - else { - /* force port into known state */ - sil24_init_port(ap); - - if (irq_stat & PORT_IRQ_ERROR) - rc = -EIO; - else - rc = -EBUSY; - } - - /* restore IRQ enabled */ - writel(irq_enabled, port + PORT_IRQ_ENABLE_SET); - - return rc; -} - -static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, - int pmp, unsigned long deadline) -{ - unsigned long timeout_msec = 0; - struct ata_taskfile tf; + u32 mask, irq_stat; const char *reason; - int rc; DPRINTK("ENTER\n"); @@ -606,22 +556,29 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, } /* do SRST */ - if (time_after(deadline, jiffies)) - timeout_msec = jiffies_to_msecs(deadline - jiffies); - - ata_tf_init(ap->device, &tf); /* doesn't really matter */ - rc = sil24_exec_polled_cmd(ap, pmp, &tf, 0, PRB_CTRL_SRST, - timeout_msec); - if (rc == -EBUSY) { - reason = "timeout"; - goto err; - } else if (rc) { - reason = "SRST command error"; + prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); + prb->fis[1] = 0; /* no PMP yet */ + + writel((u32)paddr, port + PORT_CMD_ACTIVATE); + writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); + + mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; + irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, + 100, jiffies_to_msecs(deadline - jiffies)); + + writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ + irq_stat >>= PORT_IRQ_RAW_SHIFT; + + if (!(irq_stat & PORT_IRQ_COMPLETE)) { + if (irq_stat & PORT_IRQ_ERROR) + reason = "SRST command error"; + else + reason = "timeout"; goto err; } - sil24_read_tf(ap, 0, &tf); - *class = ata_dev_classify(&tf); + sil24_update_tf(ap); + *class = ata_dev_classify(&pp->tf); if (*class == ATA_DEV_UNKNOWN) *class = ATA_DEV_NONE; @@ -635,12 +592,6 @@ static int sil24_do_softreset(struct ata_port *ap, unsigned int *class, return -EIO; } -static int sil24_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - return sil24_do_softreset(ap, class, 0, deadline); -} - static int sil24_hardreset(struct ata_port *ap, unsigned int *class, unsigned long deadline) { @@ -748,7 +699,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) } prb->ctrl = cpu_to_le16(ctrl); - ata_tf_to_fis(&qc->tf, 0, 1, prb->fis); + ata_tf_to_fis(&qc->tf, prb->fis, 0); if (qc->flags & ATA_QCFLAG_DMAMAP) sil24_fill_sg(qc, sge); @@ -803,7 +754,6 @@ static void sil24_thaw(struct ata_port *ap) static void sil24_error_intr(struct ata_port *ap) { void __iomem *port = ap->ioaddr.cmd_addr; - struct sil24_port_priv *pp = ap->private_data; struct ata_eh_info *ehi = &ap->eh_info; int freeze = 0; u32 irq_stat; @@ -819,16 +769,16 @@ static void sil24_error_intr(struct ata_port *ap) if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { ata_ehi_hotplugged(ehi); - ata_ehi_push_desc(ehi, "%s", - irq_stat & PORT_IRQ_PHYRDY_CHG ? - "PHY RDY changed" : "device exchanged"); + ata_ehi_push_desc(ehi, ", %s", + irq_stat & PORT_IRQ_PHYRDY_CHG ? + "PHY RDY changed" : "device exchanged"); freeze = 1; } if (irq_stat & PORT_IRQ_UNK_FIS) { ehi->err_mask |= AC_ERR_HSM; ehi->action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown FIS"); + ata_ehi_push_desc(ehi , ", unknown FIS"); freeze = 1; } @@ -847,18 +797,18 @@ static void sil24_error_intr(struct ata_port *ap) if (ci && ci->desc) { err_mask |= ci->err_mask; action |= ci->action; - ata_ehi_push_desc(ehi, "%s", ci->desc); + ata_ehi_push_desc(ehi, ", %s", ci->desc); } else { err_mask |= AC_ERR_OTHER; action |= ATA_EH_SOFTRESET; - ata_ehi_push_desc(ehi, "unknown command error %d", + ata_ehi_push_desc(ehi, ", unknown command error %d", cerr); } /* record error info */ qc = ata_qc_from_tag(ap, ap->active_tag); if (qc) { - sil24_read_tf(ap, qc->tag, &pp->tf); + sil24_update_tf(ap); qc->err_mask |= err_mask; } else ehi->err_mask |= err_mask; @@ -875,11 +825,8 @@ static void sil24_error_intr(struct ata_port *ap) static void sil24_finish_qc(struct ata_queued_cmd *qc) { - struct ata_port *ap = qc->ap; - struct sil24_port_priv *pp = ap->private_data; - if (qc->flags & ATA_QCFLAG_RESULT_TF) - sil24_read_tf(ap, qc->tag, &pp->tf); + sil24_update_tf(qc->ap); } static inline void sil24_host_intr(struct ata_port *ap) diff --git a/trunk/drivers/ata/sata_sis.c b/trunk/drivers/ata/sata_sis.c index 31a2f55aae66..33716b00c6b7 100644 --- a/trunk/drivers/ata/sata_sis.c +++ b/trunk/drivers/ata/sata_sis.c @@ -64,8 +64,8 @@ enum { }; static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int sis_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static const struct pci_device_id sis_pci_tbl[] = { { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */ @@ -207,37 +207,36 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val pci_write_config_dword(pdev, cfg_addr+0x10, val); } -static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 val, val2 = 0; u8 pmr; if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; if (ap->flags & SIS_FLAG_CFGSCR) return sis_scr_cfg_read(ap, sc_reg); pci_read_config_byte(pdev, SIS_PMR, &pmr); - *val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); + val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) - *val |= ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); - - *val &= 0xfffffffb; + val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); - return 0; + return (val | val2) & 0xfffffffb; } -static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 pmr; if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; pci_read_config_byte(pdev, SIS_PMR, &pmr); @@ -249,7 +248,6 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); } - return 0; } static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 92e877075037..63fe99afd59f 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -103,21 +103,20 @@ static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) return 0; } -static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int k2_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void k2_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } diff --git a/trunk/drivers/ata/sata_uli.c b/trunk/drivers/ata/sata_uli.c index 78c28512f01c..b52f83ab056a 100644 --- a/trunk/drivers/ata/sata_uli.c +++ b/trunk/drivers/ata/sata_uli.c @@ -57,8 +57,8 @@ struct uli_priv { }; static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static const struct pci_device_id uli_pci_tbl[] = { { PCI_VDEVICE(AL, 0x5289), uli_5289 }, @@ -164,22 +164,20 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) pci_write_config_dword(pdev, cfg_addr, val); } -static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return 0xffffffffU; - *val = uli_scr_cfg_read(ap, sc_reg); - return 0; + return uli_scr_cfg_read(ap, sc_reg); } -static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) +static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0 - return -EINVAL; + return; uli_scr_cfg_write(ap, sc_reg, val); - return 0; } static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 86b7bfc17324..c4124475f754 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -72,8 +72,8 @@ enum { }; static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val); -static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val); +static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); +static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void svia_noop_freeze(struct ata_port *ap); static void vt6420_error_handler(struct ata_port *ap); static int vt6421_pata_cable_detect(struct ata_port *ap); @@ -249,20 +249,18 @@ MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, svia_pci_tbl); MODULE_VERSION(DRV_VERSION); -static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); - return 0; + return 0xffffffffU; + return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg)); } -static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg)); - return 0; } static void svia_noop_freeze(struct ata_port *ap) @@ -307,19 +305,18 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) /* Resume phy. This is the old SATA resume sequence */ svia_scr_write(ap, SCR_CONTROL, 0x300); - svia_scr_read(ap, SCR_CONTROL, &scontrol); /* flush */ + svia_scr_read(ap, SCR_CONTROL); /* flush */ /* wait for phy to become ready, if necessary */ do { msleep(200); - svia_scr_read(ap, SCR_STATUS, &sstatus); - if ((sstatus & 0xf) != 1) + if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) break; } while (time_before(jiffies, timeout)); /* open code sata_print_link_status() */ - svia_scr_read(ap, SCR_STATUS, &sstatus); - svia_scr_read(ap, SCR_CONTROL, &scontrol); + sstatus = svia_scr_read(ap, SCR_STATUS); + scontrol = svia_scr_read(ap, SCR_CONTROL); online = (sstatus & 0xf) == 0x3; @@ -328,7 +325,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) online ? "up" : "down", sstatus, scontrol); /* SStatus is read one more time */ - svia_scr_read(ap, SCR_STATUS, &sstatus); + svia_scr_read(ap, SCR_STATUS); if (!online) { /* tell EH to bail */ diff --git a/trunk/drivers/ata/sata_vsc.c b/trunk/drivers/ata/sata_vsc.c index 24344d0d0575..1b5d81faa102 100644 --- a/trunk/drivers/ata/sata_vsc.c +++ b/trunk/drivers/ata/sata_vsc.c @@ -98,21 +98,20 @@ enum { VSC_SATA_INT_PHY_CHANGE), }; -static int vsc_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) +static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { if (sc_reg > SCR_CONTROL) - return -EINVAL; - *val = readl(ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; + return 0xffffffffU; + return readl(ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int vsc_sata_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val) +static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, + u32 val) { if (sc_reg > SCR_CONTROL) - return -EINVAL; + return; writel(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - return 0; } diff --git a/trunk/drivers/block/sunvdc.c b/trunk/drivers/block/sunvdc.c index d50b82381155..2288b55d916f 100644 --- a/trunk/drivers/block/sunvdc.c +++ b/trunk/drivers/block/sunvdc.c @@ -64,6 +64,7 @@ struct vdc_port { u64 operations; u32 vdisk_size; u8 vdisk_type; + u8 dev_no; char disk_name[32]; @@ -702,7 +703,7 @@ static int probe_disk(struct vdc_port *port) blk_queue_max_phys_segments(q, port->ring_cookies); blk_queue_max_sectors(q, port->max_xfer_size); g->major = vdc_major; - g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT; + g->first_minor = port->dev_no << PARTITION_SHIFT; strcpy(g->disk_name, port->disk_name); g->fops = &vdc_fops; @@ -746,16 +747,21 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, { struct mdesc_handle *hp; struct vdc_port *port; + const u64 *port_id; int err; print_version(); hp = mdesc_grab(); + port_id = mdesc_get_property(hp, vdev->mp, "id", NULL); err = -ENODEV; - if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { - printk(KERN_ERR PFX "Port id [%lu] too large.\n", - vdev->dev_no); + if (!port_id) { + printk(KERN_ERR PFX "Port lacks id property.\n"); + goto err_out_release_mdesc; + } + if ((*port_id << PARTITION_SHIFT) & ~(u64)MINORMASK) { + printk(KERN_ERR PFX "Port id [%lu] too large.\n", *port_id); goto err_out_release_mdesc; } @@ -766,14 +772,16 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, goto err_out_release_mdesc; } - if (vdev->dev_no >= 26) + port->dev_no = *port_id; + + if (port->dev_no >= 26) snprintf(port->disk_name, sizeof(port->disk_name), VDCBLK_NAME "%c%c", - 'a' + ((int)vdev->dev_no / 26) - 1, - 'a' + ((int)vdev->dev_no % 26)); + 'a' + (port->dev_no / 26) - 1, + 'a' + (port->dev_no % 26)); else snprintf(port->disk_name, sizeof(port->disk_name), - VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26)); + VDCBLK_NAME "%c", 'a' + (port->dev_no % 26)); err = vio_driver_init(&port->vio, vdev, VDEV_DISK, vdc_versions, ARRAY_SIZE(vdc_versions), @@ -841,7 +849,7 @@ static struct vio_device_id vdc_port_match[] = { }, {}, }; -MODULE_DEVICE_TABLE(vio, vdc_port_match); +MODULE_DEVICE_TABLE(vio, vdc_match); static struct vio_driver vdc_port_driver = { .id_table = vdc_port_match, diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 4373d7cdc5d2..9e8f21410d2d 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -185,7 +185,7 @@ config ESPSERIAL config MOXA_INTELLIO tristate "Moxa Intellio support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) + depends on SERIAL_NONSTANDARD help Say Y here if you have a Moxa Intellio multiport serial card. @@ -241,7 +241,7 @@ config SYNCLINK config SYNCLINKMP tristate "SyncLink Multiport support" - depends on SERIAL_NONSTANDARD && PCI + depends on SERIAL_NONSTANDARD help Enable support for the SyncLink Multiport (2 or 4 ports) serial adapter, running asynchronous and HDLC communications up diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index f1497cecffd8..c585b4738f86 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -2573,10 +2573,16 @@ static struct tty_driver *serial167_console_device(struct console *c, return cy_serial_driver; } +static int __init serial167_console_setup(struct console *co, char *options) +{ + return 0; +} + static struct console sercons = { .name = "ttyS", .write = serial167_console_write, .device = serial167_console_device, + .setup = serial167_console_setup, .flags = CON_PRINTBUFFER, .index = -1, }; diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c index 4b26ce48189b..4eba32b23b29 100644 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ b/trunk/drivers/char/tpm/tpm_bios.c @@ -427,7 +427,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, return -ENOMEM; if ((err = read_log(log))) - goto out_free; + return err; /* now register seq file */ err = seq_open(file, &tpm_ascii_b_measurments_seqops); @@ -435,15 +435,10 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode, seq = file->private_data; seq->private = log; } else { - goto out_free; + kfree(log->bios_event_log); + kfree(log); } - -out: return err; -out_free: - kfree(log->bios_event_log); - kfree(log); - goto out; } const struct file_operations tpm_ascii_bios_measurements_ops = { diff --git a/trunk/drivers/char/vme_scc.c b/trunk/drivers/char/vme_scc.c index e122a0e87bb0..bef6d886d4fb 100644 --- a/trunk/drivers/char/vme_scc.c +++ b/trunk/drivers/char/vme_scc.c @@ -1013,10 +1013,18 @@ static struct tty_driver *scc_console_device(struct console *c, int *index) return scc_driver; } + +static int __init scc_console_setup(struct console *co, char *options) +{ + return 0; +} + + static struct console sercons = { .name = "ttyS", .write = scc_console_write, .device = scc_console_device, + .setup = scc_console_setup, .flags = CON_PRINTBUFFER, .index = -1, }; diff --git a/trunk/drivers/ide/legacy/falconide.c b/trunk/drivers/ide/legacy/falconide.c index f0829b83e970..e1e9d9d6893f 100644 --- a/trunk/drivers/ide/legacy/falconide.c +++ b/trunk/drivers/ide/legacy/falconide.c @@ -8,7 +8,6 @@ * more details. */ -#include #include #include #include @@ -55,7 +54,6 @@ static int falconide_offsets[IDE_NR_PORTS] __initdata = { */ int falconide_intr_lock; -EXPORT_SYMBOL(falconide_intr_lock); /* diff --git a/trunk/drivers/lguest/io.c b/trunk/drivers/lguest/io.c index c8eb79266991..06bdba2337ef 100644 --- a/trunk/drivers/lguest/io.c +++ b/trunk/drivers/lguest/io.c @@ -187,7 +187,7 @@ static u32 copy_data(struct lguest *srclg, /* FIXME: This is not completely portable, since archs do different things for copy_to_user_page. */ if (copy_from_user(maddr + (dst->addr[di] + dstoff)%PAGE_SIZE, - (void __user *)src->addr[si], len) != 0) { + (void *__user)src->addr[si], len) != 0) { kill_guest(srclg, "bad address in sending DMA"); totlen = 0; break; diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index d90ee145effe..c8dfdb302916 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -493,12 +493,12 @@ async_copy_data(int frombio, struct bio *bio, struct page *page, if (frombio) tx = async_memcpy(page, bio_page, page_offset, b_offset, clen, - ASYNC_TX_DEP_ACK, + ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_SRC, tx, NULL, NULL); else tx = async_memcpy(bio_page, page, b_offset, page_offset, clen, - ASYNC_TX_DEP_ACK, + ASYNC_TX_DEP_ACK | ASYNC_TX_KMAP_DST, tx, NULL, NULL); } if (clen < len) /* hit end of page */ diff --git a/trunk/drivers/net/mac89x0.c b/trunk/drivers/net/mac89x0.c index 62c1c6262feb..26a3b45a4a34 100644 --- a/trunk/drivers/net/mac89x0.c +++ b/trunk/drivers/net/mac89x0.c @@ -608,7 +608,7 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)"); MODULE_LICENSE("GPL"); -int __init +int init_module(void) { net_debug = debug; diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 13f08a390e1f..a2f32151559e 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -692,7 +692,6 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) { struct sky2_port *sky2 = netdev_priv(hw->dev[port]); u16 reg; - u32 rx_reg; int i; const u8 *addr = hw->dev[port]->dev_addr; @@ -769,11 +768,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) /* Configure Rx MAC FIFO */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; + reg = GMF_OPER_ON | GMF_RX_F_FL_ON; if (hw->chip_id == CHIP_ID_YUKON_EX) - rx_reg |= GMF_RX_OVER_ON; + reg |= GMF_RX_OVER_ON; - sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); + sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg); /* Flush Rx MAC FIFO on any flow control or error */ sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); diff --git a/trunk/drivers/net/sunvnet.c b/trunk/drivers/net/sunvnet.c index ef0066bab2cf..b801e3b3a11a 100644 --- a/trunk/drivers/net/sunvnet.c +++ b/trunk/drivers/net/sunvnet.c @@ -1136,7 +1136,7 @@ static struct vio_device_id vnet_port_match[] = { }, {}, }; -MODULE_DEVICE_TABLE(vio, vnet_port_match); +MODULE_DEVICE_TABLE(vio, vnet_match); static struct vio_driver vnet_port_driver = { .id_table = vnet_port_match, diff --git a/trunk/drivers/parport/Kconfig b/trunk/drivers/parport/Kconfig index d449b150930e..09c93ff932b1 100644 --- a/trunk/drivers/parport/Kconfig +++ b/trunk/drivers/parport/Kconfig @@ -35,7 +35,7 @@ if PARPORT config PARPORT_PC tristate "PC-style hardware" - depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && (!M68K || ISA) + depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV ---help--- You should say Y here if you have a PC-style parallel port. All IBM PC compatible computers and some Alphas have PC-style diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index a947257b8964..372723161c97 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -483,7 +483,7 @@ source "drivers/scsi/aic94xx/Kconfig" # All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on !64BIT && SCSI && PCI && VIRT_TO_BUS + depends on !64BIT && SCSI && PCI help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained diff --git a/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index 79b4df158140..773d11dd9953 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -95,8 +95,6 @@ enum { /* The master ring of all esp hosts we are managing in this driver. */ static struct NCR_ESP *espchain; int nesps = 0, esps_in_use = 0, esps_running = 0; -EXPORT_SYMBOL(nesps); -EXPORT_SYMBOL(esps_running); irqreturn_t esp_intr(int irq, void *dev_id); @@ -526,7 +524,6 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) /* Eat any bitrot in the chip and we are done... */ trash = esp_read(eregs->esp_intrpt); } -EXPORT_SYMBOL(esp_bootup_reset); /* Allocate structure and insert basic data such as SCSI chip frequency * data and a pointer to the device @@ -775,7 +772,6 @@ const char *esp_info(struct Scsi_Host *host) panic("Bogon ESP revision"); }; } -EXPORT_SYMBOL(esp_info); /* From Wolfgang Stanglmeier's NCR scsi driver. */ struct info_str @@ -906,7 +902,6 @@ int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t off *start = buffer; return esp_host_info(esp, buffer, offset, length); } -EXPORT_SYMBOL(esp_proc_info); static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) { @@ -3540,7 +3535,6 @@ void esp_handle(struct NCR_ESP *esp) if(esp->dma_irq_exit) esp->dma_irq_exit(esp); } -EXPORT_SYMBOL(esp_handle); #ifndef CONFIG_SMP irqreturn_t esp_intr(int irq, void *dev_id) @@ -3637,7 +3631,6 @@ void esp_release(void) esps_in_use--; esps_running = esps_in_use; } -EXPORT_SYMBOL(esp_release); #endif EXPORT_SYMBOL(esp_abort); diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index 7829ab1e2fb4..aebcd5fcdc55 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -1885,7 +1885,7 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock, struct sockaddr_in *sin; int rc = 0, len; - addr = kmalloc(sizeof(*addr), GFP_KERNEL); + addr = kmalloc(GFP_KERNEL, sizeof(*addr)); if (!addr) return -ENOMEM; diff --git a/trunk/drivers/usb/atm/cxacru.c b/trunk/drivers/usb/atm/cxacru.c index 02c52f8d5dbf..1bc884051e0f 100644 --- a/trunk/drivers/usb/atm/cxacru.c +++ b/trunk/drivers/usb/atm/cxacru.c @@ -456,7 +456,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, int* actual_length) { struct timer_list timer; - int status = urb->status; + int status; init_timer(&timer); timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); @@ -464,6 +464,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, timer.function = cxacru_timeout_kill; add_timer(&timer); wait_for_completion(done); + status = urb->status; del_timer_sync(&timer); if (actual_length) diff --git a/trunk/drivers/usb/atm/speedtch.c b/trunk/drivers/usb/atm/speedtch.c index eb0615abff68..638b8009b3bc 100644 --- a/trunk/drivers/usb/atm/speedtch.c +++ b/trunk/drivers/usb/atm/speedtch.c @@ -612,8 +612,7 @@ static void speedtch_handle_int(struct urb *int_urb) struct speedtch_instance_data *instance = int_urb->context; struct usbatm_data *usbatm = instance->usbatm; unsigned int count = int_urb->actual_length; - int status = int_urb->status; - int ret; + int ret = int_urb->status; /* The magic interrupt for "up state" */ static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; @@ -622,8 +621,8 @@ static void speedtch_handle_int(struct urb *int_urb) atm_dbg(usbatm, "%s entered\n", __func__); - if (status < 0) { - atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, status); + if (ret < 0) { + atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); goto fail; } diff --git a/trunk/drivers/usb/atm/ueagle-atm.c b/trunk/drivers/usb/atm/ueagle-atm.c index a1a1c9d467e0..8f046659b4e9 100644 --- a/trunk/drivers/usb/atm/ueagle-atm.c +++ b/trunk/drivers/usb/atm/ueagle-atm.c @@ -1308,13 +1308,11 @@ static void uea_intr(struct urb *urb) { struct uea_softc *sc = urb->context; struct intr_pkt *intr = urb->transfer_buffer; - int status = urb->status; - uea_enters(INS_TO_USBDEV(sc)); - if (unlikely(status < 0)) { + if (unlikely(urb->status < 0)) { uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", - status); + urb->status); return; } diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index e717f5b1caee..11e9b15ca45a 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -257,10 +257,9 @@ static void usbatm_complete(struct urb *urb) { struct usbatm_channel *channel = urb->context; unsigned long flags; - int status = urb->status; vdbg("%s: urb 0x%p, status %d, actual_length %d", - __func__, urb, status, urb->actual_length); + __func__, urb, urb->status, urb->actual_length); /* usually in_interrupt(), but not always */ spin_lock_irqsave(&channel->lock, flags); @@ -270,16 +269,16 @@ static void usbatm_complete(struct urb *urb) spin_unlock_irqrestore(&channel->lock, flags); - if (unlikely(status) && + if (unlikely(urb->status) && (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || - status != -EILSEQ )) + urb->status != -EILSEQ )) { - if (status == -ESHUTDOWN) + if (urb->status == -ESHUTDOWN) return; if (printk_ratelimit()) atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", - __func__, urb, status); + __func__, urb, urb->status); /* throttle processing in case of an error */ mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); } else diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index fe940e0536e0..cd51520c7e72 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -257,10 +257,9 @@ static void acm_ctrl_irq(struct urb *urb) struct usb_cdc_notification *dr = urb->transfer_buffer; unsigned char *data; int newctrl; - int retval; - int status = urb->status; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -268,10 +267,10 @@ static void acm_ctrl_irq(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } @@ -312,10 +311,10 @@ static void acm_ctrl_irq(struct urb *urb) break; } exit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __FUNCTION__, status); } /* data interface returns incoming bytes, or we got unthrottled */ @@ -325,8 +324,7 @@ static void acm_read_bulk(struct urb *urb) struct acm_ru *rcv = urb->context; struct acm *acm = rcv->instance; int status = urb->status; - - dbg("Entering acm_read_bulk with status %d", status); + dbg("Entering acm_read_bulk with status %d", urb->status); if (!ACM_READY(acm)) return; diff --git a/trunk/drivers/usb/class/usblp.c b/trunk/drivers/usb/class/usblp.c index 5192cd9356de..9a1478972bf5 100644 --- a/trunk/drivers/usb/class/usblp.c +++ b/trunk/drivers/usb/class/usblp.c @@ -289,17 +289,16 @@ static int proto_bias = -1; static void usblp_bulk_read(struct urb *urb) { struct usblp *usblp = urb->context; - int status = urb->status; if (usblp->present && usblp->used) { - if (status) + if (urb->status) printk(KERN_WARNING "usblp%d: " "nonzero read bulk status received: %d\n", - usblp->minor, status); + usblp->minor, urb->status); } spin_lock(&usblp->lock); - if (status < 0) - usblp->rstatus = status; + if (urb->status < 0) + usblp->rstatus = urb->status; else usblp->rstatus = urb->actual_length; usblp->rcomplete = 1; @@ -312,17 +311,16 @@ static void usblp_bulk_read(struct urb *urb) static void usblp_bulk_write(struct urb *urb) { struct usblp *usblp = urb->context; - int status = urb->status; if (usblp->present && usblp->used) { - if (status) + if (urb->status) printk(KERN_WARNING "usblp%d: " "nonzero write bulk status received: %d\n", - usblp->minor, status); + usblp->minor, urb->status); } spin_lock(&usblp->lock); - if (status < 0) - usblp->wstatus = status; + if (urb->status < 0) + usblp->wstatus = urb->status; else usblp->wstatus = urb->actual_length; usblp->wcomplete = 1; @@ -743,11 +741,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t */ rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); if (rv < 0) { - if (rv == -EAGAIN) { - /* Presume that it's going to complete well. */ - writecount += transfer_length; - } - /* Leave URB dangling, to be cleaned on close. */ + /* + * If interrupted, we simply leave the URB to dangle, + * so the ->release will call usb_kill_urb(). + */ goto collect_error; } diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 42ef1d5f6c8a..963520fbef90 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -99,17 +99,12 @@ EXPORT_SYMBOL_GPL (usb_bus_list_lock); /* used for controlling access to virtual root hubs */ static DEFINE_SPINLOCK(hcd_root_hub_lock); -/* used when updating an endpoint's URB list */ -static DEFINE_SPINLOCK(hcd_urb_list_lock); +/* used when updating hcd data */ +static DEFINE_SPINLOCK(hcd_data_lock); /* wait queue for synchronous unlinks */ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); -static inline int is_root_hub(struct usb_device *udev) -{ - return (udev->parent == NULL); -} - /*-------------------------------------------------------------------------*/ /* @@ -911,13 +906,14 @@ EXPORT_SYMBOL (usb_calc_bus_time); static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) { unsigned long flags; + int at_root_hub = (urb->dev == hcd->self.root_hub); /* clear all state linking urb to this dev (and hcd) */ - spin_lock_irqsave(&hcd_urb_list_lock, flags); + spin_lock_irqsave (&hcd_data_lock, flags); list_del_init (&urb->urb_list); - spin_unlock_irqrestore(&hcd_urb_list_lock, flags); + spin_unlock_irqrestore (&hcd_data_lock, flags); - if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { + if (hcd->self.uses_dma && !at_root_hub) { if (usb_pipecontrol (urb->pipe) && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) dma_unmap_single (hcd->self.controller, urb->setup_dma, @@ -959,7 +955,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) // FIXME: verify that quiescing hc works right (RH cleans up) - spin_lock_irqsave(&hcd_urb_list_lock, flags); + spin_lock_irqsave (&hcd_data_lock, flags); ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) [usb_pipeendpoint(urb->pipe)]; if (unlikely (!ep)) @@ -976,7 +972,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) status = -ESHUTDOWN; break; } - spin_unlock_irqrestore(&hcd_urb_list_lock, flags); + spin_unlock_irqrestore (&hcd_data_lock, flags); if (status) { INIT_LIST_HEAD (&urb->urb_list); usbmon_urb_submit_error(&hcd->self, urb, status); @@ -990,7 +986,7 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) urb = usb_get_urb (urb); atomic_inc (&urb->use_count); - if (is_root_hub(urb->dev)) { + if (urb->dev == hcd->self.root_hub) { /* NOTE: requirement on hub callers (usbfs and the hub * driver, for now) that URBs' urb->transfer_buffer be * valid and usb_buffer_{sync,unmap}() not be needed, since @@ -1037,6 +1033,18 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) /*-------------------------------------------------------------------------*/ +/* called in any context */ +int usb_hcd_get_frame_number (struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!HC_IS_RUNNING (hcd->state)) + return -ESHUTDOWN; + return hcd->driver->get_frame_number (hcd); +} + +/*-------------------------------------------------------------------------*/ + /* this makes the hcd giveback() the urb more quickly, by kicking it * off hardware queues (which may take a while) and returning it as * soon as practical. we've already set up the urb's return status, @@ -1047,7 +1055,7 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb) { int value; - if (is_root_hub(urb->dev)) + if (urb->dev == hcd->self.root_hub) value = usb_rh_urb_dequeue (hcd, urb); else { @@ -1095,11 +1103,11 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) * that it was submitted. But as a rule it can't know whether or * not it's already been unlinked ... so we respect the reversed * lock sequence needed for the usb_hcd_giveback_urb() code paths - * (urb lock, then hcd_urb_list_lock) in case some other CPU is now + * (urb lock, then hcd_data_lock) in case some other CPU is now * unlinking it. */ spin_lock_irqsave (&urb->lock, flags); - spin_lock(&hcd_urb_list_lock); + spin_lock (&hcd_data_lock); sys = &urb->dev->dev; hcd = bus_to_hcd(urb->dev->bus); @@ -1131,16 +1139,17 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) * finish unlinking the initial failed usb_set_address() * or device descriptor fetch. */ - if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && - !is_root_hub(urb->dev)) { + if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) + && hcd->self.root_hub != urb->dev) { dev_warn (hcd->self.controller, "Unlink after no-IRQ? " - "Controller is probably using the wrong IRQ.\n"); + "Controller is probably using the wrong IRQ." + "\n"); set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); } urb->status = status; - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_unlock_irqrestore (&urb->lock, flags); retval = unlink1 (hcd, urb); @@ -1149,7 +1158,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) return retval; done: - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_unlock_irqrestore (&urb->lock, flags); if (retval != -EIDRM && sys && sys->driver) dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); @@ -1158,35 +1167,6 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) /*-------------------------------------------------------------------------*/ -/** - * usb_hcd_giveback_urb - return URB from HCD to device driver - * @hcd: host controller returning the URB - * @urb: urb being returned to the USB device driver. - * Context: in_interrupt() - * - * This hands the URB from HCD to its USB device driver, using its - * completion function. The HCD has freed all per-urb resources - * (and is done using urb->hcpriv). It also released all HCD locks; - * the device driver won't cause problems if it frees, modifies, - * or resubmits this URB. - */ -void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) -{ - urb_unlink(hcd, urb); - usbmon_urb_complete (&hcd->self, urb); - usb_unanchor_urb(urb); - - /* pass ownership to the completion handler */ - urb->complete (urb); - atomic_dec (&urb->use_count); - if (unlikely (urb->reject)) - wake_up (&usb_kill_urb_queue); - usb_put_urb (urb); -} -EXPORT_SYMBOL (usb_hcd_giveback_urb); - -/*-------------------------------------------------------------------------*/ - /* disables the endpoint: cancels any pending urbs, then synchronizes with * the hcd to make sure all endpoint state is gone from hardware, and then * waits until the endpoint's queue is completely drained. use for @@ -1206,7 +1186,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /* ep is already gone from udev->ep_{in,out}[]; no more submits */ rescan: - spin_lock(&hcd_urb_list_lock); + spin_lock (&hcd_data_lock); list_for_each_entry (urb, &ep->urb_list, urb_list) { int tmp; @@ -1214,7 +1194,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, if (urb->status != -EINPROGRESS) continue; usb_get_urb (urb); - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); spin_lock (&urb->lock); tmp = urb->status; @@ -1243,7 +1223,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /* list contents may have changed */ goto rescan; } - spin_unlock(&hcd_urb_list_lock); + spin_unlock (&hcd_data_lock); local_irq_enable (); /* synchronize with the hardware, so old configuration state @@ -1260,7 +1240,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, * endpoint_disable methods. */ while (!list_empty (&ep->urb_list)) { - spin_lock_irq(&hcd_urb_list_lock); + spin_lock_irq (&hcd_data_lock); /* The list may have changed while we acquired the spinlock */ urb = NULL; @@ -1269,7 +1249,7 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, urb_list); usb_get_urb (urb); } - spin_unlock_irq(&hcd_urb_list_lock); + spin_unlock_irq (&hcd_data_lock); if (urb) { usb_kill_urb (urb); @@ -1280,18 +1260,6 @@ void usb_hcd_endpoint_disable (struct usb_device *udev, /*-------------------------------------------------------------------------*/ -/* called in any context */ -int usb_hcd_get_frame_number (struct usb_device *udev) -{ - struct usb_hcd *hcd = bus_to_hcd(udev->bus); - - if (!HC_IS_RUNNING (hcd->state)) - return -ESHUTDOWN; - return hcd->driver->get_frame_number (hcd); -} - -/*-------------------------------------------------------------------------*/ - #ifdef CONFIG_PM int hcd_bus_suspend(struct usb_device *rhdev) @@ -1426,6 +1394,35 @@ EXPORT_SYMBOL (usb_bus_start_enum); /*-------------------------------------------------------------------------*/ +/** + * usb_hcd_giveback_urb - return URB from HCD to device driver + * @hcd: host controller returning the URB + * @urb: urb being returned to the USB device driver. + * Context: in_interrupt() + * + * This hands the URB from HCD to its USB device driver, using its + * completion function. The HCD has freed all per-urb resources + * (and is done using urb->hcpriv). It also released all HCD locks; + * the device driver won't cause problems if it frees, modifies, + * or resubmits this URB. + */ +void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) +{ + urb_unlink(hcd, urb); + usbmon_urb_complete (&hcd->self, urb); + usb_unanchor_urb(urb); + + /* pass ownership to the completion handler */ + urb->complete (urb); + atomic_dec (&urb->use_count); + if (unlikely (urb->reject)) + wake_up (&usb_kill_urb_queue); + usb_put_urb (urb); +} +EXPORT_SYMBOL (usb_hcd_giveback_urb); + +/*-------------------------------------------------------------------------*/ + /** * usb_hcd_irq - hook IRQs to HCD framework (bus glue) * @irq: the IRQ being raised diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index e341a1da517f..fd74c50b1804 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1335,10 +1335,6 @@ int usb_new_device(struct usb_device *udev) udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); - /* Increment the parent's count of unsuspended children */ - if (udev->parent) - usb_autoresume_device(udev->parent); - /* Register the device. The device driver is responsible * for adding the device files to sysfs and for configuring * the device. @@ -1346,11 +1342,13 @@ int usb_new_device(struct usb_device *udev) err = device_add(&udev->dev); if (err) { dev_err(&udev->dev, "can't device_add, error %d\n", err); - if (udev->parent) - usb_autosuspend_device(udev->parent); goto fail; } + /* Increment the parent's count of unsuspended children */ + if (udev->parent) + usb_autoresume_device(udev->parent); + exit: return err; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 25f63f1096b4..530e854961ce 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -34,14 +34,13 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) { struct completion done; unsigned long expire; - int retval; - int status = urb->status; + int status; init_completion(&done); urb->context = &done; urb->actual_length = 0; - retval = usb_submit_urb(urb, GFP_NOIO); - if (unlikely(retval)) + status = usb_submit_urb(urb, GFP_NOIO); + if (unlikely(status)) goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; @@ -56,15 +55,15 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) urb->transfer_buffer_length); usb_kill_urb(urb); - retval = status == -ENOENT ? -ETIMEDOUT : status; + status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; } else - retval = status; + status = urb->status; out: if (actual_length) *actual_length = urb->actual_length; usb_free_urb(urb); - return retval; + return status; } /*-------------------------------------------------------------------*/ @@ -251,7 +250,6 @@ static void sg_clean (struct usb_sg_request *io) static void sg_complete (struct urb *urb) { struct usb_sg_request *io = urb->context; - int status = urb->status; spin_lock (&io->lock); @@ -267,21 +265,21 @@ static void sg_complete (struct urb *urb) */ if (io->status && (io->status != -ECONNRESET - || status != -ECONNRESET) + || urb->status != -ECONNRESET) && urb->actual_length) { dev_err (io->dev->bus->controller, "dev %s ep%d%s scatterlist error %d/%d\n", io->dev->devpath, usb_pipeendpoint (urb->pipe), usb_pipein (urb->pipe) ? "in" : "out", - status, io->status); + urb->status, io->status); // BUG (); } - if (io->status == 0 && status && status != -ECONNRESET) { - int i, found, retval; + if (io->status == 0 && urb->status && urb->status != -ECONNRESET) { + int i, found, status; - io->status = status; + io->status = urb->status; /* the previous urbs, and this one, completed already. * unlink pending urbs so they won't rx/tx bad data. @@ -292,13 +290,13 @@ static void sg_complete (struct urb *urb) if (!io->urbs [i] || !io->urbs [i]->dev) continue; if (found) { - retval = usb_unlink_urb (io->urbs [i]); - if (retval != -EINPROGRESS && - retval != -ENODEV && - retval != -EBUSY) + status = usb_unlink_urb (io->urbs [i]); + if (status != -EINPROGRESS + && status != -ENODEV + && status != -EBUSY) dev_err (&io->dev->dev, "%s, unlink --> %d\n", - __FUNCTION__, retval); + __FUNCTION__, status); } else if (urb == io->urbs [i]) found = 1; } diff --git a/trunk/drivers/usb/core/sysfs.c b/trunk/drivers/usb/core/sysfs.c index 2ab222be8fd1..d47ae89154a7 100644 --- a/trunk/drivers/usb/core/sysfs.c +++ b/trunk/drivers/usb/core/sysfs.c @@ -441,54 +441,6 @@ static struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; -/* Binary descriptors */ - -static ssize_t -read_descriptors(struct kobject *kobj, struct bin_attribute *attr, - char *buf, loff_t off, size_t count) -{ - struct usb_device *udev = to_usb_device( - container_of(kobj, struct device, kobj)); - size_t nleft = count; - size_t srclen, n; - - usb_lock_device(udev); - - /* The binary attribute begins with the device descriptor */ - srclen = sizeof(struct usb_device_descriptor); - if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + (char *) &udev->descriptor, n); - nleft -= n; - buf += n; - off = 0; - } else { - off -= srclen; - } - - /* Then follows the raw descriptor entry for the current - * configuration (config plus subsidiary descriptors). - */ - if (udev->actconfig) { - int cfgno = udev->actconfig - udev->config; - - srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); - if (off < srclen) { - n = min_t(size_t, nleft, srclen - off); - memcpy(buf, off + udev->rawdescriptors[cfgno], n); - nleft -= n; - } - } - usb_unlock_device(udev); - return count - nleft; -} - -static struct bin_attribute dev_bin_attr_descriptors = { - .attr = {.name = "descriptors", .mode = 0444}, - .read = read_descriptors, - .size = 18 + 65535, /* dev descr + max-size raw descriptor */ -}; - int usb_create_sysfs_dev_files(struct usb_device *udev) { struct device *dev = &udev->dev; @@ -498,10 +450,6 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) if (retval) return retval; - retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); - if (retval) - goto error; - retval = add_persist_attributes(dev); if (retval) goto error; @@ -544,7 +492,6 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) device_remove_file(dev, &dev_attr_serial); remove_power_attributes(dev); remove_persist_attributes(dev); - device_remove_bin_file(dev, &dev_bin_attr_descriptors); sysfs_remove_group(&dev->kobj, &dev_attr_grp); } diff --git a/trunk/drivers/usb/core/urb.c b/trunk/drivers/usb/core/urb.c index be630228461c..52ec44b828f3 100644 --- a/trunk/drivers/usb/core/urb.c +++ b/trunk/drivers/usb/core/urb.c @@ -440,57 +440,55 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * @urb: pointer to urb describing a previously submitted request, * may be NULL * - * This routine cancels an in-progress request. URBs complete only once - * per submission, and may be canceled only once per submission. - * Successful cancellation means termination of @urb will be expedited - * and the completion handler will be called with a status code - * indicating that the request has been canceled (rather than any other - * code). - * - * This request is always asynchronous. Success is indicated by - * returning -EINPROGRESS, at which time the URB will probably not yet - * have been given back to the device driver. When it is eventually - * called, the completion function will see @urb->status == -ECONNRESET. - * Failure is indicated by usb_unlink_urb() returning any other value. - * Unlinking will fail when @urb is not currently "linked" (i.e., it was - * never submitted, or it was unlinked before, or the hardware is already - * finished with it), even if the completion handler has not yet run. + * This routine cancels an in-progress request. URBs complete only + * once per submission, and may be canceled only once per submission. + * Successful cancellation means the requests's completion handler will + * be called with a status code indicating that the request has been + * canceled (rather than any other code) and will quickly be removed + * from host controller data structures. + * + * This request is always asynchronous. + * Success is indicated by returning -EINPROGRESS, + * at which time the URB will normally have been unlinked but not yet + * given back to the device driver. When it is called, the completion + * function will see urb->status == -ECONNRESET. Failure is indicated + * by any other return value. Unlinking will fail when the URB is not + * currently "linked" (i.e., it was never submitted, or it was unlinked + * before, or the hardware is already finished with it), even if the + * completion handler has not yet run. * * Unlinking and Endpoint Queues: * - * [The behaviors and guarantees described below do not apply to virtual - * root hubs but only to endpoint queues for physical USB devices.] - * * Host Controller Drivers (HCDs) place all the URBs for a particular * endpoint in a queue. Normally the queue advances as the controller * hardware processes each request. But when an URB terminates with an - * error its queue generally stops (see below), at least until that URB's - * completion routine returns. It is guaranteed that a stopped queue - * will not restart until all its unlinked URBs have been fully retired, - * with their completion routines run, even if that's not until some time - * after the original completion handler returns. The same behavior and - * guarantee apply when an URB terminates because it was unlinked. - * - * Bulk and interrupt endpoint queues are guaranteed to stop whenever an - * URB terminates with any sort of error, including -ECONNRESET, -ENOENT, - * and -EREMOTEIO. Control endpoint queues behave the same way except - * that they are not guaranteed to stop for -EREMOTEIO errors. Queues - * for isochronous endpoints are treated differently, because they must - * advance at fixed rates. Such queues do not stop when an URB - * encounters an error or is unlinked. An unlinked isochronous URB may - * leave a gap in the stream of packets; it is undefined whether such - * gaps can be filled in. - * - * Note that early termination of an URB because a short packet was - * received will generate a -EREMOTEIO error if and only if the - * URB_SHORT_NOT_OK flag is set. By setting this flag, USB device - * drivers can build deep queues for large or complex bulk transfers - * and clean them up reliably after any sort of aborted transfer by - * unlinking all pending URBs at the first fault. - * - * When a control URB terminates with an error other than -EREMOTEIO, it - * is quite likely that the status stage of the transfer will not take - * place. + * error its queue stops, at least until that URB's completion routine + * returns. It is guaranteed that the queue will not restart until all + * its unlinked URBs have been fully retired, with their completion + * routines run, even if that's not until some time after the original + * completion handler returns. Normally the same behavior and guarantees + * apply when an URB terminates because it was unlinked; however if an + * URB is unlinked before the hardware has started to execute it, then + * its queue is not guaranteed to stop until all the preceding URBs have + * completed. + * + * This means that USB device drivers can safely build deep queues for + * large or complex transfers, and clean them up reliably after any sort + * of aborted transfer by unlinking all pending URBs at the first fault. + * + * Note that an URB terminating early because a short packet was received + * will count as an error if and only if the URB_SHORT_NOT_OK flag is set. + * Also, that all unlinks performed in any URB completion handler must + * be asynchronous. + * + * Queues for isochronous endpoints are treated differently, because they + * advance at fixed rates. Such queues do not stop when an URB is unlinked. + * An unlinked URB may leave a gap in the stream of packets. It is undefined + * whether such gaps can be filled in. + * + * When a control URB terminates with an error, it is likely that the + * status stage of the transfer will not take place, even if it is merely + * a soft error resulting from a short-packet with URB_SHORT_NOT_OK set. */ int usb_unlink_urb(struct urb *urb) { diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 767aed5b4bea..45e01e289455 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -82,27 +82,6 @@ choice Many controller drivers are platform-specific; these often need board-specific hooks. -config USB_GADGET_AMD5536UDC - boolean "AMD5536 UDC" - depends on PCI - select USB_GADGET_DUALSPEED - help - The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. - It is a USB Highspeed DMA capable USB device controller. Beside ep0 - it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). - The UDC port supports OTG operation, and may be used as a host port - if it's not being used to implement peripheral or OTG roles. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "amd5536udc" and force all - gadget drivers to also be dynamically linked. - -config USB_AMD5536UDC - tristate - depends on USB_GADGET_AMD5536UDC - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" depends on MPC834x || PPC_MPC831x @@ -177,24 +156,6 @@ config USB_PXA2XX_SMALL default y if USB_ETH default y if USB_G_SERIAL -config USB_GADGET_M66592 - boolean "Renesas M66592 USB Peripheral Controller" - select USB_GADGET_DUALSPEED - help - M66592 is a discrete USB peripheral controller chip that - supports both full and high speed USB 2.0 data transfers. - It has seven configurable endpoints, and endpoint zero. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "m66592_udc" and force all - gadget drivers to also be dynamically linked. - -config USB_M66592 - tristate - depends on USB_GADGET_M66592 - default USB_GADGET - select USB_GADGET_SELECTED - config USB_GADGET_GOKU boolean "Toshiba TC86C001 'Goku-S'" depends on PCI @@ -300,6 +261,24 @@ config USB_AT91 depends on USB_GADGET_AT91 default USB_GADGET +config USB_GADGET_M66592 + boolean "M66592 driver" + select USB_GADGET_DUALSPEED + help + M66592 is a USB 2.0 peripheral controller. + + It has seven configurable endpoints, and endpoint zero. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "m66592_udc" and force all + gadget drivers to also be dynamically linked. + +config USB_M66592 + tristate + depends on USB_GADGET_M66592 + default USB_GADGET + select USB_GADGET_SELECTED + config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL diff --git a/trunk/drivers/usb/gadget/Makefile b/trunk/drivers/usb/gadget/Makefile index 1bc0f03550ce..8ae76f738635 100644 --- a/trunk/drivers/usb/gadget/Makefile +++ b/trunk/drivers/usb/gadget/Makefile @@ -7,7 +7,6 @@ endif obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o obj-$(CONFIG_USB_NET2280) += net2280.o -obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o obj-$(CONFIG_USB_GOKU) += goku_udc.o obj-$(CONFIG_USB_OMAP) += omap_udc.o diff --git a/trunk/drivers/usb/gadget/amd5536udc.c b/trunk/drivers/usb/gadget/amd5536udc.c deleted file mode 100644 index 714156ca8fe4..000000000000 --- a/trunk/drivers/usb/gadget/amd5536udc.c +++ /dev/null @@ -1,3454 +0,0 @@ -/* - * amd5536.c -- AMD 5536 UDC high/full speed USB device controller - * - * Copyright (C) 2005-2007 AMD (http://www.amd.com) - * Author: Thomas Dahlmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536. - * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it - * provides 4 IN and 4 OUT endpoints (bulk or interrupt type). - * - * Make sure that UDC is assigned to port 4 by BIOS settings (port can also - * be used as host port) and UOC bits PAD_EN and APU are set (should be done - * by BIOS init). - * - * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not - * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0") - * can be used with gadget ether. - */ - -/* debug control */ -/* #define UDC_VERBOSE */ - -/* Driver strings */ -#define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" -#define UDC_DRIVER_VERSION_STRING "01.00.0206 - $Revision: #3 $" - -/* system */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* gadget stack */ -#include -#include - -/* udc specific */ -#include "amd5536udc.h" - - -static void udc_tasklet_disconnect(unsigned long); -static void empty_req_queue(struct udc_ep *); -static int udc_probe(struct udc *dev); -static void udc_basic_init(struct udc *dev); -static void udc_setup_endpoints(struct udc *dev); -static void udc_soft_reset(struct udc *dev); -static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); -static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); -static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags); -static int udc_remote_wakeup(struct udc *dev); -static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void udc_pci_remove(struct pci_dev *pdev); - -/* description */ -static const char mod_desc[] = UDC_MOD_DESCRIPTION; -static const char name[] = "amd5536udc"; - -/* structure to hold endpoint function pointers */ -static const struct usb_ep_ops udc_ep_ops; - -/* received setup data */ -static union udc_setup_data setup_data; - -/* pointer to device object */ -static struct udc *udc; - -/* irq spin lock for soft reset */ -static DEFINE_SPINLOCK(udc_irq_spinlock); -/* stall spin lock */ -static DEFINE_SPINLOCK(udc_stall_spinlock); - -/* -* slave mode: pending bytes in rx fifo after nyet, -* used if EPIN irq came but no req was available -*/ -static unsigned int udc_rxfifo_pending; - -/* count soft resets after suspend to avoid loop */ -static int soft_reset_occured; -static int soft_reset_after_usbreset_occured; - -/* timer */ -static struct timer_list udc_timer; -static int stop_timer; - -/* set_rde -- Is used to control enabling of RX DMA. Problem is - * that UDC has only one bit (RDE) to enable/disable RX DMA for - * all OUT endpoints. So we have to handle race conditions like - * when OUT data reaches the fifo but no request was queued yet. - * This cannot be solved by letting the RX DMA disabled until a - * request gets queued because there may be other OUT packets - * in the FIFO (important for not blocking control traffic). - * The value of set_rde controls the correspondig timer. - * - * set_rde -1 == not used, means it is alloed to be set to 0 or 1 - * set_rde 0 == do not touch RDE, do no start the RDE timer - * set_rde 1 == timer function will look whether FIFO has data - * set_rde 2 == set by timer function to enable RX DMA on next call - */ -static int set_rde = -1; - -static DECLARE_COMPLETION(on_exit); -static struct timer_list udc_pollstall_timer; -static int stop_pollstall_timer; -static DECLARE_COMPLETION(on_pollstall_exit); - -/* tasklet for usb disconnect */ -static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, - (unsigned long) &udc); - - -/* endpoint names used for print */ -static const char ep0_string[] = "ep0in"; -static const char *ep_string[] = { - ep0_string, - "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", - "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", - "ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk", - "ep15in-bulk", "ep0out", "ep1out-bulk", "ep2out-bulk", "ep3out-bulk", - "ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk", - "ep8out-bulk", "ep9out-bulk", "ep10out-bulk", "ep11out-bulk", - "ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk" -}; - -/* DMA usage flag */ -static int use_dma = 1; -/* packet per buffer dma */ -static int use_dma_ppb = 1; -/* with per descr. update */ -static int use_dma_ppb_du; -/* buffer fill mode */ -static int use_dma_bufferfill_mode; -/* full speed only mode */ -static int use_fullspeed; -/* tx buffer size for high speed */ -static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE; - -/* module parameters */ -module_param(use_dma, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma, "true for DMA"); -module_param(use_dma_ppb, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma_ppb, "true for DMA in packet per buffer mode"); -module_param(use_dma_ppb_du, bool, S_IRUGO); -MODULE_PARM_DESC(use_dma_ppb_du, - "true for DMA in packet per buffer mode with descriptor update"); -module_param(use_fullspeed, bool, S_IRUGO); -MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only"); - -/*---------------------------------------------------------------------------*/ -/* Prints UDC device registers and endpoint irq registers */ -static void print_regs(struct udc *dev) -{ - DBG(dev, "------- Device registers -------\n"); - DBG(dev, "dev config = %08x\n", readl(&dev->regs->cfg)); - DBG(dev, "dev control = %08x\n", readl(&dev->regs->ctl)); - DBG(dev, "dev status = %08x\n", readl(&dev->regs->sts)); - DBG(dev, "\n"); - DBG(dev, "dev int's = %08x\n", readl(&dev->regs->irqsts)); - DBG(dev, "dev intmask = %08x\n", readl(&dev->regs->irqmsk)); - DBG(dev, "\n"); - DBG(dev, "dev ep int's = %08x\n", readl(&dev->regs->ep_irqsts)); - DBG(dev, "dev ep intmask = %08x\n", readl(&dev->regs->ep_irqmsk)); - DBG(dev, "\n"); - DBG(dev, "USE DMA = %d\n", use_dma); - if (use_dma && use_dma_ppb && !use_dma_ppb_du) { - DBG(dev, "DMA mode = PPBNDU (packet per buffer " - "WITHOUT desc. update)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU"); - } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) { - DBG(dev, "DMA mode = PPBDU (packet per buffer " - "WITH desc. update)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU"); - } - if (use_dma && use_dma_bufferfill_mode) { - DBG(dev, "DMA mode = BF (buffer fill mode)\n"); - dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); - } - if (!use_dma) { - dev_info(&dev->pdev->dev, "FIFO mode\n"); - } - DBG(dev, "-------------------------------------------------------\n"); -} - -/* Masks unused interrupts */ -static int udc_mask_unused_interrupts(struct udc *dev) -{ - u32 tmp; - - /* mask all dev interrupts */ - tmp = AMD_BIT(UDC_DEVINT_SVC) | - AMD_BIT(UDC_DEVINT_ENUM) | - AMD_BIT(UDC_DEVINT_US) | - AMD_BIT(UDC_DEVINT_UR) | - AMD_BIT(UDC_DEVINT_ES) | - AMD_BIT(UDC_DEVINT_SI) | - AMD_BIT(UDC_DEVINT_SOF)| - AMD_BIT(UDC_DEVINT_SC); - writel(tmp, &dev->regs->irqmsk); - - /* mask all ep interrupts */ - writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk); - - return 0; -} - -/* Enables endpoint 0 interrupts */ -static int udc_enable_ep0_interrupts(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "udc_enable_ep0_interrupts()\n"); - - /* read irq mask */ - tmp = readl(&dev->regs->ep_irqmsk); - /* enable ep0 irq's */ - tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0) - & AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0); - writel(tmp, &dev->regs->ep_irqmsk); - - return 0; -} - -/* Enables device interrupts for SET_INTF and SET_CONFIG */ -static int udc_enable_dev_setup_interrupts(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "enable device interrupts for setup data\n"); - - /* read irq mask */ - tmp = readl(&dev->regs->irqmsk); - - /* enable SET_INTERFACE, SET_CONFIG and other needed irq's */ - tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI) - & AMD_UNMASK_BIT(UDC_DEVINT_SC) - & AMD_UNMASK_BIT(UDC_DEVINT_UR) - & AMD_UNMASK_BIT(UDC_DEVINT_SVC) - & AMD_UNMASK_BIT(UDC_DEVINT_ENUM); - writel(tmp, &dev->regs->irqmsk); - - return 0; -} - -/* Calculates fifo start of endpoint based on preceeding endpoints */ -static int udc_set_txfifo_addr(struct udc_ep *ep) -{ - struct udc *dev; - u32 tmp; - int i; - - if (!ep || !(ep->in)) - return -EINVAL; - - dev = ep->dev; - ep->txfifo = dev->txfifo; - - /* traverse ep's */ - for (i = 0; i < ep->num; i++) { - if (dev->ep[i].regs) { - /* read fifo size */ - tmp = readl(&dev->ep[i].regs->bufin_framenum); - tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE); - ep->txfifo += tmp; - } - } - return 0; -} - -/* CNAK pending field: bit0 = ep0in, bit16 = ep0out */ -static u32 cnak_pending; - -static void UDC_QUEUE_CNAK(struct udc_ep *ep, unsigned num) -{ - if (readl(&ep->regs->ctl) & AMD_BIT(UDC_EPCTL_NAK)) { - DBG(ep->dev, "NAK could not be cleared for ep%d\n", num); - cnak_pending |= 1 << (num); - ep->naking = 1; - } else - cnak_pending = cnak_pending & (~(1 << (num))); -} - - -/* Enables endpoint, is called by gadget driver */ -static int -udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc) -{ - struct udc_ep *ep; - struct udc *dev; - u32 tmp; - unsigned long iflags; - u8 udc_csr_epix; - - if (!usbep - || usbep->name == ep0_string - || !desc - || desc->bDescriptorType != USB_DT_ENDPOINT) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - dev = ep->dev; - - DBG(dev, "udc_ep_enable() ep %d\n", ep->num); - - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - spin_lock_irqsave(&dev->lock, iflags); - ep->desc = desc; - - ep->halted = 0; - - /* set traffic type */ - tmp = readl(&dev->ep[ep->num].regs->ctl); - tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET); - writel(tmp, &dev->ep[ep->num].regs->ctl); - - /* set max packet size */ - tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_EP_MAX_PKT_SIZE); - ep->ep.maxpacket = desc->wMaxPacketSize; - writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt); - - /* IN ep */ - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - /* set buffer size (tx fifo entries) */ - tmp = readl(&dev->ep[ep->num].regs->bufin_framenum); - /* double buffering: fifo size = 2 x max packet size */ - tmp = AMD_ADDBITS( - tmp, - desc->wMaxPacketSize * UDC_EPIN_BUFF_SIZE_MULT - / UDC_DWORD_BYTES, - UDC_EPIN_BUFF_SIZE); - writel(tmp, &dev->ep[ep->num].regs->bufin_framenum); - - /* calc. tx fifo base addr */ - udc_set_txfifo_addr(ep); - - /* flush fifo */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &ep->regs->ctl); - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - - /* set max packet size UDC CSR */ - tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, - UDC_CSR_NE_MAX_PKT); - writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); - - if (use_dma && !ep->in) { - /* alloc and init BNA dummy request */ - ep->bna_dummy_req = udc_alloc_bna_dummy(ep); - ep->bna_occurred = 0; - } - - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_enabled = 1; - } - - /* set ep values */ - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* max packet */ - tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT); - /* ep number */ - tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM); - /* ep direction */ - tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR); - /* ep type */ - tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE); - /* ep config */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG); - /* ep interface */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF); - /* ep alt */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* enable ep irq */ - tmp = readl(&dev->regs->ep_irqmsk); - tmp &= AMD_UNMASK_BIT(ep->num); - writel(tmp, &dev->regs->ep_irqmsk); - - /* - * clear NAK by writing CNAK - * avoid BNA for OUT DMA, don't clear NAK until DMA desc. written - */ - if (!use_dma || ep->in) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - tmp = desc->bEndpointAddress; - DBG(dev, "%s enabled\n", usbep->name); - - spin_unlock_irqrestore(&dev->lock, iflags); - return 0; -} - -/* Resets endpoint */ -static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep) -{ - u32 tmp; - - VDBG(ep->dev, "ep-%d reset\n", ep->num); - ep->desc = NULL; - ep->ep.ops = &udc_ep_ops; - INIT_LIST_HEAD(&ep->queue); - - ep->ep.maxpacket = (u16) ~0; - /* set NAK */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_SNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 1; - - /* disable interrupt */ - tmp = readl(®s->ep_irqmsk); - tmp |= AMD_BIT(ep->num); - writel(tmp, ®s->ep_irqmsk); - - if (ep->in) { - /* unset P and IN bit of potential former DMA */ - tmp = readl(&ep->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P); - writel(tmp, &ep->regs->ctl); - - tmp = readl(&ep->regs->sts); - tmp |= AMD_BIT(UDC_EPSTS_IN); - writel(tmp, &ep->regs->sts); - - /* flush the fifo */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &ep->regs->ctl); - - } - /* reset desc pointer */ - writel(0, &ep->regs->desptr); -} - -/* Disables endpoint, is called by gadget driver */ -static int udc_ep_disable(struct usb_ep *usbep) -{ - struct udc_ep *ep = NULL; - unsigned long iflags; - - if (!usbep) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - if (usbep->name == ep0_string || !ep->desc) - return -EINVAL; - - DBG(ep->dev, "Disable ep-%d\n", ep->num); - - spin_lock_irqsave(&ep->dev->lock, iflags); - udc_free_request(&ep->ep, &ep->bna_dummy_req->req); - empty_req_queue(ep); - ep_init(ep->dev->regs, ep); - spin_unlock_irqrestore(&ep->dev->lock, iflags); - - return 0; -} - -/* Allocates request packet, called by gadget driver */ -static struct usb_request * -udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) -{ - struct udc_request *req; - struct udc_data_dma *dma_desc; - struct udc_ep *ep; - - if (!usbep) - return NULL; - - ep = container_of(usbep, struct udc_ep, ep); - - VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num); - req = kzalloc(sizeof(struct udc_request), gfp); - if (!req) - return NULL; - - req->req.dma = DMA_DONT_USE; - INIT_LIST_HEAD(&req->queue); - - if (ep->dma) { - /* ep0 in requests are allocated from data pool here */ - dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp, - &req->td_phys); - if (!dma_desc) { - kfree(req); - return NULL; - } - - VDBG(ep->dev, "udc_alloc_req: req = %p dma_desc = %p, " - "td_phys = %lx\n", - req, dma_desc, - (unsigned long)req->td_phys); - /* prevent from using desc. - set HOST BUSY */ - dma_desc->status = AMD_ADDBITS(dma_desc->status, - UDC_DMA_STP_STS_BS_HOST_BUSY, - UDC_DMA_STP_STS_BS); - dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); - req->td_data = dma_desc; - req->td_data_last = NULL; - req->chain_len = 1; - } - - return &req->req; -} - -/* Frees request packet, called by gadget driver */ -static void -udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) -{ - struct udc_ep *ep; - struct udc_request *req; - - if (!usbep || !usbreq) - return; - - ep = container_of(usbep, struct udc_ep, ep); - req = container_of(usbreq, struct udc_request, req); - VDBG(ep->dev, "free_req req=%p\n", req); - BUG_ON(!list_empty(&req->queue)); - if (req->td_data) { - VDBG(ep->dev, "req->td_data=%p\n", req->td_data); - - /* free dma chain if created */ - if (req->chain_len > 1) { - udc_free_dma_chain(ep->dev, req); - } - - pci_pool_free(ep->dev->data_requests, req->td_data, - req->td_phys); - } - kfree(req); -} - -/* Init BNA dummy descriptor for HOST BUSY and pointing to itself */ -static void udc_init_bna_dummy(struct udc_request *req) -{ - if (req) { - /* set last bit */ - req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* set next pointer to itself */ - req->td_data->next = req->td_phys; - /* set HOST BUSY */ - req->td_data->status - = AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_DMA_DONE, - UDC_DMA_STP_STS_BS); -#ifdef UDC_VERBOSE - pr_debug("bna desc = %p, sts = %08x\n", - req->td_data, req->td_data->status); -#endif - } -} - -/* Allocate BNA dummy descriptor */ -static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep) -{ - struct udc_request *req = NULL; - struct usb_request *_req = NULL; - - /* alloc the dummy request */ - _req = udc_alloc_request(&ep->ep, GFP_ATOMIC); - if (_req) { - req = container_of(_req, struct udc_request, req); - ep->bna_dummy_req = req; - udc_init_bna_dummy(req); - } - return req; -} - -/* Write data to TX fifo for IN packets */ -static void -udc_txfifo_write(struct udc_ep *ep, struct usb_request *req) -{ - u8 *req_buf; - u32 *buf; - int i, j; - unsigned bytes = 0; - unsigned remaining = 0; - - if (!req || !ep) - return; - - req_buf = req->buf + req->actual; - prefetch(req_buf); - remaining = req->length - req->actual; - - buf = (u32 *) req_buf; - - bytes = ep->ep.maxpacket; - if (bytes > remaining) - bytes = remaining; - - /* dwords first */ - for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { - writel(*(buf + i), ep->txfifo); - } - - /* remaining bytes must be written by byte access */ - for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { - writeb((u8)(*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)), - ep->txfifo); - } - - /* dummy write confirm */ - writel(0, &ep->regs->confirm); -} - -/* Read dwords from RX fifo for OUT transfers */ -static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords) -{ - int i; - - VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); - - for (i = 0; i < dwords; i++) { - *(buf + i) = readl(dev->rxfifo); - } - return 0; -} - -/* Read bytes from RX fifo for OUT transfers */ -static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes) -{ - int i, j; - u32 tmp; - - VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); - - /* dwords first */ - for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { - *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); - } - - /* remaining bytes must be read by byte access */ - if (bytes % UDC_DWORD_BYTES) { - tmp = readl(dev->rxfifo); - for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { - *(buf + (i<<2) + j) = (u8)(tmp & UDC_BYTE_MASK); - tmp = tmp >> UDC_BITS_PER_BYTE; - } - } - - return 0; -} - -/* Read data from RX fifo for OUT transfers */ -static int -udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) -{ - u8 *buf; - unsigned buf_space; - unsigned bytes = 0; - unsigned finished = 0; - - /* received number bytes */ - bytes = readl(&ep->regs->sts); - bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE); - - buf_space = req->req.length - req->req.actual; - buf = req->req.buf + req->req.actual; - if (bytes > buf_space) { - if ((buf_space % ep->ep.maxpacket) != 0) { - DBG(ep->dev, - "%s: rx %d bytes, rx-buf space = %d bytesn\n", - ep->ep.name, bytes, buf_space); - req->req.status = -EOVERFLOW; - } - bytes = buf_space; - } - req->req.actual += bytes; - - /* last packet ? */ - if (((bytes % ep->ep.maxpacket) != 0) || (!bytes) - || ((req->req.actual == req->req.length) && !req->req.zero)) - finished = 1; - - /* read rx fifo bytes */ - VDBG(ep->dev, "ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes); - udc_rxfifo_read_bytes(ep->dev, buf, bytes); - - return finished; -} - -/* create/re-init a DMA descriptor or a DMA descriptor chain */ -static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) -{ - int retval = 0; - u32 tmp; - - VDBG(ep->dev, "prep_dma\n"); - VDBG(ep->dev, "prep_dma ep%d req->td_data=%p\n", - ep->num, req->td_data); - - /* set buffer pointer */ - req->td_data->bufptr = req->req.dma; - - /* set last bit */ - req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); - - /* build/re-init dma chain if maxpkt scatter mode, not for EP0 */ - if (use_dma_ppb) { - - retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); - if (retval != 0) { - if (retval == -ENOMEM) - DBG(ep->dev, "Out of DMA memory\n"); - return retval; - } - if (ep->in) { - if (req->req.length == ep->ep.maxpacket) { - /* write tx bytes */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - - } - } - - } - - if (ep->in) { - VDBG(ep->dev, "IN: use_dma_ppb=%d req->req.len=%d " - "maxpacket=%d ep%d\n", - use_dma_ppb, req->req.length, - ep->ep.maxpacket, ep->num); - /* - * if bytes < max packet then tx bytes must - * be written in packet per buffer mode - */ - if (!use_dma_ppb || req->req.length < ep->ep.maxpacket - || ep->num == UDC_EP0OUT_IX - || ep->num == UDC_EP0IN_IX) { - /* write tx bytes */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - req->req.length, - UDC_DMA_IN_STS_TXBYTES); - /* reset frame num */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - 0, - UDC_DMA_IN_STS_FRAMENUM); - } - /* set HOST BUSY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_BUSY, - UDC_DMA_STP_STS_BS); - } else { - VDBG(ep->dev, "OUT set host ready\n"); - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_READY, - UDC_DMA_STP_STS_BS); - - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - - } - - return retval; -} - -/* Completes request packet ... caller MUST hold lock */ -static void -complete_req(struct udc_ep *ep, struct udc_request *req, int sts) -__releases(ep->dev->lock) -__acquires(ep->dev->lock) -{ - struct udc *dev; - unsigned halted; - - VDBG(ep->dev, "complete_req(): ep%d\n", ep->num); - - dev = ep->dev; - /* unmap DMA */ - if (req->dma_mapping) { - if (ep->in) - pci_unmap_single(dev->pdev, - req->req.dma, - req->req.length, - PCI_DMA_TODEVICE); - else - pci_unmap_single(dev->pdev, - req->req.dma, - req->req.length, - PCI_DMA_FROMDEVICE); - req->dma_mapping = 0; - req->req.dma = DMA_DONT_USE; - } - - halted = ep->halted; - ep->halted = 1; - - /* set new status if pending */ - if (req->req.status == -EINPROGRESS) - req->req.status = sts; - - /* remove from ep queue */ - list_del_init(&req->queue); - - VDBG(ep->dev, "req %p => complete %d bytes at %s with sts %d\n", - &req->req, req->req.length, ep->ep.name, sts); - - spin_unlock(&dev->lock); - req->req.complete(&ep->ep, &req->req); - spin_lock(&dev->lock); - ep->halted = halted; -} - -/* frees pci pool descriptors of a DMA chain */ -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) -{ - - int ret_val = 0; - struct udc_data_dma *td; - struct udc_data_dma *td_last = NULL; - unsigned int i; - - DBG(dev, "free chain req = %p\n", req); - - /* do not free first desc., will be done by free for request */ - td_last = req->td_data; - td = phys_to_virt(td_last->next); - - for (i = 1; i < req->chain_len; i++) { - - pci_pool_free(dev->data_requests, td, - (dma_addr_t) td_last->next); - td_last = td; - td = phys_to_virt(td_last->next); - } - - return ret_val; -} - -/* Iterates to the end of a DMA chain and returns last descriptor */ -static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) -{ - struct udc_data_dma *td; - - td = req->td_data; - while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { - td = phys_to_virt(td->next); - } - - return td; - -} - -/* Iterates to the end of a DMA chain and counts bytes received */ -static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) -{ - struct udc_data_dma *td; - u32 count; - - td = req->td_data; - /* received number bytes */ - count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES); - - while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { - td = phys_to_virt(td->next); - /* received number bytes */ - if (td) { - count += AMD_GETBITS(td->status, - UDC_DMA_OUT_STS_RXBYTES); - } - } - - return count; - -} - -/* Creates or re-inits a DMA chain */ -static int udc_create_dma_chain( - struct udc_ep *ep, - struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags -) -{ - unsigned long bytes = req->req.length; - unsigned int i; - dma_addr_t dma_addr; - struct udc_data_dma *td = NULL; - struct udc_data_dma *last = NULL; - unsigned long txbytes; - unsigned create_new_chain = 0; - unsigned len; - - VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", - bytes, buf_len); - dma_addr = DMA_DONT_USE; - - /* unset L bit in first desc for OUT */ - if (!ep->in) { - req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); - } - - /* alloc only new desc's if not already available */ - len = req->req.length / ep->ep.maxpacket; - if (req->req.length % ep->ep.maxpacket) { - len++; - } - - if (len > req->chain_len) { - /* shorter chain already allocated before */ - if (req->chain_len > 1) { - udc_free_dma_chain(ep->dev, req); - } - req->chain_len = len; - create_new_chain = 1; - } - - td = req->td_data; - /* gen. required number of descriptors and buffers */ - for (i = buf_len; i < bytes; i += buf_len) { - /* create or determine next desc. */ - if (create_new_chain) { - - td = pci_pool_alloc(ep->dev->data_requests, - gfp_flags, &dma_addr); - if (!td) - return -ENOMEM; - - td->status = 0; - } else if (i == buf_len) { - /* first td */ - td = (struct udc_data_dma *) phys_to_virt( - req->td_data->next); - td->status = 0; - } else { - td = (struct udc_data_dma *) phys_to_virt(last->next); - td->status = 0; - } - - - if (td) - td->bufptr = req->req.dma + i; /* assign buffer */ - else - break; - - /* short packet ? */ - if ((bytes - i) >= buf_len) { - txbytes = buf_len; - } else { - /* short packet */ - txbytes = bytes - i; - } - - /* link td and assign tx bytes */ - if (i == buf_len) { - if (create_new_chain) { - req->td_data->next = dma_addr; - } else { - /* req->td_data->next = virt_to_phys(td); */ - } - /* write tx bytes */ - if (ep->in) { - /* first desc */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - /* second desc */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } else { - if (create_new_chain) { - last->next = dma_addr; - } else { - /* last->next = virt_to_phys(td); */ - } - if (ep->in) { - /* write tx bytes */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } - last = td; - } - /* set last bit */ - if (td) { - td->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* last desc. points to itself */ - req->td_data_last = td; - } - - return 0; -} - -/* Enabling RX DMA */ -static void udc_set_rde(struct udc *dev) -{ - u32 tmp; - - VDBG(dev, "udc_set_rde()\n"); - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* set RDE */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RDE); - writel(tmp, &dev->regs->ctl); -} - -/* Queues a request packet, called by gadget driver */ -static int -udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) -{ - int retval = 0; - u8 open_rxfifo = 0; - unsigned long iflags; - struct udc_ep *ep; - struct udc_request *req; - struct udc *dev; - u32 tmp; - - /* check the inputs */ - req = container_of(usbreq, struct udc_request, req); - - if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf - || !list_empty(&req->queue)) - return -EINVAL; - - ep = container_of(usbep, struct udc_ep, ep); - if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) - return -EINVAL; - - VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in); - dev = ep->dev; - - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - /* map dma (usually done before) */ - if (ep->dma && usbreq->length != 0 - && (usbreq->dma == DMA_DONT_USE || usbreq->dma == 0)) { - VDBG(dev, "DMA map req %p\n", req); - if (ep->in) - usbreq->dma = pci_map_single(dev->pdev, - usbreq->buf, - usbreq->length, - PCI_DMA_TODEVICE); - else - usbreq->dma = pci_map_single(dev->pdev, - usbreq->buf, - usbreq->length, - PCI_DMA_FROMDEVICE); - req->dma_mapping = 1; - } - - VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", - usbep->name, usbreq, usbreq->length, - req->td_data, usbreq->buf); - - spin_lock_irqsave(&dev->lock, iflags); - usbreq->actual = 0; - usbreq->status = -EINPROGRESS; - req->dma_done = 0; - - /* on empty queue just do first transfer */ - if (list_empty(&ep->queue)) { - /* zlp */ - if (usbreq->length == 0) { - /* IN zlp's are handled by hardware */ - complete_req(ep, req, 0); - VDBG(dev, "%s: zlp\n", ep->ep.name); - /* - * if set_config or set_intf is waiting for ack by zlp - * then set CSR_DONE - */ - if (dev->set_cfg_not_acked) { - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_CSR_DONE); - writel(tmp, &dev->regs->ctl); - dev->set_cfg_not_acked = 0; - } - /* setup command is ACK'ed now by zlp */ - if (dev->waiting_zlp_ack_ep0in) { - /* clear NAK by writing CNAK in EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], - UDC_EP0IN_IX); - dev->waiting_zlp_ack_ep0in = 0; - } - goto finished; - } - if (ep->dma) { - retval = prep_dma(ep, req, gfp); - if (retval != 0) - goto finished; - /* write desc pointer to enable DMA */ - if (ep->in) { - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - UDC_DMA_IN_STS_BS_HOST_READY, - UDC_DMA_IN_STS_BS); - } - - /* disabled rx dma while descriptor update */ - if (!ep->in) { - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* clear RDE */ - tmp = readl(&dev->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); - writel(tmp, &dev->regs->ctl); - open_rxfifo = 1; - - /* - * if BNA occurred then let BNA dummy desc. - * point to current desc. - */ - if (ep->bna_occurred) { - VDBG(dev, "copy to BNA dummy desc.\n"); - memcpy(ep->bna_dummy_req->td_data, - req->td_data, - sizeof(struct udc_data_dma)); - } - } - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - - if (ep->in) { - /* enable ep irq */ - tmp = readl(&dev->regs->ep_irqmsk); - tmp &= AMD_UNMASK_BIT(ep->num); - writel(tmp, &dev->regs->ep_irqmsk); - } - } - - } else if (ep->dma) { - - /* - * prep_dma not used for OUT ep's, this is not possible - * for PPB modes, because of chain creation reasons - */ - if (ep->in) { - retval = prep_dma(ep, req, gfp); - if (retval != 0) - goto finished; - } - } - VDBG(dev, "list_add\n"); - /* add request to ep queue */ - if (req) { - - list_add_tail(&req->queue, &ep->queue); - - /* open rxfifo if out data queued */ - if (open_rxfifo) { - /* enable DMA */ - req->dma_going = 1; - udc_set_rde(dev); - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_queued = 1; - } - /* stop OUT naking */ - if (!ep->in) { - if (!use_dma && udc_rxfifo_pending) { - DBG(dev, "udc_queue(): pending bytes in" - "rxfifo after nyet\n"); - /* - * read pending bytes afer nyet: - * referring to isr - */ - if (udc_rxfifo_read(ep, req)) { - /* finish */ - complete_req(ep, req, 0); - } - udc_rxfifo_pending = 0; - - } - } - } - -finished: - spin_unlock_irqrestore(&dev->lock, iflags); - return retval; -} - -/* Empty request queue of an endpoint; caller holds spinlock */ -static void empty_req_queue(struct udc_ep *ep) -{ - struct udc_request *req; - - ep->halted = 1; - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, - struct udc_request, - queue); - complete_req(ep, req, -ESHUTDOWN); - } -} - -/* Dequeues a request packet, called by gadget driver */ -static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq) -{ - struct udc_ep *ep; - struct udc_request *req; - unsigned halted; - unsigned long iflags; - - ep = container_of(usbep, struct udc_ep, ep); - if (!usbep || !usbreq || (!ep->desc && (ep->num != 0 - && ep->num != UDC_EP0OUT_IX))) - return -EINVAL; - - req = container_of(usbreq, struct udc_request, req); - - spin_lock_irqsave(&ep->dev->lock, iflags); - halted = ep->halted; - ep->halted = 1; - /* request in processing or next one */ - if (ep->queue.next == &req->queue) { - if (ep->dma && req->dma_going) { - if (ep->in) - ep->cancel_transfer = 1; - else { - u32 tmp; - u32 dma_sts; - /* stop potential receive DMA */ - tmp = readl(&udc->regs->ctl); - writel(tmp & AMD_UNMASK_BIT(UDC_DEVCTL_RDE), - &udc->regs->ctl); - /* - * Cancel transfer later in ISR - * if descriptor was touched. - */ - dma_sts = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_BS); - if (dma_sts != UDC_DMA_OUT_STS_BS_HOST_READY) - ep->cancel_transfer = 1; - else { - udc_init_bna_dummy(ep->req); - writel(ep->bna_dummy_req->td_phys, - &ep->regs->desptr); - } - writel(tmp, &udc->regs->ctl); - } - } - } - complete_req(ep, req, -ECONNRESET); - ep->halted = halted; - - spin_unlock_irqrestore(&ep->dev->lock, iflags); - return 0; -} - -/* Halt or clear halt of endpoint */ -static int -udc_set_halt(struct usb_ep *usbep, int halt) -{ - struct udc_ep *ep; - u32 tmp; - unsigned long iflags; - int retval = 0; - - if (!usbep) - return -EINVAL; - - pr_debug("set_halt %s: halt=%d\n", usbep->name, halt); - - ep = container_of(usbep, struct udc_ep, ep); - if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) - return -EINVAL; - if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - spin_lock_irqsave(&udc_stall_spinlock, iflags); - /* halt or clear halt */ - if (halt) { - if (ep->num == 0) - ep->dev->stall_ep0in = 1; - else { - /* - * set STALL - * rxfifo empty not taken into acount - */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - ep->halted = 1; - - /* setup poll timer */ - if (!timer_pending(&udc_pollstall_timer)) { - udc_pollstall_timer.expires = jiffies + - HZ * UDC_POLLSTALL_TIMER_USECONDS - / (1000 * 1000); - if (!stop_pollstall_timer) { - DBG(ep->dev, "start polltimer\n"); - add_timer(&udc_pollstall_timer); - } - } - } - } else { - /* ep is halted by set_halt() before */ - if (ep->halted) { - tmp = readl(&ep->regs->ctl); - /* clear stall bit */ - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - /* clear NAK by writing CNAK */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->halted = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - } - spin_unlock_irqrestore(&udc_stall_spinlock, iflags); - return retval; -} - -/* gadget interface */ -static const struct usb_ep_ops udc_ep_ops = { - .enable = udc_ep_enable, - .disable = udc_ep_disable, - - .alloc_request = udc_alloc_request, - .free_request = udc_free_request, - - .queue = udc_queue, - .dequeue = udc_dequeue, - - .set_halt = udc_set_halt, - /* fifo ops not implemented */ -}; - -/*-------------------------------------------------------------------------*/ - -/* Get frame counter (not implemented) */ -static int udc_get_frame(struct usb_gadget *gadget) -{ - return -EOPNOTSUPP; -} - -/* Remote wakeup gadget interface */ -static int udc_wakeup(struct usb_gadget *gadget) -{ - struct udc *dev; - - if (!gadget) - return -EINVAL; - dev = container_of(gadget, struct udc, gadget); - udc_remote_wakeup(dev); - - return 0; -} - -/* gadget operations */ -static const struct usb_gadget_ops udc_ops = { - .wakeup = udc_wakeup, - .get_frame = udc_get_frame, -}; - -/* Setups endpoint parameters, adds endpoints to linked list */ -static void make_ep_lists(struct udc *dev) -{ - /* make gadget ep lists */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPIN_STATUS_IX].ep.ep_list, - &dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPIN_IX].ep.ep_list, - &dev->gadget.ep_list); - list_add_tail(&dev->ep[UDC_EPOUT_IX].ep.ep_list, - &dev->gadget.ep_list); - - /* fifo config */ - dev->ep[UDC_EPIN_STATUS_IX].fifo_depth = UDC_EPIN_SMALLINT_BUFF_SIZE; - if (dev->gadget.speed == USB_SPEED_FULL) - dev->ep[UDC_EPIN_IX].fifo_depth = UDC_FS_EPIN_BUFF_SIZE; - else if (dev->gadget.speed == USB_SPEED_HIGH) - dev->ep[UDC_EPIN_IX].fifo_depth = hs_tx_buf; - dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; -} - -/* init registers at driver load time */ -static int startup_registers(struct udc *dev) -{ - u32 tmp; - - /* init controller by soft reset */ - udc_soft_reset(dev); - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* put into initial config */ - udc_basic_init(dev); - /* link up all endpoints */ - udc_setup_endpoints(dev); - - /* program speed */ - tmp = readl(&dev->regs->cfg); - if (use_fullspeed) { - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - } else { - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); - } - writel(tmp, &dev->regs->cfg); - - return 0; -} - -/* Inits UDC context */ -static void udc_basic_init(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "udc_basic_init()\n"); - - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* stop poll stall timer */ - if (timer_pending(&udc_pollstall_timer)) { - mod_timer(&udc_pollstall_timer, jiffies - 1); - } - /* disable DMA */ - tmp = readl(&dev->regs->ctl); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); - tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_TDE); - writel(tmp, &dev->regs->ctl); - - /* enable dynamic CSR programming */ - tmp = readl(&dev->regs->cfg); - tmp |= AMD_BIT(UDC_DEVCFG_CSR_PRG); - /* set self powered */ - tmp |= AMD_BIT(UDC_DEVCFG_SP); - /* set remote wakeupable */ - tmp |= AMD_BIT(UDC_DEVCFG_RWKP); - writel(tmp, &dev->regs->cfg); - - make_ep_lists(dev); - - dev->data_ep_enabled = 0; - dev->data_ep_queued = 0; -} - -/* Sets initial endpoint parameters */ -static void udc_setup_endpoints(struct udc *dev) -{ - struct udc_ep *ep; - u32 tmp; - u32 reg; - - DBG(dev, "udc_setup_endpoints()\n"); - - /* read enum speed */ - tmp = readl(&dev->regs->sts); - tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); - if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) { - dev->gadget.speed = USB_SPEED_HIGH; - } else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) { - dev->gadget.speed = USB_SPEED_FULL; - } - - /* set basic ep parameters */ - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - ep = &dev->ep[tmp]; - ep->dev = dev; - ep->ep.name = ep_string[tmp]; - ep->num = tmp; - /* txfifo size is calculated at enable time */ - ep->txfifo = dev->txfifo; - - /* fifo size */ - if (tmp < UDC_EPIN_NUM) { - ep->fifo_depth = UDC_TXFIFO_SIZE; - ep->in = 1; - } else { - ep->fifo_depth = UDC_RXFIFO_SIZE; - ep->in = 0; - - } - ep->regs = &dev->ep_regs[tmp]; - /* - * ep will be reset only if ep was not enabled before to avoid - * disabling ep interrupts when ENUM interrupt occurs but ep is - * not enabled by gadget driver - */ - if (!ep->desc) { - ep_init(dev->regs, ep); - } - - if (use_dma) { - /* - * ep->dma is not really used, just to indicate that - * DMA is active: remove this - * dma regs = dev control regs - */ - ep->dma = &dev->regs->ctl; - - /* nak OUT endpoints until enable - not for ep0 */ - if (tmp != UDC_EP0IN_IX && tmp != UDC_EP0OUT_IX - && tmp > UDC_EPIN_NUM) { - /* set NAK */ - reg = readl(&dev->ep[tmp].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_SNAK); - writel(reg, &dev->ep[tmp].regs->ctl); - dev->ep[tmp].naking = 1; - - } - } - } - /* EP0 max packet */ - if (dev->gadget.speed == USB_SPEED_FULL) { - dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_FS_EP0IN_MAX_PKT_SIZE; - dev->ep[UDC_EP0OUT_IX].ep.maxpacket = - UDC_FS_EP0OUT_MAX_PKT_SIZE; - } else if (dev->gadget.speed == USB_SPEED_HIGH) { - dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; - dev->ep[UDC_EP0OUT_IX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; - } - - /* - * with suspend bug workaround, ep0 params for gadget driver - * are set at gadget driver bind() call - */ - dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; - dev->ep[UDC_EP0IN_IX].halted = 0; - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - - /* init cfg/alt/int */ - dev->cur_config = 0; - dev->cur_intf = 0; - dev->cur_alt = 0; -} - -/* Bringup after Connect event, initial bringup to be ready for ep0 events */ -static void usb_connect(struct udc *dev) -{ - - dev_info(&dev->pdev->dev, "USB Connect\n"); - - dev->connected = 1; - - /* put into initial config */ - udc_basic_init(dev); - - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); -} - -/* - * Calls gadget with disconnect event and resets the UDC and makes - * initial bringup to be ready for ep0 events - */ -static void usb_disconnect(struct udc *dev) -{ - - dev_info(&dev->pdev->dev, "USB Disconnect\n"); - - dev->connected = 0; - - /* mask interrupts */ - udc_mask_unused_interrupts(dev); - - /* REVISIT there doesn't seem to be a point to having this - * talk to a tasklet ... do it directly, we already hold - * the spinlock needed to process the disconnect. - */ - - tasklet_schedule(&disconnect_tasklet); -} - -/* Tasklet for disconnect to be outside of interrupt context */ -static void udc_tasklet_disconnect(unsigned long par) -{ - struct udc *dev = (struct udc *)(*((struct udc **) par)); - u32 tmp; - - DBG(dev, "Tasklet disconnect\n"); - spin_lock_irq(&dev->lock); - - if (dev->driver) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - - /* empty queues */ - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - empty_req_queue(&dev->ep[tmp]); - } - - } - - /* disable ep0 */ - ep_init(dev->regs, - &dev->ep[UDC_EP0IN_IX]); - - - if (!soft_reset_occured) { - /* init controller by soft reset */ - udc_soft_reset(dev); - soft_reset_occured++; - } - - /* re-enable dev interrupts */ - udc_enable_dev_setup_interrupts(dev); - /* back to full speed ? */ - if (use_fullspeed) { - tmp = readl(&dev->regs->cfg); - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - writel(tmp, &dev->regs->cfg); - } - - spin_unlock_irq(&dev->lock); -} - -/* Reset the UDC core */ -static void udc_soft_reset(struct udc *dev) -{ - unsigned long flags; - - DBG(dev, "Soft reset\n"); - /* - * reset possible waiting interrupts, because int. - * status is lost after soft reset, - * ep int. status reset - */ - writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqsts); - /* device int. status reset */ - writel(UDC_DEV_MSK_DISABLE, &dev->regs->irqsts); - - spin_lock_irqsave(&udc_irq_spinlock, flags); - writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - readl(&dev->regs->cfg); - spin_unlock_irqrestore(&udc_irq_spinlock, flags); - -} - -/* RDE timer callback to set RDE bit */ -static void udc_timer_function(unsigned long v) -{ - u32 tmp; - - spin_lock_irq(&udc_irq_spinlock); - - if (set_rde > 0) { - /* - * open the fifo if fifo was filled on last timer call - * conditionally - */ - if (set_rde > 1) { - /* set RDE to receive setup data */ - tmp = readl(&udc->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RDE); - writel(tmp, &udc->regs->ctl); - set_rde = -1; - } else if (readl(&udc->regs->sts) - & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - /* - * if fifo empty setup polling, do not just - * open the fifo - */ - udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; - if (!stop_timer) { - add_timer(&udc_timer); - } - } else { - /* - * fifo contains data now, setup timer for opening - * the fifo when timer expires to be able to receive - * setup packets, when data packets gets queued by - * gadget layer then timer will forced to expire with - * set_rde=0 (RDE is set in udc_queue()) - */ - set_rde++; - /* debug: lhadmot_timer_start = 221070 */ - udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - - } else - set_rde = -1; /* RDE was set by udc_queue() */ - spin_unlock_irq(&udc_irq_spinlock); - if (stop_timer) - complete(&on_exit); - -} - -/* Handle halt state, used in stall poll timer */ -static void udc_handle_halt_state(struct udc_ep *ep) -{ - u32 tmp; - /* set stall as long not halted */ - if (ep->halted == 1) { - tmp = readl(&ep->regs->ctl); - /* STALL cleared ? */ - if (!(tmp & AMD_BIT(UDC_EPCTL_S))) { - /* - * FIXME: MSC spec requires that stall remains - * even on receivng of CLEAR_FEATURE HALT. So - * we would set STALL again here to be compliant. - * But with current mass storage drivers this does - * not work (would produce endless host retries). - * So we clear halt on CLEAR_FEATURE. - * - DBG(ep->dev, "ep %d: set STALL again\n", ep->num); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl);*/ - - /* clear NAK by writing CNAK */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->halted = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } - } -} - -/* Stall timer callback to poll S bit and set it again after */ -static void udc_pollstall_timer_function(unsigned long v) -{ - struct udc_ep *ep; - int halted = 0; - - spin_lock_irq(&udc_stall_spinlock); - /* - * only one IN and OUT endpoints are handled - * IN poll stall - */ - ep = &udc->ep[UDC_EPIN_IX]; - udc_handle_halt_state(ep); - if (ep->halted) - halted = 1; - /* OUT poll stall */ - ep = &udc->ep[UDC_EPOUT_IX]; - udc_handle_halt_state(ep); - if (ep->halted) - halted = 1; - - /* setup timer again when still halted */ - if (!stop_pollstall_timer && halted) { - udc_pollstall_timer.expires = jiffies + - HZ * UDC_POLLSTALL_TIMER_USECONDS - / (1000 * 1000); - add_timer(&udc_pollstall_timer); - } - spin_unlock_irq(&udc_stall_spinlock); - - if (stop_pollstall_timer) - complete(&on_pollstall_exit); -} - -/* Inits endpoint 0 so that SETUP packets are processed */ -static void activate_control_endpoints(struct udc *dev) -{ - u32 tmp; - - DBG(dev, "activate_control_endpoints\n"); - - /* flush fifo */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_F); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - - /* set ep0 directions */ - dev->ep[UDC_EP0IN_IX].in = 1; - dev->ep[UDC_EP0OUT_IX].in = 0; - - /* set buffer size (tx fifo entries) of EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EPIN0_BUFF_SIZE, - UDC_EPIN_BUFF_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EPIN0_BUFF_SIZE, - UDC_EPIN_BUFF_SIZE); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); - - /* set max packet size of EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0IN_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0IN_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); - - /* set max packet size of EP0_OUT */ - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, - UDC_EP_MAX_PKT_SIZE); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); - - /* set max packet size of EP0 in UDC CSR */ - tmp = readl(&dev->csr->ne[0]); - if (dev->gadget.speed == USB_SPEED_FULL) - tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, - UDC_CSR_NE_MAX_PKT); - else if (dev->gadget.speed == USB_SPEED_HIGH) - tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, - UDC_CSR_NE_MAX_PKT); - writel(tmp, &dev->csr->ne[0]); - - if (use_dma) { - dev->ep[UDC_EP0OUT_IX].td->status |= - AMD_BIT(UDC_DMA_OUT_STS_L); - /* write dma desc address */ - writel(dev->ep[UDC_EP0OUT_IX].td_stp_dma, - &dev->ep[UDC_EP0OUT_IX].regs->subptr); - writel(dev->ep[UDC_EP0OUT_IX].td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - /* stop RDE timer */ - if (timer_pending(&udc_timer)) { - set_rde = 0; - mod_timer(&udc_timer, jiffies - 1); - } - /* stop pollstall timer */ - if (timer_pending(&udc_pollstall_timer)) { - mod_timer(&udc_pollstall_timer, jiffies - 1); - } - /* enable DMA */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_MODE) - | AMD_BIT(UDC_DEVCTL_RDE) - | AMD_BIT(UDC_DEVCTL_TDE); - if (use_dma_bufferfill_mode) { - tmp |= AMD_BIT(UDC_DEVCTL_BF); - } else if (use_dma_ppb_du) { - tmp |= AMD_BIT(UDC_DEVCTL_DU); - } - writel(tmp, &dev->regs->ctl); - } - - /* clear NAK by writing CNAK for EP0IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); - - /* clear NAK by writing CNAK for EP0OUT */ - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); -} - -/* Make endpoint 0 ready for control traffic */ -static int setup_ep0(struct udc *dev) -{ - activate_control_endpoints(dev); - /* enable ep0 interrupts */ - udc_enable_ep0_interrupts(dev); - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); - - return 0; -} - -/* Called by gadget driver to register itself */ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct udc *dev = udc; - int retval; - u32 tmp; - - if (!driver || !driver->bind || !driver->setup - || driver->speed != USB_SPEED_HIGH) - return -EINVAL; - if (!dev) - return -ENODEV; - if (dev->driver) - return -EBUSY; - - driver->driver.bus = NULL; - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - - retval = driver->bind(&dev->gadget); - - /* Some gadget drivers use both ep0 directions. - * NOTE: to gadget driver, ep0 is just one endpoint... - */ - dev->ep[UDC_EP0OUT_IX].ep.driver_data = - dev->ep[UDC_EP0IN_IX].ep.driver_data; - - if (retval) { - DBG(dev, "binding to %s returning %d\n", - driver->driver.name, retval); - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - - /* get ready for ep0 traffic */ - setup_ep0(dev); - - /* clear SD */ - tmp = readl(&dev->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_DEVCTL_SD); - writel(tmp, &dev->regs->ctl); - - usb_connect(dev); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_register_driver); - -/* shutdown requests and disconnect from gadget */ -static void -shutdown(struct udc *dev, struct usb_gadget_driver *driver) -__releases(dev->lock) -__acquires(dev->lock) -{ - int tmp; - - /* empty queues and init hardware */ - udc_basic_init(dev); - for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { - empty_req_queue(&dev->ep[tmp]); - } - - if (dev->gadget.speed != USB_SPEED_UNKNOWN) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - /* init */ - udc_setup_endpoints(dev); -} - -/* Called by gadget driver to unregister itself */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct udc *dev = udc; - unsigned long flags; - u32 tmp; - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver || !driver->unbind) - return -EINVAL; - - spin_lock_irqsave(&dev->lock, flags); - udc_mask_unused_interrupts(dev); - shutdown(dev, driver); - spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); - dev->driver = NULL; - - /* set SD */ - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_SD); - writel(tmp, &dev->regs->ctl); - - - DBG(dev, "%s: unregistered\n", driver->driver.name); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - - -/* Clear pending NAK bits */ -static void udc_process_cnak_queue(struct udc *dev) -{ - u32 tmp; - u32 reg; - - /* check epin's */ - DBG(dev, "CNAK pending queue processing\n"); - for (tmp = 0; tmp < UDC_EPIN_NUM_USED; tmp++) { - if (cnak_pending & (1 << tmp)) { - DBG(dev, "CNAK pending for ep%d\n", tmp); - /* clear NAK by writing CNAK */ - reg = readl(&dev->ep[tmp].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_CNAK); - writel(reg, &dev->ep[tmp].regs->ctl); - dev->ep[tmp].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[tmp], dev->ep[tmp].num); - } - } - /* ... and ep0out */ - if (cnak_pending & (1 << UDC_EP0OUT_IX)) { - DBG(dev, "CNAK pending for ep%d\n", UDC_EP0OUT_IX); - /* clear NAK by writing CNAK */ - reg = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - reg |= AMD_BIT(UDC_EPCTL_CNAK); - writel(reg, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], - dev->ep[UDC_EP0OUT_IX].num); - } -} - -/* Enabling RX DMA after setup packet */ -static void udc_ep0_set_rde(struct udc *dev) -{ - if (use_dma) { - /* - * only enable RXDMA when no data endpoint enabled - * or data is queued - */ - if (!dev->data_ep_enabled || dev->data_ep_queued) { - udc_set_rde(dev); - } else { - /* - * setup timer for enabling RDE (to not enable - * RXFIFO DMA for data endpoints to early) - */ - if (set_rde != 0 && !timer_pending(&udc_timer)) { - udc_timer.expires = - jiffies + HZ/UDC_RDE_TIMER_DIV; - set_rde = 1; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - } - } -} - - -/* Interrupt handler for data OUT traffic */ -static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - struct udc_ep *ep; - struct udc_request *req; - unsigned int count; - struct udc_data_dma *td = NULL; - unsigned dma_done; - - VDBG(dev, "ep%d irq\n", ep_ix); - ep = &dev->ep[ep_ix]; - - tmp = readl(&ep->regs->sts); - if (use_dma) { - /* BNA event ? */ - if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { - DBG(dev, "BNA ep%dout occured - DESPTR = %x \n", - ep->num, readl(&ep->regs->desptr)); - /* clear BNA */ - writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); - if (!ep->cancel_transfer) - ep->bna_occurred = 1; - else - ep->cancel_transfer = 0; - ret_val = IRQ_HANDLED; - goto finished; - } - } - /* HE event ? */ - if (tmp & AMD_BIT(UDC_EPSTS_HE)) { - dev_err(&dev->pdev->dev, "HE ep%dout occured\n", ep->num); - - /* clear HE */ - writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - - if (!list_empty(&ep->queue)) { - - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - } else { - req = NULL; - udc_rxfifo_pending = 1; - } - VDBG(dev, "req = %p\n", req); - /* fifo mode */ - if (!use_dma) { - - /* read fifo */ - if (req && udc_rxfifo_read(ep, req)) { - ret_val = IRQ_HANDLED; - - /* finish */ - complete_req(ep, req, 0); - /* next request */ - if (!list_empty(&ep->queue) && !ep->halted) { - req = list_entry(ep->queue.next, - struct udc_request, queue); - } else - req = NULL; - } - - /* DMA */ - } else if (!ep->cancel_transfer && req != NULL) { - ret_val = IRQ_HANDLED; - - /* check for DMA done */ - if (!use_dma_ppb) { - dma_done = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_BS); - /* packet per buffer mode - rx bytes */ - } else { - /* - * if BNA occurred then recover desc. from - * BNA dummy desc. - */ - if (ep->bna_occurred) { - VDBG(dev, "Recover desc. from BNA dummy\n"); - memcpy(req->td_data, ep->bna_dummy_req->td_data, - sizeof(struct udc_data_dma)); - ep->bna_occurred = 0; - udc_init_bna_dummy(ep->req); - } - td = udc_get_last_dma_desc(req); - dma_done = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_BS); - } - if (dma_done == UDC_DMA_OUT_STS_BS_DMA_DONE) { - /* buffer fill mode - rx bytes */ - if (!use_dma_ppb) { - /* received number bytes */ - count = AMD_GETBITS(req->td_data->status, - UDC_DMA_OUT_STS_RXBYTES); - VDBG(dev, "rx bytes=%u\n", count); - /* packet per buffer mode - rx bytes */ - } else { - VDBG(dev, "req->td_data=%p\n", req->td_data); - VDBG(dev, "last desc = %p\n", td); - /* received number bytes */ - if (use_dma_ppb_du) { - /* every desc. counts bytes */ - count = udc_get_ppbdu_rxbytes(req); - } else { - /* last desc. counts bytes */ - count = AMD_GETBITS(td->status, - UDC_DMA_OUT_STS_RXBYTES); - if (!count && req->req.length - == UDC_DMA_MAXPACKET) { - /* - * on 64k packets the RXBYTES - * field is zero - */ - count = UDC_DMA_MAXPACKET; - } - } - VDBG(dev, "last desc rx bytes=%u\n", count); - } - - tmp = req->req.length - req->req.actual; - if (count > tmp) { - if ((tmp % ep->ep.maxpacket) != 0) { - DBG(dev, "%s: rx %db, space=%db\n", - ep->ep.name, count, tmp); - req->req.status = -EOVERFLOW; - } - count = tmp; - } - req->req.actual += count; - req->dma_going = 0; - /* complete request */ - complete_req(ep, req, 0); - - /* next request */ - if (!list_empty(&ep->queue) && !ep->halted) { - req = list_entry(ep->queue.next, - struct udc_request, - queue); - /* - * DMA may be already started by udc_queue() - * called by gadget drivers completion - * routine. This happens when queue - * holds one request only. - */ - if (req->dma_going == 0) { - /* next dma */ - if (prep_dma(ep, req, GFP_ATOMIC) != 0) - goto finished; - /* write desc pointer */ - writel(req->td_phys, - &ep->regs->desptr); - req->dma_going = 1; - /* enable DMA */ - udc_set_rde(dev); - } - } else { - /* - * implant BNA dummy descriptor to allow - * RXFIFO opening by RDE - */ - if (ep->bna_dummy_req) { - /* write desc pointer */ - writel(ep->bna_dummy_req->td_phys, - &ep->regs->desptr); - ep->bna_occurred = 0; - } - - /* - * schedule timer for setting RDE if queue - * remains empty to allow ep0 packets pass - * through - */ - if (set_rde != 0 - && !timer_pending(&udc_timer)) { - udc_timer.expires = - jiffies - + HZ*UDC_RDE_TIMER_SECONDS; - set_rde = 1; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - if (ep->num != UDC_EP0OUT_IX) - dev->data_ep_queued = 0; - } - - } else { - /* - * RX DMA must be reenabled for each desc in PPBDU mode - * and must be enabled for PPBNDU mode in case of BNA - */ - udc_set_rde(dev); - } - - } else if (ep->cancel_transfer) { - ret_val = IRQ_HANDLED; - ep->cancel_transfer = 0; - } - - /* check pending CNAKS */ - if (cnak_pending) { - /* CNAk processing when rxfifo empty only */ - if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - udc_process_cnak_queue(dev); - } - } - - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, &ep->regs->sts); -finished: - return ret_val; -} - -/* Interrupt handler for data IN traffic */ -static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - u32 epsts; - struct udc_ep *ep; - struct udc_request *req; - struct udc_data_dma *td; - unsigned dma_done; - unsigned len; - - ep = &dev->ep[ep_ix]; - - epsts = readl(&ep->regs->sts); - if (use_dma) { - /* BNA ? */ - if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { - dev_err(&dev->pdev->dev, - "BNA ep%din occured - DESPTR = %08lx \n", - ep->num, - (unsigned long) readl(&ep->regs->desptr)); - - /* clear BNA */ - writel(epsts, &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - } - /* HE event ? */ - if (epsts & AMD_BIT(UDC_EPSTS_HE)) { - dev_err(&dev->pdev->dev, - "HE ep%dn occured - DESPTR = %08lx \n", - ep->num, (unsigned long) readl(&ep->regs->desptr)); - - /* clear HE */ - writel(epsts | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); - ret_val = IRQ_HANDLED; - goto finished; - } - - /* DMA completion */ - if (epsts & AMD_BIT(UDC_EPSTS_TDC)) { - VDBG(dev, "TDC set- completion\n"); - ret_val = IRQ_HANDLED; - if (!ep->cancel_transfer && !list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, - struct udc_request, queue); - if (req) { - /* - * length bytes transfered - * check dma done of last desc. in PPBDU mode - */ - if (use_dma_ppb_du) { - td = udc_get_last_dma_desc(req); - if (td) { - dma_done = - AMD_GETBITS(td->status, - UDC_DMA_IN_STS_BS); - /* don't care DMA done */ - req->req.actual = - req->req.length; - } - } else { - /* assume all bytes transferred */ - req->req.actual = req->req.length; - } - - if (req->req.actual == req->req.length) { - /* complete req */ - complete_req(ep, req, 0); - req->dma_going = 0; - /* further request available ? */ - if (list_empty(&ep->queue)) { - /* disable interrupt */ - tmp = readl( - &dev->regs->ep_irqmsk); - tmp |= AMD_BIT(ep->num); - writel(tmp, - &dev->regs->ep_irqmsk); - } - - } - } - } - ep->cancel_transfer = 0; - - } - /* - * status reg has IN bit set and TDC not set (if TDC was handled, - * IN must not be handled (UDC defect) ? - */ - if ((epsts & AMD_BIT(UDC_EPSTS_IN)) - && !(epsts & AMD_BIT(UDC_EPSTS_TDC))) { - ret_val = IRQ_HANDLED; - if (!list_empty(&ep->queue)) { - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - /* FIFO mode */ - if (!use_dma) { - /* write fifo */ - udc_txfifo_write(ep, &req->req); - len = req->req.length - req->req.actual; - if (len > ep->ep.maxpacket) - len = ep->ep.maxpacket; - req->req.actual += len; - if (req->req.actual == req->req.length - || (len != ep->ep.maxpacket)) { - /* complete req */ - complete_req(ep, req, 0); - } - /* DMA */ - } else if (req && !req->dma_going) { - VDBG(dev, "IN DMA : req=%p req->td_data=%p\n", - req, req->td_data); - if (req->td_data) { - - req->dma_going = 1; - - /* - * unset L bit of first desc. - * for chain - */ - if (use_dma_ppb && req->req.length > - ep->ep.maxpacket) { - req->td_data->status &= - AMD_CLEAR_BIT( - UDC_DMA_IN_STS_L); - } - - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS( - req->td_data->status, - UDC_DMA_IN_STS_BS_HOST_READY, - UDC_DMA_IN_STS_BS); - - /* set poll demand bit */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_P); - writel(tmp, &ep->regs->ctl); - } - } - - } - } - /* clear status bits */ - writel(epsts, &ep->regs->sts); - -finished: - return ret_val; - -} - -/* Interrupt handler for Control OUT traffic */ -static irqreturn_t udc_control_out_isr(struct udc *dev) -__releases(dev->lock) -__acquires(dev->lock) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - int setup_supported; - u32 count; - int set = 0; - struct udc_ep *ep; - struct udc_ep *ep_tmp; - - ep = &dev->ep[UDC_EP0OUT_IX]; - - /* clear irq */ - writel(AMD_BIT(UDC_EPINT_OUT_EP0), &dev->regs->ep_irqsts); - - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); - /* check BNA and clear if set */ - if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { - VDBG(dev, "ep0: BNA set\n"); - writel(AMD_BIT(UDC_EPSTS_BNA), - &dev->ep[UDC_EP0OUT_IX].regs->sts); - ep->bna_occurred = 1; - ret_val = IRQ_HANDLED; - goto finished; - } - - /* type of data: SETUP or DATA 0 bytes */ - tmp = AMD_GETBITS(tmp, UDC_EPSTS_OUT); - VDBG(dev, "data_typ = %x\n", tmp); - - /* setup data */ - if (tmp == UDC_EPSTS_OUT_SETUP) { - ret_val = IRQ_HANDLED; - - ep->dev->stall_ep0in = 0; - dev->waiting_zlp_ack_ep0in = 0; - - /* set NAK for EP0_IN */ - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_SNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 1; - /* get setup data */ - if (use_dma) { - - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, - &dev->ep[UDC_EP0OUT_IX].regs->sts); - - setup_data.data[0] = - dev->ep[UDC_EP0OUT_IX].td_stp->data12; - setup_data.data[1] = - dev->ep[UDC_EP0OUT_IX].td_stp->data34; - /* set HOST READY */ - dev->ep[UDC_EP0OUT_IX].td_stp->status = - UDC_DMA_STP_STS_BS_HOST_READY; - } else { - /* read fifo */ - udc_rxfifo_read_dwords(dev, setup_data.data, 2); - } - - /* determine direction of control data */ - if ((setup_data.request.bRequestType & USB_DIR_IN) != 0) { - dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; - /* enable RDE */ - udc_ep0_set_rde(dev); - set = 0; - } else { - dev->gadget.ep0 = &dev->ep[UDC_EP0OUT_IX].ep; - /* - * implant BNA dummy descriptor to allow RXFIFO opening - * by RDE - */ - if (ep->bna_dummy_req) { - /* write desc pointer */ - writel(ep->bna_dummy_req->td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - ep->bna_occurred = 0; - } - - set = 1; - dev->ep[UDC_EP0OUT_IX].naking = 1; - /* - * setup timer for enabling RDE (to not enable - * RXFIFO DMA for data to early) - */ - set_rde = 1; - if (!timer_pending(&udc_timer)) { - udc_timer.expires = jiffies + - HZ/UDC_RDE_TIMER_DIV; - if (!stop_timer) { - add_timer(&udc_timer); - } - } - } - - /* - * mass storage reset must be processed here because - * next packet may be a CLEAR_FEATURE HALT which would not - * clear the stall bit when no STALL handshake was received - * before (autostall can cause this) - */ - if (setup_data.data[0] == UDC_MSCRES_DWORD0 - && setup_data.data[1] == UDC_MSCRES_DWORD1) { - DBG(dev, "MSC Reset\n"); - /* - * clear stall bits - * only one IN and OUT endpoints are handled - */ - ep_tmp = &udc->ep[UDC_EPIN_IX]; - udc_set_halt(&ep_tmp->ep, 0); - ep_tmp = &udc->ep[UDC_EPOUT_IX]; - udc_set_halt(&ep_tmp->ep, 0); - } - - /* call gadget with setup data received */ - spin_unlock(&dev->lock); - setup_supported = dev->driver->setup(&dev->gadget, - &setup_data.request); - spin_lock(&dev->lock); - - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - /* ep0 in returns data (not zlp) on IN phase */ - if (setup_supported >= 0 && setup_supported < - UDC_EP0IN_MAXPACKET) { - /* clear NAK by writing CNAK in EP0_IN */ - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - dev->ep[UDC_EP0IN_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); - - /* if unsupported request then stall */ - } else if (setup_supported < 0) { - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); - } else - dev->waiting_zlp_ack_ep0in = 1; - - - /* clear NAK by writing CNAK in EP0_OUT */ - if (!set) { - tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); - dev->ep[UDC_EP0OUT_IX].naking = 0; - UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); - } - - if (!use_dma) { - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, - &dev->ep[UDC_EP0OUT_IX].regs->sts); - } - - /* data packet 0 bytes */ - } else if (tmp == UDC_EPSTS_OUT_DATA) { - /* clear OUT bits in ep status */ - writel(UDC_EPSTS_OUT_CLEAR, &dev->ep[UDC_EP0OUT_IX].regs->sts); - - /* get setup data: only 0 packet */ - if (use_dma) { - /* no req if 0 packet, just reactivate */ - if (list_empty(&dev->ep[UDC_EP0OUT_IX].queue)) { - VDBG(dev, "ZLP\n"); - - /* set HOST READY */ - dev->ep[UDC_EP0OUT_IX].td->status = - AMD_ADDBITS( - dev->ep[UDC_EP0OUT_IX].td->status, - UDC_DMA_OUT_STS_BS_HOST_READY, - UDC_DMA_OUT_STS_BS); - /* enable RDE */ - udc_ep0_set_rde(dev); - ret_val = IRQ_HANDLED; - - } else { - /* control write */ - ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); - /* re-program desc. pointer for possible ZLPs */ - writel(dev->ep[UDC_EP0OUT_IX].td_phys, - &dev->ep[UDC_EP0OUT_IX].regs->desptr); - /* enable RDE */ - udc_ep0_set_rde(dev); - } - } else { - - /* received number bytes */ - count = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); - count = AMD_GETBITS(count, UDC_EPSTS_RX_PKT_SIZE); - /* out data for fifo mode not working */ - count = 0; - - /* 0 packet or real data ? */ - if (count != 0) { - ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); - } else { - /* dummy read confirm */ - readl(&dev->ep[UDC_EP0OUT_IX].regs->confirm); - ret_val = IRQ_HANDLED; - } - } - } - - /* check pending CNAKS */ - if (cnak_pending) { - /* CNAk processing when rxfifo empty only */ - if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { - udc_process_cnak_queue(dev); - } - } - -finished: - return ret_val; -} - -/* Interrupt handler for Control IN traffic */ -static irqreturn_t udc_control_in_isr(struct udc *dev) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - struct udc_ep *ep; - struct udc_request *req; - unsigned len; - - ep = &dev->ep[UDC_EP0IN_IX]; - - /* clear irq */ - writel(AMD_BIT(UDC_EPINT_IN_EP0), &dev->regs->ep_irqsts); - - tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); - /* DMA completion */ - if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { - VDBG(dev, "isr: TDC clear \n"); - ret_val = IRQ_HANDLED; - - /* clear TDC bit */ - writel(AMD_BIT(UDC_EPSTS_TDC), - &dev->ep[UDC_EP0IN_IX].regs->sts); - - /* status reg has IN bit set ? */ - } else if (tmp & AMD_BIT(UDC_EPSTS_IN)) { - ret_val = IRQ_HANDLED; - - if (ep->dma) { - /* clear IN bit */ - writel(AMD_BIT(UDC_EPSTS_IN), - &dev->ep[UDC_EP0IN_IX].regs->sts); - } - if (dev->stall_ep0in) { - DBG(dev, "stall ep0in\n"); - /* halt ep0in */ - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } else { - if (!list_empty(&ep->queue)) { - /* next request */ - req = list_entry(ep->queue.next, - struct udc_request, queue); - - if (ep->dma) { - /* write desc pointer */ - writel(req->td_phys, &ep->regs->desptr); - /* set HOST READY */ - req->td_data->status = - AMD_ADDBITS( - req->td_data->status, - UDC_DMA_STP_STS_BS_HOST_READY, - UDC_DMA_STP_STS_BS); - - /* set poll demand bit */ - tmp = - readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_P); - writel(tmp, - &dev->ep[UDC_EP0IN_IX].regs->ctl); - - /* all bytes will be transferred */ - req->req.actual = req->req.length; - - /* complete req */ - complete_req(ep, req, 0); - - } else { - /* write fifo */ - udc_txfifo_write(ep, &req->req); - - /* lengh bytes transfered */ - len = req->req.length - req->req.actual; - if (len > ep->ep.maxpacket) - len = ep->ep.maxpacket; - - req->req.actual += len; - if (req->req.actual == req->req.length - || (len != ep->ep.maxpacket)) { - /* complete req */ - complete_req(ep, req, 0); - } - } - - } - } - ep->halted = 0; - dev->stall_ep0in = 0; - if (!ep->dma) { - /* clear IN bit */ - writel(AMD_BIT(UDC_EPSTS_IN), - &dev->ep[UDC_EP0IN_IX].regs->sts); - } - } - - return ret_val; -} - - -/* Interrupt handler for global device events */ -static irqreturn_t udc_dev_isr(struct udc *dev, u32 dev_irq) -__releases(dev->lock) -__acquires(dev->lock) -{ - irqreturn_t ret_val = IRQ_NONE; - u32 tmp; - u32 cfg; - struct udc_ep *ep; - u16 i; - u8 udc_csr_epix; - - /* SET_CONFIG irq ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SC)) { - ret_val = IRQ_HANDLED; - - /* read config value */ - tmp = readl(&dev->regs->sts); - cfg = AMD_GETBITS(tmp, UDC_DEVSTS_CFG); - DBG(dev, "SET_CONFIG interrupt: config=%d\n", cfg); - dev->cur_config = cfg; - dev->set_cfg_not_acked = 1; - - /* make usb request for gadget driver */ - memset(&setup_data, 0 , sizeof(union udc_setup_data)); - setup_data.request.bRequest = USB_REQ_SET_CONFIGURATION; - setup_data.request.wValue = dev->cur_config; - - /* programm the NE registers */ - for (i = 0; i < UDC_EP_NUM; i++) { - ep = &dev->ep[i]; - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - } - - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* ep cfg */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, - UDC_CSR_NE_CFG); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* clear stall bits */ - ep->halted = 0; - tmp = readl(&ep->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } - /* call gadget zero with setup data received */ - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &setup_data.request); - spin_lock(&dev->lock); - - } /* SET_INTERFACE ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SI)) { - ret_val = IRQ_HANDLED; - - dev->set_cfg_not_acked = 1; - /* read interface and alt setting values */ - tmp = readl(&dev->regs->sts); - dev->cur_alt = AMD_GETBITS(tmp, UDC_DEVSTS_ALT); - dev->cur_intf = AMD_GETBITS(tmp, UDC_DEVSTS_INTF); - - /* make usb request for gadget driver */ - memset(&setup_data, 0 , sizeof(union udc_setup_data)); - setup_data.request.bRequest = USB_REQ_SET_INTERFACE; - setup_data.request.bRequestType = USB_RECIP_INTERFACE; - setup_data.request.wValue = dev->cur_alt; - setup_data.request.wIndex = dev->cur_intf; - - DBG(dev, "SET_INTERFACE interrupt: alt=%d intf=%d\n", - dev->cur_alt, dev->cur_intf); - - /* programm the NE registers */ - for (i = 0; i < UDC_EP_NUM; i++) { - ep = &dev->ep[i]; - if (ep->in) { - - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num; - - - /* OUT ep */ - } else { - /* ep ix in UDC CSR register space */ - udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; - } - - /* UDC CSR reg */ - /* set ep values */ - tmp = readl(&dev->csr->ne[udc_csr_epix]); - /* ep interface */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, - UDC_CSR_NE_INTF); - /* tmp = AMD_ADDBITS(tmp, 2, UDC_CSR_NE_INTF); */ - /* ep alt */ - tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, - UDC_CSR_NE_ALT); - /* write reg */ - writel(tmp, &dev->csr->ne[udc_csr_epix]); - - /* clear stall bits */ - ep->halted = 0; - tmp = readl(&ep->regs->ctl); - tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); - writel(tmp, &ep->regs->ctl); - } - - /* call gadget zero with setup data received */ - spin_unlock(&dev->lock); - tmp = dev->driver->setup(&dev->gadget, &setup_data.request); - spin_lock(&dev->lock); - - } /* USB reset */ - if (dev_irq & AMD_BIT(UDC_DEVINT_UR)) { - DBG(dev, "USB Reset interrupt\n"); - ret_val = IRQ_HANDLED; - - /* allow soft reset when suspend occurs */ - soft_reset_occured = 0; - - dev->waiting_zlp_ack_ep0in = 0; - dev->set_cfg_not_acked = 0; - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* call gadget to resume and reset configs etc. */ - spin_unlock(&dev->lock); - if (dev->sys_suspended && dev->driver->resume) { - dev->driver->resume(&dev->gadget); - dev->sys_suspended = 0; - } - dev->driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - - /* disable ep0 to empty req queue */ - empty_req_queue(&dev->ep[UDC_EP0IN_IX]); - ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); - - /* soft reset when rxfifo not empty */ - tmp = readl(&dev->regs->sts); - if (!(tmp & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) - && !soft_reset_after_usbreset_occured) { - udc_soft_reset(dev); - soft_reset_after_usbreset_occured++; - } - - /* - * DMA reset to kill potential old DMA hw hang, - * POLL bit is already reset by ep_init() through - * disconnect() - */ - DBG(dev, "DMA machine reset\n"); - tmp = readl(&dev->regs->cfg); - writel(tmp | AMD_BIT(UDC_DEVCFG_DMARST), &dev->regs->cfg); - writel(tmp, &dev->regs->cfg); - - /* put into initial config */ - udc_basic_init(dev); - - /* enable device setup interrupts */ - udc_enable_dev_setup_interrupts(dev); - - /* enable suspend interrupt */ - tmp = readl(&dev->regs->irqmsk); - tmp &= AMD_UNMASK_BIT(UDC_DEVINT_US); - writel(tmp, &dev->regs->irqmsk); - - } /* USB suspend */ - if (dev_irq & AMD_BIT(UDC_DEVINT_US)) { - DBG(dev, "USB Suspend interrupt\n"); - ret_val = IRQ_HANDLED; - if (dev->driver->suspend) { - spin_unlock(&dev->lock); - dev->sys_suspended = 1; - dev->driver->suspend(&dev->gadget); - spin_lock(&dev->lock); - } - } /* new speed ? */ - if (dev_irq & AMD_BIT(UDC_DEVINT_ENUM)) { - DBG(dev, "ENUM interrupt\n"); - ret_val = IRQ_HANDLED; - soft_reset_after_usbreset_occured = 0; - - /* disable ep0 to empty req queue */ - empty_req_queue(&dev->ep[UDC_EP0IN_IX]); - ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); - - /* link up all endpoints */ - udc_setup_endpoints(dev); - if (dev->gadget.speed == USB_SPEED_HIGH) { - dev_info(&dev->pdev->dev, "Connect: speed = %s\n", - "high"); - } else if (dev->gadget.speed == USB_SPEED_FULL) { - dev_info(&dev->pdev->dev, "Connect: speed = %s\n", - "full"); - } - - /* init ep 0 */ - activate_control_endpoints(dev); - - /* enable ep0 interrupts */ - udc_enable_ep0_interrupts(dev); - } - /* session valid change interrupt */ - if (dev_irq & AMD_BIT(UDC_DEVINT_SVC)) { - DBG(dev, "USB SVC interrupt\n"); - ret_val = IRQ_HANDLED; - - /* check that session is not valid to detect disconnect */ - tmp = readl(&dev->regs->sts); - if (!(tmp & AMD_BIT(UDC_DEVSTS_SESSVLD))) { - /* disable suspend interrupt */ - tmp = readl(&dev->regs->irqmsk); - tmp |= AMD_BIT(UDC_DEVINT_US); - writel(tmp, &dev->regs->irqmsk); - DBG(dev, "USB Disconnect (session valid low)\n"); - /* cleanup on disconnect */ - usb_disconnect(udc); - } - - } - - return ret_val; -} - -/* Interrupt Service Routine, see Linux Kernel Doc for parameters */ -static irqreturn_t udc_irq(int irq, void *pdev) -{ - struct udc *dev = pdev; - u32 reg; - u16 i; - u32 ep_irq; - irqreturn_t ret_val = IRQ_NONE; - - spin_lock(&dev->lock); - - /* check for ep irq */ - reg = readl(&dev->regs->ep_irqsts); - if (reg) { - if (reg & AMD_BIT(UDC_EPINT_OUT_EP0)) - ret_val |= udc_control_out_isr(dev); - if (reg & AMD_BIT(UDC_EPINT_IN_EP0)) - ret_val |= udc_control_in_isr(dev); - - /* - * data endpoint - * iterate ep's - */ - for (i = 1; i < UDC_EP_NUM; i++) { - ep_irq = 1 << i; - if (!(reg & ep_irq) || i == UDC_EPINT_OUT_EP0) - continue; - - /* clear irq status */ - writel(ep_irq, &dev->regs->ep_irqsts); - - /* irq for out ep ? */ - if (i > UDC_EPIN_NUM) - ret_val |= udc_data_out_isr(dev, i); - else - ret_val |= udc_data_in_isr(dev, i); - } - - } - - - /* check for dev irq */ - reg = readl(&dev->regs->irqsts); - if (reg) { - /* clear irq */ - writel(reg, &dev->regs->irqsts); - ret_val |= udc_dev_isr(dev, reg); - } - - - spin_unlock(&dev->lock); - return ret_val; -} - -/* Tears down device */ -static void gadget_release(struct device *pdev) -{ - struct amd5536udc *dev = dev_get_drvdata(pdev); - kfree(dev); -} - -/* Cleanup on device remove */ -static void udc_remove(struct udc *dev) -{ - /* remove timer */ - stop_timer++; - if (timer_pending(&udc_timer)) - wait_for_completion(&on_exit); - if (udc_timer.data) - del_timer_sync(&udc_timer); - /* remove pollstall timer */ - stop_pollstall_timer++; - if (timer_pending(&udc_pollstall_timer)) - wait_for_completion(&on_pollstall_exit); - if (udc_pollstall_timer.data) - del_timer_sync(&udc_pollstall_timer); - udc = NULL; -} - -/* Reset all pci context */ -static void udc_pci_remove(struct pci_dev *pdev) -{ - struct udc *dev; - - dev = pci_get_drvdata(pdev); - - /* gadget driver must not be registered */ - BUG_ON(dev->driver != NULL); - - /* dma pool cleanup */ - if (dev->data_requests) - pci_pool_destroy(dev->data_requests); - - if (dev->stp_requests) { - /* cleanup DMA desc's for ep0in */ - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td_stp, - dev->ep[UDC_EP0OUT_IX].td_stp_dma); - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td, - dev->ep[UDC_EP0OUT_IX].td_phys); - - pci_pool_destroy(dev->stp_requests); - } - - /* reset controller */ - writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - if (dev->irq_registered) - free_irq(pdev->irq, dev); - if (dev->regs) - iounmap(dev->regs); - if (dev->mem_region) - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (dev->active) - pci_disable_device(pdev); - - device_unregister(&dev->gadget.dev); - pci_set_drvdata(pdev, NULL); - - udc_remove(dev); -} - -/* create dma pools on init */ -static int init_dma_pools(struct udc *dev) -{ - struct udc_stp_dma *td_stp; - struct udc_data_dma *td_data; - int retval; - - /* consistent DMA mode setting ? */ - if (use_dma_ppb) { - use_dma_bufferfill_mode = 0; - } else { - use_dma_ppb_du = 0; - use_dma_bufferfill_mode = 1; - } - - /* DMA setup */ - dev->data_requests = dma_pool_create("data_requests", NULL, - sizeof(struct udc_data_dma), 0, 0); - if (!dev->data_requests) { - DBG(dev, "can't get request data pool\n"); - retval = -ENOMEM; - goto finished; - } - - /* EP0 in dma regs = dev control regs */ - dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl; - - /* dma desc for setup data */ - dev->stp_requests = dma_pool_create("setup requests", NULL, - sizeof(struct udc_stp_dma), 0, 0); - if (!dev->stp_requests) { - DBG(dev, "can't get stp request pool\n"); - retval = -ENOMEM; - goto finished; - } - /* setup */ - td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, - &dev->ep[UDC_EP0OUT_IX].td_stp_dma); - if (td_stp == NULL) { - retval = -ENOMEM; - goto finished; - } - dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; - - /* data: 0 packets !? */ - td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, - &dev->ep[UDC_EP0OUT_IX].td_phys); - if (td_data == NULL) { - retval = -ENOMEM; - goto finished; - } - dev->ep[UDC_EP0OUT_IX].td = td_data; - return 0; - -finished: - return retval; -} - -/* Called by pci bus driver to init pci context */ -static int udc_pci_probe( - struct pci_dev *pdev, - const struct pci_device_id *id -) -{ - struct udc *dev; - unsigned long resource; - unsigned long len; - int retval = 0; - - /* one udc only */ - if (udc) { - dev_dbg(&pdev->dev, "already probed\n"); - return -EBUSY; - } - - /* init */ - dev = kzalloc(sizeof(struct udc), GFP_KERNEL); - if (!dev) { - retval = -ENOMEM; - goto finished; - } - memset(dev, 0, sizeof(struct udc)); - - /* pci setup */ - if (pci_enable_device(pdev) < 0) { - retval = -ENODEV; - goto finished; - } - dev->active = 1; - - /* PCI resource allocation */ - resource = pci_resource_start(pdev, 0); - len = pci_resource_len(pdev, 0); - - if (!request_mem_region(resource, len, name)) { - dev_dbg(&pdev->dev, "pci device used already\n"); - retval = -EBUSY; - goto finished; - } - dev->mem_region = 1; - - dev->virt_addr = ioremap_nocache(resource, len); - if (dev->virt_addr == NULL) { - dev_dbg(&pdev->dev, "start address cannot be mapped\n"); - retval = -EFAULT; - goto finished; - } - - if (!pdev->irq) { - dev_err(&dev->pdev->dev, "irq not set\n"); - retval = -ENODEV; - goto finished; - } - - if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { - dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); - retval = -EBUSY; - goto finished; - } - dev->irq_registered = 1; - - pci_set_drvdata(pdev, dev); - - /* chip revision */ - dev->chiprev = 0; - - pci_set_master(pdev); - pci_set_mwi(pdev); - - /* chip rev for Hs AMD5536 */ - pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) &dev->chiprev); - /* init dma pools */ - if (use_dma) { - retval = init_dma_pools(dev); - if (retval != 0) - goto finished; - } - - dev->phys_addr = resource; - dev->irq = pdev->irq; - dev->pdev = pdev; - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - - /* general probing */ - if (udc_probe(dev) == 0) - return 0; - -finished: - if (dev) - udc_pci_remove(pdev); - return retval; -} - -/* general probe */ -static int udc_probe(struct udc *dev) -{ - char tmp[128]; - u32 reg; - int retval; - - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - - /* device struct setup */ - spin_lock_init(&dev->lock); - dev->gadget.ops = &udc_ops; - - strcpy(dev->gadget.dev.bus_id, "gadget"); - dev->gadget.dev.release = gadget_release; - dev->gadget.name = name; - dev->gadget.name = name; - dev->gadget.is_dualspeed = 1; - - /* udc csr registers base */ - dev->csr = dev->virt_addr + UDC_CSR_ADDR; - /* dev registers base */ - dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; - /* ep registers base */ - dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; - /* fifo's base */ - dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); - dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); - - /* init registers, interrupts, ... */ - startup_registers(dev); - - dev_info(&dev->pdev->dev, "%s\n", mod_desc); - - snprintf(tmp, sizeof tmp, "%d", dev->irq); - dev_info(&dev->pdev->dev, - "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", - tmp, dev->phys_addr, dev->chiprev, - (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); - strcpy(tmp, UDC_DRIVER_VERSION_STRING); - if (dev->chiprev == UDC_HSA0_REV) { - dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); - retval = -ENODEV; - goto finished; - } - dev_info(&dev->pdev->dev, - "driver version: %s(for Geode5536 B1)\n", tmp); - udc = dev; - - retval = device_register(&dev->gadget.dev); - if (retval) - goto finished; - - /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; - - /* set SD */ - reg = readl(&dev->regs->ctl); - reg |= AMD_BIT(UDC_DEVCTL_SD); - writel(reg, &dev->regs->ctl); - - /* print dev register info */ - print_regs(dev); - - return 0; - -finished: - return retval; -} - -/* Initiates a remote wakeup */ -static int udc_remote_wakeup(struct udc *dev) -{ - unsigned long flags; - u32 tmp; - - DBG(dev, "UDC initiates remote wakeup\n"); - - spin_lock_irqsave(&dev->lock, flags); - - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} - -/* PCI device parameters */ -static const struct pci_device_id pci_id[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, - .class_mask = 0xffffffff, - }, - {}, -}; -MODULE_DEVICE_TABLE(pci, pci_id); - -/* PCI functions */ -static struct pci_driver udc_pci_driver = { - .name = (char *) name, - .id_table = pci_id, - .probe = udc_pci_probe, - .remove = udc_pci_remove, -}; - -/* Inits driver */ -static int __init init(void) -{ - return pci_register_driver(&udc_pci_driver); -} -module_init(init); - -/* Cleans driver */ -static void __exit cleanup(void) -{ - pci_unregister_driver(&udc_pci_driver); -} -module_exit(cleanup); - -MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION); -MODULE_AUTHOR("Thomas Dahlmann"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/usb/gadget/amd5536udc.h b/trunk/drivers/usb/gadget/amd5536udc.h deleted file mode 100644 index 4bbabbbfc93f..000000000000 --- a/trunk/drivers/usb/gadget/amd5536udc.h +++ /dev/null @@ -1,626 +0,0 @@ -/* - * amd5536.h -- header for AMD 5536 UDC high/full speed USB device controller - * - * Copyright (C) 2007 AMD (http://www.amd.com) - * Author: Thomas Dahlmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef AMD5536UDC_H -#define AMD5536UDC_H - -/* various constants */ -#define UDC_RDE_TIMER_SECONDS 1 -#define UDC_RDE_TIMER_DIV 10 -#define UDC_POLLSTALL_TIMER_USECONDS 500 - -/* Hs AMD5536 chip rev. */ -#define UDC_HSA0_REV 1 -#define UDC_HSB1_REV 2 - -/* - * SETUP usb commands - * needed, because some SETUP's are handled in hw, but must be passed to - * gadget driver above - * SET_CONFIG - */ -#define UDC_SETCONFIG_DWORD0 0x00000900 -#define UDC_SETCONFIG_DWORD0_VALUE_MASK 0xffff0000 -#define UDC_SETCONFIG_DWORD0_VALUE_OFS 16 - -#define UDC_SETCONFIG_DWORD1 0x00000000 - -/* SET_INTERFACE */ -#define UDC_SETINTF_DWORD0 0x00000b00 -#define UDC_SETINTF_DWORD0_ALT_MASK 0xffff0000 -#define UDC_SETINTF_DWORD0_ALT_OFS 16 - -#define UDC_SETINTF_DWORD1 0x00000000 -#define UDC_SETINTF_DWORD1_INTF_MASK 0x0000ffff -#define UDC_SETINTF_DWORD1_INTF_OFS 0 - -/* Mass storage reset */ -#define UDC_MSCRES_DWORD0 0x0000ff21 -#define UDC_MSCRES_DWORD1 0x00000000 - -/* Global CSR's -------------------------------------------------------------*/ -#define UDC_CSR_ADDR 0x500 - -/* EP NE bits */ -/* EP number */ -#define UDC_CSR_NE_NUM_MASK 0x0000000f -#define UDC_CSR_NE_NUM_OFS 0 -/* EP direction */ -#define UDC_CSR_NE_DIR_MASK 0x00000010 -#define UDC_CSR_NE_DIR_OFS 4 -/* EP type */ -#define UDC_CSR_NE_TYPE_MASK 0x00000060 -#define UDC_CSR_NE_TYPE_OFS 5 -/* EP config number */ -#define UDC_CSR_NE_CFG_MASK 0x00000780 -#define UDC_CSR_NE_CFG_OFS 7 -/* EP interface number */ -#define UDC_CSR_NE_INTF_MASK 0x00007800 -#define UDC_CSR_NE_INTF_OFS 11 -/* EP alt setting */ -#define UDC_CSR_NE_ALT_MASK 0x00078000 -#define UDC_CSR_NE_ALT_OFS 15 - -/* max pkt */ -#define UDC_CSR_NE_MAX_PKT_MASK 0x3ff80000 -#define UDC_CSR_NE_MAX_PKT_OFS 19 - -/* Device Config Register ---------------------------------------------------*/ -#define UDC_DEVCFG_ADDR 0x400 - -#define UDC_DEVCFG_SOFTRESET 31 -#define UDC_DEVCFG_HNPSFEN 30 -#define UDC_DEVCFG_DMARST 29 -#define UDC_DEVCFG_SET_DESC 18 -#define UDC_DEVCFG_CSR_PRG 17 -#define UDC_DEVCFG_STATUS 7 -#define UDC_DEVCFG_DIR 6 -#define UDC_DEVCFG_PI 5 -#define UDC_DEVCFG_SS 4 -#define UDC_DEVCFG_SP 3 -#define UDC_DEVCFG_RWKP 2 - -#define UDC_DEVCFG_SPD_MASK 0x3 -#define UDC_DEVCFG_SPD_OFS 0 -#define UDC_DEVCFG_SPD_HS 0x0 -#define UDC_DEVCFG_SPD_FS 0x1 -#define UDC_DEVCFG_SPD_LS 0x2 -/*#define UDC_DEVCFG_SPD_FS 0x3*/ - - -/* Device Control Register --------------------------------------------------*/ -#define UDC_DEVCTL_ADDR 0x404 - -#define UDC_DEVCTL_THLEN_MASK 0xff000000 -#define UDC_DEVCTL_THLEN_OFS 24 - -#define UDC_DEVCTL_BRLEN_MASK 0x00ff0000 -#define UDC_DEVCTL_BRLEN_OFS 16 - -#define UDC_DEVCTL_CSR_DONE 13 -#define UDC_DEVCTL_DEVNAK 12 -#define UDC_DEVCTL_SD 10 -#define UDC_DEVCTL_MODE 9 -#define UDC_DEVCTL_BREN 8 -#define UDC_DEVCTL_THE 7 -#define UDC_DEVCTL_BF 6 -#define UDC_DEVCTL_BE 5 -#define UDC_DEVCTL_DU 4 -#define UDC_DEVCTL_TDE 3 -#define UDC_DEVCTL_RDE 2 -#define UDC_DEVCTL_RES 0 - - -/* Device Status Register ---------------------------------------------------*/ -#define UDC_DEVSTS_ADDR 0x408 - -#define UDC_DEVSTS_TS_MASK 0xfffc0000 -#define UDC_DEVSTS_TS_OFS 18 - -#define UDC_DEVSTS_SESSVLD 17 -#define UDC_DEVSTS_PHY_ERROR 16 -#define UDC_DEVSTS_RXFIFO_EMPTY 15 - -#define UDC_DEVSTS_ENUM_SPEED_MASK 0x00006000 -#define UDC_DEVSTS_ENUM_SPEED_OFS 13 -#define UDC_DEVSTS_ENUM_SPEED_FULL 1 -#define UDC_DEVSTS_ENUM_SPEED_HIGH 0 - -#define UDC_DEVSTS_SUSP 12 - -#define UDC_DEVSTS_ALT_MASK 0x00000f00 -#define UDC_DEVSTS_ALT_OFS 8 - -#define UDC_DEVSTS_INTF_MASK 0x000000f0 -#define UDC_DEVSTS_INTF_OFS 4 - -#define UDC_DEVSTS_CFG_MASK 0x0000000f -#define UDC_DEVSTS_CFG_OFS 0 - - -/* Device Interrupt Register ------------------------------------------------*/ -#define UDC_DEVINT_ADDR 0x40c - -#define UDC_DEVINT_SVC 7 -#define UDC_DEVINT_ENUM 6 -#define UDC_DEVINT_SOF 5 -#define UDC_DEVINT_US 4 -#define UDC_DEVINT_UR 3 -#define UDC_DEVINT_ES 2 -#define UDC_DEVINT_SI 1 -#define UDC_DEVINT_SC 0 - -/* Device Interrupt Mask Register -------------------------------------------*/ -#define UDC_DEVINT_MSK_ADDR 0x410 - -#define UDC_DEVINT_MSK 0x7f - -/* Endpoint Interrupt Register ----------------------------------------------*/ -#define UDC_EPINT_ADDR 0x414 - -#define UDC_EPINT_OUT_MASK 0xffff0000 -#define UDC_EPINT_OUT_OFS 16 -#define UDC_EPINT_IN_MASK 0x0000ffff -#define UDC_EPINT_IN_OFS 0 - -#define UDC_EPINT_IN_EP0 0 -#define UDC_EPINT_IN_EP1 1 -#define UDC_EPINT_IN_EP2 2 -#define UDC_EPINT_IN_EP3 3 -#define UDC_EPINT_OUT_EP0 16 -#define UDC_EPINT_OUT_EP1 17 -#define UDC_EPINT_OUT_EP2 18 -#define UDC_EPINT_OUT_EP3 19 - -#define UDC_EPINT_EP0_ENABLE_MSK 0x001e001e - -/* Endpoint Interrupt Mask Register -----------------------------------------*/ -#define UDC_EPINT_MSK_ADDR 0x418 - -#define UDC_EPINT_OUT_MSK_MASK 0xffff0000 -#define UDC_EPINT_OUT_MSK_OFS 16 -#define UDC_EPINT_IN_MSK_MASK 0x0000ffff -#define UDC_EPINT_IN_MSK_OFS 0 - -#define UDC_EPINT_MSK_DISABLE_ALL 0xffffffff -/* mask non-EP0 endpoints */ -#define UDC_EPDATAINT_MSK_DISABLE 0xfffefffe -/* mask all dev interrupts */ -#define UDC_DEV_MSK_DISABLE 0x7f - -/* Endpoint-specific CSR's --------------------------------------------------*/ -#define UDC_EPREGS_ADDR 0x0 -#define UDC_EPIN_REGS_ADDR 0x0 -#define UDC_EPOUT_REGS_ADDR 0x200 - -#define UDC_EPCTL_ADDR 0x0 - -#define UDC_EPCTL_RRDY 9 -#define UDC_EPCTL_CNAK 8 -#define UDC_EPCTL_SNAK 7 -#define UDC_EPCTL_NAK 6 - -#define UDC_EPCTL_ET_MASK 0x00000030 -#define UDC_EPCTL_ET_OFS 4 -#define UDC_EPCTL_ET_CONTROL 0 -#define UDC_EPCTL_ET_ISO 1 -#define UDC_EPCTL_ET_BULK 2 -#define UDC_EPCTL_ET_INTERRUPT 3 - -#define UDC_EPCTL_P 3 -#define UDC_EPCTL_SN 2 -#define UDC_EPCTL_F 1 -#define UDC_EPCTL_S 0 - -/* Endpoint Status Registers ------------------------------------------------*/ -#define UDC_EPSTS_ADDR 0x4 - -#define UDC_EPSTS_RX_PKT_SIZE_MASK 0x007ff800 -#define UDC_EPSTS_RX_PKT_SIZE_OFS 11 - -#define UDC_EPSTS_TDC 10 -#define UDC_EPSTS_HE 9 -#define UDC_EPSTS_BNA 7 -#define UDC_EPSTS_IN 6 - -#define UDC_EPSTS_OUT_MASK 0x00000030 -#define UDC_EPSTS_OUT_OFS 4 -#define UDC_EPSTS_OUT_DATA 1 -#define UDC_EPSTS_OUT_DATA_CLEAR 0x10 -#define UDC_EPSTS_OUT_SETUP 2 -#define UDC_EPSTS_OUT_SETUP_CLEAR 0x20 -#define UDC_EPSTS_OUT_CLEAR 0x30 - -/* Endpoint Buffer Size IN/ Receive Packet Frame Number OUT Registers ------*/ -#define UDC_EPIN_BUFF_SIZE_ADDR 0x8 -#define UDC_EPOUT_FRAME_NUMBER_ADDR 0x8 - -#define UDC_EPIN_BUFF_SIZE_MASK 0x0000ffff -#define UDC_EPIN_BUFF_SIZE_OFS 0 -/* EP0in txfifo = 128 bytes*/ -#define UDC_EPIN0_BUFF_SIZE 32 -/* EP0in fullspeed txfifo = 128 bytes*/ -#define UDC_FS_EPIN0_BUFF_SIZE 32 - -/* fifo size mult = fifo size / max packet */ -#define UDC_EPIN_BUFF_SIZE_MULT 2 - -/* EPin data fifo size = 1024 bytes DOUBLE BUFFERING */ -#define UDC_EPIN_BUFF_SIZE 256 -/* EPin small INT data fifo size = 128 bytes */ -#define UDC_EPIN_SMALLINT_BUFF_SIZE 32 - -/* EPin fullspeed data fifo size = 128 bytes DOUBLE BUFFERING */ -#define UDC_FS_EPIN_BUFF_SIZE 32 - -#define UDC_EPOUT_FRAME_NUMBER_MASK 0x0000ffff -#define UDC_EPOUT_FRAME_NUMBER_OFS 0 - -/* Endpoint Buffer Size OUT/Max Packet Size Registers -----------------------*/ -#define UDC_EPOUT_BUFF_SIZE_ADDR 0x0c -#define UDC_EP_MAX_PKT_SIZE_ADDR 0x0c - -#define UDC_EPOUT_BUFF_SIZE_MASK 0xffff0000 -#define UDC_EPOUT_BUFF_SIZE_OFS 16 -#define UDC_EP_MAX_PKT_SIZE_MASK 0x0000ffff -#define UDC_EP_MAX_PKT_SIZE_OFS 0 -/* EP0in max packet size = 64 bytes */ -#define UDC_EP0IN_MAX_PKT_SIZE 64 -/* EP0out max packet size = 64 bytes */ -#define UDC_EP0OUT_MAX_PKT_SIZE 64 -/* EP0in fullspeed max packet size = 64 bytes */ -#define UDC_FS_EP0IN_MAX_PKT_SIZE 64 -/* EP0out fullspeed max packet size = 64 bytes */ -#define UDC_FS_EP0OUT_MAX_PKT_SIZE 64 - -/* - * Endpoint dma descriptors ------------------------------------------------ - * - * Setup data, Status dword - */ -#define UDC_DMA_STP_STS_CFG_MASK 0x0fff0000 -#define UDC_DMA_STP_STS_CFG_OFS 16 -#define UDC_DMA_STP_STS_CFG_ALT_MASK 0x000f0000 -#define UDC_DMA_STP_STS_CFG_ALT_OFS 16 -#define UDC_DMA_STP_STS_CFG_INTF_MASK 0x00f00000 -#define UDC_DMA_STP_STS_CFG_INTF_OFS 20 -#define UDC_DMA_STP_STS_CFG_NUM_MASK 0x0f000000 -#define UDC_DMA_STP_STS_CFG_NUM_OFS 24 -#define UDC_DMA_STP_STS_RX_MASK 0x30000000 -#define UDC_DMA_STP_STS_RX_OFS 28 -#define UDC_DMA_STP_STS_BS_MASK 0xc0000000 -#define UDC_DMA_STP_STS_BS_OFS 30 -#define UDC_DMA_STP_STS_BS_HOST_READY 0 -#define UDC_DMA_STP_STS_BS_DMA_BUSY 1 -#define UDC_DMA_STP_STS_BS_DMA_DONE 2 -#define UDC_DMA_STP_STS_BS_HOST_BUSY 3 -/* IN data, Status dword */ -#define UDC_DMA_IN_STS_TXBYTES_MASK 0x0000ffff -#define UDC_DMA_IN_STS_TXBYTES_OFS 0 -#define UDC_DMA_IN_STS_FRAMENUM_MASK 0x07ff0000 -#define UDC_DMA_IN_STS_FRAMENUM_OFS 0 -#define UDC_DMA_IN_STS_L 27 -#define UDC_DMA_IN_STS_TX_MASK 0x30000000 -#define UDC_DMA_IN_STS_TX_OFS 28 -#define UDC_DMA_IN_STS_BS_MASK 0xc0000000 -#define UDC_DMA_IN_STS_BS_OFS 30 -#define UDC_DMA_IN_STS_BS_HOST_READY 0 -#define UDC_DMA_IN_STS_BS_DMA_BUSY 1 -#define UDC_DMA_IN_STS_BS_DMA_DONE 2 -#define UDC_DMA_IN_STS_BS_HOST_BUSY 3 -/* OUT data, Status dword */ -#define UDC_DMA_OUT_STS_RXBYTES_MASK 0x0000ffff -#define UDC_DMA_OUT_STS_RXBYTES_OFS 0 -#define UDC_DMA_OUT_STS_FRAMENUM_MASK 0x07ff0000 -#define UDC_DMA_OUT_STS_FRAMENUM_OFS 0 -#define UDC_DMA_OUT_STS_L 27 -#define UDC_DMA_OUT_STS_RX_MASK 0x30000000 -#define UDC_DMA_OUT_STS_RX_OFS 28 -#define UDC_DMA_OUT_STS_BS_MASK 0xc0000000 -#define UDC_DMA_OUT_STS_BS_OFS 30 -#define UDC_DMA_OUT_STS_BS_HOST_READY 0 -#define UDC_DMA_OUT_STS_BS_DMA_BUSY 1 -#define UDC_DMA_OUT_STS_BS_DMA_DONE 2 -#define UDC_DMA_OUT_STS_BS_HOST_BUSY 3 -/* max ep0in packet */ -#define UDC_EP0IN_MAXPACKET 1000 -/* max dma packet */ -#define UDC_DMA_MAXPACKET 65536 - -/* un-usable DMA address */ -#define DMA_DONT_USE (~(dma_addr_t) 0 ) - -/* other Endpoint register addresses and values-----------------------------*/ -#define UDC_EP_SUBPTR_ADDR 0x10 -#define UDC_EP_DESPTR_ADDR 0x14 -#define UDC_EP_WRITE_CONFIRM_ADDR 0x1c - -/* EP number as layouted in AHB space */ -#define UDC_EP_NUM 32 -#define UDC_EPIN_NUM 16 -#define UDC_EPIN_NUM_USED 5 -#define UDC_EPOUT_NUM 16 -/* EP number of EP's really used = EP0 + 8 data EP's */ -#define UDC_USED_EP_NUM 9 -/* UDC CSR regs are aligned but AHB regs not - offset for OUT EP's */ -#define UDC_CSR_EP_OUT_IX_OFS 12 - -#define UDC_EP0OUT_IX 16 -#define UDC_EP0IN_IX 0 - -/* Rx fifo address and size = 1k -------------------------------------------*/ -#define UDC_RXFIFO_ADDR 0x800 -#define UDC_RXFIFO_SIZE 0x400 - -/* Tx fifo address and size = 1.5k -----------------------------------------*/ -#define UDC_TXFIFO_ADDR 0xc00 -#define UDC_TXFIFO_SIZE 0x600 - -/* default data endpoints --------------------------------------------------*/ -#define UDC_EPIN_STATUS_IX 1 -#define UDC_EPIN_IX 2 -#define UDC_EPOUT_IX 18 - -/* general constants -------------------------------------------------------*/ -#define UDC_DWORD_BYTES 4 -#define UDC_BITS_PER_BYTE_SHIFT 3 -#define UDC_BYTE_MASK 0xff -#define UDC_BITS_PER_BYTE 8 - -/*---------------------------------------------------------------------------*/ -/* UDC CSR's */ -struct udc_csrs { - - /* sca - setup command address */ - u32 sca; - - /* ep ne's */ - u32 ne[UDC_USED_EP_NUM]; -} __attribute__ ((packed)); - -/* AHB subsystem CSR registers */ -struct udc_regs { - - /* device configuration */ - u32 cfg; - - /* device control */ - u32 ctl; - - /* device status */ - u32 sts; - - /* device interrupt */ - u32 irqsts; - - /* device interrupt mask */ - u32 irqmsk; - - /* endpoint interrupt */ - u32 ep_irqsts; - - /* endpoint interrupt mask */ - u32 ep_irqmsk; -} __attribute__ ((packed)); - -/* endpoint specific registers */ -struct udc_ep_regs { - - /* endpoint control */ - u32 ctl; - - /* endpoint status */ - u32 sts; - - /* endpoint buffer size in/ receive packet frame number out */ - u32 bufin_framenum; - - /* endpoint buffer size out/max packet size */ - u32 bufout_maxpkt; - - /* endpoint setup buffer pointer */ - u32 subptr; - - /* endpoint data descriptor pointer */ - u32 desptr; - - /* reserverd */ - u32 reserved; - - /* write/read confirmation */ - u32 confirm; - -} __attribute__ ((packed)); - -/* control data DMA desc */ -struct udc_stp_dma { - /* status quadlet */ - u32 status; - /* reserved */ - u32 _reserved; - /* first setup word */ - u32 data12; - /* second setup word */ - u32 data34; -} __attribute__ ((aligned (16))); - -/* normal data DMA desc */ -struct udc_data_dma { - /* status quadlet */ - u32 status; - /* reserved */ - u32 _reserved; - /* buffer pointer */ - u32 bufptr; - /* next descriptor pointer */ - u32 next; -} __attribute__ ((aligned (16))); - -/* request packet */ -struct udc_request { - /* embedded gadget ep */ - struct usb_request req; - - /* flags */ - unsigned dma_going : 1, - dma_mapping : 1, - dma_done : 1; - /* phys. address */ - dma_addr_t td_phys; - /* first dma desc. of chain */ - struct udc_data_dma *td_data; - /* last dma desc. of chain */ - struct udc_data_dma *td_data_last; - struct list_head queue; - - /* chain length */ - unsigned chain_len; - -}; - -/* UDC specific endpoint parameters */ -struct udc_ep { - struct usb_ep ep; - struct udc_ep_regs __iomem *regs; - u32 __iomem *txfifo; - u32 __iomem *dma; - dma_addr_t td_phys; - dma_addr_t td_stp_dma; - struct udc_stp_dma *td_stp; - struct udc_data_dma *td; - /* temp request */ - struct udc_request *req; - unsigned req_used; - unsigned req_completed; - /* dummy DMA desc for BNA dummy */ - struct udc_request *bna_dummy_req; - unsigned bna_occurred; - - /* NAK state */ - unsigned naking; - - struct udc *dev; - - /* queue for requests */ - struct list_head queue; - const struct usb_endpoint_descriptor *desc; - unsigned halted; - unsigned cancel_transfer; - unsigned num : 5, - fifo_depth : 14, - in : 1; -}; - -/* device struct */ -struct udc { - struct usb_gadget gadget; - spinlock_t lock; /* protects all state */ - /* all endpoints */ - struct udc_ep ep[UDC_EP_NUM]; - struct usb_gadget_driver *driver; - /* operational flags */ - unsigned active : 1, - stall_ep0in : 1, - waiting_zlp_ack_ep0in : 1, - set_cfg_not_acked : 1, - irq_registered : 1, - data_ep_enabled : 1, - data_ep_queued : 1, - mem_region : 1, - sys_suspended : 1, - connected; - - u16 chiprev; - - /* registers */ - struct pci_dev *pdev; - struct udc_csrs __iomem *csr; - struct udc_regs __iomem *regs; - struct udc_ep_regs __iomem *ep_regs; - u32 __iomem *rxfifo; - u32 __iomem *txfifo; - - /* DMA desc pools */ - struct pci_pool *data_requests; - struct pci_pool *stp_requests; - - /* device data */ - unsigned long phys_addr; - void __iomem *virt_addr; - unsigned irq; - - /* states */ - u16 cur_config; - u16 cur_intf; - u16 cur_alt; -}; - -/* setup request data */ -union udc_setup_data { - u32 data[2]; - struct usb_ctrlrequest request; -}; - -/* - *--------------------------------------------------------------------------- - * SET and GET bitfields in u32 values - * via constants for mask/offset: - * is the text between - * UDC_ and _MASK|_OFS of appropiate - * constant - * - * set bitfield value in u32 u32Val - */ -#define AMD_ADDBITS(u32Val, bitfield_val, bitfield_stub_name) \ - (((u32Val) & (((u32) ~((u32) bitfield_stub_name##_MASK)))) \ - | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ - & ((u32) bitfield_stub_name##_MASK))) - -/* - * set bitfield value in zero-initialized u32 u32Val - * => bitfield bits in u32Val are all zero - */ -#define AMD_INIT_SETBITS(u32Val, bitfield_val, bitfield_stub_name) \ - ((u32Val) \ - | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ - & ((u32) bitfield_stub_name##_MASK))) - -/* get bitfield value from u32 u32Val */ -#define AMD_GETBITS(u32Val, bitfield_stub_name) \ - ((u32Val & ((u32) bitfield_stub_name##_MASK)) \ - >> ((u32) bitfield_stub_name##_OFS)) - -/* SET and GET bits in u32 values ------------------------------------------*/ -#define AMD_BIT(bit_stub_name) (1 << bit_stub_name) -#define AMD_UNMASK_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) -#define AMD_CLEAR_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) - -/* debug macros ------------------------------------------------------------*/ - -#define DBG(udc , args...) dev_dbg(&(udc)->pdev->dev, args) - -#ifdef UDC_VERBOSE -#define VDBG DBG -#else -#define VDBG(udc , args...) do {} while (0) -#endif - -#endif /* #ifdef AMD5536UDC_H */ diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index a3376739a81b..dbaf867436df 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -305,10 +305,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); #define DEV_CONFIG_CDC #endif -#ifdef CONFIG_USB_GADGET_AMD5536UDC -#define DEV_CONFIG_CDC -#endif - /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/gadget_chips.h b/trunk/drivers/usb/gadget/gadget_chips.h index f7f159c1002b..53e9139ba388 100644 --- a/trunk/drivers/usb/gadget/gadget_chips.h +++ b/trunk/drivers/usb/gadget/gadget_chips.h @@ -17,12 +17,6 @@ #define gadget_is_net2280(g) 0 #endif -#ifdef CONFIG_USB_GADGET_AMD5536UDC -#define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name) -#else -#define gadget_is_amd5536udc(g) 0 -#endif - #ifdef CONFIG_USB_GADGET_DUMMY_HCD #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) #else @@ -208,9 +202,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) return 0x18; else if (gadget_is_fsl_usb2(gadget)) return 0x19; - else if (gadget_is_amd5536udc(gadget)) - return 0x20; else if (gadget_is_m66592(gadget)) - return 0x21; + return 0x20; return -ENOENT; } diff --git a/trunk/drivers/usb/gadget/m66592-udc.c b/trunk/drivers/usb/gadget/m66592-udc.c index 700dda8a9157..0174a322e007 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.c +++ b/trunk/drivers/usb/gadget/m66592-udc.c @@ -21,18 +21,26 @@ */ #include -#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include #include - #include #include -#include "m66592-udc.h" +#include +#include +#include +#include "m66592-udc.h" -MODULE_DESCRIPTION("M66592 USB gadget driver"); +MODULE_DESCRIPTION("M66592 USB gadget driiver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yoshihiro Shimoda"); @@ -41,21 +49,16 @@ MODULE_AUTHOR("Yoshihiro Shimoda"); /* module parameters */ static unsigned short clock = M66592_XTAL24; module_param(clock, ushort, 0644); -MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " - "(default=16384)"); - +MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)"); static unsigned short vif = M66592_LDRV; module_param(vif, ushort, 0644); -MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); - -static unsigned short endian; +MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); +static unsigned short endian = 0; module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); - +MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); static unsigned short irq_sense = M66592_INTL; module_param(irq_sense, ushort, 0644); -MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " - "(default=2)"); +MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)"); static const char udc_name[] = "m66592_udc"; static const char *m66592_ep_name[] = { @@ -69,8 +72,8 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags); static void transfer_complete(struct m66592_ep *ep, - struct m66592_request *req, int status); - + struct m66592_request *req, + int status); /*-------------------------------------------------------------------------*/ static inline u16 get_usb_speed(struct m66592 *m66592) { @@ -78,25 +81,25 @@ static inline u16 get_usb_speed(struct m66592 *m66592) } static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, - unsigned long reg) + unsigned long reg) { u16 tmp; tmp = m66592_read(m66592, M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, - M66592_INTENB0); + M66592_INTENB0); m66592_bset(m66592, (1 << pipenum), reg); m66592_write(m66592, tmp, M66592_INTENB0); } static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, - unsigned long reg) + unsigned long reg) { u16 tmp; tmp = m66592_read(m66592, M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, - M66592_INTENB0); + M66592_INTENB0); m66592_bclr(m66592, (1 << pipenum), reg); m66592_write(m66592, tmp, M66592_INTENB0); } @@ -105,19 +108,17 @@ static void m66592_usb_connect(struct m66592 *m66592) { m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, - M66592_INTENB0); + M66592_INTENB0); m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); } static void m66592_usb_disconnect(struct m66592 *m66592) -__releases(m66592->lock) -__acquires(m66592->lock) { m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, - M66592_INTENB0); + M66592_INTENB0); m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); @@ -147,7 +148,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) } static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, - u16 pid) + u16 pid) { unsigned long offset; @@ -249,7 +250,7 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum) } static int pipe_buffer_setting(struct m66592 *m66592, - struct m66592_pipe_info *info) + struct m66592_pipe_info *info) { u16 bufnum = 0, buf_bsize = 0; u16 pipecfg = 0; @@ -286,7 +287,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, } if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", - m66592->bi_bufnum); + m66592->bi_bufnum); return -ENOMEM; } @@ -327,7 +328,7 @@ static void pipe_buffer_release(struct m66592 *m66592, m66592->bulk--; } else printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", - info->pipe); + info->pipe); } static void pipe_initialize(struct m66592_ep *ep) @@ -349,8 +350,8 @@ static void pipe_initialize(struct m66592_ep *ep) } static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, - const struct usb_endpoint_descriptor *desc, - u16 pipenum, int dma) + const struct usb_endpoint_descriptor *desc, + u16 pipenum, int dma) { if ((pipenum != 0) && dma) { if (m66592->num_dma == 0) { @@ -384,7 +385,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, ep->pipectr = get_pipectr_addr(pipenum); ep->pipenum = pipenum; - ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + ep->ep.maxpacket = desc->wMaxPacketSize; m66592->pipenum2ep[pipenum] = ep; m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; INIT_LIST_HEAD(&ep->queue); @@ -406,7 +407,7 @@ static void m66592_ep_release(struct m66592_ep *ep) } static int alloc_pipe_config(struct m66592_ep *ep, - const struct usb_endpoint_descriptor *desc) + const struct usb_endpoint_descriptor *desc) { struct m66592 *m66592 = ep->m66592; struct m66592_pipe_info info; @@ -418,15 +419,15 @@ static int alloc_pipe_config(struct m66592_ep *ep, BUG_ON(ep->pipenum); - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { case USB_ENDPOINT_XFER_BULK: if (m66592->bulk >= M66592_MAX_NUM_BULK) { if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { printk(KERN_ERR "bulk pipe is insufficient\n"); return -ENODEV; } else { - info.pipe = M66592_BASE_PIPENUM_ISOC - + m66592->isochronous; + info.pipe = M66592_BASE_PIPENUM_ISOC + + m66592->isochronous; counter = &m66592->isochronous; } } else { @@ -461,7 +462,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, ep->type = info.type; info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; - info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + info.maxpacket = desc->wMaxPacketSize; info.interval = desc->bInterval; if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) info.dir_in = 1; @@ -524,8 +525,8 @@ static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) pipe_change(m66592, ep->pipenum); m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, - (M66592_ISEL | M66592_CURPIPE), - M66592_CFIFOSEL); + (M66592_ISEL | M66592_CURPIPE), + M66592_CFIFOSEL); m66592_write(m66592, M66592_BCLR, ep->fifoctr); if (req->req.length == 0) { m66592_bset(m66592, M66592_BVAL, ep->fifoctr); @@ -560,8 +561,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) if (ep->pipenum == 0) { m66592_mdfy(m66592, M66592_PIPE0, - (M66592_ISEL | M66592_CURPIPE), - M66592_CFIFOSEL); + (M66592_ISEL | M66592_CURPIPE), + M66592_CFIFOSEL); m66592_write(m66592, M66592_BCLR, ep->fifoctr); pipe_start(m66592, pipenum); pipe_irq_enable(m66592, pipenum); @@ -571,9 +572,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) pipe_change(m66592, pipenum); m66592_bset(m66592, M66592_TRENB, ep->fifosel); m66592_write(m66592, - (req->req.length + ep->ep.maxpacket - 1) - / ep->ep.maxpacket, - ep->fifotrn); + (req->req.length + ep->ep.maxpacket - 1) / + ep->ep.maxpacket, ep->fifotrn); } pipe_start(m66592, pipenum); /* trigger once */ pipe_irq_enable(m66592, pipenum); @@ -614,7 +614,7 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) static void init_controller(struct m66592 *m66592) { m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), - M66592_PINCFG); + M66592_PINCFG); m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); @@ -634,7 +634,7 @@ static void init_controller(struct m66592 *m66592) m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, - M66592_DMA0CFG); + M66592_DMA0CFG); } static void disable_controller(struct m66592 *m66592) @@ -659,9 +659,8 @@ static void m66592_start_xclock(struct m66592 *m66592) /*-------------------------------------------------------------------------*/ static void transfer_complete(struct m66592_ep *ep, - struct m66592_request *req, int status) -__releases(m66592->lock) -__acquires(m66592->lock) + struct m66592_request *req, + int status) { int restart = 0; @@ -681,9 +680,8 @@ __acquires(m66592->lock) if (!list_empty(&ep->queue)) restart = 1; - spin_unlock(&ep->m66592->lock); - req->req.complete(&ep->ep, &req->req); - spin_lock(&ep->m66592->lock); + if (likely(req->req.complete)) + req->req.complete(&ep->ep, &req->req); if (restart) { req = list_entry(ep->queue.next, struct m66592_request, queue); @@ -695,7 +693,7 @@ __acquires(m66592->lock) static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) { int i; - u16 tmp; + volatile u16 tmp; unsigned bufsize; size_t size; void *buf; @@ -733,9 +731,8 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { disable_irq_ready(m66592, pipenum); disable_irq_empty(m66592, pipenum); } else { @@ -771,19 +768,16 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) /* write fifo */ if (req->req.buf) { m66592_write_fifo(m66592, ep->fifoaddr, buf, size); - if ((size == 0) - || ((size % ep->ep.maxpacket) != 0) - || ((bufsize != ep->ep.maxpacket) - && (bufsize > size))) + if ((size == 0) || ((size % ep->ep.maxpacket) != 0) || + ((bufsize != ep->ep.maxpacket) && (bufsize > size))) m66592_bset(m66592, M66592_BVAL, ep->fifoctr); } /* update parameters */ req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { disable_irq_ready(m66592, pipenum); enable_irq_empty(m66592, pipenum); } else { @@ -827,9 +821,8 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) req->req.actual += size; /* check transfer finish */ - if ((!req->req.zero && (req->req.actual == req->req.length)) - || (size % ep->ep.maxpacket) - || (size == 0)) { + if ((!req->req.zero && (req->req.actual == req->req.length)) || + (size % ep->ep.maxpacket) || (size == 0)) { pipe_stop(m66592, pipenum); pipe_irq_disable(m66592, pipenum); finish = 1; @@ -857,7 +850,7 @@ static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, - M66592_CFIFOSEL); + M66592_CFIFOSEL); ep = &m66592->ep[0]; req = list_entry(ep->queue.next, struct m66592_request, queue); @@ -916,26 +909,23 @@ static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) } static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) -__releases(m66592->lock) -__acquires(m66592->lock) { struct m66592_ep *ep; u16 pid; u16 status = 0; - u16 w_index = le16_to_cpu(ctrl->wIndex); switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - status = 1 << USB_DEVICE_SELF_POWERED; + status = 1; /* selfpower */ break; case USB_RECIP_INTERFACE: status = 0; break; case USB_RECIP_ENDPOINT: - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pid = control_reg_get_pid(m66592, ep->pipenum); if (pid == M66592_PID_STALL) - status = 1 << USB_ENDPOINT_HALT; + status = 1; else status = 0; break; @@ -944,13 +934,11 @@ __acquires(m66592->lock) return; /* exit */ } - m66592->ep0_data = cpu_to_le16(status); - m66592->ep0_req->buf = &m66592->ep0_data; + *m66592->ep0_buf = status; + m66592->ep0_req->buf = m66592->ep0_buf; m66592->ep0_req->length = 2; /* AV: what happens if we get called again before that gets through? */ - spin_unlock(&m66592->lock); m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); - spin_lock(&m66592->lock); } static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) @@ -965,9 +953,8 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) case USB_RECIP_ENDPOINT: { struct m66592_ep *ep; struct m66592_request *req; - u16 w_index = le16_to_cpu(ctrl->wIndex); - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pipe_stop(m66592, ep->pipenum); control_reg_sqclr(m66592, ep->pipenum); @@ -1002,9 +989,8 @@ static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) break; case USB_RECIP_ENDPOINT: { struct m66592_ep *ep; - u16 w_index = le16_to_cpu(ctrl->wIndex); - ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; + ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; pipe_stall(m66592, ep->pipenum); control_end(m66592, 1); @@ -1080,16 +1066,14 @@ static void irq_device_state(struct m66592 *m66592) } if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) m66592_update_usb_speed(m66592); - if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) - && m66592->gadget.speed == USB_SPEED_UNKNOWN) + if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) && + m66592->gadget.speed == USB_SPEED_UNKNOWN) m66592_update_usb_speed(m66592); m66592->old_dvsq = dvsq; } static void irq_control_stage(struct m66592 *m66592) -__releases(m66592->lock) -__acquires(m66592->lock) { struct usb_ctrlrequest ctrl; u16 ctsq; @@ -1111,10 +1095,8 @@ __acquires(m66592->lock) case M66592_CS_WRDS: case M66592_CS_WRND: if (setup_packet(m66592, &ctrl)) { - spin_unlock(&m66592->lock); if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) pipe_stall(m66592, 0); - spin_lock(&m66592->lock); } break; case M66592_CS_RDSS: @@ -1137,8 +1119,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) u16 savepipe; u16 mask0; - spin_lock(&m66592->lock); - intsts0 = m66592_read(m66592, M66592_INTSTS0); intenb0 = m66592_read(m66592, M66592_INTENB0); @@ -1154,27 +1134,27 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) bempenb = m66592_read(m66592, M66592_BEMPENB); if (mask0 & M66592_VBINT) { - m66592_write(m66592, 0xffff & ~M66592_VBINT, - M66592_INTSTS0); + m66592_write(m66592, (u16)~M66592_VBINT, + M66592_INTSTS0); m66592_start_xclock(m66592); /* start vbus sampling */ m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) - & M66592_VBSTS; + & M66592_VBSTS; m66592->scount = M66592_MAX_SAMPLING; mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } if (intsts0 & M66592_DVSQ) irq_device_state(m66592); - if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) - && (brdysts & brdyenb)) { + if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) && + (brdysts & brdyenb)) { irq_pipe_ready(m66592, brdysts, brdyenb); } - if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) - && (bempsts & bempenb)) { + if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) && + (bempsts & bempenb)) { irq_pipe_empty(m66592, bempsts, bempenb); } @@ -1184,7 +1164,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) m66592_write(m66592, savepipe, M66592_CFIFOSEL); - spin_unlock(&m66592->lock); return IRQ_HANDLED; } @@ -1212,13 +1191,13 @@ static void m66592_timer(unsigned long _m66592) m66592_usb_disconnect(m66592); } else { mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } } else { m66592->scount = M66592_MAX_SAMPLING; m66592->old_vbus = tmp; mod_timer(&m66592->timer, - jiffies + msecs_to_jiffies(50)); + jiffies + msecs_to_jiffies(50)); } } spin_unlock_irqrestore(&m66592->lock, flags); @@ -1356,6 +1335,11 @@ static int m66592_set_halt(struct usb_ep *_ep, int value) return ret; } +static int m66592_fifo_status(struct usb_ep *_ep) +{ + return -EOPNOTSUPP; +} + static void m66592_fifo_flush(struct usb_ep *_ep) { struct m66592_ep *ep; @@ -1381,6 +1365,7 @@ static struct usb_ep_ops m66592_ep_ops = { .dequeue = m66592_dequeue, .set_halt = m66592_set_halt, + .fifo_status = m66592_fifo_status, .fifo_flush = m66592_fifo_flush, }; @@ -1392,10 +1377,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) struct m66592 *m66592 = the_controller; int retval; - if (!driver - || driver->speed != USB_SPEED_HIGH - || !driver->bind - || !driver->setup) + if (!driver || + driver->speed != USB_SPEED_HIGH || + !driver->bind || + !driver->unbind || + !driver->setup) return -EINVAL; if (!m66592) return -ENODEV; @@ -1427,7 +1413,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS; m66592->scount = M66592_MAX_SAMPLING; - mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50)); + mod_timer(&m66592->timer, + jiffies + msecs_to_jiffies(50)); } return 0; @@ -1445,9 +1432,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) struct m66592 *m66592 = the_controller; unsigned long flags; - if (driver != m66592->driver || !driver->unbind) - return -EINVAL; - spin_lock_irqsave(&m66592->lock, flags); if (m66592->gadget.speed != USB_SPEED_UNKNOWN) m66592_usb_disconnect(m66592); @@ -1477,35 +1461,46 @@ static struct usb_gadget_ops m66592_gadget_ops = { .get_frame = m66592_get_frame, }; -static int __exit m66592_remove(struct platform_device *pdev) +#if defined(CONFIG_PM) +static int m66592_suspend(struct platform_device *pdev, pm_message_t state) +{ + pdev->dev.power.power_state = state; + return 0; +} + +static int m66592_resume(struct platform_device *pdev) +{ + pdev->dev.power.power_state = PMSG_ON; + return 0; +} +#else /* if defined(CONFIG_PM) */ +#define m66592_suspend NULL +#define m66592_resume NULL +#endif + +static int __init_or_module m66592_remove(struct platform_device *pdev) { struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); del_timer_sync(&m66592->timer); iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); - m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); kfree(m66592); return 0; } -static void nop_completion(struct usb_ep *ep, struct usb_request *r) -{ -} - #define resource_len(r) (((r)->end - (r)->start) + 1) - static int __init m66592_probe(struct platform_device *pdev) { - struct resource *res; - int irq; + struct resource *res = NULL; + int irq = -1; void __iomem *reg = NULL; struct m66592 *m66592 = NULL; int ret = 0; int i; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - (char *)udc_name); + (char *)udc_name); if (!res) { ret = -ENODEV; printk(KERN_ERR "platform_get_resource_byname error.\n"); @@ -1553,7 +1548,7 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->bi_bufnum = M66592_BASE_BUFNUM; ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, - udc_name, m66592); + udc_name, m66592); if (ret < 0) { printk(KERN_ERR "request_irq error (%d)\n", ret); goto clean_up; @@ -1568,7 +1563,7 @@ static int __init m66592_probe(struct platform_device *pdev) if (i != 0) { INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); list_add_tail(&m66592->ep[i].ep.ep_list, - &m66592->gadget.ep_list); + &m66592->gadget.ep_list); } ep->m66592 = m66592; INIT_LIST_HEAD(&ep->queue); @@ -1588,18 +1583,20 @@ static int __init m66592_probe(struct platform_device *pdev) the_controller = m66592; + /* AV: leaks */ m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); if (m66592->ep0_req == NULL) - goto clean_up2; - m66592->ep0_req->complete = nop_completion; + goto clean_up; + /* AV: leaks, and do we really need it separately allocated? */ + m66592->ep0_buf = kzalloc(2, GFP_KERNEL); + if (m66592->ep0_buf == NULL) + goto clean_up; init_controller(m66592); - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); + printk("driver %s, %s\n", udc_name, DRIVER_VERSION); return 0; -clean_up2: - free_irq(irq, m66592); clean_up: if (m66592) { if (m66592->ep0_req) @@ -1614,7 +1611,10 @@ static int __init m66592_probe(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ static struct platform_driver m66592_driver = { - .remove = __exit_p(m66592_remove), + .probe = m66592_probe, + .remove = m66592_remove, + .suspend = m66592_suspend, + .resume = m66592_resume, .driver = { .name = (char *) udc_name, }, @@ -1622,7 +1622,7 @@ static struct platform_driver m66592_driver = { static int __init m66592_udc_init(void) { - return platform_driver_probe(&m66592_driver, m66592_probe); + return platform_driver_register(&m66592_driver); } module_init(m66592_udc_init); @@ -1631,3 +1631,4 @@ static void __exit m66592_udc_cleanup(void) platform_driver_unregister(&m66592_driver); } module_exit(m66592_udc_cleanup); + diff --git a/trunk/drivers/usb/gadget/m66592-udc.h b/trunk/drivers/usb/gadget/m66592-udc.h index bfa0c645f229..26b54f8b8945 100644 --- a/trunk/drivers/usb/gadget/m66592-udc.h +++ b/trunk/drivers/usb/gadget/m66592-udc.h @@ -24,73 +24,73 @@ #define __M66592_UDC_H__ #define M66592_SYSCFG 0x00 -#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ -#define M66592_XTAL48 0x8000 /* 48MHz */ -#define M66592_XTAL24 0x4000 /* 24MHz */ -#define M66592_XTAL12 0x0000 /* 12MHz */ -#define M66592_XCKE 0x2000 /* b13: External clock enable */ -#define M66592_RCKE 0x1000 /* b12: Register clock enable */ -#define M66592_PLLC 0x0800 /* b11: PLL control */ -#define M66592_SCKE 0x0400 /* b10: USB clock enable */ -#define M66592_ATCKM 0x0100 /* b8: Automatic clock supply */ -#define M66592_HSE 0x0080 /* b7: Hi-speed enable */ -#define M66592_DCFM 0x0040 /* b6: Controller function select */ -#define M66592_DMRPD 0x0020 /* b5: D- pull down control */ -#define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ -#define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ -#define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ -#define M66592_USBE 0x0001 /* b0: USB module operation enable */ +#define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ +#define M66592_XTAL48 0x8000 /* 48MHz */ +#define M66592_XTAL24 0x4000 /* 24MHz */ +#define M66592_XTAL12 0x0000 /* 12MHz */ +#define M66592_XCKE 0x2000 /* b13: External clock enable */ +#define M66592_RCKE 0x1000 /* b12: Register clock enable */ +#define M66592_PLLC 0x0800 /* b11: PLL control */ +#define M66592_SCKE 0x0400 /* b10: USB clock enable */ +#define M66592_ATCKM 0x0100 /* b8: Automatic supply functional enable */ +#define M66592_HSE 0x0080 /* b7: Hi-speed enable */ +#define M66592_DCFM 0x0040 /* b6: Controller function select */ +#define M66592_DMRPD 0x0020 /* b5: D- pull down control */ +#define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ +#define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ +#define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ +#define M66592_USBE 0x0001 /* b0: USB module operation enable */ #define M66592_SYSSTS 0x02 -#define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ -#define M66592_SE1 0x0003 /* SE1 */ -#define M66592_KSTS 0x0002 /* K State */ -#define M66592_JSTS 0x0001 /* J State */ -#define M66592_SE0 0x0000 /* SE0 */ +#define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ +#define M66592_SE1 0x0003 /* SE1 */ +#define M66592_KSTS 0x0002 /* K State */ +#define M66592_JSTS 0x0001 /* J State */ +#define M66592_SE0 0x0000 /* SE0 */ #define M66592_DVSTCTR 0x04 -#define M66592_WKUP 0x0100 /* b8: Remote wakeup */ -#define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ -#define M66592_USBRST 0x0040 /* b6: USB reset enable */ -#define M66592_RESUME 0x0020 /* b5: Resume enable */ -#define M66592_UACT 0x0010 /* b4: USB bus enable */ -#define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ -#define M66592_HSMODE 0x0003 /* Hi-Speed mode */ -#define M66592_FSMODE 0x0002 /* Full-Speed mode */ -#define M66592_HSPROC 0x0001 /* HS handshake is processing */ +#define M66592_WKUP 0x0100 /* b8: Remote wakeup */ +#define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ +#define M66592_USBRST 0x0040 /* b6: USB reset enable */ +#define M66592_RESUME 0x0020 /* b5: Resume enable */ +#define M66592_UACT 0x0010 /* b4: USB bus enable */ +#define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ +#define M66592_HSMODE 0x0003 /* Hi-Speed mode */ +#define M66592_FSMODE 0x0002 /* Full-Speed mode */ +#define M66592_HSPROC 0x0001 /* HS handshake is processing */ #define M66592_TESTMODE 0x06 -#define M66592_UTST 0x000F /* b4-0: Test select */ -#define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ -#define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ -#define M66592_H_TST_K 0x000A /* HOST TEST K */ -#define M66592_H_TST_J 0x0009 /* HOST TEST J */ -#define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ -#define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ -#define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ -#define M66592_P_TST_K 0x0002 /* PERI TEST K */ -#define M66592_P_TST_J 0x0001 /* PERI TEST J */ -#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ +#define M66592_UTST 0x000F /* b4-0: Test select */ +#define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ +#define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ +#define M66592_H_TST_K 0x000A /* HOST TEST K */ +#define M66592_H_TST_J 0x0009 /* HOST TEST J */ +#define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ +#define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ +#define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ +#define M66592_P_TST_K 0x0002 /* PERI TEST K */ +#define M66592_P_TST_J 0x0001 /* PERI TEST J */ +#define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ #define M66592_PINCFG 0x0A -#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ -#define M66592_BIGEND 0x0100 /* b8: Big endian mode */ +#define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ +#define M66592_BIGEND 0x0100 /* b8: Big endian mode */ #define M66592_DMA0CFG 0x0C #define M66592_DMA1CFG 0x0E -#define M66592_DREQA 0x4000 /* b14: Dreq active select */ -#define M66592_BURST 0x2000 /* b13: Burst mode */ -#define M66592_DACKA 0x0400 /* b10: Dack active select */ -#define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ -#define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ -#define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ -#define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ -#define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ -#define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ -#define M66592_DENDA 0x0040 /* b6: Dend active select */ -#define M66592_PKTM 0x0020 /* b5: Packet mode */ -#define M66592_DENDE 0x0010 /* b4: Dend enable */ -#define M66592_OBUS 0x0004 /* b2: OUTbus mode */ +#define M66592_DREQA 0x4000 /* b14: Dreq active select */ +#define M66592_BURST 0x2000 /* b13: Burst mode */ +#define M66592_DACKA 0x0400 /* b10: Dack active select */ +#define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ +#define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ +#define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ +#define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ +#define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ +#define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ +#define M66592_DENDA 0x0040 /* b6: Dend active select */ +#define M66592_PKTM 0x0020 /* b5: Packet mode */ +#define M66592_DENDE 0x0010 /* b4: Dend enable */ +#define M66592_OBUS 0x0004 /* b2: OUTbus mode */ #define M66592_CFIFO 0x10 #define M66592_D0FIFO 0x14 @@ -99,300 +99,300 @@ #define M66592_CFIFOSEL 0x1E #define M66592_D0FIFOSEL 0x24 #define M66592_D1FIFOSEL 0x2A -#define M66592_RCNT 0x8000 /* b15: Read count mode */ -#define M66592_REW 0x4000 /* b14: Buffer rewind */ -#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ -#define M66592_DREQE 0x1000 /* b12: DREQ output enable */ -#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ -#define M66592_MBW_8 0x0000 /* 8bit */ -#define M66592_MBW_16 0x0400 /* 16bit */ -#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ -#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ -#define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ -#define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ -#define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ +#define M66592_RCNT 0x8000 /* b15: Read count mode */ +#define M66592_REW 0x4000 /* b14: Buffer rewind */ +#define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ +#define M66592_DREQE 0x1000 /* b12: DREQ output enable */ +#define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO access */ +#define M66592_MBW_8 0x0000 /* 8bit */ +#define M66592_MBW_16 0x0400 /* 16bit */ +#define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ +#define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ +#define M66592_DEZPM 0x0080 /* b7: Zero-length packet additional mode */ +#define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ +#define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ #define M66592_CFIFOCTR 0x20 #define M66592_D0FIFOCTR 0x26 #define M66592_D1FIFOCTR 0x2c -#define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ -#define M66592_BCLR 0x4000 /* b14: Buffer clear */ -#define M66592_FRDY 0x2000 /* b13: FIFO ready */ -#define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ +#define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ +#define M66592_BCLR 0x4000 /* b14: Buffer clear */ +#define M66592_FRDY 0x2000 /* b13: FIFO ready */ +#define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ #define M66592_CFIFOSIE 0x22 -#define M66592_TGL 0x8000 /* b15: Buffer toggle */ -#define M66592_SCLR 0x4000 /* b14: Buffer clear */ -#define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ +#define M66592_TGL 0x8000 /* b15: Buffer toggle */ +#define M66592_SCLR 0x4000 /* b14: Buffer clear */ +#define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ #define M66592_D0FIFOTRN 0x28 #define M66592_D1FIFOTRN 0x2E -#define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ +#define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ #define M66592_INTENB0 0x30 -#define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ -#define M66592_RSME 0x4000 /* b14: Resume interrupt */ -#define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ -#define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ -#define M66592_CTRE 0x0800 /* b11: Control transfer stage transition irq */ -#define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ -#define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ -#define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ -#define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ -#define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ -#define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ -#define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ -#define M66592_WDST 0x0008 /* b3: Control write data stage completed irq */ -#define M66592_RDST 0x0004 /* b2: Control read data stage completed irq */ -#define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ -#define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ +#define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ +#define M66592_RSME 0x4000 /* b14: Resume interrupt */ +#define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ +#define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ +#define M66592_CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ +#define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ +#define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ +#define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ +#define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ +#define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ +#define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ +#define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ +#define M66592_WDST 0x0008 /* b3: Control write data stage completed interrupt */ +#define M66592_RDST 0x0004 /* b2: Control read data stage completed interrupt */ +#define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ +#define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ #define M66592_INTENB1 0x32 -#define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ -#define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ -#define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ -#define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ -#define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ -#define M66592_INTL 0x0002 /* b1: Interrupt sense select */ -#define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ +#define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ +#define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ +#define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ +#define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ +#define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ +#define M66592_INTL 0x0002 /* b1: Interrupt sense select */ +#define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ #define M66592_BRDYENB 0x36 #define M66592_BRDYSTS 0x46 -#define M66592_BRDY7 0x0080 /* b7: PIPE7 */ -#define M66592_BRDY6 0x0040 /* b6: PIPE6 */ -#define M66592_BRDY5 0x0020 /* b5: PIPE5 */ -#define M66592_BRDY4 0x0010 /* b4: PIPE4 */ -#define M66592_BRDY3 0x0008 /* b3: PIPE3 */ -#define M66592_BRDY2 0x0004 /* b2: PIPE2 */ -#define M66592_BRDY1 0x0002 /* b1: PIPE1 */ -#define M66592_BRDY0 0x0001 /* b1: PIPE0 */ +#define M66592_BRDY7 0x0080 /* b7: PIPE7 */ +#define M66592_BRDY6 0x0040 /* b6: PIPE6 */ +#define M66592_BRDY5 0x0020 /* b5: PIPE5 */ +#define M66592_BRDY4 0x0010 /* b4: PIPE4 */ +#define M66592_BRDY3 0x0008 /* b3: PIPE3 */ +#define M66592_BRDY2 0x0004 /* b2: PIPE2 */ +#define M66592_BRDY1 0x0002 /* b1: PIPE1 */ +#define M66592_BRDY0 0x0001 /* b1: PIPE0 */ #define M66592_NRDYENB 0x38 #define M66592_NRDYSTS 0x48 -#define M66592_NRDY7 0x0080 /* b7: PIPE7 */ -#define M66592_NRDY6 0x0040 /* b6: PIPE6 */ -#define M66592_NRDY5 0x0020 /* b5: PIPE5 */ -#define M66592_NRDY4 0x0010 /* b4: PIPE4 */ -#define M66592_NRDY3 0x0008 /* b3: PIPE3 */ -#define M66592_NRDY2 0x0004 /* b2: PIPE2 */ -#define M66592_NRDY1 0x0002 /* b1: PIPE1 */ -#define M66592_NRDY0 0x0001 /* b1: PIPE0 */ +#define M66592_NRDY7 0x0080 /* b7: PIPE7 */ +#define M66592_NRDY6 0x0040 /* b6: PIPE6 */ +#define M66592_NRDY5 0x0020 /* b5: PIPE5 */ +#define M66592_NRDY4 0x0010 /* b4: PIPE4 */ +#define M66592_NRDY3 0x0008 /* b3: PIPE3 */ +#define M66592_NRDY2 0x0004 /* b2: PIPE2 */ +#define M66592_NRDY1 0x0002 /* b1: PIPE1 */ +#define M66592_NRDY0 0x0001 /* b1: PIPE0 */ #define M66592_BEMPENB 0x3A #define M66592_BEMPSTS 0x4A -#define M66592_BEMP7 0x0080 /* b7: PIPE7 */ -#define M66592_BEMP6 0x0040 /* b6: PIPE6 */ -#define M66592_BEMP5 0x0020 /* b5: PIPE5 */ -#define M66592_BEMP4 0x0010 /* b4: PIPE4 */ -#define M66592_BEMP3 0x0008 /* b3: PIPE3 */ -#define M66592_BEMP2 0x0004 /* b2: PIPE2 */ -#define M66592_BEMP1 0x0002 /* b1: PIPE1 */ -#define M66592_BEMP0 0x0001 /* b0: PIPE0 */ +#define M66592_BEMP7 0x0080 /* b7: PIPE7 */ +#define M66592_BEMP6 0x0040 /* b6: PIPE6 */ +#define M66592_BEMP5 0x0020 /* b5: PIPE5 */ +#define M66592_BEMP4 0x0010 /* b4: PIPE4 */ +#define M66592_BEMP3 0x0008 /* b3: PIPE3 */ +#define M66592_BEMP2 0x0004 /* b2: PIPE2 */ +#define M66592_BEMP1 0x0002 /* b1: PIPE1 */ +#define M66592_BEMP0 0x0001 /* b0: PIPE0 */ #define M66592_SOFCFG 0x3C -#define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ -#define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ -#define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ -#define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ +#define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ +#define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ +#define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ +#define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ #define M66592_INTSTS0 0x40 -#define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ -#define M66592_RESM 0x4000 /* b14: Resume interrupt */ -#define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ -#define M66592_DVST 0x1000 /* b12: Device state transition */ -#define M66592_CTRT 0x0800 /* b11: Control stage transition */ -#define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ -#define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ -#define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ -#define M66592_VBSTS 0x0080 /* b7: VBUS input port */ -#define M66592_DVSQ 0x0070 /* b6-4: Device state */ -#define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ -#define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ -#define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ -#define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ -#define M66592_DS_SUSP 0x0040 /* Suspend */ -#define M66592_DS_CNFG 0x0030 /* Configured */ -#define M66592_DS_ADDS 0x0020 /* Address */ -#define M66592_DS_DFLT 0x0010 /* Default */ -#define M66592_DS_POWR 0x0000 /* Powered */ -#define M66592_DVSQS 0x0030 /* b5-4: Device state */ -#define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ -#define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ -#define M66592_CS_SQER 0x0006 /* Sequence error */ -#define M66592_CS_WRND 0x0005 /* Control write nodata status */ -#define M66592_CS_WRSS 0x0004 /* Control write status stage */ -#define M66592_CS_WRDS 0x0003 /* Control write data stage */ -#define M66592_CS_RDSS 0x0002 /* Control read status stage */ -#define M66592_CS_RDDS 0x0001 /* Control read data stage */ -#define M66592_CS_IDST 0x0000 /* Idle or setup stage */ +#define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ +#define M66592_RESM 0x4000 /* b14: Resume interrupt */ +#define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ +#define M66592_DVST 0x1000 /* b12: Device state transition interrupt */ +#define M66592_CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ +#define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ +#define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ +#define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ +#define M66592_VBSTS 0x0080 /* b7: VBUS input port */ +#define M66592_DVSQ 0x0070 /* b6-4: Device state */ +#define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ +#define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ +#define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ +#define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ +#define M66592_DS_SUSP 0x0040 /* Suspend */ +#define M66592_DS_CNFG 0x0030 /* Configured */ +#define M66592_DS_ADDS 0x0020 /* Address */ +#define M66592_DS_DFLT 0x0010 /* Default */ +#define M66592_DS_POWR 0x0000 /* Powered */ +#define M66592_DVSQS 0x0030 /* b5-4: Device state */ +#define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ +#define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ +#define M66592_CS_SQER 0x0006 /* Sequence error */ +#define M66592_CS_WRND 0x0005 /* Control write nodata status stage */ +#define M66592_CS_WRSS 0x0004 /* Control write status stage */ +#define M66592_CS_WRDS 0x0003 /* Control write data stage */ +#define M66592_CS_RDSS 0x0002 /* Control read status stage */ +#define M66592_CS_RDDS 0x0001 /* Control read data stage */ +#define M66592_CS_IDST 0x0000 /* Idle or setup stage */ #define M66592_INTSTS1 0x42 -#define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ -#define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ -#define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ -#define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ +#define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ +#define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ +#define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ +#define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ #define M66592_FRMNUM 0x4C -#define M66592_OVRN 0x8000 /* b15: Overrun error */ -#define M66592_CRCE 0x4000 /* b14: Received data error */ -#define M66592_SOFRM 0x0800 /* b11: SOF output mode */ -#define M66592_FRNM 0x07FF /* b10-0: Frame number */ +#define M66592_OVRN 0x8000 /* b15: Overrun error */ +#define M66592_CRCE 0x4000 /* b14: Received data error */ +#define M66592_SOFRM 0x0800 /* b11: SOF output mode */ +#define M66592_FRNM 0x07FF /* b10-0: Frame number */ #define M66592_UFRMNUM 0x4E -#define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ +#define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ #define M66592_RECOVER 0x50 -#define M66592_STSRECOV 0x0700 /* Status recovery */ -#define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ -#define M66592_STSR_DEFAULT 0x0100 /* Default state */ -#define M66592_STSR_ADDRESS 0x0200 /* Address state */ -#define M66592_STSR_CONFIG 0x0300 /* Configured state */ -#define M66592_USBADDR 0x007F /* b6-0: USB address */ +#define M66592_STSRECOV 0x0700 /* Status recovery */ +#define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ +#define M66592_STSR_DEFAULT 0x0100 /* Default state */ +#define M66592_STSR_ADDRESS 0x0200 /* Address state */ +#define M66592_STSR_CONFIG 0x0300 /* Configured state */ +#define M66592_USBADDR 0x007F /* b6-0: USB address */ #define M66592_USBREQ 0x54 -#define M66592_bRequest 0xFF00 /* b15-8: bRequest */ -#define M66592_GET_STATUS 0x0000 -#define M66592_CLEAR_FEATURE 0x0100 -#define M66592_ReqRESERVED 0x0200 -#define M66592_SET_FEATURE 0x0300 -#define M66592_ReqRESERVED1 0x0400 -#define M66592_SET_ADDRESS 0x0500 -#define M66592_GET_DESCRIPTOR 0x0600 -#define M66592_SET_DESCRIPTOR 0x0700 -#define M66592_GET_CONFIGURATION 0x0800 -#define M66592_SET_CONFIGURATION 0x0900 -#define M66592_GET_INTERFACE 0x0A00 -#define M66592_SET_INTERFACE 0x0B00 -#define M66592_SYNCH_FRAME 0x0C00 -#define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ -#define M66592_bmRequestTypeDir 0x0080 /* b7 : Data direction */ -#define M66592_HOST_TO_DEVICE 0x0000 -#define M66592_DEVICE_TO_HOST 0x0080 -#define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ -#define M66592_STANDARD 0x0000 -#define M66592_CLASS 0x0020 -#define M66592_VENDOR 0x0040 -#define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ -#define M66592_DEVICE 0x0000 -#define M66592_INTERFACE 0x0001 -#define M66592_ENDPOINT 0x0002 +#define M66592_bRequest 0xFF00 /* b15-8: bRequest */ +#define M66592_GET_STATUS 0x0000 +#define M66592_CLEAR_FEATURE 0x0100 +#define M66592_ReqRESERVED 0x0200 +#define M66592_SET_FEATURE 0x0300 +#define M66592_ReqRESERVED1 0x0400 +#define M66592_SET_ADDRESS 0x0500 +#define M66592_GET_DESCRIPTOR 0x0600 +#define M66592_SET_DESCRIPTOR 0x0700 +#define M66592_GET_CONFIGURATION 0x0800 +#define M66592_SET_CONFIGURATION 0x0900 +#define M66592_GET_INTERFACE 0x0A00 +#define M66592_SET_INTERFACE 0x0B00 +#define M66592_SYNCH_FRAME 0x0C00 +#define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ +#define M66592_bmRequestTypeDir 0x0080 /* b7 : Data transfer direction */ +#define M66592_HOST_TO_DEVICE 0x0000 +#define M66592_DEVICE_TO_HOST 0x0080 +#define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ +#define M66592_STANDARD 0x0000 +#define M66592_CLASS 0x0020 +#define M66592_VENDOR 0x0040 +#define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ +#define M66592_DEVICE 0x0000 +#define M66592_INTERFACE 0x0001 +#define M66592_ENDPOINT 0x0002 #define M66592_USBVAL 0x56 -#define M66592_wValue 0xFFFF /* b15-0: wValue */ +#define M66592_wValue 0xFFFF /* b15-0: wValue */ /* Standard Feature Selector */ -#define M66592_ENDPOINT_HALT 0x0000 -#define M66592_DEVICE_REMOTE_WAKEUP 0x0001 -#define M66592_TEST_MODE 0x0002 +#define M66592_ENDPOINT_HALT 0x0000 +#define M66592_DEVICE_REMOTE_WAKEUP 0x0001 +#define M66592_TEST_MODE 0x0002 /* Descriptor Types */ -#define M66592_DT_TYPE 0xFF00 -#define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) -#define M66592_DT_DEVICE 0x01 -#define M66592_DT_CONFIGURATION 0x02 -#define M66592_DT_STRING 0x03 -#define M66592_DT_INTERFACE 0x04 -#define M66592_DT_ENDPOINT 0x05 -#define M66592_DT_DEVICE_QUALIFIER 0x06 -#define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 -#define M66592_DT_INTERFACE_POWER 0x08 -#define M66592_DT_INDEX 0x00FF -#define M66592_CONF_NUM 0x00FF -#define M66592_ALT_SET 0x00FF +#define M66592_DT_TYPE 0xFF00 +#define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) +#define M66592_DT_DEVICE 0x01 +#define M66592_DT_CONFIGURATION 0x02 +#define M66592_DT_STRING 0x03 +#define M66592_DT_INTERFACE 0x04 +#define M66592_DT_ENDPOINT 0x05 +#define M66592_DT_DEVICE_QUALIFIER 0x06 +#define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 +#define M66592_DT_INTERFACE_POWER 0x08 +#define M66592_DT_INDEX 0x00FF +#define M66592_CONF_NUM 0x00FF +#define M66592_ALT_SET 0x00FF #define M66592_USBINDEX 0x58 -#define M66592_wIndex 0xFFFF /* b15-0: wIndex */ -#define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode */ -#define M66592_TEST_J 0x0100 /* Test_J */ -#define M66592_TEST_K 0x0200 /* Test_K */ -#define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ -#define M66592_TEST_PACKET 0x0400 /* Test_Packet */ -#define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ -#define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ -#define M66592_TEST_Reserved 0x4000 /* Reserved */ -#define M66592_TEST_VSTModes 0xC000 /* Vendor-specific tests */ -#define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ -#define M66592_EP_DIR_IN 0x0080 -#define M66592_EP_DIR_OUT 0x0000 +#define M66592_wIndex 0xFFFF /* b15-0: wIndex */ +#define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode Selectors */ +#define M66592_TEST_J 0x0100 /* Test_J */ +#define M66592_TEST_K 0x0200 /* Test_K */ +#define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ +#define M66592_TEST_PACKET 0x0400 /* Test_Packet */ +#define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ +#define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ +#define M66592_TEST_Reserved 0x4000 /* Reserved */ +#define M66592_TEST_VSTModes 0xC000 /* Vendor-specific test modes */ +#define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ +#define M66592_EP_DIR_IN 0x0080 +#define M66592_EP_DIR_OUT 0x0000 #define M66592_USBLENG 0x5A -#define M66592_wLength 0xFFFF /* b15-0: wLength */ +#define M66592_wLength 0xFFFF /* b15-0: wLength */ #define M66592_DCPCFG 0x5C -#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ -#define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ +#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ +#define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ #define M66592_DCPMAXP 0x5E -#define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ -#define M66592_DEVICE_0 0x0000 /* Device address 0 */ -#define M66592_DEVICE_1 0x4000 /* Device address 1 */ -#define M66592_DEVICE_2 0x8000 /* Device address 2 */ -#define M66592_DEVICE_3 0xC000 /* Device address 3 */ -#define M66592_MAXP 0x007F /* b6-0: Maxpacket size of ep0 */ +#define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ +#define M66592_DEVICE_0 0x0000 /* Device address 0 */ +#define M66592_DEVICE_1 0x4000 /* Device address 1 */ +#define M66592_DEVICE_2 0x8000 /* Device address 2 */ +#define M66592_DEVICE_3 0xC000 /* Device address 3 */ +#define M66592_MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ #define M66592_DCPCTR 0x60 -#define M66592_BSTS 0x8000 /* b15: Buffer status */ -#define M66592_SUREQ 0x4000 /* b14: Send USB request */ -#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define M66592_CCPL 0x0004 /* b2: control transfer complete */ -#define M66592_PID 0x0003 /* b1-0: Response PID */ -#define M66592_PID_STALL 0x0002 /* STALL */ -#define M66592_PID_BUF 0x0001 /* BUF */ -#define M66592_PID_NAK 0x0000 /* NAK */ +#define M66592_BSTS 0x8000 /* b15: Buffer status */ +#define M66592_SUREQ 0x4000 /* b14: Send USB request */ +#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define M66592_CCPL 0x0004 /* b2: Enable control transfer complete */ +#define M66592_PID 0x0003 /* b1-0: Response PID */ +#define M66592_PID_STALL 0x0002 /* STALL */ +#define M66592_PID_BUF 0x0001 /* BUF */ +#define M66592_PID_NAK 0x0000 /* NAK */ #define M66592_PIPESEL 0x64 -#define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ -#define M66592_PIPE0 0x0000 /* PIPE 0 */ -#define M66592_PIPE1 0x0001 /* PIPE 1 */ -#define M66592_PIPE2 0x0002 /* PIPE 2 */ -#define M66592_PIPE3 0x0003 /* PIPE 3 */ -#define M66592_PIPE4 0x0004 /* PIPE 4 */ -#define M66592_PIPE5 0x0005 /* PIPE 5 */ -#define M66592_PIPE6 0x0006 /* PIPE 6 */ -#define M66592_PIPE7 0x0007 /* PIPE 7 */ +#define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ +#define M66592_PIPE0 0x0000 /* PIPE 0 */ +#define M66592_PIPE1 0x0001 /* PIPE 1 */ +#define M66592_PIPE2 0x0002 /* PIPE 2 */ +#define M66592_PIPE3 0x0003 /* PIPE 3 */ +#define M66592_PIPE4 0x0004 /* PIPE 4 */ +#define M66592_PIPE5 0x0005 /* PIPE 5 */ +#define M66592_PIPE6 0x0006 /* PIPE 6 */ +#define M66592_PIPE7 0x0007 /* PIPE 7 */ #define M66592_PIPECFG 0x66 -#define M66592_TYP 0xC000 /* b15-14: Transfer type */ -#define M66592_ISO 0xC000 /* Isochronous */ -#define M66592_INT 0x8000 /* Interrupt */ -#define M66592_BULK 0x4000 /* Bulk */ -#define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode */ -#define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ -#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ -#define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ -#define M66592_DIR 0x0010 /* b4: Transfer direction select */ -#define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ -#define M66592_DIR_P_IN 0x0010 /* PERI IN */ -#define M66592_DIR_H_IN 0x0000 /* HOST IN */ -#define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ -#define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ -#define M66592_EP1 0x0001 -#define M66592_EP2 0x0002 -#define M66592_EP3 0x0003 -#define M66592_EP4 0x0004 -#define M66592_EP5 0x0005 -#define M66592_EP6 0x0006 -#define M66592_EP7 0x0007 -#define M66592_EP8 0x0008 -#define M66592_EP9 0x0009 -#define M66592_EP10 0x000A -#define M66592_EP11 0x000B -#define M66592_EP12 0x000C -#define M66592_EP13 0x000D -#define M66592_EP14 0x000E -#define M66592_EP15 0x000F +#define M66592_TYP 0xC000 /* b15-14: Transfer type */ +#define M66592_ISO 0xC000 /* Isochronous */ +#define M66592_INT 0x8000 /* Interrupt */ +#define M66592_BULK 0x4000 /* Bulk */ +#define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ +#define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ +#define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ +#define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ +#define M66592_DIR 0x0010 /* b4: Transfer direction select */ +#define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ +#define M66592_DIR_P_IN 0x0010 /* PERI IN */ +#define M66592_DIR_H_IN 0x0000 /* HOST IN */ +#define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ +#define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ +#define M66592_EP1 0x0001 +#define M66592_EP2 0x0002 +#define M66592_EP3 0x0003 +#define M66592_EP4 0x0004 +#define M66592_EP5 0x0005 +#define M66592_EP6 0x0006 +#define M66592_EP7 0x0007 +#define M66592_EP8 0x0008 +#define M66592_EP9 0x0009 +#define M66592_EP10 0x000A +#define M66592_EP11 0x000B +#define M66592_EP12 0x000C +#define M66592_EP13 0x000D +#define M66592_EP14 0x000E +#define M66592_EP15 0x000F #define M66592_PIPEBUF 0x68 -#define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ -#define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) -#define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ +#define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ +#define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) +#define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ #define M66592_PIPEMAXP 0x6A -#define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ +#define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ #define M66592_PIPEPERI 0x6C -#define M66592_IFIS 0x1000 /* b12: ISO in-buffer flush mode */ -#define M66592_IITV 0x0007 /* b2-0: ISO interval */ +#define M66592_IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ +#define M66592_IITV 0x0007 /* b2-0: Isochronous interval */ #define M66592_PIPE1CTR 0x70 #define M66592_PIPE2CTR 0x72 @@ -401,17 +401,19 @@ #define M66592_PIPE5CTR 0x78 #define M66592_PIPE6CTR 0x7A #define M66592_PIPE7CTR 0x7C -#define M66592_BSTS 0x8000 /* b15: Buffer status */ -#define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (PIPE 1-5) */ -#define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ -#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define M66592_PID 0x0003 /* b1-0: Response PID */ +#define M66592_BSTS 0x8000 /* b15: Buffer status */ +#define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ +#define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ +#define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define M66592_PID 0x0003 /* b1-0: Response PID */ #define M66592_INVALID_REG 0x7E +#define __iomem + #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) #define M66592_MAX_SAMPLING 10 @@ -447,7 +449,7 @@ struct m66592_ep { struct m66592 *m66592; struct list_head queue; - unsigned busy:1; + unsigned busy:1; unsigned internal_ccpl:1; /* use only control */ /* this member can able to after m66592_enable */ @@ -475,7 +477,7 @@ struct m66592 { struct m66592_ep *epaddr2ep[16]; struct usb_request *ep0_req; /* for internal request */ - u16 ep0_data; /* for internal request */ + u16 *ep0_buf; /* for internal request */ struct timer_list timer; @@ -525,8 +527,8 @@ static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) } static inline void m66592_read_fifo(struct m66592 *m66592, - unsigned long offset, - void *buf, unsigned long len) + unsigned long offset, + void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; @@ -541,8 +543,8 @@ static inline void m66592_write(struct m66592 *m66592, u16 val, } static inline void m66592_write_fifo(struct m66592 *m66592, - unsigned long offset, - void *buf, unsigned long len) + unsigned long offset, + void *buf, unsigned long len) { unsigned long fifoaddr = (unsigned long)m66592->reg + offset; unsigned long odd = len & 0x0001; @@ -556,7 +558,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, } static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, - unsigned long offset) + unsigned long offset) { u16 tmp; tmp = m66592_read(m66592, offset); diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index 9cd98e73dc1d..38138bb9ddb0 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -259,7 +258,7 @@ static const char *EP_IN_NAME; static const char *EP_OUT_NAME; static const char *EP_NOTIFY_NAME; -static struct mutex gs_open_close_lock[GS_NUM_PORTS]; +static struct semaphore gs_open_close_sem[GS_NUM_PORTS]; static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; @@ -596,7 +595,7 @@ static int __init gs_module_init(void) tty_set_operations(gs_tty_driver, &gs_tty_ops); for (i=0; i < GS_NUM_PORTS; i++) - mutex_init(&gs_open_close_lock[i]); + sema_init(&gs_open_close_sem[i], 1); retval = tty_register_driver(gs_tty_driver); if (retval) { @@ -636,7 +635,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) struct gs_port *port; struct gs_dev *dev; struct gs_buf *buf; - struct mutex *mtx; + struct semaphore *sem; int ret; port_num = tty->index; @@ -657,10 +656,10 @@ static int gs_open(struct tty_struct *tty, struct file *file) return -ENODEV; } - mtx = &gs_open_close_lock[port_num]; - if (mutex_lock_interruptible(mtx)) { + sem = &gs_open_close_sem[port_num]; + if (down_interruptible(sem)) { printk(KERN_ERR - "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", + "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n", port_num, tty, file); return -ERESTARTSYS; } @@ -755,12 +754,12 @@ static int gs_open(struct tty_struct *tty, struct file *file) exit_unlock_port: spin_unlock_irqrestore(&port->port_lock, flags); - mutex_unlock(mtx); + up(sem); return ret; exit_unlock_dev: spin_unlock_irqrestore(&dev->dev_lock, flags); - mutex_unlock(mtx); + up(sem); return ret; } @@ -782,7 +781,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) static void gs_close(struct tty_struct *tty, struct file *file) { struct gs_port *port = tty->driver_data; - struct mutex *mtx; + struct semaphore *sem; if (port == NULL) { printk(KERN_ERR "gs_close: NULL port pointer\n"); @@ -791,8 +790,8 @@ static void gs_close(struct tty_struct *tty, struct file *file) gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); - mtx = &gs_open_close_lock[port->port_num]; - mutex_lock(mtx); + sem = &gs_open_close_sem[port->port_num]; + down(sem); spin_lock_irq(&port->port_lock); @@ -847,7 +846,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) exit: spin_unlock_irq(&port->port_lock); - mutex_unlock(mtx); + up(sem); } /* diff --git a/trunk/drivers/usb/host/isp116x-hcd.c b/trunk/drivers/usb/host/isp116x-hcd.c index 5c851a36de72..46873f2534b5 100644 --- a/trunk/drivers/usb/host/isp116x-hcd.c +++ b/trunk/drivers/usb/host/isp116x-hcd.c @@ -228,6 +228,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) struct urb, urb_list); ptd = &ep->ptd; len = ep->length; + spin_lock(&urb->lock); ep->data = (unsigned char *)urb->transfer_buffer + urb->actual_length; @@ -263,6 +264,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) | PTD_EP(ep->epnum); ptd->len = PTD_LEN(len) | PTD_DIR(dir); ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); + spin_unlock(&urb->lock); if (!ep->active) { ptd->mps |= PTD_LAST_MSK; isp116x->atl_last_dir = dir; @@ -272,61 +274,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) } } -/* - Take done or failed requests out of schedule. Give back - processed urbs. -*/ -static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, - struct urb *urb) -__releases(isp116x->lock) __acquires(isp116x->lock) -{ - unsigned i; - - urb->hcpriv = NULL; - ep->error_count = 0; - - if (usb_pipecontrol(urb->pipe)) - ep->nextpid = USB_PID_SETUP; - - urb_dbg(urb, "Finish"); - - spin_unlock(&isp116x->lock); - usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); - spin_lock(&isp116x->lock); - - /* take idle endpoints out of the schedule */ - if (!list_empty(&ep->hep->urb_list)) - return; - - /* async deschedule */ - if (!list_empty(&ep->schedule)) { - list_del_init(&ep->schedule); - return; - } - - /* periodic deschedule */ - DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); - for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { - struct isp116x_ep *temp; - struct isp116x_ep **prev = &isp116x->periodic[i]; - - while (*prev && ((temp = *prev) != ep)) - prev = &temp->next; - if (*prev) - *prev = ep->next; - isp116x->load[i] -= ep->load; - } - ep->branch = PERIODIC_SIZE; - isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= - ep->load / ep->period; - - /* switch irq type? */ - if (!--isp116x->periodic_count) { - isp116x->irqenb &= ~HCuPINT_SOF; - isp116x->irqenb |= HCuPINT_ATL; - } -} - /* Analyze transfer results, handle partial transfers and errors */ @@ -337,7 +284,6 @@ static void postproc_atl_queue(struct isp116x *isp116x) struct usb_device *udev; struct ptd *ptd; int short_not_ok; - int status; u8 cc; for (ep = isp116x->atl_active; ep; ep = ep->active) { @@ -348,7 +294,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) ptd = &ep->ptd; cc = PTD_GET_CC(ptd); short_not_ok = 1; - status = -EINPROGRESS; + spin_lock(&urb->lock); /* Data underrun is special. For allowed underrun we clear the error and continue as normal. For @@ -356,36 +302,47 @@ static void postproc_atl_queue(struct isp116x *isp116x) immediately while for control transfer, we do a STATUS stage. */ if (cc == TD_DATAUNDERRUN) { - if (!(urb->transfer_flags & URB_SHORT_NOT_OK) || - usb_pipecontrol(urb->pipe)) { - DBG("Allowed or control data underrun\n"); + if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { + DBG("Allowed data underrun\n"); cc = TD_CC_NOERROR; short_not_ok = 0; } else { ep->error_count = 1; - usb_settoggle(udev, ep->epnum, - ep->nextpid == USB_PID_OUT, - PTD_GET_TOGGLE(ptd)); + if (usb_pipecontrol(urb->pipe)) + ep->nextpid = USB_PID_ACK; + else + usb_settoggle(udev, ep->epnum, + ep->nextpid == + USB_PID_OUT, + PTD_GET_TOGGLE(ptd)); urb->actual_length += PTD_GET_COUNT(ptd); - status = cc_to_error[TD_DATAUNDERRUN]; - goto done; + urb->status = cc_to_error[TD_DATAUNDERRUN]; + spin_unlock(&urb->lock); + continue; } } + /* Keep underrun error through the STATUS stage */ + if (urb->status == cc_to_error[TD_DATAUNDERRUN]) + cc = TD_DATAUNDERRUN; if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED && (++ep->error_count >= 3 || cc == TD_CC_STALL || cc == TD_DATAOVERRUN)) { - status = cc_to_error[cc]; + if (urb->status == -EINPROGRESS) + urb->status = cc_to_error[cc]; if (ep->nextpid == USB_PID_ACK) ep->nextpid = 0; - goto done; + spin_unlock(&urb->lock); + continue; } /* According to usb spec, zero-length Int transfer signals finishing of the urb. Hey, does this apply only for IN endpoints? */ if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { - status = 0; - goto done; + if (urb->status == -EINPROGRESS) + urb->status = 0; + spin_unlock(&urb->lock); + continue; } /* Relax after previously failed, but later succeeded @@ -424,8 +381,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) /* All data for this URB is transferred, let's finish */ if (usb_pipecontrol(urb->pipe)) ep->nextpid = USB_PID_ACK; - else - status = 0; + else if (urb->status == -EINPROGRESS) + urb->status = 0; break; case USB_PID_SETUP: if (PTD_GET_ACTIVE(ptd) @@ -445,27 +402,69 @@ static void postproc_atl_queue(struct isp116x *isp116x) if (PTD_GET_ACTIVE(ptd) || (cc != TD_CC_NOERROR && cc < 0x0E)) break; - if ((urb->transfer_flags & URB_SHORT_NOT_OK) && - urb->actual_length < - urb->transfer_buffer_length) - status = -EREMOTEIO; - else - status = 0; + if (urb->status == -EINPROGRESS) + urb->status = 0; ep->nextpid = 0; break; default: BUG(); } + spin_unlock(&urb->lock); + } +} - done: - if (status != -EINPROGRESS) { - spin_lock(&urb->lock); - if (urb->status == -EINPROGRESS) - urb->status = status; - spin_unlock(&urb->lock); - } - if (urb->status != -EINPROGRESS) - finish_request(isp116x, ep, urb); +/* + Take done or failed requests out of schedule. Give back + processed urbs. +*/ +static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, + struct urb *urb) +__releases(isp116x->lock) __acquires(isp116x->lock) +{ + unsigned i; + + urb->hcpriv = NULL; + ep->error_count = 0; + + if (usb_pipecontrol(urb->pipe)) + ep->nextpid = USB_PID_SETUP; + + urb_dbg(urb, "Finish"); + + spin_unlock(&isp116x->lock); + usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); + spin_lock(&isp116x->lock); + + /* take idle endpoints out of the schedule */ + if (!list_empty(&ep->hep->urb_list)) + return; + + /* async deschedule */ + if (!list_empty(&ep->schedule)) { + list_del_init(&ep->schedule); + return; + } + + /* periodic deschedule */ + DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); + for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { + struct isp116x_ep *temp; + struct isp116x_ep **prev = &isp116x->periodic[i]; + + while (*prev && ((temp = *prev) != ep)) + prev = &temp->next; + if (*prev) + *prev = ep->next; + isp116x->load[i] -= ep->load; + } + ep->branch = PERIODIC_SIZE; + isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= + ep->load / ep->period; + + /* switch irq type? */ + if (!--isp116x->periodic_count) { + isp116x->irqenb &= ~HCuPINT_SOF; + isp116x->irqenb |= HCuPINT_ATL; } } @@ -571,6 +570,9 @@ static void start_atl_transfers(struct isp116x *isp116x) */ static void finish_atl_transfers(struct isp116x *isp116x) { + struct isp116x_ep *ep; + struct urb *urb; + if (!isp116x->atl_active) return; /* Fifo not ready? */ @@ -580,6 +582,16 @@ static void finish_atl_transfers(struct isp116x *isp116x) atomic_inc(&isp116x->atl_finishing); unpack_fifo(isp116x); postproc_atl_queue(isp116x); + for (ep = isp116x->atl_active; ep; ep = ep->active) { + urb = + container_of(ep->hep->urb_list.next, struct urb, urb_list); + /* USB_PID_ACK check here avoids finishing of + control transfers, for which TD_DATAUNDERRUN + occured, while URB_SHORT_NOT_OK was set */ + if (urb && urb->status != -EINPROGRESS + && ep->nextpid != USB_PID_ACK) + finish_request(isp116x, ep, urb); + } atomic_dec(&isp116x->atl_finishing); } @@ -809,12 +821,15 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, } /* in case of unlink-during-submit */ + spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { + spin_unlock(&urb->lock); finish_request(isp116x, ep, urb); ret = 0; goto fail; } urb->hcpriv = hep; + spin_unlock(&urb->lock); start_atl_transfers(isp116x); fail: diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index d60f1985320c..a7a7070c6e2a 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -35,8 +35,10 @@ #include #include #include -#include -#include + +#include +#include +#include #include "../core/hcd.h" #include "r8a66597.h" @@ -52,21 +54,16 @@ static const char hcd_name[] = "r8a66597_hcd"; /* module parameters */ static unsigned short clock = XTAL12; module_param(clock, ushort, 0644); -MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " - "(default=0)"); - +MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=0)"); static unsigned short vif = LDRV; module_param(vif, ushort, 0644); MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); - -static unsigned short endian; +static unsigned short endian = 0; module_param(endian, ushort, 0644); -MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); - +MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); static unsigned short irq_sense = INTL; module_param(irq_sense, ushort, 0644); -MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " - "(default=32)"); +MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0(default=32)"); static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); static int r8a66597_get_frame(struct usb_hcd *hcd); @@ -311,7 +308,7 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, struct r8a66597_device *dev; int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ - dev = kzalloc(sizeof(struct r8a66597_device), GFP_ATOMIC); + dev = kzalloc(sizeof(struct r8a66597_device), GFP_KERNEL); if (dev == NULL) return -ENOMEM; @@ -614,33 +611,33 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; memset(array, 0, sizeof(array)); - switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_BULK: + switch(ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_BULK: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) array[i++] = 4; else { array[i++] = 3; array[i++] = 5; } - break; - case USB_ENDPOINT_XFER_INT: + break; + case USB_ENDPOINT_XFER_INT: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { array[i++] = 6; array[i++] = 7; array[i++] = 8; } else array[i++] = 9; - break; - case USB_ENDPOINT_XFER_ISOC: + break; + case USB_ENDPOINT_XFER_ISOC: if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) array[i++] = 2; else array[i++] = 1; - break; - default: - err("Illegal type"); - return 0; - } + break; + default: + err("Illegal type"); + return 0; + } i = 1; min = array[0]; @@ -657,7 +654,7 @@ static u16 get_r8a66597_type(__u8 type) { u16 r8a66597_type; - switch (type) { + switch(type) { case USB_ENDPOINT_XFER_BULK: r8a66597_type = R8A66597_BULK; break; @@ -877,7 +874,7 @@ static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) { r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | (1 << USB_PORT_FEAT_C_CONNECTION); - r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); + r8a66597_write(r8a66597, (u16)~DTCH, get_intsts_reg(port)); r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); } @@ -920,7 +917,7 @@ static void prepare_setup_packet(struct r8a66597 *r8a66597, r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, DCPMAXP); - r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); + r8a66597_write(r8a66597, (u16)~(SIGN | SACK), INTSTS1); for (i = 0; i < 4; i++) { r8a66597_write(r8a66597, p[i], setup_addr); @@ -951,18 +948,19 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, pipe_irq_disable(r8a66597, td->pipenum); pipe_setting(r8a66597, td); pipe_stop(r8a66597, td->pipe); - r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); + r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), + BRDYSTS); if (td->pipe->pipetre) { r8a66597_write(r8a66597, TRCLR, - td->pipe->pipetre); + td->pipe->pipetre); r8a66597_write(r8a66597, - (urb->transfer_buffer_length - + td->maxpacket - 1) - / td->maxpacket, - td->pipe->pipetrn); + (urb->transfer_buffer_length + + td->maxpacket - 1) + / td->maxpacket, + td->pipe->pipetrn); r8a66597_bset(r8a66597, TRENB, - td->pipe->pipetre); + td->pipe->pipetre); } pipe_start(r8a66597, td->pipe); @@ -993,7 +991,7 @@ static void prepare_packet_write(struct r8a66597 *r8a66597, if (td->pipe->pipetre) r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); } - r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); + r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), BRDYSTS); fifo_change_from_pipe(r8a66597, td->pipe); tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); @@ -1011,21 +1009,21 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, struct urb *urb = td->urb; r8a66597_pipe_toggle(r8a66597, td->pipe, 1); - pipe_stop(r8a66597, td->pipe); if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); - r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); - r8a66597_write(r8a66597, BCLR, CFIFOCTR); - r8a66597_write(r8a66597, BVAL, CFIFOCTR); + r8a66597_write(r8a66597, BVAL | BCLR, CFIFOCTR); + r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); enable_irq_empty(r8a66597, 0); } else { r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); r8a66597_write(r8a66597, BCLR, CFIFOCTR); + r8a66597_write(r8a66597, (u16)~BRDY0, BRDYSTS); + r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); enable_irq_ready(r8a66597, 0); } enable_irq_nrdy(r8a66597, 0); @@ -1271,7 +1269,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) /* write fifo */ if (pipenum > 0) - r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); + r8a66597_write(r8a66597, (u16)~(1 << pipenum), BEMPSTS); if (urb->transfer_buffer) { r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) @@ -1364,7 +1362,7 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, BRDYSTS) & r8a66597_read(r8a66597, BRDYENB); - r8a66597_write(r8a66597, ~mask, BRDYSTS); + r8a66597_write(r8a66597, (u16)~mask, BRDYSTS); if (mask & BRDY0) { td = r8a66597_get_td(r8a66597, 0); if (td && td->type == USB_PID_IN) @@ -1399,7 +1397,7 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, BEMPSTS) & r8a66597_read(r8a66597, BEMPENB); - r8a66597_write(r8a66597, ~mask, BEMPSTS); + r8a66597_write(r8a66597, (u16)~mask, BEMPSTS); if (mask & BEMP0) { cfifo_change(r8a66597, 0); td = r8a66597_get_td(r8a66597, 0); @@ -1436,7 +1434,7 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) mask = r8a66597_read(r8a66597, NRDYSTS) & r8a66597_read(r8a66597, NRDYENB); - r8a66597_write(r8a66597, ~mask, NRDYSTS); + r8a66597_write(r8a66597, (u16)~mask, NRDYSTS); if (mask & NRDY0) { cfifo_change(r8a66597, 0); set_urb_error(r8a66597, 0); @@ -1490,14 +1488,14 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); if (mask2) { if (mask2 & ATTCH) { - r8a66597_write(r8a66597, ~ATTCH, INTSTS2); + r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS2); r8a66597_bclr(r8a66597, ATTCHE, INTENB2); /* start usb bus sampling */ start_root_hub_sampling(r8a66597, 1); } if (mask2 & DTCH) { - r8a66597_write(r8a66597, ~DTCH, INTSTS2); + r8a66597_write(r8a66597, (u16)~DTCH, INTSTS2); r8a66597_bclr(r8a66597, DTCHE, INTENB2); r8a66597_usb_disconnect(r8a66597, 1); } @@ -1505,24 +1503,24 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) if (mask1) { if (mask1 & ATTCH) { - r8a66597_write(r8a66597, ~ATTCH, INTSTS1); + r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS1); r8a66597_bclr(r8a66597, ATTCHE, INTENB1); /* start usb bus sampling */ start_root_hub_sampling(r8a66597, 0); } if (mask1 & DTCH) { - r8a66597_write(r8a66597, ~DTCH, INTSTS1); + r8a66597_write(r8a66597, (u16)~DTCH, INTSTS1); r8a66597_bclr(r8a66597, DTCHE, INTENB1); r8a66597_usb_disconnect(r8a66597, 0); } if (mask1 & SIGN) { - r8a66597_write(r8a66597, ~SIGN, INTSTS1); + r8a66597_write(r8a66597, (u16)~SIGN, INTSTS1); set_urb_error(r8a66597, 0); check_next_phase(r8a66597); } if (mask1 & SACK) { - r8a66597_write(r8a66597, ~SACK, INTSTS1); + r8a66597_write(r8a66597, (u16)~SACK, INTSTS1); check_next_phase(r8a66597); } } @@ -1665,9 +1663,13 @@ static int check_pipe_config(struct r8a66597 *r8a66597, struct urb *urb) static int r8a66597_start(struct usb_hcd *hcd) { struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); + int ret; hcd->state = HC_STATE_RUNNING; - return enable_controller(r8a66597); + if ((ret = enable_controller(r8a66597)) < 0) + return ret; + + return 0; } static void r8a66597_stop(struct usb_hcd *hcd) @@ -1694,12 +1696,13 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb) static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, struct urb *urb, - struct usb_host_endpoint *hep) + struct usb_host_endpoint *hep, + gfp_t mem_flags) { struct r8a66597_td *td; u16 pipenum; - td = kzalloc(sizeof(struct r8a66597_td), GFP_ATOMIC); + td = kzalloc(sizeof(struct r8a66597_td), mem_flags); if (td == NULL) return NULL; @@ -1738,8 +1741,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, } if (!hep->hcpriv) { - hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), - GFP_ATOMIC); + hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), mem_flags); if (!hep->hcpriv) { ret = -ENOMEM; goto error; @@ -1753,7 +1755,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, init_pipe_config(r8a66597, urb); set_address_zero(r8a66597, urb); - td = r8a66597_make_td(r8a66597, urb, hep); + td = r8a66597_make_td(r8a66597, urb, hep, mem_flags); if (td == NULL) { ret = -ENOMEM; goto error; diff --git a/trunk/drivers/usb/host/r8a66597.h b/trunk/drivers/usb/host/r8a66597.h index fe9ceb077d9b..97c2a71ac7a1 100644 --- a/trunk/drivers/usb/host/r8a66597.h +++ b/trunk/drivers/usb/host/r8a66597.h @@ -203,14 +203,14 @@ #define DTLN 0x0FFF /* b11-0: FIFO received data length */ /* Interrupt Enable Register 0 */ -#define VBSE 0x8000 /* b15: VBUS interrupt */ -#define RSME 0x4000 /* b14: Resume interrupt */ -#define SOFE 0x2000 /* b13: Frame update interrupt */ -#define DVSE 0x1000 /* b12: Device state transition interrupt */ -#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ -#define BEMPE 0x0400 /* b10: Buffer empty interrupt */ -#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ -#define BRDYE 0x0100 /* b8: Buffer ready interrupt */ +#define VBSE 0x8000 /* b15: VBUS interrupt */ +#define RSME 0x4000 /* b14: Resume interrupt */ +#define SOFE 0x2000 /* b13: Frame update interrupt */ +#define DVSE 0x1000 /* b12: Device state transition interrupt */ +#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMPE 0x0400 /* b10: Buffer empty interrupt */ +#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDYE 0x0100 /* b8: Buffer ready interrupt */ /* Interrupt Enable Register 1 */ #define OVRCRE 0x8000 /* b15: Over-current interrupt */ @@ -268,16 +268,16 @@ #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ /* Interrupt Status Register 0 */ -#define VBINT 0x8000 /* b15: VBUS interrupt */ -#define RESM 0x4000 /* b14: Resume interrupt */ -#define SOFR 0x2000 /* b13: SOF frame update interrupt */ -#define DVST 0x1000 /* b12: Device state transition interrupt */ -#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ -#define BEMP 0x0400 /* b10: Buffer empty interrupt */ -#define NRDY 0x0200 /* b9: Buffer not ready interrupt */ -#define BRDY 0x0100 /* b8: Buffer ready interrupt */ -#define VBSTS 0x0080 /* b7: VBUS input port */ -#define DVSQ 0x0070 /* b6-4: Device state */ +#define VBINT 0x8000 /* b15: VBUS interrupt */ +#define RESM 0x4000 /* b14: Resume interrupt */ +#define SOFR 0x2000 /* b13: SOF frame update interrupt */ +#define DVST 0x1000 /* b12: Device state transition interrupt */ +#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMP 0x0400 /* b10: Buffer empty interrupt */ +#define NRDY 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDY 0x0100 /* b8: Buffer ready interrupt */ +#define VBSTS 0x0080 /* b7: VBUS input port */ +#define DVSQ 0x0070 /* b6-4: Device state */ #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ #define DS_SPD_ADDR 0x0060 /* Suspend Address */ #define DS_SPD_DFLT 0x0050 /* Suspend Default */ @@ -315,10 +315,13 @@ /* Micro Frame Number Register */ #define UFRNM 0x0007 /* b2-0: Micro frame number */ +/* USB Address / Low Power Status Recovery Register */ +//#define USBADDR 0x007F /* b6-0: USB address */ + /* Default Control Pipe Maxpacket Size Register */ /* Pipe Maxpacket Size Register */ -#define DEVSEL 0xF000 /* b15-14: Device address select */ -#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ +#define DEVSEL 0xF000 /* b15-14: Device address select */ +#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ /* Default Control Pipe Control Register */ #define BSTS 0x8000 /* b15: Buffer status */ @@ -363,21 +366,21 @@ #define MXPS 0x07FF /* b10-0: Maxpacket size */ /* Pipe Cycle Configuration Register */ -#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ -#define IITV 0x0007 /* b2-0: Isochronous interval */ +#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ +#define IITV 0x0007 /* b2-0: Isochronous interval */ /* Pipex Control Register */ -#define BSTS 0x8000 /* b15: Buffer status */ -#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ -#define CSCLR 0x2000 /* b13: complete-split status clear */ -#define CSSTS 0x1000 /* b12: complete-split status */ -#define ATREPM 0x0400 /* b10: Auto repeat mode */ -#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ -#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ -#define SQSET 0x0080 /* b7: Sequence toggle bit set */ -#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ -#define PBUSY 0x0020 /* b5: pipe busy */ -#define PID 0x0003 /* b1-0: Response PID */ +#define BSTS 0x8000 /* b15: Buffer status */ +#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ +#define CSCLR 0x2000 /* b13: complete-split status clear */ +#define CSSTS 0x1000 /* b12: complete-split status */ +#define ATREPM 0x0400 /* b10: Auto repeat mode */ +#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ +#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define PBUSY 0x0020 /* b5: pipe busy */ +#define PID 0x0003 /* b1-0: Response PID */ /* PIPExTRE */ #define TRENB 0x0200 /* b9: Transaction counter enable */ @@ -404,15 +407,15 @@ #define make_devsel(addr) (addr << 12) struct r8a66597_pipe_info { - u16 pipenum; - u16 address; /* R8A66597 HCD usb addres */ - u16 epnum; - u16 maxpacket; - u16 type; - u16 bufnum; - u16 buf_bsize; - u16 interval; - u16 dir_in; + u16 pipenum; + u16 address; /* R8A66597 HCD usb addres */ + u16 epnum; + u16 maxpacket; + u16 type; + u16 bufnum; + u16 buf_bsize; + u16 interval; + u16 dir_in; }; struct r8a66597_pipe { diff --git a/trunk/drivers/usb/host/u132-hcd.c b/trunk/drivers/usb/host/u132-hcd.c index 7f765ec038cd..e98df2ee9901 100644 --- a/trunk/drivers/usb/host/u132-hcd.c +++ b/trunk/drivers/usb/host/u132-hcd.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include @@ -84,7 +83,7 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); * u132_module_lock exists to protect access to global variables * */ -static struct mutex u132_module_lock; +static struct semaphore u132_module_lock; static int u132_exiting = 0; static int u132_instances = 0; static struct list_head u132_static_list; @@ -259,10 +258,10 @@ static void u132_hcd_delete(struct kref *kref) struct platform_device *pdev = u132->platform_dev; struct usb_hcd *hcd = u132_to_hcd(u132); u132->going += 1; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); list_del_init(&u132->u132_list); u132_instances -= 1; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); usb_put_hcd(hcd); @@ -3112,10 +3111,10 @@ static int __devinit u132_probe(struct platform_device *pdev) int retval = 0; struct u132 *u132 = hcd_to_u132(hcd); hcd->rsrc_start = 0; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); list_add_tail(&u132->u132_list, &u132_static_list); u132->sequence_num = ++u132_instances; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); u132_u132_init_kref(u132); u132_initialise(u132, pdev); hcd->product_desc = "ELAN U132 Host Controller"; @@ -3217,7 +3216,7 @@ static int __init u132_hcd_init(void) INIT_LIST_HEAD(&u132_static_list); u132_instances = 0; u132_exiting = 0; - mutex_init(&u132_module_lock); + init_MUTEX(&u132_module_lock); if (usb_disabled()) return -ENODEV; printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, @@ -3233,9 +3232,9 @@ static void __exit u132_hcd_exit(void) { struct u132 *u132; struct u132 *temp; - mutex_lock(&u132_module_lock); + down(&u132_module_lock); u132_exiting += 1; - mutex_unlock(&u132_module_lock); + up(&u132_module_lock); list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { platform_device_unregister(u132->platform_dev); } platform_driver_unregister(&u132_platform_driver); diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 3bb908ca38e9..4aed305982ec 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -827,10 +827,8 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * If direction is "send", change the packet ID from SETUP (0x2D) * to OUT (0xE1). Else change it from SETUP to IN (0x69) and * set Short Packet Detect (SPD) for all data packets. - * - * 0-length transfers always get treated as "send". */ - if (usb_pipeout(urb->pipe) || len == 0) + if (usb_pipeout(urb->pipe)) destination ^= (USB_PID_SETUP ^ USB_PID_OUT); else { destination ^= (USB_PID_SETUP ^ USB_PID_IN); @@ -841,12 +839,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, * Build the DATA TDs */ while (len > 0) { - int pktsze = maxsze; - - if (len <= pktsze) { /* The last data packet */ - pktsze = len; - status &= ~TD_CTRL_SPD; - } + int pktsze = min(len, maxsze); td = uhci_alloc_td(uhci); if (!td) @@ -873,10 +866,20 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, goto nomem; *plink = LINK_TO_TD(td); - /* Change direction for the status transaction */ - destination ^= (USB_PID_IN ^ USB_PID_OUT); + /* + * It's IN if the pipe is an output pipe or we're not expecting + * data back. + */ + destination &= ~TD_TOKEN_PID_MASK; + if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) + destination |= USB_PID_IN; + else + destination |= USB_PID_OUT; + destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ + status &= ~TD_CTRL_SPD; + uhci_add_td_to_urbp(td, urbp); uhci_fill_td(td, status | TD_CTRL_IOC, destination | uhci_explen(0), 0); @@ -1182,18 +1185,10 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) } } - /* Did we receive a short packet? */ } else if (len < uhci_expected_length(td_token(td))) { - /* For control transfers, go to the status TD if - * this isn't already the last data TD */ - if (qh->type == USB_ENDPOINT_XFER_CONTROL) { - if (td->list.next != urbp->td_list.prev) - ret = 1; - } - - /* For bulk and interrupt, this may be an error */ - else if (urb->transfer_flags & URB_SHORT_NOT_OK) + /* We received a short packet */ + if (urb->transfer_flags & URB_SHORT_NOT_OK) ret = -EREMOTEIO; /* Fixup needed only if this isn't the URB's last TD */ @@ -1213,6 +1208,10 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) err: if (ret < 0) { + /* In case a control transfer gets an error + * during the setup stage */ + urb->actual_length = max(urb->actual_length, 0); + /* Note that the queue has stopped and save * the next toggle value */ qh->element = UHCI_PTR_TERM; @@ -1490,25 +1489,9 @@ __acquires(uhci->lock) { struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; - if (qh->type == USB_ENDPOINT_XFER_CONTROL) { - - /* urb->actual_length < 0 means the setup transaction didn't - * complete successfully. Either it failed or the URB was - * unlinked first. Regardless, don't confuse people with a - * negative length. */ - urb->actual_length = max(urb->actual_length, 0); - - /* Report erroneous short transfers */ - if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && - urb->actual_length < - urb->transfer_buffer_length && - urb->status == 0)) - urb->status = -EREMOTEIO; - } - /* When giving back the first URB in an Isochronous queue, * reinitialize the QH's iso-related members for the next URB. */ - else if (qh->type == USB_ENDPOINT_XFER_ISOC && + if (qh->type == USB_ENDPOINT_XFER_ISOC && urbp->node.prev == &qh->queue && urbp->node.next != &qh->queue) { struct urb *nurb = list_entry(urbp->node.next, diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index d1131a87a5b1..36502a06f73a 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -284,9 +284,9 @@ static void mdc800_usb_irq (struct urb *urb) int data_received=0, wake_up; unsigned char* b=urb->transfer_buffer; struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status >= 0) { + if (urb->status >= 0) + { //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); @@ -324,7 +324,7 @@ static void mdc800_usb_irq (struct urb *urb) || ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) || - (status < 0) + (urb->status < 0) ); if (wake_up) @@ -376,12 +376,15 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) static void mdc800_usb_write_notify (struct urb *urb) { struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status != 0) - err ("writing command fails (status=%i)", status); + if (urb->status != 0) + { + err ("writing command fails (status=%i)", urb->status); + } else + { mdc800->state=READY; + } mdc800->written = 1; wake_up (&mdc800->write_wait); } @@ -393,9 +396,9 @@ static void mdc800_usb_write_notify (struct urb *urb) static void mdc800_usb_download_notify (struct urb *urb) { struct mdc800_data* mdc800=urb->context; - int status = urb->status; - if (status == 0) { + if (urb->status == 0) + { /* Fill output buffer with these data */ memcpy (mdc800->out, urb->transfer_buffer, 64); mdc800->out_count=64; @@ -405,8 +408,10 @@ static void mdc800_usb_download_notify (struct urb *urb) { mdc800->state=READY; } - } else { - err ("request bytes fails (status:%i)", status); + } + else + { + err ("request bytes fails (status:%i)", urb->status); } mdc800->downloaded = 1; wake_up (&mdc800->download_wait); @@ -644,9 +649,9 @@ static int mdc800_device_open (struct inode* inode, struct file *file) retval=0; mdc800->irq_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL); - if (retval) { - err ("request USB irq fails (submit_retval=%i).", retval); + if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL)) + { + err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); errn = -EIO; goto error_out; } @@ -693,7 +698,6 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l { size_t left=len, sts=len; /* single transfer size */ char __user *ptr = buf; - int retval; mutex_lock(&mdc800->io_lock); if (mdc800->state == NOT_CONNECTED) @@ -733,9 +737,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l /* Download -> Request new bytes */ mdc800->download_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL); - if (retval) { - err ("Can't submit download urb (retval=%i)",retval); + if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) + { + err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); mutex_unlock(&mdc800->io_lock); return len-left; } @@ -784,7 +788,6 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) { size_t i=0; - int retval; mutex_lock(&mdc800->io_lock); if (mdc800->state != READY) @@ -851,9 +854,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s mdc800->state=WORKING; memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); mdc800->write_urb->dev = mdc800->dev; - retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL); - if (retval) { - err ("submitting write urb fails (retval=%i)", retval); + if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) + { + err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); mutex_unlock(&mdc800->io_lock); return -EIO; } diff --git a/trunk/drivers/usb/image/microtek.c b/trunk/drivers/usb/image/microtek.c index 768b2c11a231..51bd80d2b8cc 100644 --- a/trunk/drivers/usb/image/microtek.c +++ b/trunk/drivers/usb/image/microtek.c @@ -189,7 +189,7 @@ static struct usb_driver mts_usb_driver = { #define MTS_DEBUG_INT() \ do { MTS_DEBUG_GOT_HERE(); \ MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ - MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ + MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ mts_debug_dump(context->instance);\ } while(0) #else @@ -393,6 +393,8 @@ void mts_int_submit_urb (struct urb* transfer, context ); + transfer->status = 0; + res = usb_submit_urb( transfer, GFP_ATOMIC ); if ( unlikely(res) ) { MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); @@ -442,13 +444,12 @@ static void mts_get_status( struct urb *transfer ) static void mts_data_done( struct urb* transfer ) /* Interrupt context! */ { - int status = transfer->status; MTS_INT_INIT(); if ( context->data_length != transfer->actual_length ) { context->srb->resid = context->data_length - transfer->actual_length; - } else if ( unlikely(status) ) { - context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + } else if ( unlikely(transfer->status) ) { + context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; } mts_get_status(transfer); @@ -460,11 +461,10 @@ static void mts_data_done( struct urb* transfer ) static void mts_command_done( struct urb *transfer ) /* Interrupt context! */ { - int status = transfer->status; MTS_INT_INIT(); - if ( unlikely(status) ) { - if (status == -ENOENT) { + if ( unlikely(transfer->status) ) { + if (transfer->status == -ENOENT) { /* We are being killed */ MTS_DEBUG_GOT_HERE(); context->srb->result = DID_ABORT<<16; @@ -502,13 +502,12 @@ static void mts_command_done( struct urb *transfer ) static void mts_do_sg (struct urb* transfer) { struct scatterlist * sg; - int status = transfer->status; MTS_INT_INIT(); MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); - if (unlikely(status)) { - context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; + if (unlikely(transfer->status)) { + context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; mts_transfer_cleanup(transfer); } diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c index e9fdbc8997b3..d72c42e5f22d 100644 --- a/trunk/drivers/usb/misc/adutux.c +++ b/trunk/drivers/usb/misc/adutux.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #ifdef CONFIG_USB_DEBUG @@ -81,7 +80,7 @@ MODULE_DEVICE_TABLE(usb, device_table); /* Structure to hold all of our device specific stuff */ struct adu_device { - struct mutex mtx; /* locks this structure */ + struct semaphore sem; /* locks this structure */ struct usb_device* udev; /* save off the usb device pointer */ struct usb_interface* interface; unsigned char minor; /* the starting minor number for this device */ @@ -179,18 +178,17 @@ static void adu_delete(struct adu_device *dev) static void adu_interrupt_in_callback(struct urb *urb) { struct adu_device *dev = urb->context; - int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); + dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); spin_lock(&dev->buflock); - if (status != 0) { - if ((status != -ENOENT) && (status != -ECONNRESET)) { + if (urb->status != 0) { + if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) { dbg(1," %s : nonzero status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } goto exit; } @@ -218,22 +216,21 @@ static void adu_interrupt_in_callback(struct urb *urb) wake_up_interruptible(&dev->read_wait); adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); } static void adu_interrupt_out_callback(struct urb *urb) { struct adu_device *dev = urb->context; - int status = urb->status; - dbg(4," %s : enter, status %d", __FUNCTION__, status); + dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); - if (status != 0) { - if ((status != -ENOENT) && - (status != -ECONNRESET)) { + if (urb->status != 0) { + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { dbg(1, " %s :nonzero status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } goto exit; } @@ -243,7 +240,7 @@ static void adu_interrupt_out_callback(struct urb *urb) adu_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4," %s : leave, status %d", __FUNCTION__, status); + dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); } static int adu_open(struct inode *inode, struct file *file) @@ -272,8 +269,8 @@ static int adu_open(struct inode *inode, struct file *file) } /* lock this device */ - if ((retval = mutex_lock_interruptible(&dev->mtx))) { - dbg(2, "%s : mutex lock failed", __FUNCTION__); + if ((retval = down_interruptible(&dev->sem))) { + dbg(2, "%s : sem down failed", __FUNCTION__); goto exit_no_device; } @@ -302,7 +299,7 @@ static int adu_open(struct inode *inode, struct file *file) if (retval) --dev->open_count; } - mutex_unlock(&dev->mtx); + up(&dev->sem); exit_no_device: dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); @@ -350,7 +347,7 @@ static int adu_release(struct inode *inode, struct file *file) } /* lock our device */ - mutex_lock(&dev->mtx); /* not interruptible */ + down(&dev->sem); /* not interruptible */ if (dev->open_count <= 0) { dbg(1," %s : device not opened", __FUNCTION__); @@ -360,7 +357,7 @@ static int adu_release(struct inode *inode, struct file *file) if (dev->udev == NULL) { /* the device was unplugged before the file was released */ - mutex_unlock(&dev->mtx); + up(&dev->sem); adu_delete(dev); dev = NULL; } else { @@ -370,7 +367,7 @@ static int adu_release(struct inode *inode, struct file *file) exit: if (dev) - mutex_unlock(&dev->mtx); + up(&dev->sem); dbg(2," %s : leave, return value %d", __FUNCTION__, retval); return retval; } @@ -393,7 +390,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, dev = file->private_data; dbg(2," %s : dev=%p", __FUNCTION__, dev); /* lock this object */ - if (mutex_lock_interruptible(&dev->mtx)) + if (down_interruptible(&dev->sem)) return -ERESTARTSYS; /* verify that the device wasn't unplugged */ @@ -525,7 +522,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, exit: /* unlock the device */ - mutex_unlock(&dev->mtx); + up(&dev->sem); dbg(2," %s : leave, return value %d", __FUNCTION__, retval); return retval; @@ -546,7 +543,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, dev = file->private_data; /* lock this object */ - retval = mutex_lock_interruptible(&dev->mtx); + retval = down_interruptible(&dev->sem); if (retval) goto exit_nolock; @@ -574,9 +571,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, retval = -EINTR; goto exit; } - mutex_unlock(&dev->mtx); + up(&dev->sem); timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); - retval = mutex_lock_interruptible(&dev->mtx); + retval = down_interruptible(&dev->sem); if (retval) { retval = bytes_written ? bytes_written : retval; goto exit_nolock; @@ -641,7 +638,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, exit: /* unlock the device */ - mutex_unlock(&dev->mtx); + up(&dev->sem); exit_nolock: dbg(2," %s : leave, return value %d", __FUNCTION__, retval); @@ -701,7 +698,7 @@ static int adu_probe(struct usb_interface *interface, goto exit; } - mutex_init(&dev->mtx); + init_MUTEX(&dev->sem); spin_lock_init(&dev->buflock); dev->udev = udev; init_waitqueue_head(&dev->read_wait); @@ -838,16 +835,16 @@ static void adu_disconnect(struct usb_interface *interface) usb_deregister_dev(interface, &adu_class); dev->minor = 0; - mutex_lock(&dev->mtx); /* not interruptible */ + down(&dev->sem); /* not interruptible */ /* if the device is not opened, then we clean up right now */ dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); if (!dev->open_count) { - mutex_unlock(&dev->mtx); + up(&dev->sem); adu_delete(dev); } else { dev->udev = NULL; - mutex_unlock(&dev->mtx); + up(&dev->sem); } dev_info(&interface->dev, "ADU device adutux%d now disconnected", diff --git a/trunk/drivers/usb/misc/appledisplay.c b/trunk/drivers/usb/misc/appledisplay.c index b09c83568c1a..cf70c16f0e3f 100644 --- a/trunk/drivers/usb/misc/appledisplay.c +++ b/trunk/drivers/usb/misc/appledisplay.c @@ -88,10 +88,9 @@ static void appledisplay_complete(struct urb *urb) { struct appledisplay *pdata = urb->context; unsigned long flags; - int status = urb->status; int retval; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -103,12 +102,12 @@ static void appledisplay_complete(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* This urb is terminated, clean up */ - dbg("%s - urb shuttingdown with status: %d", - __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); goto exit; } diff --git a/trunk/drivers/usb/misc/auerswald.c b/trunk/drivers/usb/misc/auerswald.c index df7e1ecc810a..42d4e6454a77 100644 --- a/trunk/drivers/usb/misc/auerswald.c +++ b/trunk/drivers/usb/misc/auerswald.c @@ -862,16 +862,14 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) pauerbuf_t bp = (pauerbuf_t) urb->context; pauerswald_t cp; int ret; - int status = urb->status; - dbg ("auerswald_ctrlread_wretcomplete called"); - dbg ("complete with status: %d", status); + dbg ("complete with status: %d", urb->status); cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); /* check if it is possible to advance */ - if (!auerswald_status_retry(status) || !cp->usbdev) { + if (!auerswald_status_retry (urb->status) || !cp->usbdev) { /* reuse the buffer */ - err ("control dummy: transmission error %d, can not retry", status); + err ("control dummy: transmission error %d, can not retry", urb->status); auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); @@ -904,23 +902,21 @@ static void auerswald_ctrlread_complete (struct urb * urb) pauerswald_t cp; pauerscon_t scp; pauerbuf_t bp = (pauerbuf_t) urb->context; - int status = urb->status; int ret; - dbg ("auerswald_ctrlread_complete called"); cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); /* check if there is valid data in this urb */ - if (status) { - dbg ("complete with non-zero status: %d", status); + if (urb->status) { + dbg ("complete with non-zero status: %d", urb->status); /* should we do a retry? */ - if (!auerswald_status_retry(status) + if (!auerswald_status_retry (urb->status) || !cp->usbdev || (cp->version < AUV_RETRY) || (bp->retries >= AU_RETRIES)) { /* reuse the buffer */ - err ("control read: transmission error %d, can not retry", status); + err ("control read: transmission error %d, can not retry", urb->status); auerbuf_releasebuf (bp); /* Wake up all processes waiting for a buffer */ wake_up (&cp->bufferwait); @@ -978,13 +974,12 @@ static void auerswald_int_complete (struct urb * urb) unsigned int channelid; unsigned int bytecount; int ret; - int status = urb->status; pauerbuf_t bp = NULL; pauerswald_t cp = (pauerswald_t) urb->context; dbg ("%s called", __FUNCTION__); - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -992,10 +987,10 @@ static void auerswald_int_complete (struct urb * urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } diff --git a/trunk/drivers/usb/misc/ftdi-elan.c b/trunk/drivers/usb/misc/ftdi-elan.c index 538b535e955b..e0f122e131d7 100644 --- a/trunk/drivers/usb/misc/ftdi-elan.c +++ b/trunk/drivers/usb/misc/ftdi-elan.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -65,7 +64,7 @@ static struct workqueue_struct *respond_queue; * ftdi_module_lock exists to protect access to global variables * */ -static struct mutex ftdi_module_lock; +static struct semaphore ftdi_module_lock; static int ftdi_instances = 0; static struct list_head ftdi_static_list; /* @@ -200,10 +199,10 @@ static void ftdi_elan_delete(struct kref *kref) dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); usb_put_dev(ftdi->udev); ftdi->disconnected += 1; - mutex_lock(&ftdi_module_lock); + down(&ftdi_module_lock); list_del_init(&ftdi->ftdi_list); ftdi_instances -= 1; - mutex_unlock(&ftdi_module_lock); + up(&ftdi_module_lock); kfree(ftdi->bulk_in_buffer); ftdi->bulk_in_buffer = NULL; } @@ -747,12 +746,10 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, static void ftdi_elan_write_bulk_callback(struct urb *urb) { struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; - int status = urb->status; - - if (status && !(status == -ENOENT || status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && !(urb->status == -ENOENT || urb->status == + -ECONNRESET || urb->status == -ESHUTDOWN)) { dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" - "d\n", urb, status); + "d\n", urb, urb->status); } usb_buffer_free(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); @@ -2783,10 +2780,10 @@ static int ftdi_elan_probe(struct usb_interface *interface, return -ENOMEM; } memset(ftdi, 0x00, sizeof(struct usb_ftdi)); - mutex_lock(&ftdi_module_lock); + down(&ftdi_module_lock); list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); ftdi->sequence_num = ++ftdi_instances; - mutex_unlock(&ftdi_module_lock); + up(&ftdi_module_lock); ftdi_elan_init_kref(ftdi); init_MUTEX(&ftdi->sw_lock); ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); @@ -2912,7 +2909,7 @@ static int __init ftdi_elan_init(void) int result; printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, __TIME__, __DATE__); - mutex_init(&ftdi_module_lock); + init_MUTEX(&ftdi_module_lock); INIT_LIST_HEAD(&ftdi_static_list); status_queue = create_singlethread_workqueue("ftdi-status-control"); if (!status_queue) diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c index 46d9f27ec173..28548d186712 100644 --- a/trunk/drivers/usb/misc/iowarrior.c +++ b/trunk/drivers/usb/misc/iowarrior.c @@ -158,10 +158,9 @@ static void iowarrior_callback(struct urb *urb) int read_idx; int aux_idx; int offset; - int status = urb->status; - int retval; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; @@ -214,10 +213,10 @@ static void iowarrior_callback(struct urb *urb) wake_up_interruptible(&dev->read_wait); exit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", - __FUNCTION__, retval); + __FUNCTION__, status); } @@ -227,15 +226,13 @@ static void iowarrior_callback(struct urb *urb) static void iowarrior_write_callback(struct urb *urb) { struct iowarrior *dev; - int status = urb->status; - dev = (struct iowarrior *)urb->context; /* sync/async unlink faults aren't errors */ - if (status && - !(status == -ENOENT || - status == -ECONNRESET || status == -ESHUTDOWN)) { + if (urb->status && + !(urb->status == -ENOENT || + urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) { dbg("%s - nonzero write bulk status received: %d", - __func__, status); + __func__, urb->status); } /* free up our allocated buffer */ usb_buffer_free(urb->dev, urb->transfer_buffer_length, diff --git a/trunk/drivers/usb/misc/ldusb.c b/trunk/drivers/usb/misc/ldusb.c index 8208496dfc63..5e950b90c541 100644 --- a/trunk/drivers/usb/misc/ldusb.c +++ b/trunk/drivers/usb/misc/ldusb.c @@ -219,17 +219,16 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) struct ld_usb *dev = urb->context; size_t *actual_buffer; unsigned int next_ring_head; - int status = urb->status; int retval; - if (status) { - if (status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN) { + if (urb->status) { + if (urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN) { goto exit; } else { dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", - __FUNCTION__, status); + __FUNCTION__, urb->status); spin_lock(&dev->rbsl); goto resubmit; /* maybe we can recover */ } @@ -276,15 +275,14 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) static void ld_usb_interrupt_out_callback(struct urb *urb) { struct ld_usb *dev = urb->context; - int status = urb->status; /* sync/async unlink faults aren't errors */ - if (status && !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) + if (urb->status && !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) dbg_info(&dev->intf->dev, "%s - nonzero write interrupt status received: %d\n", - __FUNCTION__, status); + __FUNCTION__, urb->status); dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); diff --git a/trunk/drivers/usb/misc/legousbtower.c b/trunk/drivers/usb/misc/legousbtower.c index 561970b889a5..2ed0daea894c 100644 --- a/trunk/drivers/usb/misc/legousbtower.c +++ b/trunk/drivers/usb/misc/legousbtower.c @@ -742,20 +742,19 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t static void tower_interrupt_in_callback (struct urb *urb) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; - int status = urb->status; int retval; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); + dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - if (status) { - if (status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN) { + if (urb->status) { + if (urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN) { goto exit; } else { - dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status); + dbg(1, "%s: nonzero status received: %d", __FUNCTION__, urb->status); goto resubmit; /* maybe we can recover */ } } @@ -789,7 +788,7 @@ static void tower_interrupt_in_callback (struct urb *urb) wake_up_interruptible (&dev->read_wait); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); } @@ -799,24 +798,23 @@ static void tower_interrupt_in_callback (struct urb *urb) static void tower_interrupt_out_callback (struct urb *urb) { struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; - int status = urb->status; - dbg(4, "%s: enter, status %d", __FUNCTION__, status); + dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); /* sync/async unlink faults aren't errors */ - if (status && !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { dbg(1, "%s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } dev->interrupt_out_busy = 0; wake_up_interruptible(&dev->write_wait); lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); - dbg(4, "%s: leave, status %d", __FUNCTION__, status); + dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); } diff --git a/trunk/drivers/usb/misc/phidgetkit.c b/trunk/drivers/usb/misc/phidgetkit.c index aa9bcceabe74..371bf2b1197d 100644 --- a/trunk/drivers/usb/misc/phidgetkit.c +++ b/trunk/drivers/usb/misc/phidgetkit.c @@ -305,10 +305,9 @@ static void interfacekit_irq(struct urb *urb) struct interfacekit *kit = urb->context; unsigned char *buffer = kit->data; int i, level, sensor; - int retval; - int status = urb->status; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -378,11 +377,11 @@ static void interfacekit_irq(struct urb *urb) schedule_delayed_work(&kit->do_notify, 0); resubmit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - err("can't resubmit intr, %s-%s/interfacekit0, retval %d", + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) + err("can't resubmit intr, %s-%s/interfacekit0, status %d", kit->udev->bus->bus_name, - kit->udev->devpath, retval); + kit->udev->devpath, status); } static void do_notify(struct work_struct *work) diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index df0ebcdb9d6a..5727e1ea2f91 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -95,10 +95,9 @@ static void motorcontrol_irq(struct urb *urb) struct motorcontrol *mc = urb->context; unsigned char *buffer = mc->data; int i, level; - int retval; - int status = urb->status;; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -152,12 +151,12 @@ static void motorcontrol_irq(struct urb *urb) schedule_delayed_work(&mc->do_notify, 0); resubmit: - retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status) dev_err(&mc->intf->dev, - "can't resubmit intr, %s-%s/motorcontrol0, retval %d", + "can't resubmit intr, %s-%s/motorcontrol0, status %d", mc->udev->bus->bus_name, - mc->udev->devpath, retval); + mc->udev->devpath, status); } static void do_notify(struct work_struct *work) diff --git a/trunk/drivers/usb/misc/usblcd.c b/trunk/drivers/usb/misc/usblcd.c index 719842032712..504f7221b0d0 100644 --- a/trunk/drivers/usb/misc/usblcd.c +++ b/trunk/drivers/usb/misc/usblcd.c @@ -176,17 +176,16 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u static void lcd_write_bulk_callback(struct urb *urb) { struct usb_lcd *dev; - int status = urb->status; dev = (struct usb_lcd *)urb->context; /* sync/async unlink faults aren't errors */ - if (status && - !(status == -ENOENT || - status == -ECONNRESET || - status == -ESHUTDOWN)) { + if (urb->status && + !(urb->status == -ENOENT || + urb->status == -ECONNRESET || + urb->status == -ESHUTDOWN)) { dbg("USBLCD: %s - nonzero write bulk status received: %d", - __FUNCTION__, status); + __FUNCTION__, urb->status); } /* free up our allocated buffer */ diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index e901d31e051b..fb321864a92d 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -768,8 +768,8 @@ static void ctrl_complete (struct urb *urb) /* some faults are allowed, not required */ if (subcase->expected > 0 && ( - ((status == -subcase->expected /* happened */ - || status == 0)))) /* didn't */ + ((urb->status == -subcase->expected /* happened */ + || urb->status == 0)))) /* didn't */ status = 0; /* sometimes more than one fault is allowed */ else if (subcase->number == 12 && status == -EPIPE) diff --git a/trunk/drivers/usb/misc/uss720.c b/trunk/drivers/usb/misc/uss720.c index 2734fe2b9c43..1a60f9c473ad 100644 --- a/trunk/drivers/usb/misc/uss720.c +++ b/trunk/drivers/usb/misc/uss720.c @@ -111,13 +111,12 @@ static void async_complete(struct urb *urb) struct uss720_async_request *rq; struct parport *pp; struct parport_uss720_private *priv; - int status = urb->status; rq = urb->context; priv = rq->priv; pp = priv->pp; - if (status) { - err("async_complete: urb error %d", status); + if (urb->status) { + err("async_complete: urb error %d", urb->status); } else if (rq->dr.bRequest == 3) { memcpy(priv->reg, rq->reg, sizeof(priv->reg)); #if 0 diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index b8670905bc3a..0d3903691e8c 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2794,14 +2794,16 @@ static void edge_shutdown (struct usb_serial *serial) dbg ("%s", __FUNCTION__); - for (i = 0; i < serial->num_ports; ++i) { + for (i=0; i < serial->num_ports; ++i) { edge_port = usb_get_serial_port_data(serial->port[i]); edge_remove_sysfs_attrs(edge_port->port); - edge_buf_free(edge_port->ep_out_buf); - kfree(edge_port); + if (edge_port) { + edge_buf_free(edge_port->ep_out_buf); + kfree(edge_port); + } usb_set_serial_port_data(serial->port[i], NULL); } - kfree(usb_get_serial_data(serial)); + kfree (usb_get_serial_data(serial)); usb_set_serial_data(serial, NULL); } diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index 01e811becec4..231b584f6d0f 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -110,6 +110,11 @@ static void mos7720_interrupt_callback(struct urb *urb) dbg("%s"," : Entering\n"); + if (!urb) { + dbg("%s","Invalid Pointer !!!!:\n"); + return; + } + switch (status) { case 0: /* success */ diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index f76480f1455d..37f41f576d3d 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -436,6 +436,11 @@ static void mos7840_control_callback(struct urb *urb) int result = 0; int status = urb->status; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + mos7840_port = (struct moschip_port *)urb->context; switch (status) { @@ -520,6 +525,10 @@ static void mos7840_interrupt_callback(struct urb *urb) int status = urb->status; dbg("%s", " : Entering\n"); + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } switch (status) { case 0: @@ -667,6 +676,11 @@ static void mos7840_bulk_in_callback(struct urb *urb) struct tty_struct *tty; int status = urb->status; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + if (status) { dbg("nonzero read bulk status received: %d", status); return; @@ -739,6 +753,11 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) int status = urb->status; int i; + if (!urb) { + dbg("%s", "Invalid Pointer !!!!:\n"); + return; + } + mos7840_port = (struct moschip_port *)urb->context; spin_lock(&mos7840_port->pool_lock); for (i = 0; i < NUM_URBS; i++) { diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 0794ccdebfd4..e7db20343d1a 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -1,7 +1,7 @@ /* USB Driver for Sierra Wireless - Copyright (C) 2006, 2007 Kevin Lloyd + Copyright (C) 2006 Kevin Lloyd IMPORTANT DISCLAIMER: This driver is not commercially supported by Sierra Wireless. Use at your own risk. @@ -12,9 +12,10 @@ Portions based on the option driver by Matthias Urlichs Whom based his on the Keyspan driver by Hugh Blemings + */ -#define DRIVER_VERSION "v.1.2.5b" +#define DRIVER_VERSION "v.1.0.6" #define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -27,98 +28,23 @@ #include #include -#define SWIMS_USB_REQUEST_SetMode 0x0B -#define SWIMS_USB_REQUEST_TYPE_SetMode 0x40 -#define SWIMS_USB_INDEX_SetMode 0x0000 -#define SWIMS_SET_MODE_Modem 0x0001 - -/* per port private data */ -#define N_IN_URB 4 -#define N_OUT_URB 4 -#define IN_BUFLEN 4096 - -static int debug; - -enum devicetype { - DEVICE_3_PORT = 0, - DEVICE_1_PORT = 1, - DEVICE_INSTALLER = 2, -}; - -int sierra_set_power_state(struct usb_device *udev, __u16 swiState) -{ - int result; - dev_dbg(&udev->dev, "%s", "SET POWER STATE"); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - 0x00, /* __u8 request */ - 0x40, /* __u8 request type */ - swiState, /* __u16 value */ - 0, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) -{ - int result; - dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); - result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - SWIMS_USB_REQUEST_SetMode, /* __u8 request */ - SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ - eSocMode, /* __u16 value */ - SWIMS_USB_INDEX_SetMode, /* __u16 index */ - NULL, /* void *data */ - 0, /* __u16 size */ - USB_CTRL_SET_TIMEOUT); /* int timeout */ - return result; -} - -int sierra_probe(struct usb_interface *iface, const struct usb_device_id *id) -{ - int result; - struct usb_device *udev; - - udev = usb_get_dev(interface_to_usbdev(iface)); - - /* Check if in installer mode */ - if (id->driver_info == DEVICE_INSTALLER) { - dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n"); - result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); - /*We do not want to bind to the device when in installer mode*/ - return -EIO; - } - - return usb_serial_probe(iface, id); -} static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ - - { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ - { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ - { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ + { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ { } }; MODULE_DEVICE_TABLE(usb, id_table); @@ -132,36 +58,35 @@ static struct usb_device_id id_table_1port [] = { static struct usb_device_id id_table_3port [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ + { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ - { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ - { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ - { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ + { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ - { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ - { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ - { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ - { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ - { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */ - { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */ { } }; static struct usb_driver sierra_driver = { .name = "sierra", - .probe = sierra_probe, + .probe = usb_serial_probe, .disconnect = usb_serial_disconnect, .id_table = id_table, .no_dynamic_id = 1, }; +static int debug; + +/* per port private data */ +#define N_IN_URB 4 +#define N_OUT_URB 4 +#define IN_BUFLEN 4096 + struct sierra_port_private { spinlock_t lock; /* lock the structure */ int outstanding_urbs; /* number of out urbs in flight */ @@ -496,6 +421,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) int i; struct urb *urb; int result; + __u16 set_mode_dzero = 0x0000; portdata = usb_get_serial_port_data(port); @@ -531,6 +457,12 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) port->tty->low_latency = 1; + /* set mode to D0 */ + result = usb_control_msg(serial->dev, + usb_rcvctrlpipe(serial->dev, 0), + 0x00, 0x40, set_mode_dzero, 0, NULL, + 0, USB_CTRL_SET_TIMEOUT); + sierra_send_setup(port); /* start up the interrupt endpoint if we have one */ @@ -578,9 +510,6 @@ static int sierra_startup(struct usb_serial *serial) dbg("%s", __FUNCTION__); - /*Set Device mode to D0 */ - sierra_set_power_state(serial->dev, 0x0000); - /* Now setup per port private data */ for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; diff --git a/trunk/drivers/usb/storage/dpcm.c b/trunk/drivers/usb/storage/dpcm.c index 9a410b5a6e5b..1628cb258562 100644 --- a/trunk/drivers/usb/storage/dpcm.c +++ b/trunk/drivers/usb/storage/dpcm.c @@ -46,43 +46,43 @@ */ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) { - int ret; + int ret; - if (srb == NULL) - return USB_STOR_TRANSPORT_ERROR; + if(srb == NULL) + return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); + US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); - switch (srb->device->lun) { - case 0: + switch(srb->device->lun) { + case 0: - /* - * LUN 0 corresponds to the CompactFlash card reader. - */ - ret = usb_stor_CB_transport(srb, us); - break; + /* + * LUN 0 corresponds to the CompactFlash card reader. + */ + ret = usb_stor_CB_transport(srb, us); + break; #ifdef CONFIG_USB_STORAGE_SDDR09 - case 1: + case 1: - /* - * LUN 1 corresponds to the SmartMedia card reader. - */ + /* + * LUN 1 corresponds to the SmartMedia card reader. + */ - /* - * Set the LUN to 0 (just in case). - */ - srb->device->lun = 0; us->srb->device->lun = 0; - ret = sddr09_transport(srb, us); - srb->device->lun = 1; us->srb->device->lun = 1; - break; + /* + * Set the LUN to 0 (just in case). + */ + srb->device->lun = 0; us->srb->device->lun = 0; + ret = sddr09_transport(srb, us); + srb->device->lun = 1; us->srb->device->lun = 1; + break; #endif - default: - US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); - ret = USB_STOR_TRANSPORT_ERROR; - break; - } - return ret; + default: + US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); + ret = USB_STOR_TRANSPORT_ERROR; + break; + } + return ret; } diff --git a/trunk/drivers/usb/storage/onetouch.c b/trunk/drivers/usb/storage/onetouch.c index dfd42fe9e5f0..d35369392fed 100644 --- a/trunk/drivers/usb/storage/onetouch.c +++ b/trunk/drivers/usb/storage/onetouch.c @@ -57,10 +57,9 @@ static void usb_onetouch_irq(struct urb *urb) struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; struct input_dev *dev = onetouch->dev; - int status = urb->status; - int retval; + int status; - switch (status) { + switch (urb->status) { case 0: /* success */ break; case -ECONNRESET: /* unlink */ @@ -76,11 +75,11 @@ static void usb_onetouch_irq(struct urb *urb) input_sync(dev); resubmit: - retval = usb_submit_urb (urb, GFP_ATOMIC); - if (retval) - err ("can't resubmit intr, %s-%s/input0, retval %d", + status = usb_submit_urb (urb, GFP_ATOMIC); + if (status) + err ("can't resubmit intr, %s-%s/input0, status %d", onetouch->udev->bus->bus_name, - onetouch->udev->devpath, retval); + onetouch->udev->devpath, status); } static int usb_onetouch_open(struct input_dev *dev) diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index a624e72f81dc..b6bf31a97b60 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -313,13 +313,6 @@ UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, US_SC_DEVICE, US_PR_DEVICE,NULL, US_FL_NOT_LOCKABLE ), -/* Reported by Stefan de Konink */ -UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, - "NIKON", - "NIKON DSC D100", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - /* Reported by Andreas Bockhold */ UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, "NIKON", @@ -1391,17 +1384,6 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, 0 ), -/* Reported by Kevin Lloyd - * Entry is needed for the initializer function override, - * which instructs the device to load as a modem - * device. - */ -UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, - "Sierra Wireless", - "USB MMC Storage", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_DEVICE), - /* Reported by Jaco Kroon * The usb-storage module found on the Digitech GNX4 (and supposedly other * devices) misbehaves and causes a bunch of invalid I/O errors. diff --git a/trunk/drivers/video/backlight/cr_bllcd.c b/trunk/drivers/video/backlight/cr_bllcd.c index 1b3f6586bc9f..e9bbc3455c94 100644 --- a/trunk/drivers/video/backlight/cr_bllcd.c +++ b/trunk/drivers/video/backlight/cr_bllcd.c @@ -174,7 +174,7 @@ static int cr_backlight_probe(struct platform_device *pdev) struct cr_panel *crp; u8 dev_en; - crp = kzalloc(sizeof(*crp), GFP_KERNEL); + crp = kzalloc(sizeof(crp), GFP_KERNEL); if (crp == NULL) return -ENOMEM; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 0e5ec371ce72..02ebb1f1d3b0 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2221,7 +2221,7 @@ block_page_mkwrite(struct vm_area_struct *vma, struct page *page, lock_page(page); size = i_size_read(inode); if ((page->mapping != inode->i_mapping) || - (page_offset(page) > size)) { + ((page->index << PAGE_CACHE_SHIFT) > size)) { /* page got truncated out from underneath us */ goto out_unlock; } diff --git a/trunk/fs/ecryptfs/mmap.c b/trunk/fs/ecryptfs/mmap.c index e4ab7bc14efe..7d5a43cb0d5c 100644 --- a/trunk/fs/ecryptfs/mmap.c +++ b/trunk/fs/ecryptfs/mmap.c @@ -409,7 +409,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, if (!PageUptodate(page)) rc = ecryptfs_do_readpage(file, page, page->index); if (page->index != 0) { - loff_t end_of_prev_pg_pos = page_offset(page) - 1; + loff_t end_of_prev_pg_pos = + (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { rc = ecryptfs_truncate(file->f_path.dentry, @@ -735,7 +736,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, goto out; } inode->i_blocks = lower_inode->i_blocks; - pos = page_offset(page) + to; + pos = (page->index << PAGE_CACHE_SHIFT) + to; if (pos > i_size_read(inode)) { i_size_write(inode, pos); ecryptfs_printk(KERN_DEBUG, "Expanded file size to " diff --git a/trunk/fs/ocfs2/mmap.c b/trunk/fs/ocfs2/mmap.c index 98756156d298..ee64749e2eeb 100644 --- a/trunk/fs/ocfs2/mmap.c +++ b/trunk/fs/ocfs2/mmap.c @@ -89,7 +89,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, { int ret; struct address_space *mapping = inode->i_mapping; - loff_t pos = page_offset(page); + loff_t pos = page->index << PAGE_CACHE_SHIFT; unsigned int len = PAGE_CACHE_SIZE; pgoff_t last_index; struct page *locked_page = NULL; diff --git a/trunk/include/asm-m68k/io.h b/trunk/include/asm-m68k/io.h index 47bb9cf107b7..5e0fcf41804d 100644 --- a/trunk/include/asm-m68k/io.h +++ b/trunk/include/asm-m68k/io.h @@ -27,7 +27,6 @@ #include #include -#include #ifdef CONFIG_ATARI #include @@ -153,16 +152,6 @@ static inline u16 __iomem *isa_itw(unsigned long addr) default: return NULL; /* avoid warnings, just in case */ } } -static inline u32 __iomem *isa_itl(unsigned long addr) -{ - switch(ISA_TYPE) - { -#ifdef CONFIG_AMIGA_PCMCIA - case AG_ISA: return (u32 __iomem *)AG_ISA_IO_W(addr); -#endif - default: return 0; /* avoid warnings, just in case */ - } -} static inline u8 __iomem *isa_mtb(unsigned long addr) { switch(ISA_TYPE) @@ -199,10 +188,8 @@ static inline u16 __iomem *isa_mtw(unsigned long addr) #define isa_inb(port) in_8(isa_itb(port)) #define isa_inw(port) (ISA_SEX ? in_be16(isa_itw(port)) : in_le16(isa_itw(port))) -#define isa_inl(port) (ISA_SEX ? in_be32(isa_itl(port)) : in_le32(isa_itl(port))) #define isa_outb(val,port) out_8(isa_itb(port),(val)) #define isa_outw(val,port) (ISA_SEX ? out_be16(isa_itw(port),(val)) : out_le16(isa_itw(port),(val))) -#define isa_outl(val,port) (ISA_SEX ? out_be32(isa_itl(port),(val)) : out_le32(isa_itl(port),(val))) #define isa_readb(p) in_8(isa_mtb((unsigned long)(p))) #define isa_readw(p) \ @@ -247,15 +234,6 @@ static inline void isa_delay(void) #define isa_outsw(port, buf, nr) \ (ISA_SEX ? raw_outsw(isa_itw(port), (u16 *)(buf), (nr)) : \ raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr))) - -#define isa_insl(port, buf, nr) \ - (ISA_SEX ? raw_insl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - -#define isa_outsl(port, buf, nr) \ - (ISA_SEX ? raw_outsl(isa_itl(port), (u32 *)(buf), (nr)) : \ - raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1)) - #endif /* CONFIG_ISA */ @@ -268,16 +246,14 @@ static inline void isa_delay(void) #define inw_p isa_inw_p #define outw isa_outw #define outw_p isa_outw_p -#define inl isa_inl -#define inl_p isa_inl_p -#define outl isa_outl -#define outl_p isa_outl_p +#define inl isa_inw +#define inl_p isa_inw_p +#define outl isa_outw +#define outl_p isa_outw_p #define insb isa_insb #define insw isa_insw -#define insl isa_insl #define outsb isa_outsb #define outsw isa_outsw -#define outsl isa_outsl #define readb isa_readb #define readw isa_readw #define writeb isa_writeb @@ -286,6 +262,8 @@ static inline void isa_delay(void) #if defined(CONFIG_PCI) +#define inl(port) in_le32(port) +#define outl(val,port) out_le32((port),(val)) #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) @@ -304,8 +282,6 @@ static inline void isa_delay(void) #define outb(val,port) out_8((port),(val)) #define inw(port) in_le16(port) #define outw(val,port) out_le16((port),(val)) -#define inl(port) in_le32(port) -#define outl(val,port) out_le32((port),(val)) #else /* @@ -330,35 +306,20 @@ static inline void isa_delay(void) #endif #endif /* CONFIG_PCI */ -#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) +#if !defined(CONFIG_ISA) && !defined(CONFIG_PCI) && defined(CONFIG_HP300) /* - * We need to define dummy functions for GENERIC_IOMAP support. + * We need to define dummy functions otherwise drivers/serial/8250.c doesn't link */ -#define inb(port) 0xff -#define inb_p(port) 0xff -#define outb(val,port) ((void)0) -#define outb_p(val,port) ((void)0) -#define inw(port) 0xffff -#define outw(val,port) ((void)0) -#define inl(port) 0xffffffffUL -#define outl(val,port) ((void)0) - -#define insb(port,buf,nr) ((void)0) -#define outsb(port,buf,nr) ((void)0) -#define insw(port,buf,nr) ((void)0) -#define outsw(port,buf,nr) ((void)0) -#define insl(port,buf,nr) ((void)0) -#define outsl(port,buf,nr) ((void)0) +#define inb(port) 0xff +#define inb_p(port) 0xff +#define outb(val,port) do { } while (0) +#define outb_p(val,port) do { } while (0) /* * These should be valid on any ioremap()ed region */ #define readb(addr) in_8(addr) #define writeb(val,addr) out_8((addr),(val)) -#define readw(addr) in_le16(addr) -#define writew(val,addr) out_le16((addr),(val)) -#endif -#if !defined(CONFIG_PCI) #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) #endif @@ -390,18 +351,6 @@ extern void dma_cache_wback_inv(unsigned long start, unsigned long size); extern void dma_cache_wback(unsigned long start, unsigned long size); extern void dma_cache_inv(unsigned long start, unsigned long size); -static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) -{ - __builtin_memset((void __force *) addr, val, count); -} -static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) -{ - __builtin_memcpy(dst, (void __force *) src, count); -} -static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) -{ - __builtin_memcpy((void __force *) dst, src, count); -} #ifndef CONFIG_SUN3 #define IO_SPACE_LIMIT 0xffff diff --git a/trunk/include/asm-m68k/raw_io.h b/trunk/include/asm-m68k/raw_io.h index 91c623f0994c..811ccd25d4a6 100644 --- a/trunk/include/asm-m68k/raw_io.h +++ b/trunk/include/asm-m68k/raw_io.h @@ -49,16 +49,10 @@ extern void __iounmap(void *addr, unsigned long size); #define raw_inb in_8 #define raw_inw in_be16 #define raw_inl in_be32 -#define __raw_readb in_8 -#define __raw_readw in_be16 -#define __raw_readl in_be32 #define raw_outb(val,port) out_8((port),(val)) #define raw_outw(val,port) out_be16((port),(val)) #define raw_outl(val,port) out_be32((port),(val)) -#define __raw_writeb(val,addr) out_8((addr),(val)) -#define __raw_writew(val,addr) out_be16((addr),(val)) -#define __raw_writel(val,addr) out_be32((addr),(val)) static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) { @@ -342,6 +336,8 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, : "d0", "a0", "a1", "d6"); } +#define __raw_writel raw_outl + #endif /* __KERNEL__ */ #endif /* _RAW_IO_H */ diff --git a/trunk/include/asm-sh64/unistd.h b/trunk/include/asm-sh64/unistd.h index 1a5197f369b2..ea3adc600b41 100644 --- a/trunk/include/asm-sh64/unistd.h +++ b/trunk/include/asm-sh64/unistd.h @@ -374,11 +374,10 @@ #define __NR_signalfd 349 #define __NR_timerfd 350 #define __NR_eventfd 351 -#define __NR_fallocate 352 #ifdef __KERNEL__ -#define NR_syscalls 353 +#define NR_syscalls 352 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/include/asm-sparc/unistd.h b/trunk/include/asm-sparc/unistd.h index 029b3e0d5e4c..64471bcd96f9 100644 --- a/trunk/include/asm-sparc/unistd.h +++ b/trunk/include/asm-sparc/unistd.h @@ -1,3 +1,4 @@ +/* $Id: unistd.h,v 1.74 2002/02/08 03:57:18 davem Exp $ */ #ifndef _SPARC_UNISTD_H #define _SPARC_UNISTD_H @@ -8,7 +9,7 @@ * think of right now to force the arguments into fixed registers * before the trap into the system call with gcc 'asm' statements. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * SunOS compatibility based upon preliminary work which is: * @@ -329,9 +330,8 @@ #define __NR_signalfd 311 #define __NR_timerfd 312 #define __NR_eventfd 313 -#define __NR_fallocate 314 -#define NR_SYSCALLS 315 +#define NR_SYSCALLS 314 #ifdef __KERNEL__ #define __ARCH_WANT_IPC_PARSE_VERSION diff --git a/trunk/include/asm-sparc64/power.h b/trunk/include/asm-sparc64/power.h new file mode 100644 index 000000000000..94495c1ac4f6 --- /dev/null +++ b/trunk/include/asm-sparc64/power.h @@ -0,0 +1,7 @@ +#ifndef _SPARC64_POWER_H +#define _SPARC64_POWER_H + +extern void wake_up_powerd(void); +extern int start_powerd(void); + +#endif /* !(_SPARC64_POWER_H) */ diff --git a/trunk/include/asm-sparc64/unistd.h b/trunk/include/asm-sparc64/unistd.h index cb751b4d0f56..53e96ed9c024 100644 --- a/trunk/include/asm-sparc64/unistd.h +++ b/trunk/include/asm-sparc64/unistd.h @@ -1,3 +1,4 @@ +/* $Id: unistd.h,v 1.50 2002/02/08 03:57:18 davem Exp $ */ #ifndef _SPARC64_UNISTD_H #define _SPARC64_UNISTD_H @@ -8,7 +9,7 @@ * think of right now to force the arguments into fixed registers * before the trap into the system call with gcc 'asm' statements. * - * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * * SunOS compatibility based upon preliminary work which is: * @@ -331,9 +332,8 @@ #define __NR_signalfd 311 #define __NR_timerfd 312 #define __NR_eventfd 313 -#define __NR_fallocate 314 -#define NR_SYSCALLS 315 +#define NR_SYSCALLS 314 #ifdef __KERNEL__ /* sysconf options, for SunOS compatibility */ diff --git a/trunk/include/asm-sparc64/vio.h b/trunk/include/asm-sparc64/vio.h index f7417e91b170..c0a8d4ed5bcb 100644 --- a/trunk/include/asm-sparc64/vio.h +++ b/trunk/include/asm-sparc64/vio.h @@ -275,8 +275,6 @@ struct vio_dev { char compat[VIO_MAX_COMPAT_LEN]; int compat_len; - u64 dev_no; - unsigned long channel_id; unsigned int tx_irq; diff --git a/trunk/include/linux/async_tx.h b/trunk/include/linux/async_tx.h index bdca3f1b3213..ff1255079fa1 100644 --- a/trunk/include/linux/async_tx.h +++ b/trunk/include/linux/async_tx.h @@ -51,6 +51,10 @@ struct dma_chan_ref { * @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a * dependency chain * @ASYNC_TX_DEP_ACK: ack the dependency descriptor. Useful for chaining. + * @ASYNC_TX_KMAP_SRC: if the transaction is to be performed synchronously + * take an atomic mapping (KM_USER0) on the source page(s) + * @ASYNC_TX_KMAP_DST: if the transaction is to be performed synchronously + * take an atomic mapping (KM_USER0) on the dest page(s) */ enum async_tx_flags { ASYNC_TX_XOR_ZERO_DST = (1 << 0), @@ -58,6 +62,8 @@ enum async_tx_flags { ASYNC_TX_ASSUME_COHERENT = (1 << 2), ASYNC_TX_ACK = (1 << 3), ASYNC_TX_DEP_ACK = (1 << 4), + ASYNC_TX_KMAP_SRC = (1 << 5), + ASYNC_TX_KMAP_DST = (1 << 6), }; #ifdef CONFIG_DMA_ENGINE diff --git a/trunk/include/linux/i2c-id.h b/trunk/include/linux/i2c-id.h index b69014865714..aa83d4163096 100644 --- a/trunk/include/linux/i2c-id.h +++ b/trunk/include/linux/i2c-id.h @@ -115,10 +115,9 @@ #define I2C_DRIVERID_KS0127 86 /* Samsung ks0127 video decoder */ #define I2C_DRIVERID_TLV320AIC23B 87 /* TI TLV320AIC23B audio codec */ #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ -#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ -#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ -#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ -#define I2C_DRIVERID_LM4857 92 /* LM4857 Audio Amplifier */ +#define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ +#define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ +#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ diff --git a/trunk/include/linux/ioprio.h b/trunk/include/linux/ioprio.h index baf29387cab4..2eaa142cd061 100644 --- a/trunk/include/linux/ioprio.h +++ b/trunk/include/linux/ioprio.h @@ -53,14 +53,6 @@ static inline int task_ioprio(struct task_struct *task) return IOPRIO_NORM; } -static inline int task_ioprio_class(struct task_struct *task) -{ - if (ioprio_valid(task->ioprio)) - return IOPRIO_PRIO_CLASS(task->ioprio); - - return IOPRIO_CLASS_BE; -} - static inline int task_nice_ioprio(struct task_struct *task) { return (task_nice(task) + 20) / 5; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index be5a43928c84..47cd2a1c5544 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -323,7 +323,6 @@ enum ata_completion_errors { AC_ERR_INVALID = (1 << 7), /* invalid argument */ AC_ERR_OTHER = (1 << 8), /* unknown */ AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */ - AC_ERR_NCQ = (1 << 10), /* marker for offending NCQ qc */ }; /* forward declarations */ @@ -531,7 +530,6 @@ struct ata_port { unsigned int cbl; /* cable type; ATA_CBL_xxx */ unsigned int hw_sata_spd_limit; unsigned int sata_spd_limit; /* SATA PHY speed limit */ - unsigned int sata_spd; /* current SATA PHY speed */ /* record runtime error info, protected by host lock */ struct ata_eh_info eh_info; @@ -565,9 +563,6 @@ struct ata_port { pm_message_t pm_mesg; int *pm_result; - struct timer_list fastdrain_timer; - unsigned long fastdrain_cnt; - void *private_data; #ifdef CONFIG_ATA_ACPI @@ -624,8 +619,9 @@ struct ata_port_operations { u8 (*irq_on) (struct ata_port *); u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq); - int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val); - int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val); + u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); + void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, + u32 val); int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); int (*port_resume) (struct ata_port *ap); @@ -768,8 +764,7 @@ extern unsigned int ata_dev_try_classify(struct ata_port *, unsigned int, u8 *); */ extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); -extern void ata_tf_to_fis(const struct ata_taskfile *tf, - u8 pmp, int is_cmd, u8 *fis); +extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device); extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); @@ -914,21 +909,27 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, /* * ata_eh_info helpers */ -extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); -extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...); -extern void ata_ehi_clear_desc(struct ata_eh_info *ehi); - -static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi) +#define ata_ehi_push_desc(ehi, fmt, args...) do { \ + (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ + ATA_EH_DESC_LEN - (ehi)->desc_len, \ + fmt , ##args); \ +} while (0) + +#define ata_ehi_clear_desc(ehi) do { \ + (ehi)->desc[0] = '\0'; \ + (ehi)->desc_len = 0; \ +} while (0) + +static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi) { - ehi->flags |= ATA_EHI_RESUME_LINK; + ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK; ehi->action |= ATA_EH_SOFTRESET; ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; } static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) { - ata_ehi_schedule_probe(ehi); - ehi->flags |= ATA_EHI_HOTPLUGGED; + __ata_ehi_hotplugged(ehi); ehi->err_mask |= AC_ERR_ATA_BUS; } diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index 124270df8734..07f7e4cbcee3 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -160,7 +160,7 @@ static inline struct kmem_cache *kmalloc_slab(size_t size) #define SLUB_DMA __GFP_DMA #else /* Disable DMA functionality */ -#define SLUB_DMA (__force gfp_t)0 +#define SLUB_DMA 0 #endif void *kmem_cache_alloc(struct kmem_cache *, gfp_t); diff --git a/trunk/include/sound/ak4xxx-adda.h b/trunk/include/sound/ak4xxx-adda.h index fd0a6c46f497..aa49dda4f410 100644 --- a/trunk/include/sound/ak4xxx-adda.h +++ b/trunk/include/sound/ak4xxx-adda.h @@ -43,7 +43,6 @@ struct snd_ak4xxx_ops { struct snd_akm4xxx_dac_channel { char *name; /* mixer volume name */ unsigned int num_channels; - char *switch_name; /* mixer switch*/ }; /* ADC labels and channels */ diff --git a/trunk/include/sound/cs46xx.h b/trunk/include/sound/cs46xx.h index 353910ce9755..685928e6f65a 100644 --- a/trunk/include/sound/cs46xx.h +++ b/trunk/include/sound/cs46xx.h @@ -1723,10 +1723,6 @@ struct snd_cs46xx { struct snd_cs46xx_pcm *playback_pcm; unsigned int play_ctl; #endif - -#ifdef CONFIG_PM - u32 *saved_regs; -#endif }; int snd_cs46xx_create(struct snd_card *card, diff --git a/trunk/include/sound/cs46xx_dsp_spos.h b/trunk/include/sound/cs46xx_dsp_spos.h index d9da9e59cf37..da934def31e9 100644 --- a/trunk/include/sound/cs46xx_dsp_spos.h +++ b/trunk/include/sound/cs46xx_dsp_spos.h @@ -107,7 +107,6 @@ struct dsp_scb_descriptor { char scb_name[DSP_MAX_SCB_NAME]; u32 address; int index; - u32 *data; struct dsp_scb_descriptor * sub_list_ptr; struct dsp_scb_descriptor * next_scb_ptr; @@ -128,7 +127,6 @@ struct dsp_task_descriptor { int size; u32 address; int index; - u32 *data; }; struct dsp_pcm_channel_descriptor { diff --git a/trunk/include/sound/emu10k1.h b/trunk/include/sound/emu10k1.h index 529d0a564367..23e45a4cf0e4 100644 --- a/trunk/include/sound/emu10k1.h +++ b/trunk/include/sound/emu10k1.h @@ -1120,16 +1120,6 @@ /************************************************************************************************/ /* EMU1010m HANA Destinations */ /************************************************************************************************/ -/* 32-bit destinations of signal in the Hana FPGA. Destinations are either - * physical outputs of Hana, or outputs going to Alice2 (audigy) for capture - * - 16 x EMU_DST_ALICE2_EMU32_X. - */ -/* EMU32 = 32-bit serial channel between Alice2 (audigy) and Hana (FPGA) */ -/* EMU_DST_ALICE2_EMU32_X - data channels from Hana to Alice2 used for capture. - * Which data is fed into a EMU_DST_ALICE2_EMU32_X channel in Hana depends on - * setup of mixer control for each destination - see emumixer.c - - * snd_emu1010_output_enum_ctls[], snd_emu1010_input_enum_ctls[] - */ #define EMU_DST_ALICE2_EMU32_0 0x000f /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_1 0x0000 /* 16 EMU32 channels to Alice2 +0 to +0xf */ #define EMU_DST_ALICE2_EMU32_2 0x0001 /* 16 EMU32 channels to Alice2 +0 to +0xf */ @@ -1209,12 +1199,6 @@ /************************************************************************************************/ /* EMU1010m HANA Sources */ /************************************************************************************************/ -/* 32-bit sources of signal in the Hana FPGA. The sources are routed to - * destinations using mixer control for each destination - see emumixer.c - * Sources are either physical inputs of FPGA, - * or outputs from Alice (audigy) - 16 x EMU_SRC_ALICE_EMU32A + - * 16 x EMU_SRC_ALICE_EMU32B - */ #define EMU_SRC_SILENCE 0x0000 /* Silence */ #define EMU_SRC_DOCK_MIC_A1 0x0100 /* Audio Dock Mic A, 1st or 48kHz only */ #define EMU_SRC_DOCK_MIC_A2 0x0101 /* Audio Dock Mic A, 2nd or 96kHz */ diff --git a/trunk/include/sound/sb.h b/trunk/include/sound/sb.h index 3ad854b397d2..2dd5c8e5b4fe 100644 --- a/trunk/include/sound/sb.h +++ b/trunk/include/sound/sb.h @@ -38,7 +38,6 @@ enum sb_hw_type { SB_HW_ALS100, /* Avance Logic ALS100 chip */ SB_HW_ALS4000, /* Avance Logic ALS4000 chip */ SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ - SB_HW_CS5530, /* Cyrix/NatSemi 5530 VSA1 */ }; #define SB_OPEN_PCM 0x01 diff --git a/trunk/include/sound/version.h b/trunk/include/sound/version.h index 6bbcfefd2c38..8e5b2f0f5946 100644 --- a/trunk/include/sound/version.h +++ b/trunk/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ #define CONFIG_SND_VERSION "1.0.14" -#define CONFIG_SND_DATE " (Fri Jul 20 09:12:58 2007 UTC)" +#define CONFIG_SND_DATE " (Thu May 31 09:03:25 2007 UTC)" diff --git a/trunk/include/sound/wavefront_fx.h b/trunk/include/sound/wavefront_fx.h new file mode 100644 index 000000000000..cec92b141796 --- /dev/null +++ b/trunk/include/sound/wavefront_fx.h @@ -0,0 +1,9 @@ +#ifndef __SOUND_WAVEFRONT_FX_H +#define __SOUND_WAVEFRONT_FX_H + +extern int snd_wavefront_fx_detect (snd_wavefront_t *); +extern void snd_wavefront_fx_ioctl (snd_synth_t *sdev, + unsigned int cmd, + unsigned long arg); + +#endif __SOUND_WAVEFRONT_FX_H diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 40954fb81598..43cb3b3e1679 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -138,7 +138,7 @@ static unsigned long __meminitdata dma_reserve; #endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ unsigned long __initdata required_kernelcore; unsigned long __initdata required_movablecore; - unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES]; + unsigned long __initdata zone_movable_pfn[MAX_NUMNODES]; /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */ int movable_zone; diff --git a/trunk/net/netfilter/nf_conntrack_helper.c b/trunk/net/netfilter/nf_conntrack_helper.c index ca10df40784f..b1179dd3d8c3 100644 --- a/trunk/net/netfilter/nf_conntrack_helper.c +++ b/trunk/net/netfilter/nf_conntrack_helper.c @@ -194,7 +194,7 @@ static struct nf_ct_ext_type helper_extend __read_mostly = { .id = NF_CT_EXT_HELPER, }; -int nf_conntrack_helper_init(void) +int nf_conntrack_helper_init() { int err; @@ -216,7 +216,7 @@ int nf_conntrack_helper_init(void) return err; } -void nf_conntrack_helper_fini(void) +void nf_conntrack_helper_fini() { nf_ct_extend_unregister(&helper_extend); nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc, diff --git a/trunk/scripts/Lindent b/trunk/scripts/Lindent index 9468ec7971db..7d8d8896e309 100755 --- a/trunk/scripts/Lindent +++ b/trunk/scripts/Lindent @@ -1,2 +1,2 @@ #!/bin/sh -indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1 "$@" +indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs "$@" diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 5ab7914d30ef..04579a517900 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -1076,7 +1076,6 @@ static int initexit_section_ref_ok(const char *name) ".plt", /* seen on ARCH=um build on x86_64. Harmless */ ".smp_locks", ".stab", - ".m68k_fixup", NULL }; /* Start of section names */ diff --git a/trunk/sound/Kconfig b/trunk/sound/Kconfig index e48b9b37d228..9ea473823418 100644 --- a/trunk/sound/Kconfig +++ b/trunk/sound/Kconfig @@ -65,8 +65,6 @@ source "sound/arm/Kconfig" source "sound/mips/Kconfig" -source "sound/sh/Kconfig" - # the following will depend on the order of config. # here assuming USB is defined before ALSA source "sound/usb/Kconfig" diff --git a/trunk/sound/Makefile b/trunk/sound/Makefile index 3ead922bd9c6..b7c7fb7c24c8 100644 --- a/trunk/sound/Makefile +++ b/trunk/sound/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o obj-$(CONFIG_SOUND_PRIME) += oss/ obj-$(CONFIG_DMASOUND) += oss/ -obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ +obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/ soc/ obj-$(CONFIG_SND_AOA) += aoa/ # This one must be compilable even if sound is configured out diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c index 028852374f21..ded516717940 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -661,7 +661,7 @@ static struct transfer_info onyx_transfers[] = { .tag = 2, }, #ifdef SNDRV_PCM_FMTBIT_COMPRESSED_16BE - /* Once alsa gets supports for this kind of thing we can add it... */ +Once alsa gets supports for this kind of thing we can add it... { /* digital compressed output */ .formats = SNDRV_PCM_FMTBIT_COMPRESSED_16BE, @@ -713,7 +713,7 @@ static int onyx_prepare(struct codec_info_item *cii, if (substream->runtime->format == SNDRV_PCM_FMTBIT_COMPRESSED_16BE) { /* mute and lock analog output */ onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); - if (onyx_write_register(onyx, + if (onyx_write_register(onyx ONYX_REG_DAC_CONTROL, v | ONYX_MUTE_RIGHT | ONYX_MUTE_LEFT)) goto out_unlock; diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 59b29cd482ae..a96733a5beb8 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -1487,7 +1487,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) snd_pcm_stream_lock_irq(substream); /* resume pause */ - if (substream->runtime->status->state == SNDRV_PCM_STATE_PAUSED) + if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) snd_pcm_pause(substream, 0); /* pre-start/stop - all running streams are changed to DRAINING state */ diff --git a/trunk/sound/core/seq/seq_instr.c b/trunk/sound/core/seq/seq_instr.c index 5efe6523a589..f30d171b6d96 100644 --- a/trunk/sound/core/seq/seq_instr.c +++ b/trunk/sound/core/seq/seq_instr.c @@ -109,7 +109,7 @@ void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr) spin_lock_irqsave(&list->lock, flags); while (instr->use) { spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&list->lock, flags); } spin_unlock_irqrestore(&list->lock, flags); @@ -199,7 +199,7 @@ int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list, instr = flist; flist = instr->next; while (instr->use) - schedule_timeout(1); + schedule_timeout_interruptible(1); if (snd_seq_instr_free(instr, atomic)<0) snd_printk(KERN_WARNING "instrument free problem\n"); instr = next; @@ -555,7 +555,7 @@ static int instr_free(struct snd_seq_kinstr_ops *ops, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); while (instr->use) { spin_unlock_irqrestore(&list->lock, flags); - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&list->lock, flags); } spin_unlock_irqrestore(&list->lock, flags); diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index f2bbacedd567..67520b3c0042 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -1549,11 +1549,9 @@ static int snd_timer_user_info(struct file *file, int err = 0; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); t = tu->timeri->timer; - if (!t) - return -EBADFD; + snd_assert(t != NULL, return -ENXIO); info = kzalloc(sizeof(*info), GFP_KERNEL); if (! info) @@ -1581,11 +1579,9 @@ static int snd_timer_user_params(struct file *file, int err; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); t = tu->timeri->timer; - if (!t) - return -EBADFD; + snd_assert(t != NULL, return -ENXIO); if (copy_from_user(¶ms, _params, sizeof(params))) return -EFAULT; if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { @@ -1679,8 +1675,7 @@ static int snd_timer_user_status(struct file *file, struct snd_timer_status status; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); memset(&status, 0, sizeof(status)); status.tstamp = tu->tstamp; status.resolution = snd_timer_resolution(tu->timeri); @@ -1700,8 +1695,7 @@ static int snd_timer_user_start(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); snd_timer_stop(tu->timeri); tu->timeri->lost = 0; tu->last_resolution = 0; @@ -1714,8 +1708,7 @@ static int snd_timer_user_stop(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; } @@ -1725,8 +1718,7 @@ static int snd_timer_user_continue(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); tu->timeri->lost = 0; return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; } @@ -1737,8 +1729,7 @@ static int snd_timer_user_pause(struct file *file) struct snd_timer_user *tu; tu = file->private_data; - if (!tu->timeri) - return -EBADFD; + snd_assert(tu->timeri != NULL, return -ENXIO); return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; } diff --git a/trunk/sound/drivers/dummy.c b/trunk/sound/drivers/dummy.c index 4360ae9de19c..a0f28f51fc7e 100644 --- a/trunk/sound/drivers/dummy.c +++ b/trunk/sound/drivers/dummy.c @@ -659,7 +659,7 @@ static struct platform_driver snd_dummy_driver = { }, }; -static void snd_dummy_unregister_all(void) +static void __init_or_module snd_dummy_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/mpu401/mpu401.c b/trunk/sound/drivers/mpu401/mpu401.c index 67c6e9745418..1d563e515c17 100644 --- a/trunk/sound/drivers/mpu401/mpu401.c +++ b/trunk/sound/drivers/mpu401/mpu401.c @@ -228,7 +228,7 @@ static struct pnp_driver snd_mpu401_pnp_driver = { static struct pnp_driver snd_mpu401_pnp_driver; #endif -static void snd_mpu401_unregister_all(void) +static void __init_or_module snd_mpu401_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/portman2x4.c b/trunk/sound/drivers/portman2x4.c index 0eb9b5cebfcd..497cafb57d9b 100644 --- a/trunk/sound/drivers/portman2x4.c +++ b/trunk/sound/drivers/portman2x4.c @@ -833,7 +833,7 @@ static struct platform_driver snd_portman_driver = { /********************************************************************* * module init stuff *********************************************************************/ -static void snd_portman_unregister_all(void) +static void __init_or_module snd_portman_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/serial-u16550.c b/trunk/sound/drivers/serial-u16550.c index d3e6a20edd38..838a4277929d 100644 --- a/trunk/sound/drivers/serial-u16550.c +++ b/trunk/sound/drivers/serial-u16550.c @@ -998,7 +998,7 @@ static struct platform_driver snd_serial_driver = { }, }; -static void snd_serial_unregister_all(void) +static void __init_or_module snd_serial_unregister_all(void) { int i; diff --git a/trunk/sound/drivers/virmidi.c b/trunk/sound/drivers/virmidi.c index 915c86773c21..46f3d3486067 100644 --- a/trunk/sound/drivers/virmidi.c +++ b/trunk/sound/drivers/virmidi.c @@ -145,7 +145,7 @@ static struct platform_driver snd_virmidi_driver = { }, }; -static void snd_virmidi_unregister_all(void) +static void __init_or_module snd_virmidi_unregister_all(void) { int i; diff --git a/trunk/sound/i2c/other/ak4xxx-adda.c b/trunk/sound/i2c/other/ak4xxx-adda.c index fd335159f849..8805110017a7 100644 --- a/trunk/sound/i2c/other/ak4xxx-adda.c +++ b/trunk/sound/i2c/other/ak4xxx-adda.c @@ -481,8 +481,8 @@ static int ak4xxx_switch_get(struct snd_kcontrol *kcontrol, int addr = AK_GET_ADDR(kcontrol->private_value); int shift = AK_GET_SHIFT(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); - /* we observe the (1<value.integer.value[0] = (val & (1<num_dacs; ) { - /* mute control for Revolution 7.1 - AK4381 */ - if (ak->type == SND_AK4381 - && ak->dac_info[mixer_ch].switch_name) { - memset(&knew, 0, sizeof(knew)); - knew.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - knew.count = 1; - knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE; - knew.name = ak->dac_info[mixer_ch].switch_name; - knew.info = ak4xxx_switch_info; - knew.get = ak4xxx_switch_get; - knew.put = ak4xxx_switch_put; - knew.access = 0; - /* register 1, bit 0 (SMUTE): 0 = normal operation, - 1 = mute */ - knew.private_value = - AK_COMPOSE(idx/2, 1, 0, 0) | AK_INVERT; - err = snd_ctl_add(ak->card, snd_ctl_new1(&knew, ak)); - if (err < 0) - return err; - } memset(&knew, 0, sizeof(knew)); if (! ak->dac_info || ! ak->dac_info[mixer_ch].name) { knew.name = "DAC Volume"; diff --git a/trunk/sound/isa/Kconfig b/trunk/sound/isa/Kconfig index ea5084abe60f..cf3803cd579c 100644 --- a/trunk/sound/isa/Kconfig +++ b/trunk/sound/isa/Kconfig @@ -1,5 +1,8 @@ # ALSA ISA drivers +menu "ISA devices" + depends on SND!=n && ISA && ISA_DMA_API + config SND_AD1848_LIB tristate select SND_PCM @@ -8,22 +11,6 @@ config SND_CS4231_LIB tristate select SND_PCM -config SND_SB_COMMON - tristate - -config SND_SB8_DSP - tristate - select SND_PCM - select SND_SB_COMMON - -config SND_SB16_DSP - tristate - select SND_PCM - select SND_SB_COMMON - -menu "ISA devices" - depends on SND!=n && ISA && ISA_DMA_API - config SND_ADLIB tristate "AdLib FM card" depends on SND @@ -68,7 +55,7 @@ config SND_ALS100 select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for soundcards based on Avance Logic ALS100, ALS110, ALS120 and ALS200 chips. @@ -94,7 +81,6 @@ config SND_CMI8330 tristate "C-Media CMI8330" depends on SND select SND_AD1848_LIB - select SND_SB16_DSP help Say Y here to include support for soundcards based on the C-Media CMI8330 chip. @@ -146,7 +132,7 @@ config SND_DT019X select ISAPNP select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for soundcards based on the Diamond Technologies DT-019X or Avance Logic ALS-007 chips. @@ -159,7 +145,7 @@ config SND_ES968 depends on SND && PNP && ISA select ISAPNP select SND_MPU401_UART - select SND_SB8_DSP + select SND_PCM help Say Y here to include support for ESS AudioDrive ES968 chips. @@ -335,7 +321,7 @@ config SND_SB8 depends on SND select SND_OPL3_LIB select SND_RAWMIDI - select SND_SB8_DSP + select SND_PCM help Say Y here to include support for Creative Sound Blaster 1.0/ 2.0/Pro (8-bit) or 100% compatible soundcards. @@ -348,7 +334,7 @@ config SND_SB16 depends on SND select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for Sound Blaster 16 soundcards (including the Plug and Play version). @@ -361,7 +347,7 @@ config SND_SBAWE depends on SND select SND_OPL3_LIB select SND_MPU401_UART - select SND_SB16_DSP + select SND_PCM help Say Y here to include support for Sound Blaster AWE soundcards (including the Plug and Play version). diff --git a/trunk/sound/isa/ad1848/ad1848_lib.c b/trunk/sound/isa/ad1848/ad1848_lib.c index 1bc2e3fd5721..8094282c2ae1 100644 --- a/trunk/sound/isa/ad1848/ad1848_lib.c +++ b/trunk/sound/isa/ad1848/ad1848_lib.c @@ -245,7 +245,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n"); return; } - time = schedule_timeout(time); + time = schedule_timeout_interruptible(time); spin_lock_irqsave(&chip->reg_lock, flags); } #if 0 @@ -258,7 +258,7 @@ static void snd_ad1848_mce_down(struct snd_ad1848 *chip) snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n"); return; } - time = schedule_timeout(time); + time = schedule_timeout_interruptible(time); spin_lock_irqsave(&chip->reg_lock, flags); } spin_unlock_irqrestore(&chip->reg_lock, flags); diff --git a/trunk/sound/isa/opl3sa2.c b/trunk/sound/isa/opl3sa2.c index e70db32991d9..4f6800b43b0e 100644 --- a/trunk/sound/isa/opl3sa2.c +++ b/trunk/sound/isa/opl3sa2.c @@ -164,8 +164,6 @@ static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { { .id = "YMH0801", .devs = { { "YMH0021" } } }, /* NeoMagic MagicWave 3DX */ { .id = "NMX2200", .devs = { { "YMH2210" } } }, - /* NeoMagic MagicWave 3D */ - { .id = "NMX2200", .devs = { { "NMX2210" } } }, /* --- */ { .id = "" } /* end */ }; diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index 049d479ce2b3..60c120ffb9de 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -1927,12 +1927,10 @@ static struct snd_card *snd_opti9xx_card_new(void) static int __devinit snd_opti9xx_isa_match(struct device *devptr, unsigned int dev) { -#ifdef CONFIG_PNP if (snd_opti9xx_pnp_is_probed) return 0; if (isapnp) return 0; -#endif return 1; } @@ -2098,7 +2096,6 @@ static int __init alsa_card_opti9xx_init(void) pnp_register_card_driver(&opti9xx_pnpc_driver); if (snd_opti9xx_pnp_is_probed) return 0; - pnp_unregister_card_driver(&opti9xx_pnpc_driver); #endif return isa_register_driver(&snd_opti9xx_driver, 1); } diff --git a/trunk/sound/isa/sb/Makefile b/trunk/sound/isa/sb/Makefile index 556e66928029..fd9d9c5726fc 100644 --- a/trunk/sound/isa/sb/Makefile +++ b/trunk/sound/isa/sb/Makefile @@ -22,13 +22,14 @@ snd-es968-objs := es968.o sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1))) # Toplevel Module Dependency -obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o -obj-$(CONFIG_SND_SB16_DSP) += snd-sb16-dsp.o -obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o -obj-$(CONFIG_SND_SB8) += snd-sb8.o -obj-$(CONFIG_SND_SB16) += snd-sb16.o -obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o -obj-$(CONFIG_SND_ES968) += snd-es968.o +obj-$(CONFIG_SND_ALS100) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_CMI8330) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_DT019X) += snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SB8) += snd-sb8.o snd-sb8-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SB16) += snd-sb16.o snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o snd-sb16-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ES968) += snd-es968.o snd-sb8-dsp.o snd-sb-common.o +obj-$(CONFIG_SND_ALS4000) += snd-sb-common.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o diff --git a/trunk/sound/isa/sb/sb16_main.c b/trunk/sound/isa/sb/sb16_main.c index 5d4d3aafe2d5..383911b9e74d 100644 --- a/trunk/sound/isa/sb/sb16_main.c +++ b/trunk/sound/isa/sb/sb16_main.c @@ -563,11 +563,6 @@ static int snd_sb16_playback_open(struct snd_pcm_substream *substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; - if (chip->hardware == SB_HW_CS5530) { - runtime->hw.buffer_bytes_max = 32 * 1024; - runtime->hw.periods_min = 2; - runtime->hw.rate_min = 44100; - } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->playback_substream = substream; @@ -638,11 +633,6 @@ static int snd_sb16_capture_open(struct snd_pcm_substream *substream) __open_ok: if (chip->hardware == SB_HW_ALS100) runtime->hw.rate_max = 48000; - if (chip->hardware == SB_HW_CS5530) { - runtime->hw.buffer_bytes_max = 32 * 1024; - runtime->hw.periods_min = 2; - runtime->hw.rate_min = 44100; - } if (chip->mode & SB_RATE_LOCK) runtime->hw.rate_min = runtime->hw.rate_max = chip->locked_rate; chip->capture_substream = substream; diff --git a/trunk/sound/isa/sb/sb_common.c b/trunk/sound/isa/sb/sb_common.c index efa9d5c2558a..3094f3852167 100644 --- a/trunk/sound/isa/sb/sb_common.c +++ b/trunk/sound/isa/sb/sb_common.c @@ -128,7 +128,7 @@ static int snd_sbdsp_probe(struct snd_sb * chip) minor = version & 0xff; snd_printdd("SB [0x%lx]: DSP chip found, version = %i.%i\n", chip->port, major, minor); - + switch (chip->hardware) { case SB_HW_AUTO: switch (major) { @@ -168,9 +168,6 @@ static int snd_sbdsp_probe(struct snd_sb * chip) case SB_HW_DT019X: str = "(DT019X/ALS007)"; break; - case SB_HW_CS5530: - str = "16 (CS5530)"; - break; default: return -ENODEV; } diff --git a/trunk/sound/isa/sb/sb_mixer.c b/trunk/sound/isa/sb/sb_mixer.c index 3d4befcff28e..490b1ca5cf58 100644 --- a/trunk/sound/isa/sb/sb_mixer.c +++ b/trunk/sound/isa/sb/sb_mixer.c @@ -821,7 +821,6 @@ int snd_sbmixer_new(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: if ((err = snd_sbmixer_init(chip, snd_sb16_controls, ARRAY_SIZE(snd_sb16_controls), @@ -951,7 +950,6 @@ void snd_sbmixer_suspend(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); break; case SB_HW_ALS4000: @@ -977,7 +975,6 @@ void snd_sbmixer_resume(struct snd_sb *chip) break; case SB_HW_16: case SB_HW_ALS100: - case SB_HW_CS5530: restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs)); break; case SB_HW_ALS4000: diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index cbad2a51cbaa..9ea417bcf3e5 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -382,7 +382,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout) unsigned long flags; unsigned char x; - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&s->lock, flags); x = inb(HOST_DATA_IO(s->io_base)); @@ -409,7 +409,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout) unsigned long flags; unsigned char x; - schedule_timeout(1); + schedule_timeout_interruptible(1); spin_lock_irqsave(&s->lock, flags); x = inb(HOST_DATA_IO(s->io_base)); diff --git a/trunk/sound/isa/wavefront/wavefront_synth.c b/trunk/sound/isa/wavefront/wavefront_synth.c index bacc51c86587..78020d832e04 100644 --- a/trunk/sound/isa/wavefront/wavefront_synth.c +++ b/trunk/sound/isa/wavefront/wavefront_synth.c @@ -1780,7 +1780,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev, outb (val,port); spin_unlock_irq(&dev->irq_lock); while (1) { - if ((timeout = schedule_timeout(timeout)) == 0) + if ((timeout = schedule_timeout_interruptible(timeout)) == 0) return; if (dev->irq_ok) return; diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index c6b44102aa5b..61e35ecc57b8 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -33,7 +33,6 @@ config SND_ALS4000 select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM - select SND_SB_COMMON help Say Y here to include support for soundcards based on Avance Logic ALS4000 chips. @@ -216,16 +215,6 @@ config SND_CS46XX_NEW_DSP This works better than the old code, so say Y. -config SND_CS5530 - tristate "CS5530 Audio" - depends on SND && ISA_DMA_API - select SND_SB16_DSP - help - Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips. - - To compile this driver as a module, choose M here: the module - will be called snd-cs5530. - config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" depends on SND && X86 && !X86_64 diff --git a/trunk/sound/pci/Makefile b/trunk/sound/pci/Makefile index cd76e0293d06..e06736da9ef1 100644 --- a/trunk/sound/pci/Makefile +++ b/trunk/sound/pci/Makefile @@ -12,7 +12,6 @@ snd-azt3328-objs := azt3328.o snd-bt87x-objs := bt87x.o snd-cmipci-objs := cmipci.o snd-cs4281-objs := cs4281.o -snd-cs5530-objs := cs5530.o snd-ens1370-objs := ens1370.o snd-ens1371-objs := ens1371.o snd-es1938-objs := es1938.o @@ -37,7 +36,6 @@ obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o obj-$(CONFIG_SND_BT87X) += snd-bt87x.o obj-$(CONFIG_SND_CMIPCI) += snd-cmipci.o obj-$(CONFIG_SND_CS4281) += snd-cs4281.o -obj-$(CONFIG_SND_CS5530) += snd-cs5530.o obj-$(CONFIG_SND_ENS1370) += snd-ens1370.o obj-$(CONFIG_SND_ENS1371) += snd-ens1371.o obj-$(CONFIG_SND_ES1938) += snd-es1938.o diff --git a/trunk/sound/pci/ali5451/ali5451.c b/trunk/sound/pci/ali5451/ali5451.c index 05b4c8696941..41543a4933e7 100644 --- a/trunk/sound/pci/ali5451/ali5451.c +++ b/trunk/sound/pci/ali5451/ali5451.c @@ -239,7 +239,7 @@ struct snd_ali_image { struct snd_ali { - int irq; + unsigned long irq; unsigned long port; unsigned char revision; @@ -731,7 +731,8 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) return; } - for (count = 0; count <= 50000; count++) { + count = 0; + while (count++ <= 50000) { snd_ali_delay(codec, 6); bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); R2 = bval & 0x1F; @@ -2342,7 +2343,7 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, strcpy(card->driver, "ALI5451"); strcpy(card->shortname, "ALI 5451"); - sprintf(card->longname, "%s at 0x%lx, irq %i", + sprintf(card->longname, "%s at 0x%lx, irq %li", card->shortname, codec->port, codec->irq); snd_ali_printk("register card.\n"); diff --git a/trunk/sound/pci/als300.c b/trunk/sound/pci/als300.c index 48cc39b771d9..8afcb98ca7bb 100644 --- a/trunk/sound/pci/als300.c +++ b/trunk/sound/pci/als300.c @@ -88,8 +88,8 @@ #define PLAYBACK_BLOCK_COUNTER 0x9A #define RECORD_BLOCK_COUNTER 0x9B -#define DEBUG_CALLS 0 -#define DEBUG_PLAY_REC 0 +#define DEBUG_CALLS 1 +#define DEBUG_PLAY_REC 1 #if DEBUG_CALLS #define snd_als300_dbgcalls(format, args...) printk(format, ##args) @@ -733,8 +733,7 @@ static int __devinit snd_als300_create(struct snd_card *card, snd_als300_init(chip); - err = snd_als300_ac97(chip); - if (err < 0) { + if (snd_als300_ac97(chip) < 0) { snd_printk(KERN_WARNING "Could not create ac97\n"); snd_als300_free(chip); return err; diff --git a/trunk/sound/pci/ca0106/ca0106_main.c b/trunk/sound/pci/ca0106/ca0106_main.c index fcab8fb97e38..9fd7b8a5b75e 100644 --- a/trunk/sound/pci/ca0106/ca0106_main.c +++ b/trunk/sound/pci/ca0106/ca0106_main.c @@ -168,25 +168,6 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); #include "ca0106.h" static struct snd_ca0106_details ca0106_chip_details[] = { - /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ - /* It is really just a normal SB Live 24bit. */ - /* - * CTRL:CA0111-WTLF - * ADC: WM8775SEDS - * DAC: CS4382-KQZ - */ - /* Tested: - * Playback on front, rear, center/lfe speakers - * Capture from Mic in. - * Not-Tested: - * Capture from Line in. - * Playback to digital out. - */ - { .serial = 0x10121102, - .name = "X-Fi Extreme Audio [SB0790]", - .gpio_type = 1, - .i2c_adc = 1 } , - /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97. */ /* AudigyLS[SB0310] */ { .serial = 0x10021102, .name = "AudigyLS [SB0310]", diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.c b/trunk/sound/pci/cs46xx/cs46xx_lib.c index 71d7aab9d869..bef1f6d1859c 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.c +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.c @@ -2897,10 +2897,6 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) } #endif -#ifdef CONFIG_PM - kfree(chip->saved_regs); -#endif - pci_disable_device(chip->pci); kfree(chip); return 0; @@ -3144,23 +3140,6 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) /* * start and load DSP */ - -static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) -{ - unsigned int tmp; - - snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); - - tmp = snd_cs46xx_peek(chip, BA1_PFIE); - tmp &= ~0x0000f03f; - snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ - - tmp = snd_cs46xx_peek(chip, BA1_CIE); - tmp &= ~0x0000003f; - tmp |= 0x00000001; - snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ -} - int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) { unsigned int tmp; @@ -3235,7 +3214,19 @@ int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip) snd_cs46xx_proc_start(chip); - cs46xx_enable_stream_irqs(chip); + /* + * Enable interrupts on the part. + */ + snd_cs46xx_pokeBA0(chip, BA0_HICR, HICR_IEV | HICR_CHGM); + + tmp = snd_cs46xx_peek(chip, BA1_PFIE); + tmp &= ~0x0000f03f; + snd_cs46xx_poke(chip, BA1_PFIE, tmp); /* playback interrupt enable */ + + tmp = snd_cs46xx_peek(chip, BA1_CIE); + tmp &= ~0x0000003f; + tmp |= 0x00000001; + snd_cs46xx_poke(chip, BA1_CIE, tmp); /* capture interrupt enable */ #ifndef CONFIG_SND_CS46XX_NEW_DSP /* set the attenuation to 0dB */ @@ -3674,19 +3665,11 @@ static struct cs_card_type __devinitdata cards[] = { * APM support */ #ifdef CONFIG_PM -static unsigned int saved_regs[] = { - BA0_ACOSV, - BA0_ASER_FADDR, - BA0_ASER_MASTER, - BA1_PVOL, - BA1_CVOL, -}; - int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; - int i, amp_saved; + int amp_saved; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); chip->in_suspend = 1; @@ -3697,10 +3680,6 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); - /* save some registers */ - for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - chip->saved_regs[i] = snd_cs46xx_peekBA0(chip, saved_regs[i]); - amp_saved = chip->amplifier; /* turn off amp */ chip->amplifier_ctrl(chip, -chip->amplifier); @@ -3719,7 +3698,7 @@ int snd_cs46xx_resume(struct pci_dev *pci) { struct snd_card *card = pci_get_drvdata(pci); struct snd_cs46xx *chip = card->private_data; - int i, amp_saved; + int amp_saved; pci_set_power_state(pci, PCI_D0); pci_restore_state(pci); @@ -3737,16 +3716,6 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_cs46xx_chip_init(chip); - snd_cs46xx_reset(chip); -#ifdef CONFIG_SND_CS46XX_NEW_DSP - cs46xx_dsp_resume(chip); - /* restore some registers */ - for (i = 0; i < ARRAY_SIZE(saved_regs); i++) - snd_cs46xx_pokeBA0(chip, saved_regs[i], chip->saved_regs[i]); -#else - snd_cs46xx_download_image(chip); -#endif - #if 0 snd_cs46xx_codec_write(chip, BA0_AC97_GENERAL_PURPOSE, chip->ac97_general_purpose); @@ -3761,13 +3730,6 @@ int snd_cs46xx_resume(struct pci_dev *pci) snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]); snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]); - /* reset playback/capture */ - snd_cs46xx_set_play_sample_rate(chip, 8000); - snd_cs46xx_set_capture_sample_rate(chip, 8000); - snd_cs46xx_proc_start(chip); - - cs46xx_enable_stream_irqs(chip); - if (amp_saved) chip->amplifier_ctrl(chip, 1); /* turn amp on */ else @@ -3934,15 +3896,6 @@ int __devinit snd_cs46xx_create(struct snd_card *card, snd_cs46xx_proc_init(card, chip); -#ifdef CONFIG_PM - chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) * - ARRAY_SIZE(saved_regs), GFP_KERNEL); - if (!chip->saved_regs) { - snd_cs46xx_free(chip); - return -ENOMEM; - } -#endif - chip->active_ctrl(chip, -1); /* disable CLKRUN */ snd_card_set_dev(card, &pci->dev); diff --git a/trunk/sound/pci/cs46xx/cs46xx_lib.h b/trunk/sound/pci/cs46xx/cs46xx_lib.h index 20dcd72f06c1..f75750c2bd24 100644 --- a/trunk/sound/pci/cs46xx/cs46xx_lib.h +++ b/trunk/sound/pci/cs46xx/cs46xx_lib.h @@ -86,9 +86,6 @@ static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip); void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip); int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module); -#ifdef CONFIG_PM -int cs46xx_dsp_resume(struct snd_cs46xx * chip); -#endif struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type); #ifdef CONFIG_PROC_FS diff --git a/trunk/sound/pci/cs46xx/dsp_spos.c b/trunk/sound/pci/cs46xx/dsp_spos.c index 590b35d91df2..336e77e2600c 100644 --- a/trunk/sound/pci/cs46xx/dsp_spos.c +++ b/trunk/sound/pci/cs46xx/dsp_spos.c @@ -306,59 +306,13 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) mutex_unlock(&chip->spos_mutex); } -static int dsp_load_parameter(struct snd_cs46xx *chip, - struct dsp_segment_desc *parameter) -{ - u32 doffset, dsize; - - if (!parameter) { - snd_printdd("dsp_spos: module got no parameter segment\n"); - return 0; - } - - doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); - dsize = parameter->size * 4; - - snd_printdd("dsp_spos: " - "downloading parameter data to chip (%08x-%08x)\n", - doffset,doffset + dsize); - if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { - snd_printk(KERN_ERR "dsp_spos: " - "failed to download parameter data to DSP\n"); - return -EINVAL; - } - return 0; -} - -static int dsp_load_sample(struct snd_cs46xx *chip, - struct dsp_segment_desc *sample) -{ - u32 doffset, dsize; - - if (!sample) { - snd_printdd("dsp_spos: module got no sample segment\n"); - return 0; - } - - doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); - dsize = sample->size * 4; - - snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", - doffset,doffset + dsize); - - if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { - snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); - return -EINVAL; - } - return 0; -} - int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM); + struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER); + struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE); u32 doffset, dsize; - int err; if (ins->nmodules == DSP_MAX_MODULES - 1) { snd_printk(KERN_ERR "dsp_spos: to many modules loaded into DSP\n"); @@ -372,20 +326,49 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, DSP_PARAMETER_BYTE_SIZE); } - err = dsp_load_parameter(chip, get_segment_desc(module, - SEGTYPE_SP_PARAMETER)); - if (err < 0) - return err; + if (parameter == NULL) { + snd_printdd("dsp_spos: module got no parameter segment\n"); + } else { + if (ins->nmodules > 0) { + snd_printk(KERN_WARNING "dsp_spos: WARNING current parameter data may be overwriten!\n"); + } + + doffset = (parameter->offset * 4 + DSP_PARAMETER_BYTE_OFFSET); + dsize = parameter->size * 4; + + snd_printdd("dsp_spos: downloading parameter data to chip (%08x-%08x)\n", + doffset,doffset + dsize); + + if (snd_cs46xx_download (chip, parameter->data, doffset, dsize)) { + snd_printk(KERN_ERR "dsp_spos: failed to download parameter data to DSP\n"); + return -EINVAL; + } + } if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing sample area\n"); snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, DSP_SAMPLE_BYTE_SIZE); } - err = dsp_load_sample(chip, get_segment_desc(module, - SEGTYPE_SP_SAMPLE)); - if (err < 0) - return err; + if (sample == NULL) { + snd_printdd("dsp_spos: module got no sample segment\n"); + } else { + if (ins->nmodules > 0) { + snd_printk(KERN_WARNING "dsp_spos: WARNING current sample data may be overwriten\n"); + } + + doffset = (sample->offset * 4 + DSP_SAMPLE_BYTE_OFFSET); + dsize = sample->size * 4; + + snd_printdd("dsp_spos: downloading sample data to chip (%08x-%08x)\n", + doffset,doffset + dsize); + + if (snd_cs46xx_download (chip,sample->data,doffset,dsize)) { + snd_printk(KERN_ERR "dsp_spos: failed to sample data to DSP\n"); + return -EINVAL; + } + } + if (ins->nmodules == 0) { snd_printdd("dsp_spos: clearing code area\n"); @@ -1003,10 +986,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) return NULL; } - if (name) - strcpy(ins->tasks[ins->ntask].task_name, name); - else - strcpy(ins->tasks[ins->ntask].task_name, "(NULL)"); + strcpy(ins->tasks[ins->ntask].task_name,name); ins->tasks[ins->ntask].address = dest; ins->tasks[ins->ntask].size = size; @@ -1015,8 +995,7 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size) desc = (ins->tasks + ins->ntask); ins->ntask++; - if (name) - add_symbol (chip,name,dest,SYMBOL_PARAMETER); + add_symbol (chip,name,dest,SYMBOL_PARAMETER); return desc; } @@ -1027,7 +1006,6 @@ cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 desc = _map_scb (chip,name,dest); if (desc) { - desc->data = scb_data; _dsp_create_scb(chip,scb_data,dest); } else { snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n"); @@ -1045,7 +1023,6 @@ cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_da desc = _map_task_tree (chip,name,dest,size); if (desc) { - desc->data = task_data; _dsp_create_task_tree(chip,task_data,dest,size); } else { snd_printk(KERN_ERR "dsp_spos: failed to map TASK\n"); @@ -1343,10 +1320,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) 0x0000ffff }; - if (!cs46xx_dsp_create_task_tree(chip, NULL, - (u32 *)&mix2_ostream_spb, - WRITE_BACK_SPB, 2)) - goto _fail_end; + /* dirty hack ... */ + _dsp_create_task_tree (chip,(u32 *)&mix2_ostream_spb,WRITE_BACK_SPB,2); } /* input sample converter */ @@ -1647,6 +1622,7 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, return 0; } + static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; @@ -1918,61 +1894,3 @@ int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right) return 0; } - -#ifdef CONFIG_PM -int cs46xx_dsp_resume(struct snd_cs46xx * chip) -{ - struct dsp_spos_instance * ins = chip->dsp_spos_instance; - int i, err; - - /* clear parameter, sample and code areas */ - snd_cs46xx_clear_BA1(chip, DSP_PARAMETER_BYTE_OFFSET, - DSP_PARAMETER_BYTE_SIZE); - snd_cs46xx_clear_BA1(chip, DSP_SAMPLE_BYTE_OFFSET, - DSP_SAMPLE_BYTE_SIZE); - snd_cs46xx_clear_BA1(chip, DSP_CODE_BYTE_OFFSET, DSP_CODE_BYTE_SIZE); - - for (i = 0; i < ins->nmodules; i++) { - struct dsp_module_desc *module = &ins->modules[i]; - struct dsp_segment_desc *seg; - u32 doffset, dsize; - - seg = get_segment_desc(module, SEGTYPE_SP_PARAMETER); - err = dsp_load_parameter(chip, seg); - if (err < 0) - return err; - - seg = get_segment_desc(module, SEGTYPE_SP_SAMPLE); - err = dsp_load_sample(chip, seg); - if (err < 0) - return err; - - seg = get_segment_desc(module, SEGTYPE_SP_PROGRAM); - if (!seg) - continue; - - doffset = seg->offset * 4 + module->load_address * 4 - + DSP_CODE_BYTE_OFFSET; - dsize = seg->size * 4; - err = snd_cs46xx_download(chip, - ins->code.data + module->load_address, - doffset, dsize); - if (err < 0) - return err; - } - - for (i = 0; i < ins->ntask; i++) { - struct dsp_task_descriptor *t = &ins->tasks[i]; - _dsp_create_task_tree(chip, t->data, t->address, t->size); - } - - for (i = 0; i < ins->nscb; i++) { - struct dsp_scb_descriptor *s = &ins->scbs[i]; - if (s->deleted) - continue; - _dsp_create_scb(chip, s->data, s->address); - } - - return 0; -} -#endif diff --git a/trunk/sound/pci/cs5530.c b/trunk/sound/pci/cs5530.c deleted file mode 100644 index 240a0a462209..000000000000 --- a/trunk/sound/pci/cs5530.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio - * - * (C) Copyright 2007 Ash Willis - * (C) Copyright 2003 Red Hat Inc - * - * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did - * mess with it a bit. The chip seems to have to have trouble with full duplex - * mode. If we're recording in 8bit 8000kHz, say, and we then attempt to - * simultaneously play back audio at 16bit 44100kHz, the device actually plays - * back in the same format in which it is capturing. By forcing the chip to - * always play/capture in 16/44100, we can let alsa-lib convert the samples and - * that way we can hack up some full duplex audio. - * - * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. - * The older version (VSA1) provides fairly good soundblaster emulation - * although there are a couple of bugs: large DMA buffers break record, - * and the MPU event handling seems suspect. VSA2 allows the native driver - * to control the AC97 audio engine directly and requires a different driver. - * - * Thanks to National Semiconductor for providing the needed information - * on the XpressAudio(tm) internals. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * TO DO: - * Investigate whether we can portably support Cognac (5520) in the - * same manner. - */ - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Ash Willis"); -MODULE_DESCRIPTION("CS5530 Audio"); -MODULE_LICENSE("GPL"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -struct snd_cs5530 { - struct snd_card *card; - struct pci_dev *pci; - struct snd_sb *sb; - unsigned long pci_base; -}; - -static struct pci_device_id snd_cs5530_ids[] = { - {PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, - PCI_ANY_ID, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, snd_cs5530_ids); - -static int snd_cs5530_free(struct snd_cs5530 *chip) -{ - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); - return 0; -} - -static int snd_cs5530_dev_free(struct snd_device *device) -{ - struct snd_cs5530 *chip = device->device_data; - return snd_cs5530_free(chip); -} - -static void __devexit snd_cs5530_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); - pci_set_drvdata(pci, NULL); -} - -static u8 __devinit snd_cs5530_mixer_read(unsigned long io, u8 reg) -{ - outb(reg, io + 4); - udelay(20); - reg = inb(io + 5); - udelay(20); - return reg; -} - -static int __devinit snd_cs5530_create(struct snd_card *card, - struct pci_dev *pci, - struct snd_cs5530 **rchip) -{ - struct snd_cs5530 *chip; - unsigned long sb_base; - u8 irq, dma8, dma16 = 0; - u16 map; - void __iomem *mem; - int err; - - static struct snd_device_ops ops = { - .dev_free = snd_cs5530_dev_free, - }; - *rchip = NULL; - - err = pci_enable_device(pci); - if (err < 0) - return err; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - - chip->card = card; - chip->pci = pci; - - err = pci_request_regions(pci, "CS5530"); - if (err < 0) { - kfree(chip); - pci_disable_device(pci); - return err; - } - chip->pci_base = pci_resource_start(pci, 0); - - mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); - if (mem == NULL) { - kfree(chip); - pci_disable_device(pci); - return -EBUSY; - } - - map = readw(mem + 0x18); - iounmap(mem); - - /* Map bits - 0:1 * 0x20 + 0x200 = sb base - 2 sb enable - 3 adlib enable - 5 MPU enable 0x330 - 6 MPU enable 0x300 - - The other bits may be used internally so must be masked */ - - sb_base = 0x220 + 0x20 * (map & 3); - - if (map & (1<<2)) - printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base); - else { - printk(KERN_ERR "Could not find XpressAudio!\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (map & (1<<5)) - printk(KERN_INFO "CS5530: MPU at 0x300\n"); - else if (map & (1<<6)) - printk(KERN_INFO "CS5530: MPU at 0x330\n"); - - irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F; - dma8 = snd_cs5530_mixer_read(sb_base, 0x81); - - if (dma8 & 0x20) - dma16 = 5; - else if (dma8 & 0x40) - dma16 = 6; - else if (dma8 & 0x80) - dma16 = 7; - else { - printk(KERN_ERR "CS5530: No 16bit DMA enabled\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (dma8 & 0x01) - dma8 = 0; - else if (dma8 & 02) - dma8 = 1; - else if (dma8 & 0x08) - dma8 = 3; - else { - printk(KERN_ERR "CS5530: No 8bit DMA enabled\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - if (irq & 1) - irq = 9; - else if (irq & 2) - irq = 5; - else if (irq & 4) - irq = 7; - else if (irq & 8) - irq = 10; - else { - printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n"); - snd_cs5530_free(chip); - return -ENODEV; - } - - printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8, - dma16); - - err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8, - dma16, SB_HW_CS5530, &chip->sb); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create SoundBlaster\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create PCM\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_sbmixer_new(chip->sb); - if (err < 0) { - printk(KERN_ERR "CS5530: Could not create Mixer\n"); - snd_cs5530_free(chip); - return err; - } - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - snd_cs5530_free(chip); - return err; - } - - snd_card_set_dev(card, &pci->dev); - *rchip = chip; - return 0; -} - -static int __devinit snd_cs5530_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - struct snd_card *card; - struct snd_cs5530 *chip = NULL; - int err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - dev++; - return -ENOENT; - } - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - - if (card == NULL) - return -ENOMEM; - - err = snd_cs5530_create(card, pci, &chip); - if (err < 0) { - snd_card_free(card); - return err; - } - - strcpy(card->driver, "CS5530"); - strcpy(card->shortname, "CS5530 Audio"); - sprintf(card->longname, "%s at 0x%lx", card->shortname, chip->pci_base); - - err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } - pci_set_drvdata(pci, card); - dev++; - return 0; -} - -static struct pci_driver driver = { - .name = "CS5530_Audio", - .id_table = snd_cs5530_ids, - .probe = snd_cs5530_probe, - .remove = __devexit_p(snd_cs5530_remove), -}; - -static int __init alsa_card_cs5530_init(void) -{ - return pci_register_driver(&driver); -} - -static void __exit alsa_card_cs5530_exit(void) -{ - pci_unregister_driver(&driver); -} - -module_init(alsa_card_cs5530_init) -module_exit(alsa_card_cs5530_exit) - diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 404ae1be0a4b..4a9b59ad8ab1 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -51,15 +51,9 @@ #define HANA_FILENAME "emu/hana.fw" #define DOCK_FILENAME "emu/audio_dock.fw" -#define EMU1010B_FILENAME "emu/emu1010b.fw" -#define MICRO_DOCK_FILENAME "emu/micro_dock.fw" -#define EMU1010_NOTEBOOK_FILENAME "emu/emu1010_notebook.fw" MODULE_FIRMWARE(HANA_FILENAME); MODULE_FIRMWARE(DOCK_FILENAME); -MODULE_FIRMWARE(EMU1010B_FILENAME); -MODULE_FIRMWARE(MICRO_DOCK_FILENAME); -MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME); /************************************************************************* @@ -666,12 +660,10 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return err; } snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); -#if 0 if (fw_entry->size != 0x133a4) { snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename); return -EINVAL; } -#endif /* The FPGA is a Xilinx Spartan IIE XC2S50E */ /* GPIO7 -> FPGA PGMN @@ -702,37 +694,6 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file return 0; } -/* - * EMU-1010 - details found out from this driver, official MS Win drivers, - * testing the card: - * - * Audigy2 (aka Alice2): - * --------------------- - * * communication over PCI - * * conversion of 32-bit data coming over EMU32 links from HANA FPGA - * to 2 x 16-bit, using internal DSP instructions - * * slave mode, clock supplied by HANA - * * linked to HANA using: - * 32 x 32-bit serial EMU32 output channels - * 16 x EMU32 input channels - * (?) x I2S I/O channels (?) - * - * FPGA (aka HANA): - * --------------- - * * provides all (?) physical inputs and outputs of the card - * (ADC, DAC, SPDIF I/O, ADAT I/O, etc.) - * * provides clock signal for the card and Alice2 - * * two crystals - for 44.1kHz and 48kHz multiples - * * provides internal routing of signal sources to signal destinations - * * inputs/outputs to Alice2 - see above - * - * Current status of the driver: - * ---------------------------- - * * only 44.1/48kHz supported (the MS Win driver supports up to 192 kHz) - * * PCM device nb. 2: - * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops - * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops - */ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) { unsigned int i; @@ -766,7 +727,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printdd("reg1=0x%x\n",reg); - if ((reg & 0x3f) == 0x15) { + if (reg == 0x55) { /* FPGA netlist already present so clear it */ /* Return to programming mode */ @@ -774,32 +735,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) } snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printdd("reg2=0x%x\n",reg); - if ((reg & 0x3f) == 0x15) { + if (reg == 0x55) { /* FPGA failed to return to programming mode */ - snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010B_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010B_FILENAME); - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, EMU1010_NOTEBOOK_FILENAME)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Firmware file %s failed\n", EMU1010_NOTEBOOK_FILENAME); - return err; - } + if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { + snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); + return err; } /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); - if ((reg & 0x3f) != 0x15) { + if (reg != 0x55) { /* FPGA failed to be programmed */ snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); return -ENODEV; @@ -902,27 +850,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1); snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1); - /* Pavel Hofman - setting defaults for 8 more capture channels - * Defaults only, users will set their own values anyways, let's - * just copy/paste. - */ - - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_9, EMU_SRC_DOCK_MIC_B1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_A, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_B, EMU_SRC_HAMOA_ADC_LEFT2); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_ADC1_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_ADC1_RIGHT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_E, EMU_SRC_DOCK_ADC2_LEFT1); - snd_emu1010_fpga_link_dst_src_write(emu, - EMU_DST_ALICE2_EMU32_F, EMU_SRC_DOCK_ADC2_RIGHT1); #endif #if 0 /* Original */ @@ -1016,27 +943,16 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if (emu->card_capabilities->emu1010 == 1) { - if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 2) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } - } else if (emu->card_capabilities->emu1010 == 3) { - if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { - return err; - } + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { + return err; } - snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, ® ); snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ snd_emu1010_fpga_read(emu, EMU_HANA_ID, ® ); snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); - if ((reg & 0x3f) != 0x15) { + if (reg != 0x55) { /* FPGA failed to be programmed */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); return 0; @@ -1311,15 +1227,9 @@ static struct snd_emu_chip_details emu_chip_details[] = { .emu10k2_chip = 1, .ca0108_chip = 1, .ca_cardbus_chip = 1, - .spk71 = 1 , - .emu1010 = 3} , - {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, - .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", - .id = "EMU1010", - .emu10k2_chip = 1, - .ca0108_chip = 1, - .spk71 = 1 , - .emu1010 = 2} , + .spi_dac = 1, + .i2c_adc = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", @@ -1753,13 +1663,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card, emu->fx8010.extout_mask = extout_mask; emu->enable_ir = enable_ir; - if (emu->card_capabilities->ca_cardbus_chip) { - if ((err = snd_emu10k1_cardbus_init(emu)) < 0) - goto error; - } if (emu->card_capabilities->ecard) { if ((err = snd_emu10k1_ecard_init(emu)) < 0) goto error; + } else if (emu->card_capabilities->ca_cardbus_chip) { + if ((err = snd_emu10k1_cardbus_init(emu)) < 0) + goto error; } else if (emu->card_capabilities->emu1010) { if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { snd_emu10k1_free(emu); @@ -1905,10 +1814,10 @@ void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu) void snd_emu10k1_resume_init(struct snd_emu10k1 *emu) { - if (emu->card_capabilities->ca_cardbus_chip) - snd_emu10k1_cardbus_init(emu); if (emu->card_capabilities->ecard) snd_emu10k1_ecard_init(emu); + else if (emu->card_capabilities->ca_cardbus_chip) + snd_emu10k1_cardbus_init(emu); else if (emu->card_capabilities->emu1010) snd_emu10k1_emu1010_init(emu); else diff --git a/trunk/sound/pci/emu10k1/emufx.c b/trunk/sound/pci/emu10k1/emufx.c index 7206c0fa06f2..c02012cccd8e 100644 --- a/trunk/sound/pci/emu10k1/emufx.c +++ b/trunk/sound/pci/emu10k1/emufx.c @@ -1123,11 +1123,6 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; } -/* - * Used for emu1010 - conversion from 32-bit capture inputs from HANA - * to 2 x 16-bit registers in audigy - their values are read via DMA. - * Conversion is performed by Audigy DSP instructions of FX8010. - */ static int snd_emu10k1_audigy_dsp_convert_32_to_2x16( struct snd_emu10k1_fx8010_code *icode, u32 *ptr, int tmp, int bit_shifter16, @@ -1198,11 +1193,7 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); #if 1 - /* PCM front Playback Volume (independent from stereo mix) - * playback = 0 + ( gpr * FXBUS_PCM_LEFT_FRONT >> 31) - * where gpr contains attenuation from corresponding mixer control - * (snd_emu10k1_init_stereo_control) - */ + /* PCM front Playback Volume (independent from stereo mix) */ A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT)); snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100); @@ -1558,7 +1549,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) if (emu->card_capabilities->emu1010) { snd_printk("EMU inputs on\n"); - /* Capture 16 (originally 8) channels of S32_LE sound */ + /* Capture 8 channels of S32_LE sound */ /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */ /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */ @@ -1569,11 +1560,6 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) ); /* Right ADC in 1 of 2 */ gpr_map[gpr++] = 0x00000000; - /* Delaying by one sample: instead of copying the input - * value A_P16VIN to output A_FXBUS2 as in the first channel, - * we use an auxiliary register, delaying the value by one - * sample - */ snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) ); A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000); gpr_map[gpr++] = 0x00000000; @@ -1597,66 +1583,6 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) gpr_map[gpr++] = 0x00000000; snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) ); A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000); - /* Pavel Hofman - we still have voices, A_FXBUS2s, and - * A_P16VINs available - - * let's add 8 more capture channels - total of 16 - */ - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x10)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x8), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x12)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x9), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x14)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xa), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x16)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xb), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x18)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xc), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1a)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xd), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1c)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xe), - A_C_00000000, A_C_00000000); - gpr_map[gpr++] = 0x00000000; - snd_emu10k1_audigy_dsp_convert_32_to_2x16(icode, &ptr, tmp, - bit_shifter16, - A_GPR(gpr - 1), - A_FXBUS2(0x1e)); - A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0xf), - A_C_00000000, A_C_00000000); #if 0 for (z = 4; z < 8; z++) { diff --git a/trunk/sound/pci/emu10k1/emumixer.c b/trunk/sound/pci/emu10k1/emumixer.c index 7b2c1dcc5337..4db6e1ca1665 100644 --- a/trunk/sound/pci/emu10k1/emumixer.c +++ b/trunk/sound/pci/emu10k1/emumixer.c @@ -77,10 +77,6 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol, return 0; } -/* - * Items labels in enum mixer controls assigning source data to - * each destination - */ static char *emu1010_src_texts[] = { "Silence", "Dock Mic A", @@ -137,9 +133,6 @@ static char *emu1010_src_texts[] = { "DSP 31", }; -/* - * List of data sources available for each destination - */ static unsigned int emu1010_src_regs[] = { EMU_SRC_SILENCE,/* 0 */ EMU_SRC_DOCK_MIC_A1, /* 1 */ @@ -196,10 +189,6 @@ static unsigned int emu1010_src_regs[] = { EMU_SRC_ALICE_EMU32B+0xf, /* 52 */ }; -/* - * Data destinations - physical EMU outputs. - * Each destination has an enum mixer control to choose a data source - */ static unsigned int emu1010_output_dst[] = { EMU_DST_DOCK_DAC1_LEFT1, /* 0 */ EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */ @@ -227,11 +216,6 @@ static unsigned int emu1010_output_dst[] = { EMU_DST_HANA_ADAT+7, /* 23 */ }; -/* - * Data destinations - HANA outputs going to Alice2 (audigy) for - * capture (EMU32 + I2S links) - * Each destination has an enum mixer control to choose a data source - */ static unsigned int emu1010_input_dst[] = { EMU_DST_ALICE2_EMU32_0, EMU_DST_ALICE2_EMU32_1, diff --git a/trunk/sound/pci/emu10k1/emupcm.c b/trunk/sound/pci/emu10k1/emupcm.c index eda5cb373ded..ab4f5df5241b 100644 --- a/trunk/sound/pci/emu10k1/emupcm.c +++ b/trunk/sound/pci/emu10k1/emupcm.c @@ -1233,26 +1233,24 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) runtime->hw.rate_min = runtime->hw.rate_max = 48000; spin_lock_irq(&emu->reg_lock); if (emu->card_capabilities->emu1010) { - /* Nb. of channels has been increased to 16 */ - /* TODO + /* TODO * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 * rate_min = 44100, * rate_max = 192000, - * channels_min = 16, - * channels_max = 16, + * channels_min = 8, + * channels_max = 8, * Need to add mixer control to fix sample rate * - * There are 32 mono channels of 16bits each. + * There are 16 mono channels of 16bits each. * 24bit Audio uses 2x channels over 16bit * 96kHz uses 2x channels over 48kHz * 192kHz uses 4x channels over 48kHz - * So, for 48kHz 24bit, one has 16 channels - * for 96kHz 24bit, one has 8 channels - * for 192kHz 24bit, one has 4 channels - * + * So, for 48kHz 24bit, one has 8 channels + * for 96kHz 24bit, one has 4 channels + * for 192kHz 24bit, one has 2 channels */ #if 1 switch (emu->emu1010.internal_clock) { @@ -1260,15 +1258,13 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) /* For 44.1kHz */ runtime->hw.rates = SNDRV_PCM_RATE_44100; runtime->hw.rate_min = runtime->hw.rate_max = 44100; - runtime->hw.channels_min = - runtime->hw.channels_max = 16; + runtime->hw.channels_min = runtime->hw.channels_max = 8; break; case 1: /* For 48kHz */ runtime->hw.rates = SNDRV_PCM_RATE_48000; runtime->hw.rate_min = runtime->hw.rate_max = 48000; - runtime->hw.channels_min = - runtime->hw.channels_max = 16; + runtime->hw.channels_min = runtime->hw.channels_max = 8; break; }; #endif @@ -1286,7 +1282,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) #endif runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; /* efx_voices_mask[0] is expected to be zero - * efx_voices_mask[1] is expected to have 32bits set + * efx_voices_mask[1] is expected to have 16bits set */ } else { runtime->hw.channels_min = runtime->hw.channels_max = 0; @@ -1791,24 +1787,11 @@ int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct s /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */ if (emu->audigy) { emu->efx_voices_mask[0] = 0; - if (emu->card_capabilities->emu1010) - /* Pavel Hofman - 32 voices will be used for - * capture (write mode) - - * each bit = corresponding voice - */ - emu->efx_voices_mask[1] = 0xffffffff; - else - emu->efx_voices_mask[1] = 0xffff; + emu->efx_voices_mask[1] = 0xffff; } else { emu->efx_voices_mask[0] = 0xffff0000; emu->efx_voices_mask[1] = 0; } - /* For emu1010, the control has to set 32 upper bits (voices) - * out of the 64 bits (voices) to true for the 16-channels capture - * to work correctly. Correct A_FXWC2 initial value (0xffffffff) - * is already defined but the snd_emu10k1_pcm_efx_voices_mask - * control can override this register's value. - */ kctl = snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu); if (!kctl) return -ENOMEM; diff --git a/trunk/sound/pci/ens1370.c b/trunk/sound/pci/ens1370.c index 21cb4268a59b..7c403965153b 100644 --- a/trunk/sound/pci/ens1370.c +++ b/trunk/sound/pci/ens1370.c @@ -1607,8 +1607,8 @@ struct es1371_quirk { unsigned char rev; /* revision */ }; -static int es1371_quirk_lookup(struct ensoniq *ensoniq, - struct es1371_quirk *list) +static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq, + struct es1371_quirk *list) { while (list->vid != (unsigned short)PCI_ANY_ID) { if (ensoniq->pci->vendor == list->vid && diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 92bc8b3fa2a0..2fa281cbef91 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -341,9 +341,6 @@ struct azx { unsigned int single_cmd :1; unsigned int polling_mode :1; unsigned int msi :1; - - /* for debugging */ - unsigned int last_cmd; /* last issued command (to sync) */ }; /* driver types */ @@ -469,10 +466,18 @@ static void azx_free_cmd_io(struct azx *chip) } /* send a command */ -static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) +static int azx_corb_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, + unsigned int verb, unsigned int para) { struct azx *chip = codec->bus->private_data; unsigned int wp; + u32 val; + + val = (u32)(codec->addr & 0x0f) << 28; + val |= (u32)direct << 27; + val |= (u32)nid << 20; + val |= verb << 8; + val |= para; /* add command to corb */ wp = azx_readb(chip, CORBWP); @@ -533,12 +538,12 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) } if (! chip->rirb.cmds) return chip->rirb.res; /* the last value */ - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_after_eq(timeout, jiffies)); if (chip->msi) { snd_printk(KERN_WARNING "hda_intel: No response from codec, " - "disabling MSI: last cmd=0x%08x\n", chip->last_cmd); + "disabling MSI...\n"); free_irq(chip->irq, chip); chip->irq = -1; pci_disable_msi(chip->pci); @@ -550,15 +555,13 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) if (!chip->polling_mode) { snd_printk(KERN_WARNING "hda_intel: azx_get_response timeout, " - "switching to polling mode: last cmd=0x%08x\n", - chip->last_cmd); + "switching to polling mode...\n"); chip->polling_mode = 1; goto again; } snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " - "switching to single_cmd mode: last cmd=0x%08x\n", - chip->last_cmd); + "switching to single_cmd mode...\n"); chip->rirb.rp = azx_readb(chip, RIRBWP); chip->rirb.cmds = 0; /* switch to single_cmd mode */ @@ -578,11 +581,20 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) */ /* send a command */ -static int azx_single_send_cmd(struct hda_codec *codec, u32 val) +static int azx_single_send_cmd(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, + unsigned int para) { struct azx *chip = codec->bus->private_data; + u32 val; int timeout = 50; + val = (u32)(codec->addr & 0x0f) << 28; + val |= (u32)direct << 27; + val |= (u32)nid << 20; + val |= verb << 8; + val |= para; + while (timeout--) { /* check ICB busy bit */ if (! (azx_readw(chip, IRS) & ICH6_IRS_BUSY)) { @@ -627,19 +639,10 @@ static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, unsigned int para) { struct azx *chip = codec->bus->private_data; - u32 val; - - val = (u32)(codec->addr & 0x0f) << 28; - val |= (u32)direct << 27; - val |= (u32)nid << 20; - val |= verb << 8; - val |= para; - chip->last_cmd = val; - if (chip->single_cmd) - return azx_single_send_cmd(codec, val); + return azx_single_send_cmd(codec, nid, direct, verb, para); else - return azx_corb_send_cmd(codec, val); + return azx_corb_send_cmd(codec, nid, direct, verb, para); } /* get a response */ @@ -1785,12 +1788,6 @@ static struct pci_device_id azx_ids[] = { { 0x10de, 0x044b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP65 */ { 0x10de, 0x055c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ { 0x10de, 0x055d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP67 */ - { 0x10de, 0x07fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ - { 0x10de, 0x07fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP73 */ - { 0x10de, 0x0774, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0775, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0776, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ - { 0x10de, 0x0777, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA MCP77 */ { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index ac15066fd300..e313e685f161 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -250,12 +250,6 @@ static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffe snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); - - if (codec->mfg) - snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg); - else - snd_iprintf(buffer, "No Modem Function Group found\n"); - if (! codec->afg) return; snd_iprintf(buffer, "Default PCM:\n"); diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index 4d7f8d11ad75..0e1a879663fa 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -1,8 +1,7 @@ /* - * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, - * AD1986A, AD1988 + * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988 * - * Copyright (c) 2005-2007 Takashi Iwai + * Copyright (c) 2005 Takashi Iwai * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,7 +61,7 @@ struct ad198x_spec { int num_channel_mode; /* PCM information */ - struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ + struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ struct mutex amp_mutex; /* PCM volume/mute control mutex */ unsigned int spdif_route; @@ -2775,635 +2774,12 @@ static int patch_ad1988(struct hda_codec *codec) } -/* - * AD1884 / AD1984 - * - * port-B - front line/mic-in - * port-E - aux in/out - * port-F - aux in/out - * port-C - rear line/mic-in - * port-D - rear line/hp-out - * port-A - front line/hp-out - * - * AD1984 = AD1884 + two digital mic-ins - * - * FIXME: - * For simplicity, we share the single DAC for both HP and line-outs - * right now. The inidividual playbacks could be easily implemented, - * but no build-up framework is given, so far. - */ - -static hda_nid_t ad1884_dac_nids[1] = { - 0x04, -}; - -static hda_nid_t ad1884_adc_nids[2] = { - 0x08, 0x09, -}; - -static hda_nid_t ad1884_capsrc_nids[2] = { - 0x0c, 0x0d, -}; - -#define AD1884_SPDIF_OUT 0x02 - -static struct hda_input_mux ad1884_capture_source = { - .num_items = 4, - .items = { - { "Front Mic", 0x0 }, - { "Mic", 0x1 }, - { "CD", 0x2 }, - { "Mix", 0x3 }, - }, -}; - -static struct snd_kcontrol_new ad1884_base_mixers[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), - /* - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Digital Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT), - */ - HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - /* SPDIF controls */ - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - /* identical with ad1983 */ - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1984_dmic_mixers[] = { - HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, - HDA_INPUT), - HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0, - HDA_INPUT), - { } /* end */ -}; - -/* - * initialization verbs - */ -static struct hda_verb ad1884_init_verbs[] = { - /* DACs; mute as default */ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Port-A (HP) mixer */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-A pin */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* HP selector - select DAC2 */ - {0x22, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-D (Line-out) mixer */ - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-D pin */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono-out mixer */ - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Mono-out pin */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono selector */ - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-B (front mic) pin */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-C (rear mic) pin */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer; mute as default */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - /* Analog Mix output amp */ - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ - /* SPDIF output selector */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - { } /* end */ -}; - -static int patch_ad1884(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids); - spec->multiout.dac_nids = ad1884_dac_nids; - spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; - spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids); - spec->adc_nids = ad1884_adc_nids; - spec->capsrc_nids = ad1884_capsrc_nids; - spec->input_mux = &ad1884_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = ad1884_base_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = ad1884_init_verbs; - spec->spdif_route = 0; - - codec->patch_ops = ad198x_patch_ops; - - return 0; -} - -/* - * Lenovo Thinkpad T61/X61 - */ -static struct hda_input_mux ad1984_thinkpad_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - { "Mix", 0x3 }, - }, -}; - -static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - { } /* end */ -}; - -/* additional verbs */ -static struct hda_verb ad1984_thinkpad_init_verbs[] = { - /* Port-E (docking station mic) pin */ - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* docking mic boost */ - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer - docking mic; mute as default */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* enable EAPD bit */ - {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, - { } /* end */ -}; - -/* Digial MIC ADC NID 0x05 + 0x06 */ -static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - unsigned int stream_tag, - unsigned int format, - struct snd_pcm_substream *substream) -{ - snd_hda_codec_setup_stream(codec, 0x05 + substream->number, - stream_tag, 0, format); - return 0; -} - -static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, - struct hda_codec *codec, - struct snd_pcm_substream *substream) -{ - snd_hda_codec_setup_stream(codec, 0x05 + substream->number, - 0, 0, 0); - return 0; -} - -static struct hda_pcm_stream ad1984_pcm_dmic_capture = { - .substreams = 2, - .channels_min = 2, - .channels_max = 2, - .nid = 0x05, - .ops = { - .prepare = ad1984_pcm_dmic_prepare, - .cleanup = ad1984_pcm_dmic_cleanup - }, -}; - -static int ad1984_build_pcms(struct hda_codec *codec) -{ - struct ad198x_spec *spec = codec->spec; - struct hda_pcm *info; - int err; - - err = ad198x_build_pcms(codec); - if (err < 0) - return err; - - info = spec->pcm_rec + codec->num_pcms; - codec->num_pcms++; - info->name = "AD1984 Digital Mic"; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture; - return 0; -} - -/* models */ -enum { - AD1984_BASIC, - AD1984_THINKPAD, - AD1984_MODELS -}; - -static const char *ad1984_models[AD1984_MODELS] = { - [AD1984_BASIC] = "basic", - [AD1984_THINKPAD] = "thinkpad", -}; - -static struct snd_pci_quirk ad1984_cfg_tbl[] = { - /* Lenovo Thinkpad T61/X61 */ - SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1984_THINKPAD), - {} -}; - -static int patch_ad1984(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - int board_config, err; - - err = patch_ad1884(codec); - if (err < 0) - return err; - spec = codec->spec; - board_config = snd_hda_check_board_config(codec, AD1984_MODELS, - ad1984_models, ad1984_cfg_tbl); - switch (board_config) { - case AD1984_BASIC: - /* additional digital mics */ - spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers; - codec->patch_ops.build_pcms = ad1984_build_pcms; - break; - case AD1984_THINKPAD: - spec->multiout.dig_out_nid = 0; - spec->input_mux = &ad1984_thinkpad_capture_source; - spec->mixers[0] = ad1984_thinkpad_mixers; - spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; - break; - } - return 0; -} - - -/* - * AD1882 - * - * port-A - front hp-out - * port-B - front mic-in - * port-C - rear line-in, shared surr-out (3stack) - * port-D - rear line-out - * port-E - rear mic-in, shared clfe-out (3stack) - * port-F - rear surr-out (6stack) - * port-G - rear clfe-out (6stack) - */ - -static hda_nid_t ad1882_dac_nids[3] = { - 0x04, 0x03, 0x05 -}; - -static hda_nid_t ad1882_adc_nids[2] = { - 0x08, 0x09, -}; - -static hda_nid_t ad1882_capsrc_nids[2] = { - 0x0c, 0x0d, -}; - -#define AD1882_SPDIF_OUT 0x02 - -/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ -static struct hda_input_mux ad1882_capture_source = { - .num_items = 5, - .items = { - { "Front Mic", 0x1 }, - { "Mic", 0x4 }, - { "Line", 0x2 }, - { "CD", 0x3 }, - { "Mix", 0x7 }, - }, -}; - -static struct snd_kcontrol_new ad1882_base_mixers[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = ad198x_mux_enum_info, - .get = ad198x_mux_enum_get, - .put = ad198x_mux_enum_put, - }, - /* SPDIF controls */ - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", - /* identical with ad1983 */ - .info = ad1983_spdif_route_info, - .get = ad1983_spdif_route_get, - .put = ad1983_spdif_route_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1882_3stack_mixers[] = { - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = ad198x_ch_mode_info, - .get = ad198x_ch_mode_get, - .put = ad198x_ch_mode_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new ad1882_6stack_mixers[] = { - HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -static struct hda_verb ad1882_ch2_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - { } /* end */ -}; - -static struct hda_verb ad1882_ch4_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - { } /* end */ -}; - -static struct hda_verb ad1882_ch6_init[] = { - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } /* end */ -}; - -static struct hda_channel_mode ad1882_modes[3] = { - { 2, ad1882_ch2_init }, - { 4, ad1882_ch4_init }, - { 6, ad1882_ch6_init }, -}; - -/* - * initialization verbs - */ -static struct hda_verb ad1882_init_verbs[] = { - /* DACs; mute as default */ - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Port-A (HP) mixer */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-A pin */ - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* HP selector - select DAC2 */ - {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, - /* Port-D (Line-out) mixer */ - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Port-D pin */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mono-out mixer */ - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Mono-out pin */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-B (front mic) pin */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-C (line-in) pin */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-C mixer - mute as input */ - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Port-E (mic-in) pin */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ - /* Port-E mixer - mute as input */ - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Port-F (surround) */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-G (CLFE) */ - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Analog mixer; mute as default */ - /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, - /* Analog Mix output amp */ - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ - /* SPDIF output selector */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ - { } /* end */ -}; - -/* models */ -enum { - AD1882_3STACK, - AD1882_6STACK, - AD1882_MODELS -}; - -static const char *ad1882_models[AD1986A_MODELS] = { - [AD1882_3STACK] = "3stack", - [AD1882_6STACK] = "6stack", -}; - - -static int patch_ad1882(struct hda_codec *codec) -{ - struct ad198x_spec *spec; - int board_config; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - mutex_init(&spec->amp_mutex); - codec->spec = spec; - - spec->multiout.max_channels = 6; - spec->multiout.num_dacs = 3; - spec->multiout.dac_nids = ad1882_dac_nids; - spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; - spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); - spec->adc_nids = ad1882_adc_nids; - spec->capsrc_nids = ad1882_capsrc_nids; - spec->input_mux = &ad1882_capture_source; - spec->num_mixers = 1; - spec->mixers[0] = ad1882_base_mixers; - spec->num_init_verbs = 1; - spec->init_verbs[0] = ad1882_init_verbs; - spec->spdif_route = 0; - - codec->patch_ops = ad198x_patch_ops; - - /* override some parameters */ - board_config = snd_hda_check_board_config(codec, AD1882_MODELS, - ad1882_models, NULL); - switch (board_config) { - default: - case AD1882_3STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_3stack_mixers; - spec->channel_mode = ad1882_modes; - spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); - spec->need_dac_fix = 1; - spec->multiout.max_channels = 2; - spec->multiout.num_dacs = 1; - break; - case AD1882_6STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_6stack_mixers; - break; - } - return 0; -} - - /* * patch entries */ struct hda_codec_preset snd_hda_preset_analog[] = { - { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, - { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, - { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, diff --git a/trunk/sound/pci/hda/patch_atihdmi.c b/trunk/sound/pci/hda/patch_atihdmi.c index 72d3ab9751ac..f8eb4c90f801 100644 --- a/trunk/sound/pci/hda/patch_atihdmi.c +++ b/trunk/sound/pci/hda/patch_atihdmi.c @@ -172,7 +172,6 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, {} /* terminator */ diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 4d8e8af5c819..bef214bcdddf 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -801,9 +801,7 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30d9, "HP Spartan", CXT5045_LAPTOP), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), - SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP), SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} }; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 9a47eec5a27b..4776de93928b 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -94,18 +94,10 @@ enum { ALC262_HP_BPC_D7000_WF, ALC262_BENQ_ED8, ALC262_SONY_ASSAMD, - ALC262_BENQ_T31, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; -/* ALC268 models */ -enum { - ALC268_3ST, - ALC268_AUTO, - ALC268_MODEL_LAST /* last tag */ -}; - /* ALC861 models */ enum { ALC861_3ST, @@ -123,7 +115,6 @@ enum { /* ALC861-VD models */ enum { ALC660VD_3ST, - ALC660VD_3ST_DIG, ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, @@ -153,7 +144,6 @@ enum { ALC882_TARGA, ALC882_ASUS_A7J, ALC885_MACPRO, - ALC885_IMAC24, ALC882_AUTO, ALC882_MODEL_LAST, }; @@ -173,8 +163,6 @@ enum { ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, ALC888_LENOVO_MS7195_DIG, - ALC888_6ST_HP, - ALC888_3ST_HP, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -724,38 +712,6 @@ static void alc_subsystem_id(struct hda_codec *codec, } } -/* - * Fix-up pin default configurations - */ - -struct alc_pincfg { - hda_nid_t nid; - u32 val; -}; - -static void alc_fix_pincfg(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_pincfg **pinfix) -{ - const struct alc_pincfg *cfg; - - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (!quirk) - return; - - cfg = pinfix[quirk->value]; - for (; cfg->nid; cfg++) { - int i; - u32 val = cfg->val; - for (i = 0; i < 4; i++) { - snd_hda_codec_write(codec, cfg->nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i, - val & 0xff); - val >>= 8; - } - } -} - /* * ALC880 3-stack model * @@ -1922,53 +1878,31 @@ static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) * Pin assignment: * Speaker-out: 0x14 * Mic-In: 0x18 - * Built-in Mic-In: 0x19 - * Line-In: 0x1b - * HP-Out: 0x1a + * Built-in Mic-In: 0x19 (?) + * HP-Out: 0x1b * SPDIF-Out: 0x1e */ +/* seems analog CD is not working */ static struct hda_input_mux alc880_lg_lw_capture_source = { - .num_items = 3, + .num_items = 2, .items = { { "Mic", 0x0 }, { "Internal Mic", 0x1 }, - { "Line In", 0x2 }, }, }; -#define alc880_lg_lw_modes alc880_threestack_modes - static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc_ch_mode_info, - .get = alc_ch_mode_get, - .put = alc_ch_mode_put, - }, { } /* end */ }; static struct hda_verb alc880_lg_lw_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ - /* set capture source to mic-in */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -1978,6 +1912,7 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* HP-out */ + {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* mic-in to input */ @@ -2921,11 +2856,11 @@ static struct alc_config_preset alc880_presets[] = { .mixers = { alc880_lg_lw_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_lg_lw_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_dac_nids), + .num_dacs = 1, .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), - .channel_mode = alc880_lg_lw_modes, + .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), + .channel_mode = alc880_2_jack_modes, .input_mux = &alc880_lg_lw_capture_source, .unsol_event = alc880_lg_lw_unsol_event, .init_hook = alc880_lg_lw_automute, @@ -5119,60 +5054,6 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; -/* iMac 24 mixer. */ -static struct snd_kcontrol_new alc885_imac24_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), - { } /* end */ -}; - -/* iMac 24 init verbs. */ -static struct hda_verb alc885_imac24_init_verbs[] = { - /* Internal speakers: output 0 (0x0c) */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Internal speakers: output 0 (0x0c) */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Headphone: output 0 (0x0c) */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - /* Front Mic: input vref at 80% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - { } -}; - -/* Toggle speaker-output according to the hp-jack state */ -static void alc885_imac24_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); -} - -/* Processes unsolicited events. */ -static void alc885_imac24_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - /* Headphone insertion or removal. */ - if ((res >> 26) == ALC880_HP_EVENT) - alc885_imac24_automute(codec); -} - static struct hda_verb alc882_targa_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -5393,7 +5274,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_ARIMA] = "arima", [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", - [ALC885_IMAC24] = "imac24", [ALC882_AUTO] = "auto", }; @@ -5404,7 +5284,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), - SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), {} @@ -5466,19 +5345,6 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_ch_modes, .input_mux = &alc882_capture_source, }, - [ALC885_IMAC24] = { - .mixers = { alc885_imac24_mixer }, - .init_verbs = { alc885_imac24_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .input_mux = &alc882_capture_source, - .unsol_event = alc885_imac24_unsol_event, - .init_hook = alc885_imac24_automute, - }, [ALC882_TARGA] = { .mixers = { alc882_targa_mixer, alc882_chmode_mixer, alc882_capture_mixer }, @@ -5512,29 +5378,6 @@ static struct alc_config_preset alc882_presets[] = { }; -/* - * Pin config fixes - */ -enum { - PINFIX_ABIT_AW9D_MAX -}; - -static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { - { 0x15, 0x01080104 }, /* side */ - { 0x16, 0x01011012 }, /* rear */ - { 0x17, 0x01016011 }, /* clfe */ - { } -}; - -static const struct alc_pincfg *alc882_pin_fixes[] = { - [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, -}; - -static struct snd_pci_quirk alc882_pinfix_tbl[] = { - SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), - {} -}; - /* * BIOS auto configuration */ @@ -5651,9 +5494,6 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b0c00: /* Mac Pro */ board_config = ALC885_MACPRO; break; - case 0x106b1000: /* iMac 24 */ - board_config = ALC885_IMAC24; - break; default: printk(KERN_INFO "hda_codec: Unknown model for ALC882, " "trying auto-probe from BIOS...\n"); @@ -5661,8 +5501,6 @@ static int patch_alc882(struct hda_codec *codec) } } - alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); - if (board_config == ALC882_AUTO) { /* automatic parse from the BIOS config */ err = alc882_parse_auto_config(codec); @@ -5680,7 +5518,7 @@ static int patch_alc882(struct hda_codec *codec) if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); - if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) { + if (board_config == ALC885_MACPRO) { alc882_gpio_mute(codec, 0, 0); alc882_gpio_mute(codec, 1, 0); } @@ -6157,84 +5995,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc888_6st_hp_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .put = alc883_mux_enum_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new alc888_3st_hp_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc883_mux_enum_info, - .get = alc883_mux_enum_get, - .put = alc883_mux_enum_put, - }, - { } /* end */ -}; - static struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -6366,42 +6126,6 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { { } /* end */ }; -static struct hda_verb alc888_6st_hp_verbs[] = { - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */ - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */ - { } -}; - -static struct hda_verb alc888_3st_hp_verbs[] = { - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ - {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ - { } -}; - -static struct hda_verb alc888_3st_hp_2ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } -}; - -static struct hda_verb alc888_3st_hp_6ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { } -}; - -static struct hda_channel_mode alc888_3st_hp_modes[2] = { - { 2, alc888_3st_hp_2ch_init }, - { 6, alc888_3st_hp_6ch_init }, -}; - /* toggle front-jack and RCA according to the hp-jack state */ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) { @@ -6644,14 +6368,11 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", - [ALC888_6ST_HP] = "6stack-hp", - [ALC888_3ST_HP] = "3stack-hp", [ALC883_AUTO] = "auto", }; static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), @@ -6660,8 +6381,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), @@ -6681,9 +6400,6 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), - SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), {} }; @@ -6868,31 +6584,6 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_lenovo_ms7195_unsol_event, .init_hook = alc888_lenovo_ms7195_front_automute, }, - [ALC888_6ST_HP] = { - .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, - [ALC888_3ST_HP] = { - .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), - .channel_mode = alc888_3st_hp_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - }, }; @@ -7166,16 +6857,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { } /* end */ -}; + #define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer @@ -7507,15 +7189,6 @@ static struct hda_verb alc262_EAPD_verbs[] = { {} }; -static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, - {} -}; - /* add playback controls from the parsed DAC table */ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) @@ -7911,8 +7584,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_HP_BPC] = "hp-bpc", [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", [ALC262_BENQ_ED8] = "benq", - [ALC262_BENQ_T31] = "benq-t31", - [ALC262_SONY_ASSAMD] = "sony-assamd", + [ALC262_BENQ_ED8] = "sony-assamd", [ALC262_AUTO] = "auto", }; @@ -7920,12 +7592,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), @@ -7938,7 +7606,6 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), - SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), @@ -8043,17 +7710,6 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, - }, - [ALC262_BENQ_T31] = { - .mixers = { alc262_benq_t31_mixer }, - .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, }, }; @@ -8144,521 +7800,12 @@ static int patch_alc262(struct hda_codec *codec) } /* - * ALC268 channel source setting (2 channel) + * ALC861 channel source setting (2/6 channel selection for 3-stack) */ -#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID -#define alc268_modes alc260_modes - -static hda_nid_t alc268_dac_nids[2] = { - /* front, hp */ - 0x02, 0x03 -}; - -static hda_nid_t alc268_adc_nids[2] = { - /* ADC0-1 */ - 0x08, 0x07 -}; - -static hda_nid_t alc268_adc_nids_alt[1] = { - /* ADC0 */ - 0x08 -}; - -static struct snd_kcontrol_new alc268_base_mixer[] = { - /* output mixer control */ - HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - { } -}; /* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc268_base_init_verbs[] = { - /* Unmute DAC0-1 and set vol = 0 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - /* - * Set up output mixers (0x0c - 0x0e) - */ - /* set vol=0 to output mixers */ - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, - - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, - { } -}; - -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc268_volume_init_verbs[] = { - /* set output DAC */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - - /* set PCBEEP vol = 0 */ - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))}, - - { } -}; - -#define alc268_mux_enum_info alc_mux_enum_info -#define alc268_mux_enum_get alc_mux_enum_get - -static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - const struct hda_input_mux *imux = spec->input_mux; - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - static hda_nid_t capture_mixers[3] = { 0x23, 0x24 }; - hda_nid_t nid = capture_mixers[adc_idx]; - unsigned int *cur_val = &spec->cur_mux[adc_idx]; - unsigned int i, idx; - - idx = ucontrol->value.enumerated.item[0]; - if (idx >= imux->num_items) - idx = imux->num_items - 1; - if (*cur_val == idx && !codec->in_resume) - return 0; - for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0x7000 : 0x7080; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - v | (imux->items[i].index << 8)); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, - idx ); - } - *cur_val = idx; - return 1; -} - -static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 1, - .info = alc268_mux_enum_info, - .get = alc268_mux_enum_get, - .put = alc268_mux_enum_put, - }, - { } /* end */ -}; - -static struct snd_kcontrol_new alc268_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* The multiple "Capture Source" controls confuse alsamixer - * So call somewhat different.. - * FIXME: the controls appear in the "playback" view! - */ - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 2, - .info = alc268_mux_enum_info, - .get = alc268_mux_enum_get, - .put = alc268_mux_enum_put, - }, - { } /* end */ -}; - -static struct hda_input_mux alc268_capture_source = { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Front Mic", 0x1 }, - { "Line", 0x2 }, - { "CD", 0x3 }, - }, -}; - -/* create input playback/capture controls for the given pin */ -static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, - const char *ctlname, int idx) -{ - char name[32]; - int err; - - sprintf(name, "%s Playback Volume", ctlname); - if (nid == 0x14) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x02, 3, idx, - HDA_OUTPUT)); - if (err < 0) - return err; - } else if (nid == 0x15) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x03, 3, idx, - HDA_OUTPUT)); - if (err < 0) - return err; - } else - return -1; - sprintf(name, "%s Playback Switch", ctlname); - err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); - if (err < 0) - return err; - return 0; -} - -/* add playback controls from the parsed DAC table */ -static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg) -{ - hda_nid_t nid; - int err; - - spec->multiout.num_dacs = 2; /* only use one dac */ - spec->multiout.dac_nids = spec->private_dac_nids; - spec->multiout.dac_nids[0] = 2; - spec->multiout.dac_nids[1] = 3; - - nid = cfg->line_out_pins[0]; - if (nid) - alc268_new_analog_output(spec, nid, "Front", 0); - - nid = cfg->speaker_pins[0]; - if (nid == 0x1d) { - err = add_control(spec, ALC_CTL_WIDGET_VOL, - "Speaker Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); - if (err < 0) - return err; - } - nid = cfg->hp_pins[0]; - if (nid) - alc268_new_analog_output(spec, nid, "Headphone", 0); - - nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; - if (nid == 0x16) { - err = add_control(spec, ALC_CTL_WIDGET_MUTE, - "Mono Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); - if (err < 0) - return err; - } - return 0; -} - -/* create playback/capture controls for input pins */ -static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg) -{ - struct hda_input_mux *imux = &spec->private_imux; - int i, idx1; - - for (i = 0; i < AUTO_PIN_LAST; i++) { - switch(cfg->input_pins[i]) { - case 0x18: - idx1 = 0; /* Mic 1 */ - break; - case 0x19: - idx1 = 1; /* Mic 2 */ - break; - case 0x1a: - idx1 = 2; /* Line In */ - break; - case 0x1c: - idx1 = 3; /* CD */ - break; - default: - continue; - } - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - imux->items[imux->num_items].index = idx1; - imux->num_items++; - } - return 0; -} - -static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; - hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; - unsigned int dac_vol1, dac_vol2; - - if (speaker_nid) { - snd_hda_codec_write(codec, speaker_nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(1)); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_AMP_GAIN_MUTE, - AMP_IN_UNMUTE(1)); - } else { - snd_hda_codec_write(codec, 0x0f, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); - } - - dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ - if (line_nid == 0x14) - dac_vol2 = AMP_OUT_ZERO; - else if (line_nid == 0x15) - dac_vol1 = AMP_OUT_ZERO; - if (hp_nid == 0x14) - dac_vol2 = AMP_OUT_ZERO; - else if (hp_nid == 0x15) - dac_vol1 = AMP_OUT_ZERO; - if (line_nid != 0x16 || hp_nid != 0x16 || - spec->autocfg.line_out_pins[1] != 0x16 || - spec->autocfg.line_out_pins[2] != 0x16) - dac_vol1 = dac_vol2 = AMP_OUT_ZERO; - - snd_hda_codec_write(codec, 0x02, 0, - AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); - snd_hda_codec_write(codec, 0x03, 0, - AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); -} - -/* pcm configuration: identiacal with ALC880 */ -#define alc268_pcm_analog_playback alc880_pcm_analog_playback -#define alc268_pcm_analog_capture alc880_pcm_analog_capture -#define alc268_pcm_digital_playback alc880_pcm_digital_playback - -/* - * BIOS auto configuration - */ -static int alc268_parse_auto_config(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int err; - static hda_nid_t alc268_ignore[] = { 0 }; - - err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc268_ignore); - if (err < 0) - return err; - if (!spec->autocfg.line_outs) - return 0; /* can't find valid BIOS pin config */ - - err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); - if (err < 0) - return err; - - spec->multiout.max_channels = 2; - - /* digital only support output */ - if (spec->autocfg.dig_out_pin) - spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; - - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - - spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; - spec->num_mux_defs = 1; - spec->input_mux = &spec->private_imux; - - return 1; -} - -#define alc268_auto_init_multi_out alc882_auto_init_multi_out -#define alc268_auto_init_hp_out alc882_auto_init_hp_out -#define alc268_auto_init_analog_input alc882_auto_init_analog_input - -/* init callback for auto-configuration model -- overriding the default init */ -static void alc268_auto_init(struct hda_codec *codec) -{ - alc268_auto_init_multi_out(codec); - alc268_auto_init_hp_out(codec); - alc268_auto_init_mono_speaker_out(codec); - alc268_auto_init_analog_input(codec); -} - -/* - * configuration and preset - */ -static const char *alc268_models[ALC268_MODEL_LAST] = { - [ALC268_3ST] = "3stack", - [ALC268_AUTO] = "auto", -}; - -static struct snd_pci_quirk alc268_cfg_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), - {} -}; - -static struct alc_config_preset alc268_presets[] = { - [ALC268_3ST] = { - .mixers = { alc268_base_mixer, alc268_capture_alt_mixer }, - .init_verbs = { alc268_base_init_verbs }, - .num_dacs = ARRAY_SIZE(alc268_dac_nids), - .dac_nids = alc268_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), - .adc_nids = alc268_adc_nids_alt, - .hp_nid = 0x03, - .dig_out_nid = ALC268_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc268_modes), - .channel_mode = alc268_modes, - .input_mux = &alc268_capture_source, - }, -}; - -static int patch_alc268(struct hda_codec *codec) -{ - struct alc_spec *spec; - int board_config; - int err; - - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); - if (spec == NULL) - return -ENOMEM; - - codec->spec = spec; - - board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, - alc268_models, - alc268_cfg_tbl); - - if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { - printk(KERN_INFO "hda_codec: Unknown model for ALC268, " - "trying auto-probe from BIOS...\n"); - board_config = ALC268_AUTO; - } - - if (board_config == ALC268_AUTO) { - /* automatic parse from the BIOS config */ - err = alc268_parse_auto_config(codec); - if (err < 0) { - alc_free(codec); - return err; - } else if (!err) { - printk(KERN_INFO - "hda_codec: Cannot set up configuration " - "from BIOS. Using base mode...\n"); - board_config = ALC268_3ST; - } - } - - if (board_config != ALC268_AUTO) - setup_preset(spec, &alc268_presets[board_config]); - - spec->stream_name_analog = "ALC268 Analog"; - spec->stream_analog_playback = &alc268_pcm_analog_playback; - spec->stream_analog_capture = &alc268_pcm_analog_capture; - - spec->stream_name_digital = "ALC268 Digital"; - spec->stream_digital_playback = &alc268_pcm_digital_playback; - - if (board_config == ALC268_AUTO) { - if (!spec->adc_nids && spec->input_mux) { - /* check whether NID 0x07 is valid */ - unsigned int wcap = get_wcaps(codec, 0x07); - - /* get type */ - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; - if (wcap != AC_WID_AUD_IN) { - spec->adc_nids = alc268_adc_nids_alt; - spec->num_adc_nids = - ARRAY_SIZE(alc268_adc_nids_alt); - spec->mixers[spec->num_mixers] = - alc268_capture_alt_mixer; - spec->num_mixers++; - } else { - spec->adc_nids = alc268_adc_nids; - spec->num_adc_nids = - ARRAY_SIZE(alc268_adc_nids); - spec->mixers[spec->num_mixers] = - alc268_capture_mixer; - spec->num_mixers++; - } - } - } - codec->patch_ops = alc_patch_ops; - if (board_config == ALC268_AUTO) - spec->init_hook = alc268_auto_init; - - return 0; -} - -/* - * ALC861 channel source setting (2/6 channel selection for 3-stack) - */ - -/* - * set the path ways for 2 channel output - * need to set the codec line out and mic 1 pin widgets to inputs + * set the path ways for 2 channel output + * need to set the codec line out and mic 1 pin widgets to inputs */ static struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ @@ -9620,21 +8767,13 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), - SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), - SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), - /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) - * Any other models that need this preset? - */ - /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ + SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), - SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), - SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), - SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), {} }; @@ -10325,7 +9464,6 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re */ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", - [ALC660VD_3ST_DIG]= "3stack-660-digout", [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", @@ -10337,7 +9475,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), - SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), + SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), @@ -10345,7 +9483,6 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS), SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), - SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), {} }; @@ -10362,19 +9499,6 @@ static struct alc_config_preset alc861vd_presets[] = { .channel_mode = alc861vd_3stack_2ch_modes, .input_mux = &alc861vd_capture_source, }, - [ALC660VD_3ST_DIG] = { - .mixers = { alc861vd_3st_mixer }, - .init_verbs = { alc861vd_volume_init_verbs, - alc861vd_3stack_init_verbs }, - .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), - .dac_nids = alc660vd_dac_nids, - .dig_out_nid = ALC861VD_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), - .adc_nids = alc861vd_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), - .channel_mode = alc861vd_3stack_2ch_modes, - .input_mux = &alc861vd_capture_source, - }, [ALC861VD_3ST] = { .mixers = { alc861vd_3st_mixer }, .init_verbs = { alc861vd_volume_init_verbs, @@ -11296,7 +10420,7 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, for (i = 0; i < cfg->line_outs; i++) { if (!spec->multiout.dac_nids[i]) continue; - nid = alc880_idx_to_mixer(i); + nid = alc880_idx_to_dac(i); if (i == 2) { /* Center/LFE */ err = add_control(spec, ALC_CTL_WIDGET_VOL, @@ -11519,10 +10643,14 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; - spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; + if (err < 0) + return err; + else if (err > 0) + /* hack - override the init verbs */ + spec->init_verbs[0] = alc662_auto_init_verbs; spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; - return 1; + return err; } /* additional initialization for auto-configuration model */ @@ -11559,7 +10687,7 @@ static int patch_alc662(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (!err) { + } else if (err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -11596,7 +10724,6 @@ static int patch_alc662(struct hda_codec *codec) struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, - { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, diff --git a/trunk/sound/pci/hda/patch_si3054.c b/trunk/sound/pci/hda/patch_si3054.c index 6d2ecc38905c..43f537ef40bf 100644 --- a/trunk/sound/pci/hda/patch_si3054.c +++ b/trunk/sound/pci/hda/patch_si3054.c @@ -304,12 +304,8 @@ struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x10573055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573057, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x10573155, .name = "Si3054", .patch = patch_si3054 }, - /* VIA HDA on Clevo m540 */ - { .id = 0x11063288, .name = "Si3054", .patch = patch_si3054 }, /* Asus A8J Modem (SM56) */ { .id = 0x15433155, .name = "Si3054", .patch = patch_si3054 }, - /* LG LW20 modem */ - { .id = 0x18540018, .name = "Si3054", .patch = patch_si3054 }, {} }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 3f25de72966b..e3964fc4c405 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -44,7 +44,6 @@ enum { enum { STAC_9205_REF, - STAC_M43xx, STAC_9205_MODELS }; @@ -60,19 +59,11 @@ enum { STAC_D945_REF, STAC_D945GTP3, STAC_D945GTP5, - STAC_922X_DELL, - STAC_INTEL_MAC_V1, - STAC_INTEL_MAC_V2, - STAC_INTEL_MAC_V3, - STAC_INTEL_MAC_V4, - STAC_INTEL_MAC_V5, - /* for backward compitability */ STAC_MACMINI, STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, STAC_IMAC_INTEL, - STAC_IMAC_INTEL_20, STAC_922X_MODELS }; @@ -219,6 +210,7 @@ static hda_nid_t stac9205_pin_nids[12] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x16, 0x17, 0x18, 0x21, 0x22, + }; static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, @@ -334,6 +326,8 @@ static struct snd_kcontrol_new stac9200_mixer[] = { }; static struct snd_kcontrol_new stac925x_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -555,78 +549,44 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int intel_mac_v1_pin_configs[10] = { - 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, - 0x400000fc, 0x400000fb, -}; - -static unsigned int intel_mac_v2_pin_configs[10] = { - 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, - 0x400000fc, 0x400000fb, -}; - -static unsigned int intel_mac_v3_pin_configs[10] = { - 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, - 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, - 0x400000fc, 0x400000fb, +static unsigned int macbook_pro_v1_pin_configs[10] = { + 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, + 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, + 0x02a19320, 0x400000fb }; -static unsigned int intel_mac_v4_pin_configs[10] = { - 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, - 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, +static unsigned int macbook_pro_v2_pin_configs[10] = { + 0x0221401f, 0x90a70120, 0x01813024, 0x01014010, + 0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v5_pin_configs[10] = { - 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, - 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, +static unsigned int imac_intel_pin_configs[10] = { + 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, + 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, 0x400000fc, 0x400000fb, }; -static unsigned int stac922x_dell_pin_configs[10] = { - 0x0221121e, 0x408103ff, 0x02a1123e, 0x90100310, - 0x408003f1, 0x0221122f, 0x03451340, 0x40c003f2, - 0x50a003f3, 0x405003f4 -}; - static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_922X_DELL] = stac922x_dell_pin_configs, - [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, - [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, - [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, - [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, - [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, - /* for backward compitability */ - [STAC_MACMINI] = intel_mac_v3_pin_configs, - [STAC_MACBOOK] = intel_mac_v5_pin_configs, - [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, - [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, - [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, - [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, + [STAC_MACMINI] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, + [STAC_IMAC_INTEL] = imac_intel_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", [STAC_D945GTP3] = "3stack", - [STAC_922X_DELL] = "dell", - [STAC_INTEL_MAC_V1] = "intel-mac-v1", - [STAC_INTEL_MAC_V2] = "intel-mac-v2", - [STAC_INTEL_MAC_V3] = "intel-mac-v3", - [STAC_INTEL_MAC_V4] = "intel-mac-v4", - [STAC_INTEL_MAC_V5] = "intel-mac-v5", - /* for backward compitability */ [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", [STAC_IMAC_INTEL] = "imac-intel", - [STAC_IMAC_INTEL_20] = "imac-intel-20", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -689,10 +649,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { /* other systems */ /* Apple Mac Mini (early 2006) */ SND_PCI_QUIRK(0x8384, 0x7680, - "Mac Mini", STAC_INTEL_MAC_V3), - /* Dell */ - SND_PCI_QUIRK(0x1028, 0x01d7, "Dell XPS M1210", STAC_922X_DELL), - + "Mac Mini", STAC_MACMINI), {} /* terminator */ }; @@ -773,8 +730,7 @@ static unsigned int ref9205_pin_configs[12] = { }; static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { - [STAC_REF] = ref9205_pin_configs, - [STAC_M43xx] = NULL, + ref9205_pin_configs, }; static const char *stac9205_models[STAC_9205_MODELS] = { @@ -785,10 +741,6 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01f8, - "Dell Precision", STAC_M43xx), - SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x01ff, - "Dell Precision", STAC_M43xx), {} /* terminator */ }; @@ -818,56 +770,33 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec) return 0; } -static void stac92xx_set_config_reg(struct hda_codec *codec, - hda_nid_t pin_nid, unsigned int pin_config) -{ - int i; - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, - pin_config & 0x000000ff); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, - (pin_config & 0x0000ff00) >> 8); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, - (pin_config & 0x00ff0000) >> 16); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, - pin_config >> 24); - i = snd_hda_codec_read(codec, pin_nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, - 0x00); - snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", - pin_nid, i); -} - static void stac92xx_set_config_regs(struct hda_codec *codec) { int i; struct sigmatel_spec *spec = codec->spec; + unsigned int pin_cfg; - if (!spec->pin_configs) - return; - - for (i = 0; i < spec->num_pins; i++) - stac92xx_set_config_reg(codec, spec->pin_nids[i], - spec->pin_configs[i]); -} + if (! spec->pin_nids || ! spec->pin_configs) + return; -static void stac92xx_enable_gpio_mask(struct hda_codec *codec, - int gpio_mask, int gpio_data) -{ - /* Configure GPIOx as output */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpio_mask); - /* Configure GPIOx as CMOS */ - snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); - /* Assert GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, gpio_data); - /* Enable GPIOx */ - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, gpio_mask); + for (i = 0; i < spec->num_pins; i++) { + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, + spec->pin_configs[i] & 0x000000ff); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, + (spec->pin_configs[i] & 0x0000ff00) >> 8); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, + (spec->pin_configs[i] & 0x00ff0000) >> 16); + snd_hda_codec_write(codec, spec->pin_nids[i], 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + spec->pin_configs[i] >> 24); + pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg); + } } /* @@ -1239,7 +1168,7 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) * and 9202/925x. For those, dac_nids[] must be hard-coded. */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, - struct auto_pin_cfg *cfg) + const struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; int i, j, conn_len = 0; @@ -1264,13 +1193,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, } if (j == conn_len) { - if (spec->multiout.num_dacs > 0) { - /* we have already working output pins, - * so let's drop the broken ones again - */ - cfg->line_outs = spec->multiout.num_dacs; - break; - } /* error out, no available DAC found */ snd_printk(KERN_ERR "%s: No available DAC for pin 0x%x\n", @@ -1412,15 +1334,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, continue; add_spec_dacs(spec, nid); } - for (i = 0; i < cfg->line_outs; i++) { - nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - if (check_in_dac_nids(spec, nid)) - nid = 0; - if (! nid) - continue; - add_spec_dacs(spec, nid); - } + for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { static const char *pfxs[] = { "Speaker", "External Speaker", "Speaker2", @@ -1977,7 +1891,7 @@ static int patch_stac9200(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); + spec->num_pins = 8; spec->pin_nids = stac9200_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, stac9200_models, @@ -2027,7 +1941,7 @@ static int patch_stac925x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); + spec->num_pins = 8; spec->pin_nids = stac925x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, stac925x_models, @@ -2099,41 +2013,29 @@ static int patch_stac922x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); + spec->num_pins = 10; spec->pin_nids = stac922x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, stac922x_models, stac922x_cfg_tbl); - if (spec->board_config == STAC_INTEL_MAC_V3) { + if (spec->board_config == STAC_MACMINI) { spec->gpio_mute = 1; /* Intel Macs have all same PCI SSID, so we need to check * codec SSID to distinguish the exact models */ printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { - - case 0x106b0800: - spec->board_config = STAC_INTEL_MAC_V1; - break; - case 0x106b0600: - case 0x106b0700: - spec->board_config = STAC_INTEL_MAC_V2; + case 0x106b0a00: /* MacBook First generatoin */ + spec->board_config = STAC_MACBOOK; break; - case 0x106b0e00: - case 0x106b0f00: - case 0x106b1600: - case 0x106b1700: - case 0x106b0200: - case 0x106b1e00: - spec->board_config = STAC_INTEL_MAC_V3; + case 0x106b0200: /* MacBook Pro first generation */ + spec->board_config = STAC_MACBOOK_PRO_V1; break; - case 0x106b1a00: - case 0x00000100: - spec->board_config = STAC_INTEL_MAC_V4; + case 0x106b1e00: /* MacBook Pro second generation */ + spec->board_config = STAC_MACBOOK_PRO_V2; break; - case 0x106b0a00: - case 0x106b2200: - spec->board_config = STAC_INTEL_MAC_V5; + case 0x106b0700: /* Intel-based iMac */ + spec->board_config = STAC_IMAC_INTEL; break; } } @@ -2180,13 +2082,6 @@ static int patch_stac922x(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; - /* Fix Mux capture level; max to 2 */ - snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, - (0 << AC_AMPCAP_OFFSET_SHIFT) | - (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | - (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | - (0 << AC_AMPCAP_MUTE_SHIFT)); - return 0; } @@ -2200,7 +2095,7 @@ static int patch_stac927x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); + spec->num_pins = 14; spec->pin_nids = stac927x_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, stac927x_models, @@ -2246,9 +2141,7 @@ static int patch_stac927x(struct hda_codec *codec) } spec->multiout.dac_nids = spec->dac_nids; - /* GPIO0 High = Enable EAPD */ - stac92xx_enable_gpio_mask(codec, 0x00000001, 0x00000001); - + err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); if (!err) { if (spec->board_config < 0) { @@ -2266,20 +2159,27 @@ static int patch_stac927x(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; + /* Fix Mux capture level; max to 2 */ + snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, + (0 << AC_AMPCAP_OFFSET_SHIFT) | + (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (0 << AC_AMPCAP_MUTE_SHIFT)); + return 0; } static int patch_stac9205(struct hda_codec *codec) { struct sigmatel_spec *spec; - int err, gpio_mask, gpio_data; + int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; codec->spec = spec; - spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); + spec->num_pins = 14; spec->pin_nids = stac9205_pin_nids; spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, stac9205_models, @@ -2309,21 +2209,19 @@ static int patch_stac9205(struct hda_codec *codec) spec->mixer = stac9205_mixer; spec->multiout.dac_nids = spec->dac_nids; - - if (spec->board_config == STAC_M43xx) { - /* Enable SPDIF in/out */ - stac92xx_set_config_reg(codec, 0x1f, 0x01441030); - stac92xx_set_config_reg(codec, 0x20, 0x1c410030); - - gpio_mask = 0x00000007; /* GPIO0-2 */ - /* GPIO0 High = EAPD, GPIO1 Low = DRM, - * GPIO2 High = Headphone Mute - */ - gpio_data = 0x00000005; - } else - gpio_mask = gpio_data = 0x00000001; /* GPIO0 High = EAPD */ - stac92xx_enable_gpio_mask(codec, gpio_mask, gpio_data); + /* Configure GPIO0 as EAPD output */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DIRECTION, 0x00000001); + /* Configure GPIO0 as CMOS */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000); + /* Assert GPIO0 high */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DATA, 0x00000001); + /* Enable GPIO0 */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_MASK, 0x00000001); + err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); if (!err) { if (spec->board_config < 0) { @@ -2358,8 +2256,8 @@ static struct hda_input_mux vaio_mux = { .num_items = 2, .items = { /* { "HP", 0x0 }, */ - { "Mic Jack", 0x1 }, - { "Internal Mic", 0x2 }, + { "Line", 0x1 }, + { "Mic", 0x2 }, { "PCM", 0x3 }, } }; @@ -2370,7 +2268,7 @@ static struct hda_verb vaio_init[] = { {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ @@ -2386,7 +2284,7 @@ static struct hda_verb vaio_ar_init[] = { {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x2}, /* mic-sel: 0a,0d,14,02 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ diff --git a/trunk/sound/pci/ice1712/revo.c b/trunk/sound/pci/ice1712/revo.c index d18a31e188a9..690ceb340644 100644 --- a/trunk/sound/pci/ice1712/revo.c +++ b/trunk/sound/pci/ice1712/revo.c @@ -186,12 +186,7 @@ static int revo51_i2c_init(struct snd_ice1712 *ice, #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } static const struct snd_akm4xxx_dac_channel revo71_front[] = { - { - .name = "PCM Playback Volume", - .num_channels = 2, - /* front channels DAC supports muting */ - .switch_name = "PCM Playback Switch", - }, + AK_DAC("PCM Playback Volume", 2) }; static const struct snd_akm4xxx_dac_channel revo71_surround[] = { diff --git a/trunk/sound/pci/nm256/nm256.c b/trunk/sound/pci/nm256/nm256.c index c7621bd770a6..03b3a4792f73 100644 --- a/trunk/sound/pci/nm256/nm256.c +++ b/trunk/sound/pci/nm256/nm256.c @@ -1533,8 +1533,7 @@ snd_nm256_create(struct snd_card *card, struct pci_dev *pci, printk(KERN_ERR " force the driver to load by " "passing in the module parameter\n"); printk(KERN_ERR " force_ac97=1\n"); - printk(KERN_ERR " or try sb16, opl3sa2, or " - "cs423x drivers instead.\n"); + printk(KERN_ERR " or try sb16 or cs423x drivers instead.\n"); err = -ENXIO; goto __error; } diff --git a/trunk/sound/pci/rme9652/rme9652.c b/trunk/sound/pci/rme9652/rme9652.c index 2de27405a0bd..bd7dbd267ed1 100644 --- a/trunk/sound/pci/rme9652/rme9652.c +++ b/trunk/sound/pci/rme9652/rme9652.c @@ -406,7 +406,7 @@ static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652) } else if (!frag) return 0; offset -= rme9652->max_jitter; - if ((int)offset < 0) + if (offset < 0) offset += period_size * 2; } else { if (offset > period_size + rme9652->max_jitter) { diff --git a/trunk/sound/pci/via82xx.c b/trunk/sound/pci/via82xx.c index 6ea09df0c73a..50c9f92cfd1b 100644 --- a/trunk/sound/pci/via82xx.c +++ b/trunk/sound/pci/via82xx.c @@ -2098,7 +2098,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -2117,7 +2117,7 @@ static int snd_via82xx_chip_init(struct via82xx *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/trunk/sound/pci/via82xx_modem.c b/trunk/sound/pci/via82xx_modem.c index 72425e73abae..8cbf8eba4ae9 100644 --- a/trunk/sound/pci/via82xx_modem.c +++ b/trunk/sound/pci/via82xx_modem.c @@ -983,7 +983,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ break; - schedule_timeout(1); + schedule_timeout_uninterruptible(1); } while (time_before(jiffies, end_time)); if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) @@ -1001,7 +1001,7 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip) chip->ac97_secondary = 1; goto __ac97_ok2; } - schedule_timeout(1); + schedule_timeout_interruptible(1); } while (time_before(jiffies, end_time)); /* This is ok, the most of motherboards have only one codec */ diff --git a/trunk/sound/ppc/Kconfig b/trunk/sound/ppc/Kconfig index cacb0b136883..a3fb1496e4dc 100644 --- a/trunk/sound/ppc/Kconfig +++ b/trunk/sound/ppc/Kconfig @@ -33,23 +33,3 @@ config SND_POWERMAC_AUTO_DRC option. endmenu - -menu "ALSA PowerPC devices" - depends on SND!=n && ( PPC64 || PPC32 ) - -config SND_PS3 - tristate "PS3 Audio support" - depends on SND && PS3_PS3AV - select SND_PCM - default m - help - Say Y here to include support for audio on the PS3 - - To compile this driver as a module, choose M here: the module - will be called snd_ps3. - -config SND_PS3_DEFAULT_START_DELAY - int "Startup delay time in ms" - depends on SND_PS3 - default "2000" -endmenu diff --git a/trunk/sound/ppc/Makefile b/trunk/sound/ppc/Makefile index eacee2d0675c..4d95c652c8ca 100644 --- a/trunk/sound/ppc/Makefile +++ b/trunk/sound/ppc/Makefile @@ -6,5 +6,4 @@ snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o # Toplevel Module Dependency -obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o -obj-$(CONFIG_SND_PS3) += snd_ps3.o +obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o diff --git a/trunk/sound/ppc/snd_ps3.c b/trunk/sound/ppc/snd_ps3.c deleted file mode 100644 index 1aa0b467599f..000000000000 --- a/trunk/sound/ppc/snd_ps3.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * All rights reserved. - * Copyright 2006, 2007 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the Licence. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "snd_ps3_reg.h" -#include "snd_ps3.h" - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("PS3 sound driver"); -MODULE_AUTHOR("Sony Computer Entertainment Inc."); - -/* module entries */ -static int __init snd_ps3_init(void); -static void __exit snd_ps3_exit(void); - -/* ALSA snd driver ops */ -static int snd_ps3_pcm_open(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_close(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream); -static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, - int cmd); -static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream - *substream); -static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params); -static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream); - - -/* ps3_system_bus_driver entries */ -static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev); -static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev); - -/* address setup */ -static int snd_ps3_map_mmio(void); -static void snd_ps3_unmap_mmio(void); -static int snd_ps3_allocate_irq(void); -static void snd_ps3_free_irq(void); -static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); - -/* interrupt handler */ -static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id); - - -/* set sampling rate/format */ -static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream); -/* take effect parameter change */ -static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card); -/* initialize avsetting and take it effect */ -static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card); -/* setup dma */ -static int snd_ps3_program_dma(struct snd_ps3_card_info *card, - enum snd_ps3_dma_filltype filltype); -static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card); - -static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch); - - -module_init(snd_ps3_init); -module_exit(snd_ps3_exit); - -/* - * global - */ -static struct snd_ps3_card_info the_card; - -static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; - -module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); -MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); - -static int index = SNDRV_DEFAULT_IDX1; -static char *id = SNDRV_DEFAULT_STR1; - -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for PS3 soundchip."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for PS3 soundchip."); - - -/* - * PS3 audio register access - */ -static inline u32 read_reg(unsigned int reg) -{ - return in_be32(the_card.mapped_mmio_vaddr + reg); -} -static inline void write_reg(unsigned int reg, u32 val) -{ - out_be32(the_card.mapped_mmio_vaddr + reg, val); -} -static inline void update_reg(unsigned int reg, u32 or_val) -{ - u32 newval = read_reg(reg) | or_val; - write_reg(reg, newval); -} -static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val) -{ - u32 newval = (read_reg(reg) & mask) | or_val; - write_reg(reg, newval); -} - -/* - * ALSA defs - */ -const static struct snd_pcm_hardware snd_ps3_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_NONINTERLEAVED | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = (SNDRV_PCM_FMTBIT_S16_BE | - SNDRV_PCM_FMTBIT_S24_BE), - .rates = (SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000), - .rate_min = 44100, - .rate_max = 96000, - - .channels_min = 2, /* stereo only */ - .channels_max = 2, - - .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64, - - /* interrupt by four stages */ - .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4, - .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4, - - .periods_min = 16, - .periods_max = 32, /* buffer_size_max/ period_bytes_max */ - - .fifo_size = PS3_AUDIO_FIFO_SIZE -}; - -static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = -{ - .open = snd_ps3_pcm_open, - .close = snd_ps3_pcm_close, - .prepare = snd_ps3_pcm_prepare, - .ioctl = snd_pcm_lib_ioctl, - .trigger = snd_ps3_pcm_trigger, - .pointer = snd_ps3_pcm_pointer, - .hw_params = snd_ps3_pcm_hw_params, - .hw_free = snd_ps3_pcm_hw_free -}; - -static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, - int count, int force_stop) -{ - int dma_ch, done, retries, stop_forced = 0; - uint32_t status; - - for (dma_ch = 0; dma_ch < 8; dma_ch ++) { - retries = count; - do { - status = read_reg(PS3_AUDIO_KICK(dma_ch)) & - PS3_AUDIO_KICK_STATUS_MASK; - switch (status) { - case PS3_AUDIO_KICK_STATUS_DONE: - case PS3_AUDIO_KICK_STATUS_NOTIFY: - case PS3_AUDIO_KICK_STATUS_CLEAR: - case PS3_AUDIO_KICK_STATUS_ERROR: - done = 1; - break; - default: - done = 0; - udelay(10); - } - } while (!done && --retries); - if (!retries && force_stop) { - pr_info("%s: DMA ch %d is not stopped.", - __func__, dma_ch); - /* last resort. force to stop dma. - * NOTE: this cause DMA done interrupts - */ - update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR); - stop_forced = 1; - } - } - return stop_forced; -} - -/* - * wait for all dma is done. - * NOTE: caller should reset card->running before call. - * If not, the interrupt handler will re-start DMA, - * then DMA is never stopped. - */ -static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card) -{ - int stop_forced; - /* - * wait for the last dma is done - */ - - /* - * expected maximum DMA done time is 5.7ms + something (DMA itself). - * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next - * DMA kick event would occur. - */ - stop_forced = snd_ps3_verify_dma_stop(card, 700, 1); - - /* - * clear outstanding interrupts. - */ - update_reg(PS3_AUDIO_INTR_0, 0); - update_reg(PS3_AUDIO_AX_IS, 0); - - /* - *revert CLEAR bit since it will not reset automatically after DMA stop - */ - if (stop_forced) - update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0); - /* ensure the hardware sees changes */ - wmb(); -} - -static void snd_ps3_kick_dma(struct snd_ps3_card_info *card) -{ - - update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST); - /* ensure the hardware sees the change */ - wmb(); -} - -/* - * convert virtual addr to ioif bus addr. - */ -static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, - void * paddr, - int ch) -{ - return card->dma_start_bus_addr[ch] + - (paddr - card->dma_start_vaddr[ch]); -}; - - -/* - * increment ring buffer pointer. - * NOTE: caller must hold write spinlock - */ -static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card, - enum snd_ps3_ch ch, size_t byte_count, - int stage) -{ - if (!stage) - card->dma_last_transfer_vaddr[ch] = - card->dma_next_transfer_vaddr[ch]; - card->dma_next_transfer_vaddr[ch] += byte_count; - if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <= - card->dma_next_transfer_vaddr[ch]) { - card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch]; - } -} -/* - * setup dmac to send data to audio and attenuate samples on the ring buffer - */ -static int snd_ps3_program_dma(struct snd_ps3_card_info *card, - enum snd_ps3_dma_filltype filltype) -{ - /* this dmac does not support over 4G */ - uint32_t dma_addr; - int fill_stages, dma_ch, stage; - enum snd_ps3_ch ch; - uint32_t ch0_kick_event = 0; /* initialize to mute gcc */ - void *start_vaddr; - unsigned long irqsave; - int silent = 0; - - switch (filltype) { - case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL: - silent = 1; - /* intentionally fall thru */ - case SND_PS3_DMA_FILLTYPE_FIRSTFILL: - ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS; - break; - - case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING: - silent = 1; - /* intentionally fall thru */ - case SND_PS3_DMA_FILLTYPE_RUNNING: - ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY; - break; - } - - snd_ps3_verify_dma_stop(card, 700, 0); - fill_stages = 4; - spin_lock_irqsave(&card->dma_lock, irqsave); - for (ch = 0; ch < 2; ch++) { - start_vaddr = card->dma_next_transfer_vaddr[0]; - for (stage = 0; stage < fill_stages; stage ++) { - dma_ch = stage * 2 + ch; - if (silent) - dma_addr = card->null_buffer_start_dma_addr; - else - dma_addr = - v_to_bus(card, - card->dma_next_transfer_vaddr[ch], - ch); - - write_reg(PS3_AUDIO_SOURCE(dma_ch), - (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY | - dma_addr)); - - /* dst: fixed to 3wire#0 */ - if (ch == 0) - write_reg(PS3_AUDIO_DEST(dma_ch), - (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | - PS3_AUDIO_AO_3W_LDATA(0))); - else - write_reg(PS3_AUDIO_DEST(dma_ch), - (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | - PS3_AUDIO_AO_3W_RDATA(0))); - - /* count always 1 DMA block (1/2 stage = 128 bytes) */ - write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0); - /* bump pointer if needed */ - if (!silent) - snd_ps3_bump_buffer(card, ch, - PS3_AUDIO_DMAC_BLOCK_SIZE, - stage); - - /* kick event */ - if (dma_ch == 0) - write_reg(PS3_AUDIO_KICK(dma_ch), - ch0_kick_event); - else - write_reg(PS3_AUDIO_KICK(dma_ch), - PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch - - 1) | - PS3_AUDIO_KICK_REQUEST); - } - } - /* ensure the hardware sees the change */ - wmb(); - spin_unlock_irqrestore(&card->dma_lock, irqsave); - - return 0; -} - -/* - * audio mute on/off - * mute_on : 0 output enabled - * 1 mute - */ -static int snd_ps3_mute(int mute_on) -{ - return ps3av_audio_mute(mute_on); -} - -/* - * PCM operators - */ -static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - int pcm_index; - - pcm_index = substream->pcm->device; - /* to retrieve substream/runtime in interrupt handler */ - card->substream = substream; - - runtime->hw = snd_ps3_pcm_hw; - - card->start_delay = snd_ps3_start_delay; - - /* mute off */ - snd_ps3_mute(0); /* this function sleep */ - - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2); - return 0; -}; - -static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - size_t size; - - /* alloc transport buffer */ - size = params_buffer_bytes(hw_params); - snd_pcm_lib_malloc_pages(substream, size); - return 0; -}; - -static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, - unsigned int delay_ms) -{ - int ret; - int rate ; - - rate = substream->runtime->rate; - ret = snd_pcm_format_size(substream->runtime->format, - rate * delay_ms / 1000) - * substream->runtime->channels; - - pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", - __func__, - delay_ms, - rate, - snd_pcm_format_size(substream->runtime->format, rate), - rate * delay_ms / 1000, - ret); - - return ret; -}; - -static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - unsigned long irqsave; - - if (!snd_ps3_set_avsetting(substream)) { - /* some parameter changed */ - write_reg(PS3_AUDIO_AX_IE, - PS3_AUDIO_AX_IE_ASOBEIE(0) | - PS3_AUDIO_AX_IE_ASOBUIE(0)); - /* - * let SPDIF device re-lock with SPDIF signal, - * start with some silence - */ - card->silent = snd_ps3_delay_to_bytes(substream, - card->start_delay) / - (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */ - } - - /* restart ring buffer pointer */ - spin_lock_irqsave(&card->dma_lock, irqsave); - { - card->dma_buffer_size = runtime->dma_bytes; - - card->dma_last_transfer_vaddr[SND_PS3_CH_L] = - card->dma_next_transfer_vaddr[SND_PS3_CH_L] = - card->dma_start_vaddr[SND_PS3_CH_L] = - runtime->dma_area; - card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr; - - card->dma_last_transfer_vaddr[SND_PS3_CH_R] = - card->dma_next_transfer_vaddr[SND_PS3_CH_R] = - card->dma_start_vaddr[SND_PS3_CH_R] = - runtime->dma_area + (runtime->dma_bytes / 2); - card->dma_start_bus_addr[SND_PS3_CH_R] = - runtime->dma_addr + (runtime->dma_bytes / 2); - - pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, - card->dma_start_vaddr[SND_PS3_CH_L], - card->dma_start_bus_addr[SND_PS3_CH_L]); - - } - spin_unlock_irqrestore(&card->dma_lock, irqsave); - - /* ensure the hardware sees the change */ - mb(); - - return 0; -}; - -static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* clear outstanding interrupts */ - update_reg(PS3_AUDIO_AX_IS, 0); - - spin_lock(&card->dma_lock); - { - card->running = 1; - } - spin_unlock(&card->dma_lock); - - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - while (read_reg(PS3_AUDIO_KICK(7)) & - PS3_AUDIO_KICK_STATUS_MASK) { - udelay(1); - } - snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); - snd_ps3_kick_dma(card); - break; - - case SNDRV_PCM_TRIGGER_STOP: - spin_lock(&card->dma_lock); - { - card->running = 0; - } - spin_unlock(&card->dma_lock); - snd_ps3_wait_for_dma_stop(card); - break; - default: - break; - - } - - return ret; -}; - -/* - * report current pointer - */ -static snd_pcm_uframes_t snd_ps3_pcm_pointer( - struct snd_pcm_substream *substream) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - size_t bytes; - snd_pcm_uframes_t ret; - - spin_lock(&card->dma_lock); - { - bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] - - card->dma_start_vaddr[SND_PS3_CH_L]); - } - spin_unlock(&card->dma_lock); - - ret = bytes_to_frames(substream->runtime, bytes * 2); - - return ret; -}; - -static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) -{ - int ret; - ret = snd_pcm_lib_free_pages(substream); - return ret; -}; - -static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) -{ - /* mute on */ - snd_ps3_mute(1); - return 0; -}; - -static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) -{ - /* - * avsetting driver seems to never change the followings - * so, init them here once - */ - - /* no dma interrupt needed */ - write_reg(PS3_AUDIO_INTR_EN_0, 0); - - /* use every 4 buffer empty interrupt */ - update_mask_reg(PS3_AUDIO_AX_IC, - PS3_AUDIO_AX_IC_AASOIMD_MASK, - PS3_AUDIO_AX_IC_AASOIMD_EVERY4); - - /* enable 3wire clocks */ - update_mask_reg(PS3_AUDIO_AO_3WMCTRL, - ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | - PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), - 0); - update_reg(PS3_AUDIO_AO_3WMCTRL, - PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); -} - -/* - * av setting - * NOTE: calling this function may generate audio interrupt. - */ -static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) -{ - int ret, retries, i; - pr_debug("%s: start\n", __func__); - - ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, - card->avs.avs_audio_rate, - card->avs.avs_audio_width, - card->avs.avs_audio_format, - card->avs.avs_audio_source); - /* - * Reset the following unwanted settings: - */ - - /* disable all 3wire buffers */ - update_mask_reg(PS3_AUDIO_AO_3WMCTRL, - ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | - PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), - 0); - wmb(); /* ensure the hardware sees the change */ - /* wait for actually stopped */ - retries = 1000; - while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & - (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | - PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && - --retries) { - udelay(1); - } - - /* reset buffer pointer */ - for (i = 0; i < 4; i++) { - update_reg(PS3_AUDIO_AO_3WCTRL(i), - PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); - udelay(10); - } - wmb(); /* ensure the hardware actually start resetting */ - - /* enable 3wire#0 buffer */ - update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); - - - /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ - update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), - ~PS3_AUDIO_AO_3WCTRL_ASODF, - PS3_AUDIO_AO_3WCTRL_ASODF_LSB); - update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), - ~PS3_AUDIO_AO_SPDCTRL_SPODF, - PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); - /* ensure all the setting above is written back to register */ - wmb(); - /* avsetting driver altered AX_IE, caller must reset it if you want */ - pr_debug("%s: end\n", __func__); - return ret; -} - -static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) -{ - int ret; - pr_debug("%s: start\n", __func__); - card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; - card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; - card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; - card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; - card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; - - ret = snd_ps3_change_avsetting(card); - - snd_ps3_audio_fixup(card); - - /* to start to generate SPDIF signal, fill data */ - snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - pr_debug("%s: end\n", __func__); - return ret; -} - -/* - * set sampling rate according to the substream - */ -static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) -{ - struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); - struct snd_ps3_avsetting_info avs; - - avs = card->avs; - - pr_debug("%s: called freq=%d width=%d\n", __func__, - substream->runtime->rate, - snd_pcm_format_width(substream->runtime->format)); - - pr_debug("%s: before freq=%d width=%d\n", __func__, - card->avs.avs_audio_rate, card->avs.avs_audio_width); - - /* sample rate */ - switch (substream->runtime->rate) { - case 44100: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; - break; - case 48000: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; - break; - case 88200: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; - break; - case 96000: - avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; - break; - default: - pr_info("%s: invalid rate %d\n", __func__, - substream->runtime->rate); - return 1; - } - - /* width */ - switch (snd_pcm_format_width(substream->runtime->format)) { - case 16: - avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; - break; - case 24: - avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; - break; - default: - pr_info("%s: invalid width %d\n", __func__, - snd_pcm_format_width(substream->runtime->format)); - return 1; - } - - if ((card->avs.avs_audio_width != avs.avs_audio_width) || - (card->avs.avs_audio_rate != avs.avs_audio_rate)) { - card->avs = avs; - snd_ps3_change_avsetting(card); - - pr_debug("%s: after freq=%d width=%d\n", __func__, - card->avs.avs_audio_rate, card->avs.avs_audio_width); - - return 0; - } else - return 1; -} - - - -static int snd_ps3_map_mmio(void) -{ - the_card.mapped_mmio_vaddr = - ioremap(the_card.ps3_dev->m_region->bus_addr, - the_card.ps3_dev->m_region->len); - - if (!the_card.mapped_mmio_vaddr) { - pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n", - __func__, the_card.ps3_dev->m_region->lpar_addr, - the_card.ps3_dev->m_region->len); - return -ENXIO; - } - - return 0; -}; - -static void snd_ps3_unmap_mmio(void) -{ - iounmap(the_card.mapped_mmio_vaddr); - the_card.mapped_mmio_vaddr = NULL; -} - -static int snd_ps3_allocate_irq(void) -{ - int ret; - u64 lpar_addr, lpar_size; - u64 __iomem *mapped; - - /* FIXME: move this to device_init (H/W probe) */ - - /* get irq outlet */ - ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size); - if (ret) { - pr_info("%s: device map 1 failed %d\n", __func__, - ret); - return -ENXIO; - } - - mapped = ioremap(lpar_addr, lpar_size); - if (!mapped) { - pr_info("%s: ioremap 1 failed \n", __func__); - return -ENXIO; - } - - the_card.audio_irq_outlet = in_be64(mapped); - - iounmap(mapped); - ret = lv1_gpu_device_unmap(1); - if (ret) - pr_info("%s: unmap 1 failed\n", __func__); - - /* irq */ - ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, - the_card.audio_irq_outlet, - &the_card.irq_no); - if (ret) { - pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret); - return ret; - } - - ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, - SND_PS3_DRIVER_NAME, &the_card); - if (ret) { - pr_info("%s: request_irq failed (%d)\n", __func__, ret); - goto cleanup_irq; - } - - return 0; - - cleanup_irq: - ps3_irq_plug_destroy(the_card.irq_no); - return ret; -}; - -static void snd_ps3_free_irq(void) -{ - free_irq(the_card.irq_no, &the_card); - ps3_irq_plug_destroy(the_card.irq_no); -} - -static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) -{ - uint64_t val; - int ret; - - val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) | - (0x03UL << 24) | - (0x0fUL << 12) | - (PS3_AUDIO_IOID); - - ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); - if (ret) - pr_info("%s: gpu_attribute failed %d\n", __func__, - ret); -} - -static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) -{ - int ret; - u64 lpar_addr, lpar_size; - - BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); - BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND); - - the_card.ps3_dev = dev; - - ret = ps3_open_hv_device(dev); - - if (ret) - return -ENXIO; - - /* setup MMIO */ - ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size); - if (ret) { - pr_info("%s: device map 2 failed %d\n", __func__, ret); - goto clean_open; - } - ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size, - PAGE_SHIFT); - - ret = snd_ps3_map_mmio(); - if (ret) - goto clean_dev_map; - - /* setup DMA area */ - ps3_dma_region_init(dev, dev->d_region, - PAGE_SHIFT, /* use system page size */ - 0, /* dma type; not used */ - NULL, - _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE)); - dev->d_region->ioid = PS3_AUDIO_IOID; - - ret = ps3_dma_region_create(dev->d_region); - if (ret) { - pr_info("%s: region_create\n", __func__); - goto clean_mmio; - } - - snd_ps3_audio_set_base_addr(dev->d_region->bus_addr); - - /* CONFIG_SND_PS3_DEFAULT_START_DELAY */ - the_card.start_delay = snd_ps3_start_delay; - - /* irq */ - if (snd_ps3_allocate_irq()) { - ret = -ENXIO; - goto clean_dma_region; - } - - /* create card instance */ - the_card.card = snd_card_new(index, id, THIS_MODULE, 0); - if (!the_card.card) { - ret = -ENXIO; - goto clean_irq; - } - - strcpy(the_card.card->driver, "PS3"); - strcpy(the_card.card->shortname, "PS3"); - strcpy(the_card.card->longname, "PS3 sound"); - /* create PCM devices instance */ - /* NOTE:this driver works assuming pcm:substream = 1:1 */ - ret = snd_pcm_new(the_card.card, - "SPDIF", - 0, /* instance index, will be stored pcm.device*/ - 1, /* output substream */ - 0, /* input substream */ - &(the_card.pcm)); - if (ret) - goto clean_card; - - the_card.pcm->private_data = &the_card; - strcpy(the_card.pcm->name, "SPDIF"); - - /* set pcm ops */ - snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_ps3_pcm_spdif_ops); - - the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED; - /* pre-alloc PCM DMA buffer*/ - ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm, - SNDRV_DMA_TYPE_DEV, - &dev->core, - SND_PS3_PCM_PREALLOC_SIZE, - SND_PS3_PCM_PREALLOC_SIZE); - if (ret < 0) { - pr_info("%s: prealloc failed\n", __func__); - goto clean_card; - } - - /* - * allocate null buffer - * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 - * PAGE_SIZE is enogh - */ - if (!(the_card.null_buffer_start_vaddr = - dma_alloc_coherent(&the_card.ps3_dev->core, - PAGE_SIZE, - &the_card.null_buffer_start_dma_addr, - GFP_KERNEL))) { - pr_info("%s: nullbuffer alloc failed\n", __func__); - goto clean_preallocate; - } - pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); - /* set default sample rate/word width */ - snd_ps3_init_avsetting(&the_card); - - /* register the card */ - ret = snd_card_register(the_card.card); - if (ret < 0) - goto clean_dma_map; - - pr_info("%s started. start_delay=%dms\n", - the_card.card->longname, the_card.start_delay); - return 0; - -clean_dma_map: - dma_free_coherent(&the_card.ps3_dev->core, - PAGE_SIZE, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); -clean_preallocate: - snd_pcm_lib_preallocate_free_for_all(the_card.pcm); -clean_card: - snd_card_free(the_card.card); -clean_irq: - snd_ps3_free_irq(); -clean_dma_region: - ps3_dma_region_free(dev->d_region); -clean_mmio: - snd_ps3_unmap_mmio(); -clean_dev_map: - lv1_gpu_device_unmap(2); -clean_open: - ps3_close_hv_device(dev); - /* - * there is no destructor function to pcm. - * midlayer automatically releases if the card removed - */ - return ret; -}; /* snd_ps3_probe */ - -/* called when module removal */ -static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev) -{ - int ret; - pr_info("%s:start id=%d\n", __func__, dev->match_id); - if (dev->match_id != PS3_MATCH_ID_SOUND) - return -ENXIO; - - /* - * ctl and preallocate buffer will be freed in - * snd_card_free - */ - ret = snd_card_free(the_card.card); - if (ret) - pr_info("%s: ctl freecard=%d\n", __func__, ret); - - dma_free_coherent(&dev->core, - PAGE_SIZE, - the_card.null_buffer_start_vaddr, - the_card.null_buffer_start_dma_addr); - - ps3_dma_region_free(dev->d_region); - - snd_ps3_free_irq(); - snd_ps3_unmap_mmio(); - - lv1_gpu_device_unmap(2); - ps3_close_hv_device(dev); - pr_info("%s:end id=%d\n", __func__, dev->match_id); - return 0; -} /* snd_ps3_remove */ - -static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { - .match_id = PS3_MATCH_ID_SOUND, - .probe = snd_ps3_driver_probe, - .remove = snd_ps3_driver_remove, - .shutdown = snd_ps3_driver_remove, - .core = { - .name = SND_PS3_DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - - -/* - * Interrupt handler - */ -static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) -{ - - uint32_t port_intr; - int underflow_occured = 0; - struct snd_ps3_card_info *card = dev_id; - - if (!card->running) { - update_reg(PS3_AUDIO_AX_IS, 0); - update_reg(PS3_AUDIO_INTR_0, 0); - return IRQ_HANDLED; - } - - port_intr = read_reg(PS3_AUDIO_AX_IS); - /* - *serial buffer empty detected (every 4 times), - *program next dma and kick it - */ - if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { - write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); - if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { - write_reg(PS3_AUDIO_AX_IS, port_intr); - underflow_occured = 1; - } - if (card->silent) { - /* we are still in silent time */ - snd_ps3_program_dma(card, - (underflow_occured) ? - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : - SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); - snd_ps3_kick_dma(card); - card->silent --; - } else { - snd_ps3_program_dma(card, - (underflow_occured) ? - SND_PS3_DMA_FILLTYPE_FIRSTFILL : - SND_PS3_DMA_FILLTYPE_RUNNING); - snd_ps3_kick_dma(card); - snd_pcm_period_elapsed(card->substream); - } - } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { - write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); - /* - * serial out underflow, but buffer empty not detected. - * in this case, fill fifo with 0 to recover. After - * filling dummy data, serial automatically start to - * consume them and then will generate normal buffer - * empty interrupts. - * If both buffer underflow and buffer empty are occured, - * it is better to do nomal data transfer than empty one - */ - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - snd_ps3_program_dma(card, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); - snd_ps3_kick_dma(card); - } - /* clear interrupt cause */ - return IRQ_HANDLED; -}; - -/* - * module/subsystem initialize/terminate - */ -static int __init snd_ps3_init(void) -{ - int ret; - - if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return -ENXIO; - - memset(&the_card, 0, sizeof(the_card)); - spin_lock_init(&the_card.dma_lock); - - /* register systembus DRIVER, this calls our probe() func */ - ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info); - - return ret; -} - -static void __exit snd_ps3_exit(void) -{ - ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); -} - -MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); diff --git a/trunk/sound/ppc/snd_ps3.h b/trunk/sound/ppc/snd_ps3.h deleted file mode 100644 index 4b7e6fbbe500..000000000000 --- a/trunk/sound/ppc/snd_ps3.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * All rights reserved. - * Copyright 2006, 2007 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the Licence. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if !defined(_SND_PS3_H_) -#define _SND_PS3_H_ - -#include - -#define SND_PS3_DRIVER_NAME "snd_ps3" - -enum snd_ps3_out_channel { - SND_PS3_OUT_SPDIF_0, - SND_PS3_OUT_SPDIF_1, - SND_PS3_OUT_SERIAL_0, - SND_PS3_OUT_DEVS -}; - -enum snd_ps3_dma_filltype { - SND_PS3_DMA_FILLTYPE_FIRSTFILL, - SND_PS3_DMA_FILLTYPE_RUNNING, - SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL, - SND_PS3_DMA_FILLTYPE_SILENT_RUNNING -}; - -enum snd_ps3_ch { - SND_PS3_CH_L = 0, - SND_PS3_CH_R = 1, - SND_PS3_CH_MAX = 2 -}; - -struct snd_ps3_avsetting_info { - uint32_t avs_audio_ch; /* fixed */ - uint32_t avs_audio_rate; - uint32_t avs_audio_width; - uint32_t avs_audio_format; /* fixed */ - uint32_t avs_audio_source; /* fixed */ -}; -/* - * PS3 audio 'card' instance - * there should be only ONE hardware. - */ -struct snd_ps3_card_info { - struct ps3_system_bus_device *ps3_dev; - struct snd_card *card; - - struct snd_pcm *pcm; - struct snd_pcm_substream *substream; - - /* hvc info */ - u64 audio_lpar_addr; - u64 audio_lpar_size; - - /* registers */ - void __iomem *mapped_mmio_vaddr; - - /* irq */ - u64 audio_irq_outlet; - unsigned int irq_no; - - /* remember avsetting */ - struct snd_ps3_avsetting_info avs; - - /* dma buffer management */ - spinlock_t dma_lock; - /* dma_lock start */ - void * dma_start_vaddr[2]; /* 0 for L, 1 for R */ - dma_addr_t dma_start_bus_addr[2]; - size_t dma_buffer_size; - void * dma_last_transfer_vaddr[2]; - void * dma_next_transfer_vaddr[2]; - int silent; - /* dma_lock end */ - - int running; - - /* null buffer */ - void *null_buffer_start_vaddr; - dma_addr_t null_buffer_start_dma_addr; - - /* start delay */ - unsigned int start_delay; - -}; - - -/* PS3 audio DMAC block size in bytes */ -#define PS3_AUDIO_DMAC_BLOCK_SIZE (128) -/* one stage (stereo) of audio FIFO in bytes */ -#define PS3_AUDIO_FIFO_STAGE_SIZE (256) -/* how many stages the fifo have */ -#define PS3_AUDIO_FIFO_STAGE_COUNT (8) -/* fifo size 128 bytes * 8 stages * stereo (2ch) */ -#define PS3_AUDIO_FIFO_SIZE \ - (PS3_AUDIO_FIFO_STAGE_SIZE * PS3_AUDIO_FIFO_STAGE_COUNT) - -/* PS3 audio DMAC max block count in one dma shot = 128 (0x80) blocks*/ -#define PS3_AUDIO_DMAC_MAX_BLOCKS (PS3_AUDIO_DMASIZE_BLOCKS_MASK + 1) - -#define PS3_AUDIO_NORMAL_DMA_START_CH (0) -#define PS3_AUDIO_NORMAL_DMA_COUNT (8) -#define PS3_AUDIO_NULL_DMA_START_CH \ - (PS3_AUDIO_NORMAL_DMA_START_CH + PS3_AUDIO_NORMAL_DMA_COUNT) -#define PS3_AUDIO_NULL_DMA_COUNT (2) - -#define SND_PS3_MAX_VOL (0x0F) -#define SND_PS3_MIN_VOL (0x00) -#define SND_PS3_MIN_ATT SND_PS3_MIN_VOL -#define SND_PS3_MAX_ATT SND_PS3_MAX_VOL - -#define SND_PS3_PCM_PREALLOC_SIZE \ - (PS3_AUDIO_DMAC_BLOCK_SIZE * PS3_AUDIO_DMAC_MAX_BLOCKS * 4) - -#define SND_PS3_DMA_REGION_SIZE \ - (SND_PS3_PCM_PREALLOC_SIZE + PAGE_SIZE) - -#define PS3_AUDIO_IOID (1UL) - -#endif /* _SND_PS3_H_ */ diff --git a/trunk/sound/ppc/snd_ps3_reg.h b/trunk/sound/ppc/snd_ps3_reg.h deleted file mode 100644 index 03fdee4aaaf2..000000000000 --- a/trunk/sound/ppc/snd_ps3_reg.h +++ /dev/null @@ -1,891 +0,0 @@ -/* - * Audio support for PS3 - * Copyright (C) 2007 Sony Computer Entertainment Inc. - * Copyright 2006, 2007 Sony Corporation - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * interrupt / configure registers - */ - -#define PS3_AUDIO_INTR_0 (0x00000100) -#define PS3_AUDIO_INTR_EN_0 (0x00000140) -#define PS3_AUDIO_CONFIG (0x00000200) - -/* - * DMAC registers - * n:0..9 - */ -#define PS3_AUDIO_DMAC_REGBASE(x) (0x0000210 + 0x20 * (x)) - -#define PS3_AUDIO_KICK(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x00) -#define PS3_AUDIO_SOURCE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x04) -#define PS3_AUDIO_DEST(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x08) -#define PS3_AUDIO_DMASIZE(n) (PS3_AUDIO_DMAC_REGBASE(n) + 0x0C) - -/* - * mute control - */ -#define PS3_AUDIO_AX_MCTRL (0x00004000) -#define PS3_AUDIO_AX_ISBP (0x00004004) -#define PS3_AUDIO_AX_AOBP (0x00004008) -#define PS3_AUDIO_AX_IC (0x00004010) -#define PS3_AUDIO_AX_IE (0x00004014) -#define PS3_AUDIO_AX_IS (0x00004018) - -/* - * three wire serial - * n:0..3 - */ -#define PS3_AUDIO_AO_MCTRL (0x00006000) -#define PS3_AUDIO_AO_3WMCTRL (0x00006004) - -#define PS3_AUDIO_AO_3WCTRL(n) (0x00006200 + 0x200 * (n)) - -/* - * S/PDIF - * n:0..1 - * x:0..11 - * y:0..5 - */ -#define PS3_AUDIO_AO_SPD_REGBASE(n) (0x00007200 + 0x200 * (n)) - -#define PS3_AUDIO_AO_SPDCTRL(n) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x00) -#define PS3_AUDIO_AO_SPDUB(n, x) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x04 + 0x04 * (x)) -#define PS3_AUDIO_AO_SPDCS(n, y) \ - (PS3_AUDIO_AO_SPD_REGBASE(n) + 0x34 + 0x04 * (y)) - - -/* - PS3_AUDIO_INTR_0 register tells an interrupt handler which audio - DMA channel triggered the interrupt. The interrupt status for a channel - can be cleared by writing a '1' to the corresponding bit. A new interrupt - cannot be generated until the previous interrupt has been cleared. - - Note that the status reported by PS3_AUDIO_INTR_0 is independent of the - value of PS3_AUDIO_INTR_EN_0. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -#define PS3_AUDIO_INTR_0_CHAN(n) (1 << ((n) * 2)) -#define PS3_AUDIO_INTR_0_CHAN9 PS3_AUDIO_INTR_0_CHAN(9) -#define PS3_AUDIO_INTR_0_CHAN8 PS3_AUDIO_INTR_0_CHAN(8) -#define PS3_AUDIO_INTR_0_CHAN7 PS3_AUDIO_INTR_0_CHAN(7) -#define PS3_AUDIO_INTR_0_CHAN6 PS3_AUDIO_INTR_0_CHAN(6) -#define PS3_AUDIO_INTR_0_CHAN5 PS3_AUDIO_INTR_0_CHAN(5) -#define PS3_AUDIO_INTR_0_CHAN4 PS3_AUDIO_INTR_0_CHAN(4) -#define PS3_AUDIO_INTR_0_CHAN3 PS3_AUDIO_INTR_0_CHAN(3) -#define PS3_AUDIO_INTR_0_CHAN2 PS3_AUDIO_INTR_0_CHAN(2) -#define PS3_AUDIO_INTR_0_CHAN1 PS3_AUDIO_INTR_0_CHAN(1) -#define PS3_AUDIO_INTR_0_CHAN0 PS3_AUDIO_INTR_0_CHAN(0) - -/* - The PS3_AUDIO_INTR_EN_0 register specifies which DMA channels can generate - an interrupt to the PU. Each bit of PS3_AUDIO_INTR_EN_0 is ANDed with the - corresponding bit in PS3_AUDIO_INTR_0. The resulting bits are OR'd together - to generate the Audio interrupt. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C|0|C| INTR_EN_0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - - Bit assignments are same as PS3_AUDIO_INTR_0 -*/ - -/* - PS3_AUDIO_CONFIG - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 0|0 0 0 0 0 0 0 C|0 0 0 0 0 0 0 0| CONFIG - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ - -/* The CLEAR field cancels all pending transfers, and stops any running DMA - transfers. Any interrupts associated with the canceled transfers - will occur as if the transfer had finished. - Since this bit is designed to recover from DMA related issues - which are caused by unpredictable situations, it is prefered to wait - for normal DMA transfer end without using this bit. -*/ -#define PS3_AUDIO_CONFIG_CLEAR (1 << 8) /* RWIVF */ - -/* - PS3_AUDIO_AX_MCTRL: Audio Port Mute Control Register - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|A|A|0 0 0 0 0 0 0|S|S|A|A|A|A| AX_MCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* 3 Wire Audio Serial Output Channel Mutes (0..3) */ -#define PS3_AUDIO_AX_MCTRL_ASOMT(n) (1 << (3 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO3MT (1 << 0) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO2MT (1 << 1) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO1MT (1 << 2) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_ASO0MT (1 << 3) /* RWIVF */ - -/* S/PDIF mutes (0,1)*/ -#define PS3_AUDIO_AX_MCTRL_SPOMT(n) (1 << (5 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_SPO1MT (1 << 4) /* RWIVF */ -#define PS3_AUDIO_AX_MCTRL_SPO0MT (1 << 5) /* RWIVF */ - -/* All 3 Wire Serial Outputs Mute */ -#define PS3_AUDIO_AX_MCTRL_AASOMT (1 << 13) /* RWIVF */ - -/* All S/PDIF Mute */ -#define PS3_AUDIO_AX_MCTRL_ASPOMT (1 << 14) /* RWIVF */ - -/* All Audio Outputs Mute */ -#define PS3_AUDIO_AX_MCTRL_AAOMT (1 << 15) /* RWIVF */ - -/* - S/PDIF Outputs Buffer Read/Write Pointer Register - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B|0 0 0 0 0 0 0 0|0|SPO0B|0|SPO1B| AX_ISBP - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ -/* - S/PDIF Output Channel Read Buffer Numbers - Buffer number is value of field. - Indicates current read access buffer ID from Audio Data - Transfer controller of S/PDIF Output -*/ - -#define PS3_AUDIO_AX_ISBP_SPOBRN_MASK(n) (0x7 << 4 * (1 - (n))) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO1BRN_MASK (0x7 << 0) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO0BRN_MASK (0x7 << 4) /* R-IUF */ - -/* -S/PDIF Output Channel Buffer Write Numbers -Indicates current write access buffer ID from bus master. -*/ -#define PS3_AUDIO_AX_ISBP_SPOBWN_MASK(n) (0x7 << 4 * (5 - (n))) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO1BWN_MASK (0x7 << 16) /* R-IUF */ -#define PS3_AUDIO_AX_ISBP_SPO0BWN_MASK (0x7 << 20) /* R-IUF */ - -/* - 3 Wire Audio Serial Outputs Buffer Read/Write - Pointer Register - Buffer number is value of field - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B|0|ASO0B|0|ASO1B|0|ASO2B|0|ASO3B| AX_AOBP - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -3 Wire Audio Serial Output Channel Buffer Read Numbers -Indicates current read access buffer Id from Audio Data Transfer -Controller of 3 Wire Audio Serial Output Channels -*/ -#define PS3_AUDIO_AX_AOBP_ASOBRN_MASK(n) (0x7 << 4 * (3 - (n))) /* R-IUF */ - -#define PS3_AUDIO_AX_AOBP_ASO3BRN_MASK (0x7 << 0) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO2BRN_MASK (0x7 << 4) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO1BRN_MASK (0x7 << 8) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO0BRN_MASK (0x7 << 12) /* R-IUF */ - -/* -3 Wire Audio Serial Output Channel Buffer Write Numbers -Indicates current write access buffer ID from bus master. -*/ -#define PS3_AUDIO_AX_AOBP_ASOBWN_MASK(n) (0x7 << 4 * (7 - (n))) /* R-IUF */ - -#define PS3_AUDIO_AX_AOBP_ASO3BWN_MASK (0x7 << 16) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO2BWN_MASK (0x7 << 20) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO1BWN_MASK (0x7 << 24) /* R-IUF */ -#define PS3_AUDIO_AX_AOBP_ASO0BWN_MASK (0x7 << 28) /* R-IUF */ - - - -/* -Audio Port Interrupt Condition Register -For the fields in this register, the following values apply: -0 = Interrupt is generated every interrupt event. -1 = Interrupt is generated every 2 interrupt events. -2 = Interrupt is generated every 4 interrupt events. -3 = Reserved - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|0 0|SPO|0 0|SPO|0 0|AAS|0 0 0 0 0 0 0 0 0 0 0 0| AX_IC - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -All 3-Wire Audio Serial Outputs Interrupt Mode -Configures the Interrupt and Signal Notification -condition of all 3-wire Audio Serial Outputs. -*/ -#define PS3_AUDIO_AX_IC_AASOIMD_MASK (0x3 << 12) /* RWIVF */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY1 (0x0 << 12) /* RWI-V */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY2 (0x1 << 12) /* RW--V */ -#define PS3_AUDIO_AX_IC_AASOIMD_EVERY4 (0x2 << 12) /* RW--V */ - -/* -S/PDIF Output Channel Interrupt Modes -Configures the Interrupt and signal Notification -conditions of S/PDIF output channels. -*/ -#define PS3_AUDIO_AX_IC_SPO1IMD_MASK (0x3 << 16) /* RWIVF */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY1 (0x0 << 16) /* RWI-V */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY2 (0x1 << 16) /* RW--V */ -#define PS3_AUDIO_AX_IC_SPO1IMD_EVERY4 (0x2 << 16) /* RW--V */ - -#define PS3_AUDIO_AX_IC_SPO0IMD_MASK (0x3 << 20) /* RWIVF */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY1 (0x0 << 20) /* RWI-V */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY2 (0x1 << 20) /* RW--V */ -#define PS3_AUDIO_AX_IC_SPO0IMD_EVERY4 (0x2 << 20) /* RW--V */ - -/* -Audio Port interrupt Enable Register -Configures whether to enable or disable each Interrupt Generation. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ - -/* -3 Wire Audio Serial Output Channel Buffer Underflow -Interrupt Enables -Select enable/disable of Buffer Underflow Interrupts for -3-Wire Audio Serial Output Channels -DISABLED=Interrupt generation disabled. -*/ -#define PS3_AUDIO_AX_IE_ASOBUIE(n) (1 << (3 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO3BUIE (1 << 0) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO2BUIE (1 << 1) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO1BUIE (1 << 2) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO0BUIE (1 << 3) /* RWIVF */ - -/* S/PDIF Output Channel Buffer Underflow Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBUIE(n) (1 << (7 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BUIE (1 << 6) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BUIE (1 << 7) /* RWIVF */ - -/* S/PDIF Output Channel One Block Transfer Completion Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBTCIE(n) (1 << (11 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BTCIE (1 << 10) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BTCIE (1 << 11) /* RWIVF */ - -/* 3-Wire Audio Serial Output Channel Buffer Empty Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_ASOBEIE(n) (1 << (19 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO3BEIE (1 << 16) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO2BEIE (1 << 17) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO1BEIE (1 << 18) /* RWIVF */ -#define PS3_AUDIO_AX_IE_ASO0BEIE (1 << 19) /* RWIVF */ - -/* S/PDIF Output Channel Buffer Empty Interrupt Enables */ - -#define PS3_AUDIO_AX_IE_SPOBEIE(n) (1 << (23 - (n))) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO1BEIE (1 << 22) /* RWIVF */ -#define PS3_AUDIO_AX_IE_SPO0BEIE (1 << 23) /* RWIVF */ - -/* -Audio Port Interrupt Status Register -Indicates Interrupt status, which interrupt has occured, and can clear -each interrupt in this register. -Writing 1b to a field containing 1b clears field and de-asserts interrupt. -Writing 0b to a field has no effect. -Field vaules are the following: -0 - Interrupt hasn't occured. -1 - Interrupt has occured. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0|S|S|0 0|A|A|A|A|0 0 0 0|S|S|0 0|S|S|0 0|A|A|A|A| AX_IS - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - - Bit assignment are same as AX_IE -*/ - -/* -Audio Output Master Control Register -Configures Master Clock and other master Audio Output Settings - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0|SCKSE|0|SCKSE| MR0 | MR1 |MCL|MCL|0 0 0 0|0 0 0 0 0 0 0 0| AO_MCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -MCLK Output Control -Controls mclko[1] output. -0 - Disable output (fixed at High) -1 - Output clock produced by clock selected -with scksel1 by mr1 -2 - Reserved -3 - Reserved -*/ - -#define PS3_AUDIO_AO_MCTRL_MCLKC1_MASK (0x3 << 12) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_DISABLED (0x0 << 12) /* RWI-V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_ENABLED (0x1 << 12) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD2 (0x2 << 12) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC1_RESVD3 (0x3 << 12) /* RW--V */ - -/* -MCLK Output Control -Controls mclko[0] output. -0 - Disable output (fixed at High) -1 - Output clock produced by clock selected -with SCKSEL0 by MR0 -2 - Reserved -3 - Reserved -*/ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_MASK (0x3 << 14) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_DISABLED (0x0 << 14) /* RWI-V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_ENABLED (0x1 << 14) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD2 (0x2 << 14) /* RW--V */ -#define PS3_AUDIO_AO_MCTRL_MCLKC0_RESVD3 (0x3 << 14) /* RW--V */ -/* -Master Clock Rate 1 -Sets the divide ration of Master Clock1 (clock output from -mclko[1] for the input clock selected by scksel1. -*/ -#define PS3_AUDIO_AO_MCTRL_MR1_MASK (0xf << 16) -#define PS3_AUDIO_AO_MCTRL_MR1_DEFAULT (0x0 << 16) /* RWI-V */ -/* -Master Clock Rate 0 -Sets the divide ratio of Master Clock0 (clock output from -mclko[0] for the input clock selected by scksel0). -*/ -#define PS3_AUDIO_AO_MCTRL_MR0_MASK (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_MR0_DEFAULT (0x0 << 20) /* RWI-V */ -/* -System Clock Select 0/1 -Selects the system clock to be used as Master Clock 0/1 -Input the system clock that is appropriate for the sampling -rate. -*/ -#define PS3_AUDIO_AO_MCTRL_SCKSEL1_MASK (0x7 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_SCKSEL1_DEFAULT (0x2 << 24) /* RWI-V */ - -#define PS3_AUDIO_AO_MCTRL_SCKSEL0_MASK (0x7 << 28) /* RWIVF */ -#define PS3_AUDIO_AO_MCTRL_SCKSEL0_DEFAULT (0x2 << 28) /* RWI-V */ - - -/* -3-Wire Audio Output Master Control Register -Configures clock, 3-Wire Audio Serial Output Enable, and -other 3-Wire Audio Serial Output Master Settings - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |A|A|A|A|0 0 0|A| ASOSR |0 0 0 0|A|A|A|A|A|A|0|1|0 0 0 0 0 0 0 0| AO_3WMCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - - -/* -LRCKO Polarity -0 - Reserved -1 - default -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK (1 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT (1 << 8) /* RW--V */ - -/* LRCK Output Disable */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD (1 << 10) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_ENABLED (0 << 10) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED (1 << 10) /* RWI-V */ - -/* Bit Clock Output Disable */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_ENABLED (0 << 11) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED (1 << 11) /* RWI-V */ - -/* -3-Wire Audio Serial Output Channel 0-3 Operational -Status. Each bit becomes 1 after each 3-Wire Audio -Serial Output Channel N is in action by setting 1 to -asoen. -Each bit becomes 0 after each 3-Wire Audio Serial Output -Channel N is out of action by setting 0 to asoen. -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN(n) (1 << (15 - (n))) /* R-IVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(n) (0 << (15 - (n))) /* R-I-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(n) (1 << (15 - (n))) /* R---V */ -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN0_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(0) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN1_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(1) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN2_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(2) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3 \ - PS3_AUDIO_AO_3WMCTRL_ASORUN(3) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_STOPPED \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_STOPPED(3) -#define PS3_AUDIO_AO_3WMCTRL_ASORUN3_RUNNING \ - PS3_AUDIO_AO_3WMCTRL_ASORUN_RUNNING(3) - -/* -Sampling Rate -Specifies the divide ratio of the bit clock (clock output -from bclko) used by the 3-wire Audio Output Clock, whcih -is applied to the master clock selected by mcksel. -Data output is synchronized with this clock. -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_MASK (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV2 (0x1 << 20) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV4 (0x2 << 20) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV8 (0x4 << 20) /* RW--V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOSR_DIV12 (0x6 << 20) /* RW--V */ - -/* -Master Clock Select -0 - Master Clock 0 -1 - Master Clock 1 -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL (1 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK0 (0 << 24) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOMCKSEL_CLK1 (1 << 24) /* RW--V */ - -/* -Enables and disables 4ch 3-Wire Audio Serial Output -operation. Each Bit from 0 to 3 corresponds to an -output channel, which means that each output channel -can be enabled or disabled individually. When -multiple channels are enabled at the same time, output -operations are performed in synchronization. -Bit 0 - Output Channel 0 (SDOUT[0]) -Bit 1 - Output Channel 1 (SDOUT[1]) -Bit 2 - Output Channel 2 (SDOUT[2]) -Bit 3 - Output Channel 3 (SDOUT[3]) -*/ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN(n) (1 << (31 - (n))) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(n) (0 << (31 - (n))) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(n) (1 << (31 - (n))) /* RW--V */ - -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(0) /* RWIVF */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(0) /* RWI-V */ -#define PS3_AUDIO_AO_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(0) /* RW--V */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(1) /* RWIVF */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(1) /* RWI-V */ -#define PS3_AUDIO_A1_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(1) /* RW--V */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(2) /* RWIVF */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(2) /* RWI-V */ -#define PS3_AUDIO_A2_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(2) /* RW--V */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0 \ - PS3_AUDIO_AO_3WMCTRL_ASOEN(3) /* RWIVF */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_DISABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_DISABLED(3) /* RWI-V */ -#define PS3_AUDIO_A3_3WMCTRL_ASOEN0_ENABLED \ - PS3_AUDIO_AO_3WMCTRL_ASOEN_ENABLED(3) /* RW--V */ - -/* -3-Wire Audio Serial output Channel 0-3 Control Register -Configures settings for 3-Wire Serial Audio Output Channel 0-3 - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|A|0 0 0 0|A|0|ASO|0 0 0|0|0|0|0|0| AO_3WCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -*/ -/* -Data Bit Mode -Specifies the number of data bits -0 - 16 bits -1 - reserved -2 - 20 bits -3 - 24 bits -*/ -#define PS3_AUDIO_AO_3WCTRL_ASODB_MASK (0x3 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_16BIT (0x0 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_RESVD (0x1 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_20BIT (0x2 << 8) /* RW--V */ -#define PS3_AUDIO_AO_3WCTRL_ASODB_24BIT (0x3 << 8) /* RW--V */ -/* -Data Format Mode -Specifies the data format where (LSB side or MSB) the data(in 20 bit -or 24 bit resolution mode) is put in a 32 bit field. -0 - Data put on LSB side -1 - Data put on MSB side -*/ -#define PS3_AUDIO_AO_3WCTRL_ASODF (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASODF_LSB (0 << 11) /* RWI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASODF_MSB (1 << 11) /* RW--V */ -/* -Buffer Reset -Performs buffer reset. Writing 1 to this bit initializes the -corresponding 3-Wire Audio Output buffers(both L and R). -*/ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST (1 << 16) /* CWIVF */ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST_IDLE (0 << 16) /* -WI-V */ -#define PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET (1 << 16) /* -W--T */ - -/* -S/PDIF Audio Output Channel 0/1 Control Register -Configures settings for S/PDIF Audio Output Channel 0/1. - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |S|0 0 0|S|0 0|S| SPOSR |0 0|SPO|0 0 0 0|S|0|SPO|0 0 0 0 0 0 0|S| AO_SPDCTRL - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -Buffer reset. Writing 1 to this bit initializes the -corresponding S/PDIF output buffer pointer. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST (1 << 0) /* CWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_IDLE (0 << 0) /* -WI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOBRST_RESET (1 << 0) /* -W--T */ - -/* -Data Bit Mode -Specifies number of data bits -0 - 16 bits -1 - Reserved -2 - 20 bits -3 - 24 bits -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_MASK (0x3 << 8) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_16BIT (0x0 << 8) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_RESVD (0x1 << 8) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_20BIT (0x2 << 8) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODB_24BIT (0x3 << 8) /* RW--V */ -/* -Data format Mode -Specifies the data format, where (LSB side or MSB) -the data(in 20 or 24 bit resolution) is put in the -32 bit field. -0 - LSB Side -1 - MSB Side -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPODF (1 << 11) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPODF_LSB (0 << 11) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPODF_MSB (1 << 11) /* RW--V */ -/* -Source Select -Specifies the source of the S/PDIF output. When 0, output -operation is controlled by 3wen[0] of AO_3WMCTRL register. -The SR must have the same setting as the a0_3wmctrl reg. -0 - 3-Wire Audio OUT Ch0 Buffer -1 - S/PDIF buffer -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_MASK (0x3 << 16) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_3WEN (0x0 << 16) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSS_SPDIF (0x1 << 16) /* RW--V */ -/* -Sampling Rate -Specifies the divide ratio of the bit clock (clock output -from bclko) used by the S/PDIF Output Clock, which -is applied to the master clock selected by mcksel. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR (0xf << 20) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV2 (0x1 << 20) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV4 (0x2 << 20) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV8 (0x4 << 20) /* RW--V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOSR_DIV12 (0x6 << 20) /* RW--V */ -/* -Master Clock Select -0 - Master Clock 0 -1 - Master Clock 1 -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL (1 << 24) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK0 (0 << 24) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOMCKSEL_CLK1 (1 << 24) /* RW--V */ - -/* -S/PDIF Output Channel Operational Status -This bit becomes 1 after S/PDIF Output Channel is in -action by setting 1 to spoen. This bit becomes 0 -after S/PDIF Output Channel is out of action by setting -0 to spoen. -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN (1 << 27) /* R-IVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN_STOPPED (0 << 27) /* R-I-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPORUN_RUNNING (1 << 27) /* R---V */ - -/* -S/PDIF Audio Output Channel Output Enable -Enables and disables output operation. This bit is used -only when sposs = 1 -*/ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN (1 << 31) /* RWIVF */ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN_DISABLED (0 << 31) /* RWI-V */ -#define PS3_AUDIO_AO_SPDCTRL_SPOEN_ENABLED (1 << 31) /* RW--V */ - -/* -S/PDIF Audio Output Channel Channel Status -Setting Registers. -Configures channel status bit settings for each block -(192 bits). -Output is performed from the MSB(AO_SPDCS0 register bit 31). -The same value is added for subframes within the same frame. - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | SPOCS | AO_SPDCS - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - -S/PDIF Audio Output Channel User Bit Setting -Configures user bit settings for each block (384 bits). -Output is performed from the MSB(ao_spdub0 register bit 31). - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | SPOUB | AO_SPDUB - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/***************************************************************************** - * - * DMAC register - * - *****************************************************************************/ -/* -The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor -its status - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0|STATU|0 0 0| EVENT |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ -/* -The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT -occurs. -It will return to the DONE state when the request is completed. -The registers for a DMA channel should only be written if REQUEST is IDLE. -*/ - -#define PS3_AUDIO_KICK_REQUEST (1 << 0) /* RWIVF */ -#define PS3_AUDIO_KICK_REQUEST_IDLE (0 << 0) /* RWI-V */ -#define PS3_AUDIO_KICK_REQUEST_ACTIVE (1 << 0) /* -W--T */ - -/* - *The EVENT field is used to set the event in which - *the DMA request becomes active. - */ -#define PS3_AUDIO_KICK_EVENT_MASK (0x1f << 16) /* RWIVF */ -#define PS3_AUDIO_KICK_EVENT_ALWAYS (0x00 << 16) /* RWI-V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY (0x01 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW (0x02 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY (0x03 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW (0x04 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY (0x05 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW (0x06 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY (0x07 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW (0x08 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE \ - (0x09 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW (0x0A << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY (0x0B << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE \ - (0x0C << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW (0x0D << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY (0x0E << 16) /* RW--V */ - -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n) \ - ((0x13 + (n)) << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0 (0x13 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1 (0x14 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2 (0x15 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3 (0x16 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4 (0x17 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5 (0x18 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6 (0x19 << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7 (0x1A << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8 (0x1B << 16) /* RW--V */ -#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9 (0x1C << 16) /* RW--V */ - -/* -The STATUS field can be used to monitor the progress of a DMA request. -DONE indicates the previous request has completed. -EVENT indicates that the DMA engine is waiting for the EVENT to occur. -PENDING indicates that the DMA engine has not started processing this -request, but the EVENT has occured. -DMA indicates that the data transfer is in progress. -NOTIFY indicates that the notifier signalling end of transfer is being written. -CLEAR indicated that the previous transfer was cleared. -ERROR indicates the previous transfer requested an unsupported -source/destination combination. -*/ - -#define PS3_AUDIO_KICK_STATUS_MASK (0x7 << 24) /* R-IVF */ -#define PS3_AUDIO_KICK_STATUS_DONE (0x0 << 24) /* R-I-V */ -#define PS3_AUDIO_KICK_STATUS_EVENT (0x1 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_PENDING (0x2 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_DMA (0x3 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_NOTIFY (0x4 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_CLEAR (0x5 << 24) /* R---V */ -#define PS3_AUDIO_KICK_STATUS_ERROR (0x6 << 24) /* R---V */ - -/* -The PS3_AUDIO_SOURCE register specifies the source address for transfers. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | START |0 0 0 0 0|TAR| SOURCE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -The Audio DMA engine uses 128-byte transfers, thus the address must be aligned -to a 128 byte boundary. The low seven bits are assumed to be 0. -*/ - -#define PS3_AUDIO_SOURCE_START_MASK (0x01FFFFFF << 7) /* RWIUF */ - -/* -The TARGET field specifies the memory space containing the source address. -*/ - -#define PS3_AUDIO_SOURCE_TARGET_MASK (3 << 0) /* RWIVF */ -#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY (2 << 0) /* RW--V */ - -/* -The PS3_AUDIO_DEST register specifies the destination address for transfers. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - | START |0 0 0 0 0|TAR| DEST - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - -/* -The Audio DMA engine uses 128-byte transfers, thus the address must be aligned -to a 128 byte boundary. The low seven bits are assumed to be 0. -*/ - -#define PS3_AUDIO_DEST_START_MASK (0x01FFFFFF << 7) /* RWIUF */ - -/* -The TARGET field specifies the memory space containing the destination address -AUDIOFIFO = Audio WriteData FIFO, -*/ - -#define PS3_AUDIO_DEST_TARGET_MASK (3 << 0) /* RWIVF */ -#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO (1 << 0) /* RW--V */ - -/* -PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer. -So a value of 0 means 128-bytes will get transfered. - - - 31 24 23 16 15 8 7 0 - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ - |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| BLOCKS | DMASIZE - +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+ -*/ - - -#define PS3_AUDIO_DMASIZE_BLOCKS_MASK (0x7f << 0) /* RWIUF */ - -/* - * source/destination address for internal fifos - */ -#define PS3_AUDIO_AO_3W_LDATA(n) (0x1000 + (0x100 * (n))) -#define PS3_AUDIO_AO_3W_RDATA(n) (0x1080 + (0x100 * (n))) - -#define PS3_AUDIO_AO_SPD_DATA(n) (0x2000 + (0x400 * (n))) - - -/* - * field attiribute - * - * Read - * ' ' = Other Information - * '-' = Field is part of a write-only register - * 'C' = Value read is always the same, constant value line follows (C) - * 'R' = Value is read - * - * Write - * ' ' = Other Information - * '-' = Must not be written (D), value ignored when written (R,A,F) - * 'W' = Can be written - * - * Internal State - * ' ' = Other Information - * '-' = No internal state - * 'X' = Internal state, initial value is unknown - * 'I' = Internal state, initial value is known and follows (I) - * - * Declaration/Size - * ' ' = Other Information - * '-' = Does Not Apply - * 'V' = Type is void - * 'U' = Type is unsigned integer - * 'S' = Type is signed integer - * 'F' = Type is IEEE floating point - * '1' = Byte size (008) - * '2' = Short size (016) - * '3' = Three byte size (024) - * '4' = Word size (032) - * '8' = Double size (064) - * - * Define Indicator - * ' ' = Other Information - * 'D' = Device - * 'M' = Memory - * 'R' = Register - * 'A' = Array of Registers - * 'F' = Field - * 'V' = Value - * 'T' = Task - */ - diff --git a/trunk/sound/sh/Kconfig b/trunk/sound/sh/Kconfig deleted file mode 100644 index b7e08ef22a94..000000000000 --- a/trunk/sound/sh/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# ALSA SH drivers - -menu "SUPERH devices" - depends on SND!=n && SUPERH - -config SND_AICA - tristate "Dreamcast Yamaha AICA sound" - depends on SH_DREAMCAST && SND - select SND_PCM - help - ALSA Sound driver for the SEGA Dreamcast console. - -endmenu - diff --git a/trunk/sound/sh/Makefile b/trunk/sound/sh/Makefile deleted file mode 100644 index 8fdcb6e26f00..000000000000 --- a/trunk/sound/sh/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for ALSA -# - -snd-aica-objs := aica.o - -# Toplevel Module Dependency -obj-$(CONFIG_SND_AICA) += snd-aica.o diff --git a/trunk/sound/sh/aica.c b/trunk/sound/sh/aica.c deleted file mode 100644 index 739786529ca5..000000000000 --- a/trunk/sound/sh/aica.c +++ /dev/null @@ -1,665 +0,0 @@ -/* -* This code is licenced under -* the General Public Licence -* version 2 -* -* Copyright Adrian McMenamin 2005, 2006, 2007 -* -* Requires firmware (BSD licenced) available from: -* http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/ -* or the maintainer -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of version 2 of the GNU General Public License as published by -* the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "aica.h" - -MODULE_AUTHOR("Adrian McMenamin "); -MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}"); - -/* module parameters */ -#define CARD_NAME "AICA" -static int index = -1; -static char *id; -static int enable = 1; -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); -module_param(enable, bool, 0644); -MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); - -/* Use workqueue */ -static struct workqueue_struct *aica_queue; - -/* Simple platform device */ -static struct platform_device *pd; -static struct resource aica_memory_space[2] = { - { - .name = "AICA ARM CONTROL", - .start = ARM_RESET_REGISTER, - .flags = IORESOURCE_MEM, - .end = ARM_RESET_REGISTER + 3, - }, - { - .name = "AICA Sound RAM", - .start = SPU_MEMORY_BASE, - .flags = IORESOURCE_MEM, - .end = SPU_MEMORY_BASE + 0x200000 - 1, - }, -}; - -/* SPU specific functions */ -/* spu_write_wait - wait for G2-SH FIFO to clear */ -static void spu_write_wait(void) -{ - int time_count; - time_count = 0; - while (1) { - if (!(readl(G2_FIFO) & 0x11)) - break; - /* To ensure hardware failure doesn't wedge kernel */ - time_count++; - if (time_count > 0x10000) { - snd_printk - ("WARNING: G2 FIFO appears to be blocked.\n"); - break; - } - } -} - -/* spu_memset - write to memory in SPU address space */ -static void spu_memset(u32 toi, u32 what, int length) -{ - int i; - snd_assert(length % 4 == 0, return); - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - writel(what, toi + SPU_MEMORY_BASE); - toi++; - } -} - -/* spu_memload - write to SPU address space */ -static void spu_memload(u32 toi, void *from, int length) -{ - u32 *froml = from; - u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi); - int i; - u32 val; - length = DIV_ROUND_UP(length, 4); - spu_write_wait(); - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - val = *froml; - writel(val, to); - froml++; - to++; - } -} - -/* spu_disable - set spu registers to stop sound output */ -static void spu_disable(void) -{ - int i; - u32 regval; - spu_write_wait(); - regval = readl(ARM_RESET_REGISTER); - regval |= 1; - spu_write_wait(); - writel(regval, ARM_RESET_REGISTER); - for (i = 0; i < 64; i++) { - spu_write_wait(); - regval = readl(SPU_REGISTER_BASE + (i * 0x80)); - regval = (regval & ~0x4000) | 0x8000; - spu_write_wait(); - writel(regval, SPU_REGISTER_BASE + (i * 0x80)); - } -} - -/* spu_enable - set spu registers to enable sound output */ -static void spu_enable(void) -{ - u32 regval = readl(ARM_RESET_REGISTER); - regval &= ~1; - spu_write_wait(); - writel(regval, ARM_RESET_REGISTER); -} - -/* - * Halt the sound processor, clear the memory, - * load some default ARM7 code, and then restart ARM7 -*/ -static void spu_reset(void) -{ - spu_disable(); - spu_memset(0, 0, 0x200000 / 4); - /* Put ARM7 in endless loop */ - ctrl_outl(0xea000002, SPU_MEMORY_BASE); - spu_enable(); -} - -/* aica_chn_start - write to spu to start playback */ -static void aica_chn_start(void) -{ - spu_write_wait(); - writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT); -} - -/* aica_chn_halt - write to spu to halt playback */ -static void aica_chn_halt(void) -{ - spu_write_wait(); - writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT); -} - -/* ALSA code below */ -static struct snd_pcm_hardware snd_pcm_aica_playback_hw = { - .info = (SNDRV_PCM_INFO_NONINTERLEAVED), - .formats = - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_IMA_ADPCM), - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = AICA_BUFFER_SIZE, - .period_bytes_min = AICA_PERIOD_SIZE, - .period_bytes_max = AICA_PERIOD_SIZE, - .periods_min = AICA_PERIOD_NUMBER, - .periods_max = AICA_PERIOD_NUMBER, -}; - -static int aica_dma_transfer(int channels, int buffer_size, - struct snd_pcm_substream *substream) -{ - int q, err, period_offset; - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - err = 0; - dreamcastcard = substream->pcm->private_data; - period_offset = dreamcastcard->clicks; - period_offset %= (AICA_PERIOD_NUMBER / channels); - runtime = substream->runtime; - for (q = 0; q < channels; q++) { - err = dma_xfer(AICA_DMA_CHANNEL, - (unsigned long) (runtime->dma_area + - (AICA_BUFFER_SIZE * q) / - channels + - AICA_PERIOD_SIZE * - period_offset), - AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET + - AICA_PERIOD_SIZE * period_offset, - buffer_size / channels, AICA_DMA_MODE); - if (unlikely(err < 0)) - break; - dma_wait_for_completion(AICA_DMA_CHANNEL); - } - return err; -} - -static void startup_aica(struct snd_card_aica *dreamcastcard) -{ - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - aica_chn_start(); -} - -static void run_spu_dma(struct work_struct *work) -{ - int buffer_size; - struct snd_pcm_runtime *runtime; - struct snd_card_aica *dreamcastcard; - dreamcastcard = - container_of(work, struct snd_card_aica, spu_dma_work); - runtime = dreamcastcard->substream->runtime; - if (unlikely(dreamcastcard->dma_check == 0)) { - buffer_size = - frames_to_bytes(runtime, runtime->buffer_size); - if (runtime->channels > 1) - dreamcastcard->channel->flags |= 0x01; - aica_dma_transfer(runtime->channels, buffer_size, - dreamcastcard->substream); - startup_aica(dreamcastcard); - dreamcastcard->clicks = - buffer_size / (AICA_PERIOD_SIZE * runtime->channels); - return; - } else { - aica_dma_transfer(runtime->channels, - AICA_PERIOD_SIZE * runtime->channels, - dreamcastcard->substream); - snd_pcm_period_elapsed(dreamcastcard->substream); - dreamcastcard->clicks++; - if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER)) - dreamcastcard->clicks %= AICA_PERIOD_NUMBER; - mod_timer(&dreamcastcard->timer, jiffies + 1); - } -} - -static void aica_period_elapsed(unsigned long timer_var) -{ - /*timer function - so cannot sleep */ - int play_period; - struct snd_pcm_runtime *runtime; - struct snd_pcm_substream *substream; - struct snd_card_aica *dreamcastcard; - substream = (struct snd_pcm_substream *) timer_var; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /* Have we played out an additional period? */ - play_period = - frames_to_bytes(runtime, - readl - (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) / - AICA_PERIOD_SIZE; - if (play_period == dreamcastcard->current_period) { - /* reschedule the timer */ - mod_timer(&(dreamcastcard->timer), jiffies + 1); - return; - } - if (runtime->channels > 1) - dreamcastcard->current_period = play_period; - if (unlikely(dreamcastcard->dma_check == 0)) - dreamcastcard->dma_check = 1; - queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); -} - -static void spu_begin_dma(struct snd_pcm_substream *substream) -{ - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /*get the queue to do the work */ - queue_work(aica_queue, &(dreamcastcard->spu_dma_work)); - /* Timer may already be running */ - if (unlikely(dreamcastcard->timer.data)) { - mod_timer(&dreamcastcard->timer, jiffies + 4); - return; - } - init_timer(&(dreamcastcard->timer)); - dreamcastcard->timer.data = (unsigned long) substream; - dreamcastcard->timer.function = aica_period_elapsed; - dreamcastcard->timer.expires = jiffies + 4; - add_timer(&(dreamcastcard->timer)); -} - -static int snd_aicapcm_pcm_open(struct snd_pcm_substream - *substream) -{ - struct snd_pcm_runtime *runtime; - struct aica_channel *channel; - struct snd_card_aica *dreamcastcard; - if (!enable) - return -ENOENT; - dreamcastcard = substream->pcm->private_data; - channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL); - if (!channel) - return -ENOMEM; - /* set defaults for channel */ - channel->sfmt = SM_8BIT; - channel->cmd = AICA_CMD_START; - channel->vol = dreamcastcard->master_volume; - channel->pan = 0x80; - channel->pos = 0; - channel->flags = 0; /* default to mono */ - dreamcastcard->channel = channel; - runtime = substream->runtime; - runtime->hw = snd_pcm_aica_playback_hw; - spu_enable(); - dreamcastcard->clicks = 0; - dreamcastcard->current_period = 0; - dreamcastcard->dma_check = 0; - return 0; -} - -static int snd_aicapcm_pcm_close(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - flush_workqueue(aica_queue); - if (dreamcastcard->timer.data) - del_timer(&dreamcastcard->timer); - kfree(dreamcastcard->channel); - spu_disable(); - return 0; -} - -static int snd_aicapcm_pcm_hw_free(struct snd_pcm_substream - *substream) -{ - /* Free the DMA buffer */ - return snd_pcm_lib_free_pages(substream); -} - -static int snd_aicapcm_pcm_hw_params(struct snd_pcm_substream - *substream, struct snd_pcm_hw_params - *hw_params) -{ - /* Allocate a DMA buffer using ALSA built-ins */ - return - snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE) - dreamcastcard->channel->sfmt = SM_16BIT; - dreamcastcard->channel->freq = substream->runtime->rate; - dreamcastcard->substream = substream; - return 0; -} - -static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream - *substream, int cmd) -{ - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - spu_begin_dma(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - aica_chn_halt(); - break; - default: - return -EINVAL; - } - return 0; -} - -static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream - *substream) -{ - return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); -} - -static struct snd_pcm_ops snd_aicapcm_playback_ops = { - .open = snd_aicapcm_pcm_open, - .close = snd_aicapcm_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_aicapcm_pcm_hw_params, - .hw_free = snd_aicapcm_pcm_hw_free, - .prepare = snd_aicapcm_pcm_prepare, - .trigger = snd_aicapcm_pcm_trigger, - .pointer = snd_aicapcm_pcm_pointer, -}; - -/* TO DO: set up to handle more than one pcm instance */ -static int __init snd_aicapcmchip(struct snd_card_aica - *dreamcastcard, int pcm_index) -{ - struct snd_pcm *pcm; - int err; - /* AICA has no capture ability */ - err = - snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, - &pcm); - if (unlikely(err < 0)) - return err; - pcm->private_data = dreamcastcard; - strcpy(pcm->name, "AICA PCM"); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_aicapcm_playback_ops); - /* Allocate the DMA buffers */ - err = - snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data - (GFP_KERNEL), - AICA_BUFFER_SIZE, - AICA_BUFFER_SIZE); - return err; -} - -/* Mixer controls */ -static int aica_pcmswitch_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */ - return 0; -} - -static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (ucontrol->value.integer.value[0] == 1) - return 0; /* TO DO: Fix me */ - else - aica_chn_halt(); - return 0; -} - -static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0xFF; - return 0; -} - -static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; /* we've not yet been set up */ - ucontrol->value.integer.value[0] = dreamcastcard->channel->vol; - return 0; -} - -static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; - if (unlikely(dreamcastcard->channel->vol == - ucontrol->value.integer.value[0])) - return 0; - dreamcastcard->channel->vol = ucontrol->value.integer.value[0]; - dreamcastcard->master_volume = ucontrol->value.integer.value[0]; - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - return 1; -} - -static struct snd_kcontrol_new snd_aica_pcmswitch_control __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .index = 0, - .info = aica_pcmswitch_info, - .get = aica_pcmswitch_get, - .put = aica_pcmswitch_put -}; - -static struct snd_kcontrol_new snd_aica_pcmvolume_control __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .info = aica_pcmvolume_info, - .get = aica_pcmvolume_get, - .put = aica_pcmvolume_put -}; - -static int load_aica_firmware(void) -{ - int err; - const struct firmware *fw_entry; - spu_reset(); - err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); - if (unlikely(err)) - return err; - /* write firware into memory */ - spu_disable(); - spu_memload(0, fw_entry->data, fw_entry->size); - spu_enable(); - release_firmware(fw_entry); - return err; -} - -static int __devinit add_aicamixer_controls(struct snd_card_aica - *dreamcastcard) -{ - int err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - return 0; -} - -static int snd_aica_remove(struct platform_device *devptr) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = platform_get_drvdata(devptr); - if (unlikely(!dreamcastcard)) - return -ENODEV; - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - platform_set_drvdata(devptr, NULL); - return 0; -} - -static int __init snd_aica_probe(struct platform_device *devptr) -{ - int err; - struct snd_card_aica *dreamcastcard; - dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); - if (unlikely(!dreamcastcard)) - return -ENOMEM; - dreamcastcard->card = - snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); - if (unlikely(!dreamcastcard->card)) { - kfree(dreamcastcard); - return -ENODEV; - } - strcpy(dreamcastcard->card->driver, "snd_aica"); - strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); - strcpy(dreamcastcard->card->longname, - "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast"); - /* Prepare to use the queue */ - INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma); - /* Load the PCM 'chip' */ - err = snd_aicapcmchip(dreamcastcard, 0); - if (unlikely(err < 0)) - goto freedreamcast; - snd_card_set_dev(dreamcastcard->card, &devptr->dev); - dreamcastcard->timer.data = 0; - dreamcastcard->channel = NULL; - /* Add basic controls */ - err = add_aicamixer_controls(dreamcastcard); - if (unlikely(err < 0)) - goto freedreamcast; - /* Register the card with ALSA subsystem */ - err = snd_card_register(dreamcastcard->card); - if (unlikely(err < 0)) - goto freedreamcast; - platform_set_drvdata(devptr, dreamcastcard); - aica_queue = create_workqueue(CARD_NAME); - if (unlikely(!aica_queue)) - goto freedreamcast; - snd_printk - ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n"); - return 0; - freedreamcast: - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - return err; -} - -static struct platform_driver snd_aica_driver = { - .probe = snd_aica_probe, - .remove = snd_aica_remove, - .driver = { - .name = SND_AICA_DRIVER}, -}; - -static int __init aica_init(void) -{ - int err; - err = platform_driver_register(&snd_aica_driver); - if (unlikely(err < 0)) - return err; - pd = platform_device_register_simple(SND_AICA_DRIVER, -1, - aica_memory_space, 2); - if (unlikely(IS_ERR(pd))) { - platform_driver_unregister(&snd_aica_driver); - return PTR_ERR(pd); - } - /* Load the firmware */ - return load_aica_firmware(); -} - -static void __exit aica_exit(void) -{ - /* Destroy the aica kernel thread * - * being extra cautious to check if it exists*/ - if (likely(aica_queue)) - destroy_workqueue(aica_queue); - platform_device_unregister(pd); - platform_driver_unregister(&snd_aica_driver); - /* Kill any sound still playing and reset ARM7 to safe state */ - spu_reset(); -} - -module_init(aica_init); -module_exit(aica_exit); diff --git a/trunk/sound/sh/aica.h b/trunk/sound/sh/aica.h deleted file mode 100644 index 8c11e3d10a50..000000000000 --- a/trunk/sound/sh/aica.h +++ /dev/null @@ -1,81 +0,0 @@ -/* aica.h - * Header file for ALSA driver for - * Sega Dreamcast Yamaha AICA sound - * Copyright Adrian McMenamin - * - * 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -/* SPU memory and register constants etc */ -#define G2_FIFO 0xa05f688c -#define SPU_MEMORY_BASE 0xA0800000 -#define ARM_RESET_REGISTER 0xA0702C00 -#define SPU_REGISTER_BASE 0xA0700000 - -/* AICA channels stuff */ -#define AICA_CONTROL_POINT 0xA0810000 -#define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008 -#define AICA_CHANNEL0_CONTROL_OFFSET 0x10004 - -/* Command values */ -#define AICA_CMD_KICK 0x80000000 -#define AICA_CMD_NONE 0 -#define AICA_CMD_START 1 -#define AICA_CMD_STOP 2 -#define AICA_CMD_VOL 3 - -/* Sound modes */ -#define SM_8BIT 1 -#define SM_16BIT 0 -#define SM_ADPCM 2 - -/* Buffer and period size */ -#define AICA_BUFFER_SIZE 0x8000 -#define AICA_PERIOD_SIZE 0x800 -#define AICA_PERIOD_NUMBER 16 - -#define AICA_CHANNEL0_OFFSET 0x11000 -#define AICA_CHANNEL1_OFFSET 0x21000 -#define CHANNEL_OFFSET 0x10000 - -#define AICA_DMA_CHANNEL 0 -#define AICA_DMA_MODE 5 - -#define SND_AICA_DRIVER "AICA" - -struct aica_channel { - uint32_t cmd; /* Command ID */ - uint32_t pos; /* Sample position */ - uint32_t length; /* Sample length */ - uint32_t freq; /* Frequency */ - uint32_t vol; /* Volume 0-255 */ - uint32_t pan; /* Pan 0-255 */ - uint32_t sfmt; /* Sound format */ - uint32_t flags; /* Bit flags */ -}; - -struct snd_card_aica { - struct work_struct spu_dma_work; - struct snd_card *card; - struct aica_channel *channel; - struct snd_pcm_substream *substream; - int clicks; - int current_period; - struct timer_list timer; - int master_volume; - int dma_check; -}; diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig index 97b255233175..10cffc087181 100644 --- a/trunk/sound/soc/Kconfig +++ b/trunk/sound/soc/Kconfig @@ -27,7 +27,6 @@ config SND_SOC source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" -source "sound/soc/sh/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile index 304140377632..0ae2e49036f9 100644 --- a/trunk/sound/soc/Makefile +++ b/trunk/sound/soc/Makefile @@ -1,4 +1,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o -obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ sh/ +obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ diff --git a/trunk/sound/soc/s3c24xx/Kconfig b/trunk/sound/soc/s3c24xx/Kconfig index e97c68306a9a..044a3712077a 100644 --- a/trunk/sound/soc/s3c24xx/Kconfig +++ b/trunk/sound/soc/s3c24xx/Kconfig @@ -1,7 +1,6 @@ config SND_S3C24XX_SOC tristate "SoC Audio for the Samsung S3C24XX chips" depends on ARCH_S3C2410 && SND_SOC - select SND_PCM help Say Y or M if you want to add support for codecs attached to the S3C24XX AC97, I2S or SSP interface. You will also need @@ -9,29 +8,3 @@ config SND_S3C24XX_SOC config SND_S3C24XX_SOC_I2S tristate - -config SND_S3C2443_SOC_AC97 - tristate - select AC97_BUS - select SND_AC97_CODEC - select SND_SOC_AC97_BUS - -config SND_S3C24XX_SOC_NEO1973_WM8753 - tristate "SoC I2S Audio support for NEO1973 - WM8753" - depends on SND_S3C24XX_SOC && MACH_GTA01 - select SND_S3C24XX_SOC_I2S - select SND_SOC_WM8753 - help - Say Y if you want to add support for SoC audio on smdk2440 - with the WM8753. - -config SND_S3C24XX_SOC_SMDK2443_WM9710 - tristate "SoC AC97 Audio support for SMDK2443 - WM9710" - depends on SND_S3C24XX_SOC && MACH_SMDK2443 - select SND_S3C2443_SOC_AC97 - select SND_SOC_AC97_CODEC - help - Say Y if you want to add support for SoC audio on smdk2443 - with the WM9710. - - diff --git a/trunk/sound/soc/s3c24xx/Makefile b/trunk/sound/soc/s3c24xx/Makefile index 13c92f0fa1e4..6f0fffcb30f5 100644 --- a/trunk/sound/soc/s3c24xx/Makefile +++ b/trunk/sound/soc/s3c24xx/Makefile @@ -1,15 +1,6 @@ # S3c24XX Platform Support snd-soc-s3c24xx-objs := s3c24xx-pcm.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o -snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o - -# S3C24XX Machine Support -snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o -snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o - -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o diff --git a/trunk/sound/soc/s3c24xx/lm4857.h b/trunk/sound/soc/s3c24xx/lm4857.h deleted file mode 100644 index 0cf5b7011d6f..000000000000 --- a/trunk/sound/soc/s3c24xx/lm4857.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * lm4857.h -- ALSA Soc Audio Layer - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 18th Jun 2007 Initial version. - */ - -#ifndef LM4857_H_ -#define LM4857_H_ - -/* The register offsets in the cache array */ -#define LM4857_MVOL 0 -#define LM4857_LVOL 1 -#define LM4857_RVOL 2 -#define LM4857_CTRL 3 - -/* the shifts required to set these bits */ -#define LM4857_3D 5 -#define LM4857_WAKEUP 5 -#define LM4857_EPGAIN 4 - -#endif /*LM4857_H_*/ - diff --git a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c b/trunk/sound/soc/s3c24xx/neo1973_wm8753.c deleted file mode 100644 index d5a8fc2cf8d6..000000000000 --- a/trunk/sound/soc/s3c24xx/neo1973_wm8753.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * neo1973_wm8753.c -- SoC audio for Neo1973 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 20th Jan 2007 Initial version. - * 05th Feb 2007 Rename all to Neo1973 - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../codecs/wm8753.h" -#include "lm4857.h" -#include "s3c24xx-pcm.h" -#include "s3c24xx-i2s.h" - -/* define the scenarios */ -#define NEO_AUDIO_OFF 0 -#define NEO_GSM_CALL_AUDIO_HANDSET 1 -#define NEO_GSM_CALL_AUDIO_HEADSET 2 -#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 -#define NEO_STEREO_TO_SPEAKERS 4 -#define NEO_STEREO_TO_HEADPHONES 5 -#define NEO_CAPTURE_HANDSET 6 -#define NEO_CAPTURE_HEADSET 7 -#define NEO_CAPTURE_BLUETOOTH 8 - -static struct snd_soc_machine neo1973; -static struct i2c_client *i2c; - -static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int pll_out = 0, bclk = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - switch (params_rate(params)) { - case 8000: - case 16000: - pll_out = 12288000; - break; - case 48000: - bclk = WM8753_BCLK_DIV_4; - pll_out = 12288000; - break; - case 96000: - bclk = WM8753_BCLK_DIV_2; - pll_out = 12288000; - break; - case 11025: - bclk = WM8753_BCLK_DIV_16; - pll_out = 11289600; - break; - case 22050: - bclk = WM8753_BCLK_DIV_8; - pll_out = 11289600; - break; - case 44100: - bclk = WM8753_BCLK_DIV_4; - pll_out = 11289600; - break; - case 88200: - bclk = WM8753_BCLK_DIV_2; - pll_out = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = cpu_dai->dai_ops.set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_MCLK, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS ); - if (ret < 0) - return ret; - - /* set codec BCLK division for sample rate */ - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4,4)); - if (ret < 0) - return ret; - - /* codec PLL input is PCLK/4 */ - ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, - iis_clkrate / 4, pll_out); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - - /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL1, 0, 0); -} - -/* - * Neo1973 WM8753 HiFi DAI opserations. - */ -static struct snd_soc_ops neo1973_hifi_ops = { - .hw_params = neo1973_hifi_hw_params, - .hw_free = neo1973_hifi_hw_free, -}; - -static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - unsigned int pcmdiv = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - if (params_rate(params) != 8000) - return -EINVAL; - if (params_channels(params) != 1) - return -EINVAL; - - pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - - /* todo: gg check mode (DSP_B) against CSR datasheet */ - /* set codec DAI configuration */ - ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec PCM division for sample rate */ - ret = codec_dai->dai_ops.set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); - if (ret < 0) - return ret; - - /* configue and enable PLL for 12.288MHz output */ - ret = codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, - iis_clkrate / 4, 12288000); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; - - /* disable the PLL */ - return codec_dai->dai_ops.set_pll(codec_dai, WM8753_PLL2, 0, 0); -} - -static struct snd_soc_ops neo1973_voice_ops = { - .hw_params = neo1973_voice_hw_params, - .hw_free = neo1973_voice_hw_free, -}; - -static int neo1973_scenario = 0; - -static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = neo1973_scenario; - return 0; -} - -static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) -{ - switch(neo1973_scenario) { - case NEO_AUDIO_OFF: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); - break; - case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 1); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 1); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_CAPTURE_HANDSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 1); - break; - case NEO_CAPTURE_HEADSET: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 1); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - break; - default: - snd_soc_dapm_set_endpoint(codec, "Audio Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line Out", 0); - snd_soc_dapm_set_endpoint(codec, "GSM Line In", 0); - snd_soc_dapm_set_endpoint(codec, "Headset Mic", 0); - snd_soc_dapm_set_endpoint(codec, "Call Mic", 0); - } - - snd_soc_dapm_sync_endpoints(codec); - - return 0; -} - -static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - if (neo1973_scenario == ucontrol->value.integer.value[0]) - return 0; - - neo1973_scenario = ucontrol->value.integer.value[0]; - set_scenario_endpoints(codec, neo1973_scenario); - return 1; -} - -static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; - -static void lm4857_write_regs(void) -{ - if (i2c_master_send(i2c, lm4857_regs, 4) != 4) - printk(KERN_ERR "lm4857: i2c write failed\n"); -} - -static int lm4857_get_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int reg=kcontrol->private_value & 0xFF; - int shift = (kcontrol->private_value >> 8) & 0x0F; - int mask = (kcontrol->private_value >> 16) & 0xFF; - - ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; - return 0; -} - -static int lm4857_set_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int reg = kcontrol->private_value & 0xFF; - int shift = (kcontrol->private_value >> 8) & 0x0F; - int mask = (kcontrol->private_value >> 16) & 0xFF; - - if (((lm4857_regs[reg] >> shift ) & mask) == - ucontrol->value.integer.value[0]) - return 0; - - lm4857_regs[reg] &= ~ (mask << shift); - lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift; - lm4857_write_regs(); - return 1; -} - -static int lm4857_get_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; - - if (value) - value -= 5; - - ucontrol->value.integer.value[0] = value; - return 0; -} - -static int lm4857_set_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = ucontrol->value.integer.value[0]; - - if (value) - value += 5; - - if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value) - return 0; - - lm4857_regs[LM4857_CTRL] &= 0xF0; - lm4857_regs[LM4857_CTRL] |= value; - lm4857_write_regs(); - return 1; -} - -static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { - SND_SOC_DAPM_LINE("Audio Out", NULL), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Call Mic", NULL), -}; - - -/* example machine audio_mapnections */ -static const char* audio_map[][3] = { - - /* Connections to the lm4857 amp */ - {"Audio Out", NULL, "LOUT1"}, - {"Audio Out", NULL, "ROUT1"}, - - /* Connections to the GSM Module */ - {"GSM Line Out", NULL, "MONO1"}, - {"GSM Line Out", NULL, "MONO2"}, - {"RXP", NULL, "GSM Line In"}, - {"RXN", NULL, "GSM Line In"}, - - /* Connections to Headset */ - {"MIC1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Mic"}, - - /* Call Mic */ - {"MIC2", NULL, "Mic Bias"}, - {"MIC2N", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Call Mic"}, - - /* Connect the ALC pins */ - {"ACIN", NULL, "ACOP"}, - - {NULL, NULL, NULL}, -}; - -static const char *lm4857_mode[] = { - "Off", - "Call Speaker", - "Stereo Speakers", - "Stereo Speakers + Headphones", - "Headphones" -}; - -static const struct soc_enum lm4857_mode_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), -}; - -static const char *neo_scenarios[] = { - "Off", - "GSM Handset", - "GSM Headset", - "GSM Bluetooth", - "Speakers", - "Headphones", - "Capture Handset", - "Capture Headset", - "Capture Bluetooth" -}; - -static const struct soc_enum neo_scenario_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios),neo_scenarios), -}; - -static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { - SOC_SINGLE_EXT("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], - lm4857_get_mode, lm4857_set_mode), - SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], - neo1973_get_scenario, neo1973_set_scenario), - SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0, - lm4857_get_reg, lm4857_set_reg), -}; - -/* - * This is an example machine initialisation for a wm8753 connected to a - * neo1973 II. It is missing logic to detect hp/mic insertions and logic - * to re-route the audio in such an event. - */ -static int neo1973_wm8753_init(struct snd_soc_codec *codec) -{ - int i, err; - - /* set up NC codec pins */ - snd_soc_dapm_set_endpoint(codec, "LOUT2", 0); - snd_soc_dapm_set_endpoint(codec, "ROUT2", 0); - snd_soc_dapm_set_endpoint(codec, "OUT3", 0); - snd_soc_dapm_set_endpoint(codec, "OUT4", 0); - snd_soc_dapm_set_endpoint(codec, "LINE1", 0); - snd_soc_dapm_set_endpoint(codec, "LINE2", 0); - - - /* set endpoints to default mode */ - set_scenario_endpoints(codec, NEO_AUDIO_OFF); - - /* Add neo1973 specific widgets */ - for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); - - /* add neo1973 specific controls */ - for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { - err = snd_ctl_add(codec->card, - snd_soc_cnew(&wm8753_neo1973_controls[i], - codec, NULL)); - if (err < 0) - return err; - } - - /* set up neo1973 specific audio path audio_mapnects */ - for (i = 0; audio_map[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, audio_map[i][0], - audio_map[i][1], audio_map[i][2]); - } - - snd_soc_dapm_sync_endpoints(codec); - return 0; -} - -/* - * BT Codec DAI - */ -static struct snd_soc_cpu_dai bt_dai = -{ .name = "Bluetooth", - .id = 0, - .type = SND_SOC_DAI_PCM, - .playback = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_dai_link neo1973_dai[] = { -{ /* Hifi Playback - for similatious use with voice below */ - .name = "WM8753", - .stream_name = "WM8753 HiFi", - .cpu_dai = &s3c24xx_i2s_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_HIFI], - .init = neo1973_wm8753_init, - .ops = &neo1973_hifi_ops, -}, -{ /* Voice via BT */ - .name = "Bluetooth", - .stream_name = "Voice", - .cpu_dai = &bt_dai, - .codec_dai = &wm8753_dai[WM8753_DAI_VOICE], - .ops = &neo1973_voice_ops, -}, -}; - -static struct snd_soc_machine neo1973 = { - .name = "neo1973", - .dai_link = neo1973_dai, - .num_links = ARRAY_SIZE(neo1973_dai), -}; - -static struct wm8753_setup_data neo1973_wm8753_setup = { - .i2c_address = 0x1a, -}; - -static struct snd_soc_device neo1973_snd_devdata = { - .machine = &neo1973, - .platform = &s3c24xx_soc_platform, - .codec_dev = &soc_codec_dev_wm8753, - .codec_data = &neo1973_wm8753_setup, -}; - -static struct i2c_client client_template; - -static unsigned short normal_i2c[] = { 0x7C, I2C_CLIENT_END }; - -/* Magic definition of all other variables and things */ -I2C_CLIENT_INSMOD; - -static int lm4857_amp_probe(struct i2c_adapter *adap, int addr, int kind) -{ - int ret; - - client_template.adapter = adap; - client_template.addr = addr; - - i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); - if (i2c == NULL) - return -ENOMEM; - - ret = i2c_attach_client(i2c); - if (ret < 0) { - printk(KERN_ERR "LM4857 failed to attach at addr %x\n", addr); - goto exit_err; - } - - lm4857_write_regs(); - return ret; - -exit_err: - kfree(i2c); - return ret; -} - -static int lm4857_i2c_detach(struct i2c_client *client) -{ - i2c_detach_client(client); - kfree(client); - return 0; -} - -static int lm4857_i2c_attach(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, lm4857_amp_probe); -} - -/* corgi i2c codec control layer */ -static struct i2c_driver lm4857_i2c_driver = { - .driver = { - .name = "LM4857 I2C Amp", - .owner = THIS_MODULE, - }, - .id = I2C_DRIVERID_LM4857, - .attach_adapter = lm4857_i2c_attach, - .detach_client = lm4857_i2c_detach, - .command = NULL, -}; - -static struct i2c_client client_template = { - .name = "LM4857", - .driver = &lm4857_i2c_driver, -}; - -static struct platform_device *neo1973_snd_device; - -static int __init neo1973_init(void) -{ - int ret; - - neo1973_snd_device = platform_device_alloc("soc-audio", -1); - if (!neo1973_snd_device) - return -ENOMEM; - - platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata); - neo1973_snd_devdata.dev = &neo1973_snd_device->dev; - ret = platform_device_add(neo1973_snd_device); - - if (ret) - platform_device_put(neo1973_snd_device); - - ret = i2c_add_driver(&lm4857_i2c_driver); - if (ret != 0) - printk(KERN_ERR "can't add i2c driver"); - - return ret; -} - -static void __exit neo1973_exit(void) -{ - platform_device_unregister(neo1973_snd_device); -} - -module_init(neo1973_init); -module_exit(neo1973_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c b/trunk/sound/soc/s3c24xx/s3c2443-ac97.c deleted file mode 100644 index 75acf7ef5528..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c2443-ac97.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * s3c2443-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright (C) 2005, Sean Choi - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Revision history - * 21st Mar 2007 Initial Version - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "s3c24xx-pcm.h" -#include "s3c24xx-ac97.h" - -struct s3c24xx_ac97_info { - void __iomem *regs; - struct clk *ac97_clk; -}; -static struct s3c24xx_ac97_info s3c24xx_ac97; - -DECLARE_COMPLETION(ac97_completion); -static u32 codec_ready; -static DECLARE_MUTEX(ac97_mutex); - -static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - u32 stat, addr, data; - - down(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT); - addr = (stat >> 16) & 0x7f; - data = (stat & 0xffff); - - if (addr != reg) - printk(KERN_ERR "s3c24xx-ac97: req addr = %02x," - " rep addr = %02x\n", reg, addr); - - up(&ac97_mutex); - - return (unsigned short)data; -} - -static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - u32 ac_glbctrl; - u32 ac_codec_cmd; - - down(&ac97_mutex); - - codec_ready = S3C_AC97_GLBSTAT_CODECREADY; - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - wait_for_completion(&ac97_completion); - - ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; - writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); - - up(&ac97_mutex); - -} - -static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); -} - -static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA | - S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); -} - -static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id) -{ - int status; - u32 ac_glbctrl; - - status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready; - - if (status) { - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - complete(&ac97_completion); - } - return IRQ_HANDLED; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = s3c2443_ac97_read, - .write = s3c2443_ac97_write, - .warm_reset = s3c2443_ac97_warm_reset, - .reset = s3c2443_ac97_cold_reset, -}; - -static struct s3c2410_dma_client s3c2443_dma_client_out = { - .name = "AC97 PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_in = { - .name = "AC97 PCM Stereo in" -}; - -static struct s3c2410_dma_client s3c2443_dma_client_micin = { - .name = "AC97 Mic Mono in" -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = { - .client = &s3c2443_dma_client_out, - .channel = DMACH_PCM_OUT, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = { - .client = &s3c2443_dma_client_in, - .channel = DMACH_PCM_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - .dma_size = 4, -}; - -static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = { - .client = &s3c2443_dma_client_micin, - .channel = DMACH_MIC_IN, - .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, - .dma_size = 4, -}; - -static int s3c2443_ac97_probe(struct platform_device *pdev) -{ - int ret; - u32 ac_glbctrl; - - s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100); - if (s3c24xx_ac97.regs == NULL) - return -ENXIO; - - s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); - if (s3c24xx_ac97.ac97_clk == NULL) { - printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n"); - iounmap(s3c24xx_ac97.regs); - return -ENODEV; - } - clk_enable(s3c24xx_ac97.ac97_clk); - - s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET); - s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC); - s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI); - s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = 0; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - ret = request_irq(IRQ_S3C2443_AC97, s3c2443_ac97_irq, - IRQF_DISABLED, "AC97", NULL); - if (ret < 0) { - printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n"); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); - } - return ret; -} - -static void s3c2443_ac97_remove(struct platform_device *pdev) -{ - free_irq(IRQ_S3C2443_AC97, NULL); - clk_disable(s3c24xx_ac97.ac97_clk); - clk_put(s3c24xx_ac97.ac97_clk); - iounmap(s3c24xx_ac97.regs); -} - -static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out; - else - cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in; - - return 0; -} - -static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch(cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - else - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - else - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; - break; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - return 0; -} - -static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in; - - return 0; -} - -static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - u32 ac_glbctrl; - - ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - switch(cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - } - writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); - - return 0; -} - -#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) - -struct snd_soc_cpu_dai s3c2443_ac97_dai[] = { -{ - .name = "s3c2443-ac97", - .id = 0, - .type = SND_SOC_DAI_AC97, - .probe = s3c2443_ac97_probe, - .remove = s3c2443_ac97_remove, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = s3c2443_ac97_hw_params, - .trigger = s3c2443_ac97_trigger}, -}, -{ - .name = "pxa2xx-ac97-mic", - .id = 1, - .type = SND_SOC_DAI_AC97, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = s3c2443_AC97_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .hw_params = s3c2443_ac97_hw_mic_params, - .trigger = s3c2443_ac97_mic_trigger,}, -}, -}; - -EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -MODULE_AUTHOR("Graeme Gregory"); -MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h b/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h deleted file mode 100644 index 2b835e8260fa..000000000000 --- a/trunk/sound/soc/s3c24xx/s3c24xx-ac97.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * s3c24xx-ac97.c -- ALSA Soc Audio Layer - * - * (c) 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 10th Nov 2006 Initial version. - */ - -#ifndef S3C24XXAC97_H_ -#define S3C24XXAC97_H_ - -#define AC_CMD_ADDR(x) (x << 16) -#define AC_CMD_DATA(x) (x & 0xffff) - -extern struct snd_soc_cpu_dai s3c2443_ac97_dai[]; - -#endif /*S3C24XXAC97_H_*/ diff --git a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c index 39f02462e07d..8ca314dc8891 100644 --- a/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -344,11 +344,11 @@ static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, DBG("Entered %s\n", __FUNCTION__); switch (div_id) { - case S3C24XX_DIV_BCLK: + case S3C24XX_DIV_MCLK: reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); break; - case S3C24XX_DIV_MCLK: + case S3C24XX_DIV_BCLK: reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); break; diff --git a/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c b/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c deleted file mode 100644 index d46cd811ceb3..000000000000 --- a/trunk/sound/soc/s3c24xx/smdk2443_wm9710.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * smdk2443_wm9710.c -- SoC audio for smdk2443 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Revision history - * 8th Mar 2007 Initial version. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "../codecs/ac97.h" -#include "s3c24xx-pcm.h" -#include "s3c24xx-ac97.h" - -static struct snd_soc_machine smdk2443; - -static struct snd_soc_dai_link smdk2443_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &s3c2443_ac97_dai[0], - .codec_dai = &ac97_dai, -}, -}; - -static struct snd_soc_machine smdk2443 = { - .name = "SMDK2443", - .dai_link = smdk2443_dai, - .num_links = ARRAY_SIZE(smdk2443_dai), -}; - -static struct snd_soc_device smdk2443_snd_ac97_devdata = { - .machine = &smdk2443, - .platform = &s3c24xx_soc_platform, - .codec_dev = &soc_codec_dev_ac97, -}; - -static struct platform_device *smdk2443_snd_ac97_device; - -static int __init smdk2443_init(void) -{ - int ret; - - smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!smdk2443_snd_ac97_device) - return -ENOMEM; - - platform_set_drvdata(smdk2443_snd_ac97_device, - &smdk2443_snd_ac97_devdata); - smdk2443_snd_ac97_devdata.dev = &smdk2443_snd_ac97_device->dev; - ret = platform_device_add(smdk2443_snd_ac97_device); - - if (ret) - platform_device_put(smdk2443_snd_ac97_device); - - return ret; -} - -static void __exit smdk2443_exit(void) -{ - platform_device_unregister(smdk2443_snd_ac97_device); -} - -module_init(smdk2443_init); -module_exit(smdk2443_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/sh/Kconfig b/trunk/sound/soc/sh/Kconfig deleted file mode 100644 index f03220d23e73..000000000000 --- a/trunk/sound/soc/sh/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -menu "SoC Audio support for SuperH" - -config SND_SOC_PCM_SH7760 - tristate "SoC Audio support for Renesas SH7760" - depends on CPU_SUBTYPE_SH7760 && SND_SOC && SH_DMABRG - help - Enable this option for SH7760 AC97/I2S audio support. - - -## -## Audio unit modules -## - -config SND_SOC_SH4_HAC - select AC97_BUS - select SND_SOC_AC97_BUS - select SND_AC97_CODEC - tristate - -config SND_SOC_SH4_SSI - tristate - - - -## -## Boards -## - -config SND_SH7760_AC97 - tristate "SH7760 AC97 sound support" - depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760 - select SND_SOC_SH4_HAC - select SND_SOC_AC97_CODEC - help - This option enables generic sound support for the first - AC97 unit of the SH7760. - -endmenu diff --git a/trunk/sound/soc/sh/Makefile b/trunk/sound/soc/sh/Makefile deleted file mode 100644 index a8e8ab81cc6a..000000000000 --- a/trunk/sound/soc/sh/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -## DMA engines -snd-soc-dma-sh7760-objs := dma-sh7760.o -obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o - -## audio units found on some SH-4 -snd-soc-hac-objs := hac.o -snd-soc-ssi-objs := ssi.o -obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o -obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o - -## boards -snd-soc-sh7760-ac97-objs := sh7760-ac97.o - -obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o diff --git a/trunk/sound/soc/sh/dma-sh7760.c b/trunk/sound/soc/sh/dma-sh7760.c deleted file mode 100644 index cdee374b843e..000000000000 --- a/trunk/sound/soc/sh/dma-sh7760.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * SH7760 ("camelot") DMABRG audio DMA unit support - * - * Copyright (C) 2007 Manuel Lauss - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which - * trigger an interrupt when one half of the programmed transfer size - * has been xmitted. - * - * FIXME: little-endian only for now - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* registers and bits */ -#define BRGATXSAR 0x00 -#define BRGARXDAR 0x04 -#define BRGATXTCR 0x08 -#define BRGARXTCR 0x0C -#define BRGACR 0x10 -#define BRGATXTCNT 0x14 -#define BRGARXTCNT 0x18 - -#define ACR_RAR (1 << 18) -#define ACR_RDS (1 << 17) -#define ACR_RDE (1 << 16) -#define ACR_TAR (1 << 2) -#define ACR_TDS (1 << 1) -#define ACR_TDE (1 << 0) - -/* receiver/transmitter data alignment */ -#define ACR_RAM_NONE (0 << 24) -#define ACR_RAM_4BYTE (1 << 24) -#define ACR_RAM_2WORD (2 << 24) -#define ACR_TAM_NONE (0 << 8) -#define ACR_TAM_4BYTE (1 << 8) -#define ACR_TAM_2WORD (2 << 8) - - -struct camelot_pcm { - unsigned long mmio; /* DMABRG audio channel control reg MMIO */ - unsigned int txid; /* ID of first DMABRG IRQ for this unit */ - - struct snd_pcm_substream *tx_ss; - unsigned long tx_period_size; - unsigned int tx_period; - - struct snd_pcm_substream *rx_ss; - unsigned long rx_period_size; - unsigned int rx_period; - -} cam_pcm_data[2] = { - { - .mmio = 0xFE3C0040, - .txid = DMABRGIRQ_A0TXF, - }, - { - .mmio = 0xFE3C0060, - .txid = DMABRGIRQ_A1TXF, - }, -}; - -#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x))) - -/* - * set a minimum of 16kb per period, to avoid interrupt-"storm" and - * resulting skipping. In general, the bigger the minimum size, the - * better for overall system performance. (The SH7760 is a puny CPU - * with a slow SDRAM interface and poor internal bus bandwidth, - * *especially* when the LCDC is active). The minimum for the DMAC - * is 8 bytes; 16kbytes are enough to get skip-free playback of a - * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain - * reasonable responsiveness in MPlayer. - */ -#define DMABRG_PERIOD_MIN 16 * 1024 -#define DMABRG_PERIOD_MAX 0x03fffffc -#define DMABRG_PREALLOC_BUFFER 32 * 1024 -#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 - -/* support everything the SSI supports */ -#define DMABRG_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define DMABRG_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -static struct snd_pcm_hardware camelot_pcm_hardware = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID), - .formats = DMABRG_FMTS, - .rates = DMABRG_RATES, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 8, /* max of the SSI */ - .buffer_bytes_max = DMABRG_PERIOD_MAX, - .period_bytes_min = DMABRG_PERIOD_MIN, - .period_bytes_max = DMABRG_PERIOD_MAX / 2, - .periods_min = 2, - .periods_max = 2, - .fifo_size = 128, -}; - -static void camelot_txdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->tx_period ^= 1; - snd_pcm_period_elapsed(cam->tx_ss); -} - -static void camelot_rxdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->rx_period ^= 1; - snd_pcm_period_elapsed(cam->rx_ss); -} - -static int camelot_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret, dmairq; - - snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware); - - /* DMABRG buffer half/full events */ - dmairq = (recv) ? cam->txid + 2 : cam->txid; - if (recv) { - cam->rx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - rtd->dai->cpu_dai->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); - } else { - cam->tx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - rtd->dai->cpu_dai->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); - } - return 0; -} - -static int camelot_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int dmairq; - - dmairq = (recv) ? cam->txid + 2 : cam->txid; - - if (recv) - cam->rx_ss = NULL; - else - cam->tx_ss = NULL; - - dmabrg_free_irq(dmairq + 1); - dmabrg_free_irq(dmairq); - - return 0; -} - -static int camelot_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret; - - ret = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (ret < 0) - return ret; - - if (recv) { - cam->rx_period_size = params_period_bytes(hw_params); - cam->rx_period = 0; - } else { - cam->tx_period_size = params_period_bytes(hw_params); - cam->tx_period = 0; - } - return 0; -} - -static int camelot_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int camelot_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - - pr_debug("PCM data: addr 0x%08ulx len %d\n", - (u32)runtime->dma_addr, runtime->dma_bytes); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGATXTCR) = runtime->dma_bytes; - } else { - BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGARXTCR) = runtime->dma_bytes; - } - - return 0; -} - -static inline void dmabrg_play_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: XFER start, auto-addr-reload */ - BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD; -} - -static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data transmission */ - BRGREG(BRGACR) = acr | ACR_TDS; -} - -static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: recv start, auto-reload */ - BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD; -} - -static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data receiver */ - BRGREG(BRGACR) = acr | ACR_RDS; -} - -static int camelot_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (recv) - dmabrg_rec_dma_start(cam); - else - dmabrg_play_dma_start(cam); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (recv) - dmabrg_rec_dma_stop(cam); - else - dmabrg_play_dma_stop(cam); - break; - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct camelot_pcm *cam = &cam_pcm_data[rtd->dai->cpu_dai->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - unsigned long pos; - - /* cannot use the DMABRG pointer register: under load, by the - * time ALSA comes around to read the register, it is already - * far ahead (or worse, already done with the fragment) of the - * position at the time the IRQ was triggered, which results in - * fast-playback sound in my test application (ScummVM) - */ - if (recv) - pos = cam->rx_period ? cam->rx_period_size : 0; - else - pos = cam->tx_period ? cam->tx_period_size : 0; - - return bytes_to_frames(runtime, pos); -} - -static struct snd_pcm_ops camelot_pcm_ops = { - .open = camelot_pcm_open, - .close = camelot_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = camelot_hw_params, - .hw_free = camelot_hw_free, - .prepare = camelot_prepare, - .trigger = camelot_trigger, - .pointer = camelot_pos, -}; - -static void camelot_pcm_free(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -static int camelot_pcm_new(struct snd_card *card, - struct snd_soc_codec_dai *dai, - struct snd_pcm *pcm) -{ - /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel - * in MMAP mode (i.e. aplay -M) - */ - snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX); - - return 0; -} - -struct snd_soc_platform sh7760_soc_platform = { - .name = "sh7760-pcm", - .pcm_ops = &camelot_pcm_ops, - .pcm_new = camelot_pcm_new, - .pcm_free = camelot_pcm_free, -}; -EXPORT_SYMBOL_GPL(sh7760_soc_platform); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/hac.c b/trunk/sound/soc/sh/hac.c deleted file mode 100644 index 8e3f03908cdb..000000000000 --- a/trunk/sound/soc/sh/hac.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Hitachi Audio Controller (AC97) support for SH7760/SH7780 - * - * Copyright (c) 2007 Manuel Lauss - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * dont forget to set IPSEL/OMSEL register bits (in your board code) to - * enable HAC output pins! - */ - -/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only - * the FIRST can be used since ASoC does not pass any information to the - * ac97_read/write() functions regarding WHICH unit to use. You'll have - * to edit the code a bit to use the other AC97 unit. --mlau - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* regs and bits */ -#define HACCR 0x08 -#define HACCSAR 0x20 -#define HACCSDR 0x24 -#define HACPCML 0x28 -#define HACPCMR 0x2C -#define HACTIER 0x50 -#define HACTSR 0x54 -#define HACRIER 0x58 -#define HACRSR 0x5C -#define HACACR 0x60 - -#define CR_CR (1 << 15) /* "codec-ready" indicator */ -#define CR_CDRT (1 << 11) /* cold reset */ -#define CR_WMRT (1 << 10) /* warm reset */ -#define CR_B9 (1 << 9) /* the mysterious "bit 9" */ -#define CR_ST (1 << 5) /* AC97 link start bit */ - -#define CSAR_RD (1 << 19) /* AC97 data read bit */ -#define CSAR_WR (0) - -#define TSR_CMDAMT (1 << 31) -#define TSR_CMDDMT (1 << 30) - -#define RSR_STARY (1 << 22) -#define RSR_STDRY (1 << 21) - -#define ACR_DMARX16 (1 << 30) -#define ACR_DMATX16 (1 << 29) -#define ACR_TX12ATOM (1 << 26) -#define ACR_DMARX20 ((1 << 24) | (1 << 22)) -#define ACR_DMATX20 ((1 << 23) | (1 << 21)) - -#define CSDR_SHIFT 4 -#define CSDR_MASK (0xffff << CSDR_SHIFT) -#define CSAR_SHIFT 12 -#define CSAR_MASK (0x7f << CSAR_SHIFT) - -#define AC97_WRITE_RETRY 1 -#define AC97_READ_RETRY 5 - -/* manual-suggested AC97 codec access timeouts (us) */ -#define TMO_E1 500 /* 21 < E1 < 1000 */ -#define TMO_E2 13 /* 13 < E2 */ -#define TMO_E3 21 /* 21 < E3 */ -#define TMO_E4 500 /* 21 < E4 < 1000 */ - -struct hac_priv { - unsigned long mmio; /* HAC base address */ -} hac_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE240000, - }, - { - .mmio = 0xFE250000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE40000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg))) - -/* - * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906) - */ -static int hac_get_codec_data(struct hac_priv *hac, unsigned short r, - unsigned short *v) -{ - unsigned int to1, to2, i; - unsigned short adr; - - for (i = 0; i < AC97_READ_RETRY; ++i) { - *v = 0; - /* wait for HAC to receive something from the codec */ - for (to1 = TMO_E4; - to1 && !(HACREG(HACRSR) & RSR_STARY); - --to1) - udelay(1); - for (to2 = TMO_E4; - to2 && !(HACREG(HACRSR) & RSR_STDRY); - --to2) - udelay(1); - - if (!to1 && !to2) - return 0; /* codec comm is down */ - - adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT); - *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT); - - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - - if (r == adr) - break; - - /* manual says: wait at least 21 usec before retrying */ - udelay(21); - } - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - return (i < AC97_READ_RETRY); -} - -static unsigned short hac_read_codec_aux(struct hac_priv *hac, - unsigned short reg) -{ - unsigned short val; - unsigned int i, to; - - for (i = 0; i < AC97_READ_RETRY; i++) { - /* send_read_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDAMT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD; - local_irq_enable(); - - for (to = TMO_E3; - to && !(HACREG(HACTSR) & TSR_CMDAMT); - --to) - udelay(1); - - HACREG(HACTSR) &= ~TSR_CMDAMT; - val = 0; - if (hac_get_codec_data(hac, reg, &val) != 0) - break; - } - - if (i == AC97_READ_RETRY) - return ~0; - - return val; -} - -static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int i, to; - /* write_codec_aux */ - for (i = 0; i < AC97_WRITE_RETRY; i++) { - /* send_write_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT); - HACREG(HACCSDR) = (val << CSDR_SHIFT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD); - local_irq_enable(); - - /* poll-wait for CMDAMT and CMDDMT */ - for (to = TMO_E1; - to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT)); - --to) - udelay(1); - - HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT); - if (to) - break; - /* timeout, try again */ - } -} - -static unsigned short hac_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - return hac_read_codec_aux(hac, reg); -} - -static void hac_ac97_warmrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int tmo; - - HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9; - msleep(10); - HACREG(HACCR) = CR_ST | CR_B9; - for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--) - udelay(1); - - if (!tmo) - printk(KERN_INFO "hac: reset: AC97 link down!\n"); - /* settings this bit lets us have a conversation with codec */ - HACREG(HACACR) |= ACR_TX12ATOM; -} - -static void hac_ac97_coldrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac; - hac = &hac_cpu_data[unit_id]; - - HACREG(HACCR) = 0; - HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9; - msleep(10); - hac_ac97_warmrst(ac97); -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = hac_ac97_read, - .write = hac_ac97_write, - .reset = hac_ac97_coldrst, - .warm_reset = hac_ac97_warmrst, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int hac_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; - int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - - switch (params->msbits) { - case 16: - HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16; - HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20; - break; - case 20: - HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16; - HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20; - break; - default: - pr_debug("hac: invalid depth %d bit\n", params->msbits); - return -EINVAL; - break; - } - - return 0; -} - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define AC97_FMTS \ - SNDRV_PCM_FMTBIT_S16_LE - -struct snd_soc_cpu_dai sh4_hac_dai[] = { -{ - .name = "HAC0", - .id = 0, - .type = SND_SOC_DAI_AC97, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = { - .hw_params = hac_hw_params, - }, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "HAC1", - .id = 1, - .type = SND_SOC_DAI_AC97, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = { - .hw_params = hac_hw_params, - }, - -}, -#endif -}; -EXPORT_SYMBOL_GPL(sh4_hac_dai); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/sh7760-ac97.c b/trunk/sound/soc/sh/sh7760-ac97.c deleted file mode 100644 index 5563f14511fa..000000000000 --- a/trunk/sound/soc/sh/sh7760-ac97.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Generic AC97 sound support for SH7760 - * - * (c) 2007 Manuel Lauss - * - * Licensed under the GPLv2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../codecs/ac97.h" - -#define IPSEL 0xFE400034 - -/* platform specific structs can be declared here */ -extern struct snd_soc_cpu_dai sh4_hac_dai[2]; -extern struct snd_soc_platform sh7760_soc_platform; - -static int machine_init(struct snd_soc_codec *codec) -{ - snd_soc_dapm_sync_endpoints(codec); - return 0; -} - -static struct snd_soc_dai_link sh7760_ac97_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &sh4_hac_dai[0], /* HAC0 */ - .codec_dai = &ac97_dai, - .init = machine_init, - .ops = NULL, -}; - -static struct snd_soc_machine sh7760_ac97_soc_machine = { - .name = "SH7760 AC97", - .dai_link = &sh7760_ac97_dai, - .num_links = 1, -}; - -static struct snd_soc_device sh7760_ac97_snd_devdata = { - .machine = &sh7760_ac97_soc_machine, - .platform = &sh7760_soc_platform, - .codec_dev = &soc_codec_dev_ac97, -}; - -static struct platform_device *sh7760_ac97_snd_device; - -static int __init sh7760_ac97_init(void) -{ - int ret; - unsigned short ipsel; - - /* enable both AC97 controllers in pinmux reg */ - ipsel = ctrl_inw(IPSEL); - ctrl_outw(ipsel | (3 << 10), IPSEL); - - ret = -ENOMEM; - sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1); - if (!sh7760_ac97_snd_device) - goto out; - - platform_set_drvdata(sh7760_ac97_snd_device, - &sh7760_ac97_snd_devdata); - sh7760_ac97_snd_devdata.dev = &sh7760_ac97_snd_device->dev; - ret = platform_device_add(sh7760_ac97_snd_device); - - if (ret) - platform_device_put(sh7760_ac97_snd_device); - -out: - return ret; -} - -static void __exit sh7760_ac97_exit(void) -{ - platform_device_unregister(sh7760_ac97_snd_device); -} - -module_init(sh7760_ac97_init); -module_exit(sh7760_ac97_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/soc/sh/ssi.c b/trunk/sound/soc/sh/ssi.c deleted file mode 100644 index b72bc316cb8e..000000000000 --- a/trunk/sound/soc/sh/ssi.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Serial Sound Interface (I2S) support for SH7760/SH7780 - * - * Copyright (c) 2007 Manuel Lauss - * - * licensed under the terms outlined in the file COPYING at the root - * of the linux kernel sources. - * - * dont forget to set IPSEL/OMSEL register bits (in your board code) to - * enable SSI output pins! - */ - -/* - * LIMITATIONS: - * The SSI unit has only one physical data line, so full duplex is - * impossible. This can be remedied on the SH7760 by using the - * other SSI unit for recording; however the SH7780 has only 1 SSI - * unit, and its pins are shared with the AC97 unit, among others. - * - * FEATURES: - * The SSI features "compressed mode": in this mode it continuously - * streams PCM data over the I2S lines and uses LRCK as a handshake - * signal. Can be used to send compressed data (AC3/DTS) to a DSP. - * The number of bits sent over the wire in a frame can be adjusted - * and can be independent from the actual sample bit depth. This is - * useful to support TDM mode codecs like the AD1939 which have a - * fixed TDM slot size, regardless of sample resolution. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SSICR 0x00 -#define SSISR 0x04 - -#define CR_DMAEN (1 << 28) -#define CR_CHNL_SHIFT 22 -#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT) -#define CR_DWL_SHIFT 19 -#define CR_DWL_MASK (7 << CR_DWL_SHIFT) -#define CR_SWL_SHIFT 16 -#define CR_SWL_MASK (7 << CR_SWL_SHIFT) -#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */ -#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */ -#define CR_SCKP (1 << 13) /* I2Sclock polarity */ -#define CR_SWSP (1 << 12) /* LRCK polarity */ -#define CR_SPDP (1 << 11) -#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */ -#define CR_PDTA (1 << 9) /* fifo data alignment */ -#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */ -#define CR_BREN (1 << 7) /* clock gating in burst mode */ -#define CR_CKDIV_SHIFT 4 -#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */ -#define CR_MUTE (1 << 3) /* SSI mute */ -#define CR_CPEN (1 << 2) /* compressed mode */ -#define CR_TRMD (1 << 1) /* transmit/receive select */ -#define CR_EN (1 << 0) /* enable SSI */ - -#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg))) - -struct ssi_priv { - unsigned long mmio; - unsigned long sysclk; - int inuse; -} ssi_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE680000, - }, - { - .mmio = 0xFE690000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE70000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -/* - * track usage of the SSI; it is simplex-only so prevent attempts of - * concurrent playback + capture. FIXME: any locking required? - */ -static int ssi_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - if (ssi->inuse) { - pr_debug("ssi: already in use!\n"); - return -EBUSY; - } else - ssi->inuse = 1; - return 0; -} - -static void ssi_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - - ssi->inuse = 0; -} - -static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - SSIREG(SSICR) |= CR_DMAEN | CR_EN; - break; - case SNDRV_PCM_TRIGGER_STOP: - SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ssi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; - unsigned long ssicr = SSIREG(SSICR); - unsigned int bits, channels, swl, recv, i; - - channels = params_channels(params); - bits = params->msbits; - recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; - - pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); - pr_debug("bits: %d channels: %d\n", bits, channels); - - ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | - CR_SWL_MASK); - - /* direction (send/receive) */ - if (!recv) - ssicr |= CR_TRMD; /* transmit */ - - /* channels */ - if ((channels < 2) || (channels > 8) || (channels & 1)) { - pr_debug("ssi: invalid number of channels\n"); - return -EINVAL; - } - ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT; - - /* DATA WORD LENGTH (DWL): databits in audio sample */ - i = 0; - switch (bits) { - case 32: ++i; - case 24: ++i; - case 22: ++i; - case 20: ++i; - case 18: ++i; - case 16: ++i; - ssicr |= i << CR_DWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid sample width\n"); - return -EINVAL; - } - - /* - * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S - * wires. This is usually bits_per_sample x channels/2; i.e. in - * Stereo mode the SWL equals DWL. SWL can be bigger than the - * product of (channels_per_slot x samplebits), e.g. for codecs - * like the AD1939 which only accept 32bit wide TDM slots. For - * "standard" I2S operation we set SWL = chans / 2 * DWL here. - * Waiting for ASoC to get TDM support ;-) - */ - if ((bits > 16) && (bits <= 24)) { - bits = 24; /* these are padded by the SSI */ - /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */ - } - i = 0; - swl = (bits * channels) / 2; - switch (swl) { - case 256: ++i; - case 128: ++i; - case 64: ++i; - case 48: ++i; - case 32: ++i; - case 16: ++i; - ssicr |= i << CR_SWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid system word length computed\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - - pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr); - return 0; -} - -static int ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, int clk_id, - unsigned int freq, int dir) -{ - struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; - - ssi->sysclk = freq; - - return 0; -} - -/* - * This divider is used to generate the SSI_SCK (I2S bitclock) from the - * clock at the HAC_BIT_CLK ("oversampling clock") pin. - */ -static int ssi_set_clkdiv(struct snd_soc_cpu_dai *dai, int did, int div) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr; - int i; - - i = 0; - ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK; - switch (div) { - case 16: ++i; - case 8: ++i; - case 4: ++i; - case 2: ++i; - SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT); - case 1: break; - default: - pr_debug("ssi: invalid sck divider %d\n", div); - return -EINVAL; - } - - return 0; -} - -static int ssi_set_fmt(struct snd_soc_cpu_dai *dai, unsigned int fmt) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - - pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr); - - ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP | - CR_SWS_MASTER | CR_SCK_MASTER); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - case SND_SOC_DAIFMT_RIGHT_J: - ssicr |= CR_DEL | CR_PDTA; - break; - case SND_SOC_DAIFMT_LEFT_J: - ssicr |= CR_DEL; - break; - default: - pr_debug("ssi: unsupported format\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - break; - case SND_SOC_DAIFMT_GATED: - ssicr |= CR_BREN; - break; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - ssicr |= CR_SCKP; /* sample data at low clkedge */ - break; - case SND_SOC_DAIFMT_NB_IF: - ssicr |= CR_SCKP | CR_SWSP; - break; - case SND_SOC_DAIFMT_IB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - ssicr |= CR_SWSP; /* word select starts low */ - break; - default: - pr_debug("ssi: invalid inversion\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - break; - case SND_SOC_DAIFMT_CBS_CFM: - ssicr |= CR_SCK_MASTER; - break; - case SND_SOC_DAIFMT_CBM_CFS: - ssicr |= CR_SWS_MASTER; - break; - case SND_SOC_DAIFMT_CBS_CFS: - ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; - break; - default: - pr_debug("ssi: invalid master/slave configuration\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr); - - return 0; -} - -/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in - * Master mode, so really this is board specific; the SSI can do any - * rate with the right bitclk and divider settings. - */ -#define SSI_RATES \ - SNDRV_PCM_RATE_8000_192000 - -/* the SSI can do 8-32 bit samples, with 8 possible channels */ -#define SSI_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -struct snd_soc_cpu_dai sh4_ssi_dai[] = { -{ - .name = "SSI0", - .id = 0, - .type = SND_SOC_DAI_I2S, - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - }, - .dai_ops = { - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, - }, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "SSI1", - .id = 1, - .type = SND_SOC_DAI_I2S, - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - }, - .dai_ops = { - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, - }, -}, -#endif -}; -EXPORT_SYMBOL_GPL(sh4_ssi_dai); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 7bd5852fcc0d..8ebc1adb5ed9 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -2350,9 +2350,7 @@ static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat * return 1; break; case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ - if (device_setup[chip->index] == 0x00 || - fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3) - return 1; + return 1; } return 0; } @@ -2532,18 +2530,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat * * but we give normal PCM format to get the existing * apps working... */ - switch (chip->usb_id) { - - case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ - if (device_setup[chip->index] == 0x00 && - fp->altsetting == 6) - pcm_format = SNDRV_PCM_FORMAT_S16_BE; - else - pcm_format = SNDRV_PCM_FORMAT_S16_LE; - break; - default: - pcm_format = SNDRV_PCM_FORMAT_S16_LE; - } + pcm_format = SNDRV_PCM_FORMAT_S16_LE; } else { pcm_format = parse_audio_format_i_type(chip, fp, format, fmt); if (pcm_format < 0) @@ -3264,11 +3251,6 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, int iface, int altno) { - /* Reset ALL ifaces to 0 altsetting. - * Call it for every possible altsetting of every interface. - */ - usb_set_interface(chip->dev, iface, 0); - if (device_setup[chip->index] & AUDIOPHILE_SET) { if ((device_setup[chip->index] & AUDIOPHILE_SET_DTS) && altno != 6) diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index 5a2f518c6629..374fbf657a2d 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -52,24 +52,6 @@ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, -{ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .idVendor = 0x046d, - .idProduct = 0x08ae, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL -}, -{ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .idVendor = 0x046d, - .idProduct = 0x08c6, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL -}, { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_CLASS | @@ -1069,15 +1051,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_MIDI_STANDARD_INTERFACE } }, -{ - USB_DEVICE(0x0582, 0x0060), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "EXR Series", - .ifnum = 0, - .type = QUIRK_MIDI_STANDARD_INTERFACE - } -}, + /* TODO: add Roland EXR support */ { /* has ID 0x0067 when not in "Advanced Driver" mode */ USB_DEVICE(0x0582, 0x0065), @@ -1120,19 +1094,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - USB_DEVICE(0x582, 0x00a6), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "Juno-G", - .ifnum = 0, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - } -}, { /* * This quirk is for the "Advanced" modes of the Edirol UA-25. * If the switch is not in an advanced setting, the UA-25 has @@ -1269,37 +1230,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, /* TODO: add Edirol MD-P1 support */ -{ - /* Roland SH-201 */ - USB_DEVICE(0x0582, 0x00ad), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "SH-201", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = & (const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0001, - .in_cables = 0x0001 - } - }, - { - .ifnum = -1 - } - } - } -}, /* Guillemot devices */ { diff --git a/trunk/sound/usb/usx2y/usbusx2yaudio.c b/trunk/sound/usb/usx2y/usbusx2yaudio.c index 48e9aa3f18c9..0a352e46862f 100644 --- a/trunk/sound/usb/usx2y/usbusx2yaudio.c +++ b/trunk/sound/usb/usx2y/usbusx2yaudio.c @@ -935,9 +935,10 @@ static struct snd_pcm_ops snd_usX2Y_pcm_ops = */ static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream) { - kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); - usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; - + if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) { + kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]); + usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL; + } kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]); usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL; }