]> err.no Git - linux-2.6/commitdiff
[PATCH] The scheduled removal of some OSS drivers
authorAdrian Bunk <bunk@stusta.de>
Wed, 4 Oct 2006 09:17:22 +0000 (02:17 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 4 Oct 2006 14:55:32 +0000 (07:55 -0700)
This patch contains the scheduled removal of OSS drivers that:
- have ALSA drivers for the same hardware without known regressions and
- whose Kconfig options have been removed in 2.6.17.

[michal.k.k.piotrowski@gmail.com: build fix]
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
81 files changed:
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
Documentation/sound/oss/AWE32 [deleted file]
Documentation/sound/oss/CMI8338 [deleted file]
Documentation/sound/oss/INSTALL.awe [deleted file]
Documentation/sound/oss/MAD16 [deleted file]
Documentation/sound/oss/Maestro [deleted file]
Documentation/sound/oss/Maestro3 [deleted file]
Documentation/sound/oss/NEWS [deleted file]
Documentation/sound/oss/OPL3-SA [deleted file]
Documentation/sound/oss/README.awe [deleted file]
Documentation/sound/oss/Wavefront [deleted file]
Documentation/sound/oss/es1370 [deleted file]
Documentation/sound/oss/rme96xx [deleted file]
Documentation/sound/oss/solo1 [deleted file]
Documentation/sound/oss/sonicvibes [deleted file]
MAINTAINERS
include/linux/Kbuild
include/linux/ac97_codec.h
include/linux/sound.h
include/linux/wavefront.h [deleted file]
sound/oss/Makefile
sound/oss/ac97.c
sound/oss/ac97.h
sound/oss/ac97_codec.c
sound/oss/ac97_plugin_ad1980.c [deleted file]
sound/oss/ad1848.c
sound/oss/ad1848.h
sound/oss/ali5455.c [deleted file]
sound/oss/au1000.c [deleted file]
sound/oss/audio_syms.c
sound/oss/awe_hw.h [deleted file]
sound/oss/awe_wave.c [deleted file]
sound/oss/awe_wave.h [deleted file]
sound/oss/cmpci.c [deleted file]
sound/oss/cs4281/Makefile [deleted file]
sound/oss/cs4281/cs4281_hwdefs.h [deleted file]
sound/oss/cs4281/cs4281_wrapper-24.c [deleted file]
sound/oss/cs4281/cs4281m.c [deleted file]
sound/oss/cs4281/cs4281pm-24.c [deleted file]
sound/oss/cs4281/cs4281pm.h [deleted file]
sound/oss/dm.h [deleted file]
sound/oss/dmabuf.c
sound/oss/es1370.c [deleted file]
sound/oss/esssolo1.c [deleted file]
sound/oss/forte.c [deleted file]
sound/oss/gus.h [deleted file]
sound/oss/gus_card.c [deleted file]
sound/oss/gus_hw.h [deleted file]
sound/oss/gus_linearvol.h [deleted file]
sound/oss/gus_midi.c [deleted file]
sound/oss/gus_vol.c [deleted file]
sound/oss/gus_wave.c [deleted file]
sound/oss/harmony.c [deleted file]
sound/oss/ics2101.c [deleted file]
sound/oss/iwmem.h [deleted file]
sound/oss/mad16.c [deleted file]
sound/oss/maestro.c [deleted file]
sound/oss/maestro.h [deleted file]
sound/oss/maestro3.c [deleted file]
sound/oss/maestro3.h [deleted file]
sound/oss/maui.c [deleted file]
sound/oss/mpu401.c
sound/oss/mpu401.h
sound/oss/opl3sa.c [deleted file]
sound/oss/rme96xx.c [deleted file]
sound/oss/rme96xx.h [deleted file]
sound/oss/sequencer.c
sound/oss/sequencer_syms.c
sound/oss/sgalaxy.c [deleted file]
sound/oss/sonicvibes.c [deleted file]
sound/oss/sound_calls.h
sound/oss/tuning.h
sound/oss/wavfront.c [deleted file]
sound/oss/wf_midi.c [deleted file]
sound/oss/ymfpci.c [deleted file]
sound/oss/ymfpci.h [deleted file]
sound/oss/ymfpci_image.h [deleted file]
sound/oss/yss225.c [deleted file]
sound/oss/yss225.h [deleted file]
sound/sound_core.c

index 42b95e0ad558d3de7fd1cd50c0455ba164cfc26c..24f3c63b301710ba461e04e9fc353c9f4a5eabcd 100644 (file)
@@ -29,14 +29,6 @@ Who: Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  drivers that were depending on OBSOLETE_OSS_DRIVER
-        (config options already removed)
-When:  before 2.6.19
-Why:   OSS drivers with ALSA replacements
-Who:   Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:  raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 When:  November 2006
 Why:   Deprecated in favour of the new ioctl-based rawiso interface, which is
index e1543a32a55727456e1292340243c2f003e23910..ff571f9298e0530bb38d3ffdaabea01f1b4aec17 100644 (file)
@@ -289,9 +289,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        autotest        [IA64]
 
-       awe=            [HW,OSS] AWE32/SB32/AWE64 wave table synth
-                       Format: <io>,<memsize>,<isapnp>
-
        aztcd=          [HW,CD] Aztech CD268 CDROM driver
                        Format: <io>,0x79 (?)
 
@@ -536,10 +533,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Default value is 0.
                        Value can be changed at runtime via /selinux/enforce.
 
-       es1370=         [HW,OSS]
-                       Format: <lineout>[,<micbias>]
-                       See also header of sound/oss/es1370.c.
-
        es1371=         [HW,OSS]
                        Format: <spdif>,[<nomix>,[<amplifier>]]
                        See also header of sound/oss/es1371.c.
@@ -580,9 +573,6 @@ and is between 256 and 4096 characters. It is defined in the file
        gscd=           [HW,CD]
                        Format: <io>
 
-       gus=            [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma16>
-
        gvp11=          [HW,SCSI]
 
        hashdist=       [KNL,NUMA] Large hashes allocated during boot
@@ -841,12 +831,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        (machvec) in a generic kernel.
                        Example: machvec=hpzx1_swiotlb
 
-       mad16=          [HW,OSS] Format:
-                       <io>,<irq>,<dma>,<dma16>,<mpu_io>,<mpu_irq>,<joystick>
-
-       maui=           [HW,OSS]
-                       Format: <io>,<irq>
-
        max_loop=       [LOOP] Maximum number of loopback devices that can
                        be mounted
                        Format: <1-256>
@@ -1114,9 +1098,6 @@ and is between 256 and 4096 characters. It is defined in the file
        opl3=           [HW,OSS]
                        Format: <io>
 
-       opl3sa=         [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma2>,<mpu_io>,<mpu_irq>
-
        opl3sa2=        [HW,OSS] Format:
                        <io>,<irq>,<dma>,<dma2>,<mss_io>,<mpu_io>,<ymode>,<loopback>[,<isapnp>,<multiple]
 
@@ -1451,9 +1432,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        sg_def_reserved_size=   [SCSI]
 
-       sgalaxy=        [HW,OSS]
-                       Format: <io>,<irq>,<dma>,<dma2>,<sgbase>
-
        shapers=        [NET]
                        Maximal number of shapers.
 
@@ -1594,9 +1572,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        snd-ymfpci=     [HW,ALSA]
 
-       sonicvibes=     [HW,OSS]
-                       Format: <reverb>
-
        sonycd535=      [HW,CD]
                        Format: <io>[,<irq>]
 
diff --git a/Documentation/sound/oss/AWE32 b/Documentation/sound/oss/AWE32
deleted file mode 100644 (file)
index b5908a6..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-       Installing and using Creative AWE midi sound under Linux.
-
-This documentation is devoted to the Creative Sound Blaster AWE32, AWE64 and 
-SB32.
-
-1) Make sure you have an ORIGINAL Creative SB32, AWE32 or AWE64 card. This
-   is important, because the driver works only with real Creative cards.
-
-2) The first thing you need to do is re-compile your kernel with support for
-   your sound card. Run your favourite tool to configure the kernel and when
-   you get to the "Sound" menu you should enable support for the following:
-
-   Sound card support,
-   OSS sound modules,
-   100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support,
-   AWE32 synth
-
-   If your card is "Plug and Play" you will also need to enable these two
-   options, found under the "Plug and Play configuration" menu:
-
-   Plug and Play support
-   ISA Plug and Play support
-
-   Now compile and install the kernel in normal fashion. If you don't know
-   how to do this you can find instructions for this in the README file
-   located in the root directory of the kernel source.
-
-3) Before you can start playing midi files you will have to load a sound
-   bank file. The utility needed for doing this is called "sfxload", and it
-   is one of the utilities found in a package called "awesfx". If this
-   package is not available in your distribution you can download the AWE
-   snapshot from Creative Labs Open Source website:
-
-   http://www.opensource.creative.com/snapshot.html
-
-   Once you have unpacked the AWE snapshot you will see a "awesfx"
-   directory. Follow the instructions in awesfx/docs/INSTALL to install the
-   utilities in this package. After doing this, sfxload should be installed
-   as:
-
-   /usr/local/bin/sfxload
-
-   To enable AWE general midi synthesis you should also get the sound bank
-   file for general midi from:
-
-   http://members.xoom.com/yar/synthgm.sbk.gz
-
-   Copy it to a directory of your choice, and unpack it there.
-
-4) Edit /etc/modprobe.conf, and insert the following lines at the end of the
-   file:
-
-  alias sound-slot-0 sb
-  alias sound-service-0-1 awe_wave
-  install awe_wave /sbin/modprobe --first-time -i awe_wave && /usr/local/bin/sfxload PATH_TO_SOUND_BANK_FILE
-
-  You will of course have to change "PATH_TO_SOUND_BANK_FILE" to the full
-  path of the sound bank file. That will enable the Sound Blaster and AWE
-  wave synthesis. To play midi files you should get one of these programs if
-  you don't already have them:
-
-  Playmidi:                    http://playmidi.openprojects.net
-
-  AWEMidi Player (drvmidi)     Included in the previously mentioned AWE
-                               snapshot.
-
-  You will probably have to pass the "-e" switch to playmidi to have it use
-  your midi device. drvmidi should work without switches.
-
-  If something goes wrong please e-mail me. All comments and suggestions are
-  welcome.
-
-                   Yaroslav Rosomakho (alons55@dialup.ptt.ru)
-                           http://www.yar.opennet.ru
-
-Last Updated: Feb 3 2001
diff --git a/Documentation/sound/oss/CMI8338 b/Documentation/sound/oss/CMI8338
deleted file mode 100644 (file)
index 387d058..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-Audio driver for CM8338/CM8738 chips by Chen-Li Tien
-
-
-HARDWARE SUPPORTED
-================================================================================
-C-Media CMI8338
-C-Media CMI8738
-On-board C-Media chips
-
-
-STEPS TO BUILD DRIVER
-================================================================================
-
-  1. Backup the Config.in and Makefile in the sound driver directory
-     (/usr/src/linux/driver/sound).
-     The Configure.help provide help when you config driver in step
-     4, please backup the original one (/usr/src/linux/Document) and
-     copy this file.
-     The cmpci is document for the driver in detail, please copy it
-     to /usr/src/linux/Document/sound so you can refer it. Backup if
-     there is already one.
-
-  2. Extract the tar file by 'tar xvzf cmpci-xx.tar.gz' in the above
-     directory.
-
-  3. Change directory to /usr/src/linux
-
-  4. Config cm8338 driver by 'make menuconfig', 'make config' or
-     'make xconfig' command.
-
-  5. Please select Sound Card (CONFIG_SOUND=m) support and CMPCI
-     driver (CONFIG_SOUND_CMPCI=m) as modules. Resident mode not tested.
-     For driver option, please refer 'DRIVER PARAMETER'
-
-  6. Compile the kernel if necessary.
-
-  7. Compile the modules by 'make modules'.
-
-  8. Install the modules by 'make modules_install'
-
-
-INSTALL DRIVER
-================================================================================
-
-  1. Before first time to run the driver, create module dependency by
-     'depmod -a'
-
-  2. To install the driver manually, enter 'modprobe cmpci'.
-
-  3. Driver installation for various distributions:
-
-    a. Slackware 4.0
-       Add the 'modprobe cmpci' command in your /etc/rc.d/rc.modules
-       file.so you can start the driver automatically each time booting.
-
-    b. Caldera OpenLinux 2.2
-       Use LISA to load the cmpci module.
-
-    c. RedHat 6.0 and S.u.S.E. 6.1
-       Add following command in /etc/conf.modules:
-
-       alias sound cmpci
-
-       also visit http://www.cmedia.com.tw for installation instruction.
-
-DRIVER PARAMETER
-================================================================================
-
-  Some functions for the cm8738 can be configured in Kernel Configuration
-  or modules parameters. Set these parameters to 1 to enable.
-
-  mpuio:       I/O ports base for MPU-401, 0 if disabled.
-  fmio:                I/O ports base for OPL-3, 0 if disabled.
-  spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
-               CD-ROM or DVD-ROM.
-  spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
-                directly.
-  speakers:     Number of speakers used.
-  use_line_as_rear:Enable this if you want to use line-in as
-                rear-out.
-  use_line_as_bass:Enable this if you want to use line-in as
-                bass-out.
-  joystick:    Enable joystick. You will need to install Linux joystick
-               driver.
-
diff --git a/Documentation/sound/oss/INSTALL.awe b/Documentation/sound/oss/INSTALL.awe
deleted file mode 100644 (file)
index 310f42c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-================================================================
-       INSTALLATION OF AWE32 SOUND DRIVER FOR LINUX
-       Takashi Iwai    <iwai@ww.uni-erlangen.de>
-================================================================
-
-----------------------------------------------------------------
-* Attention to SB-PnP Card Users
-
-If you're using PnP cards, the initialization of PnP is required
-before loading this driver.  You have now three options:
-  1. Use isapnptools.
-  2. Use in-kernel isapnp support.
-  3. Initialize PnP on DOS/Windows, then boot linux by loadlin.
-In this document, only the case 1 case is treated.
-
-----------------------------------------------------------------
-* Installation on Red Hat 5.0 Sound Driver
-
-Please use install-rh.sh under RedHat5.0 directory.
-DO NOT USE install.sh below.
-See INSTALL.RH for more details.
-
-----------------------------------------------------------------
-* Installation/Update by Shell Script
-
-  1. Become root
-
-       % su
-
-  2. If you have never configured the kernel tree yet, run make config
-    once (to make dependencies and symlinks).
-
-       # cd /usr/src/linux
-       # make xconfig
-    
-  3. Run install.sh script
-
-       # sh ./install.sh
-
-  4. Configure your kernel
-
-       (for Linux 2.[01].x user)
-       # cd /usr/src/linux
-       # make xconfig (or make menuconfig)
-
-       (for Linux 1.2.x user)
-       # cd /usr/src/linux
-       # make config
-
-    Answer YES to both "lowlevel drivers" and "AWE32 wave synth" items 
-    in Sound menu.  ("lowlevel drivers" will appear only in 2.x
-    kernel.)
-
-  5. Make your kernel (and modules), and install them as usual.
-
-       5a. make kernel image
-               # make zImage
-
-       5b. make modules and install them
-               # make modules && make modules_install
-
-       5c. If you're using lilo, copy the kernel image and run lilo.
-           Otherwise, copy the kernel image to suitable directory or
-           media for your system.
-
-  6. Reboot the kernel if necessary.
-       - If you updated only the modules, you don't have to reboot
-         the system.  Just remove the old sound modules here.
-               in 
-               # rmmod sound.o         (linux-2.0 or OSS/Free)
-               # rmmod awe_wave.o      (linux-2.1)
-
-  7. If your AWE card is a PnP and not initialized yet, you'll have to
-    do it by isapnp tools.  Otherwise, skip to 8.
-
-       This section described only a brief explanation.  For more
-       details, please see the AWE64-Mini-HOWTO or isapnp tools FAQ.
-
-       7a. If you have no isapnp.conf file, generate it by pnpdump.
-           Otherwise, skip to 7d.
-               # pnpdump > /etc/isapnp.conf
-
-       7b. Edit isapnp.conf file.  Comment out the appropriate
-           lines containing desirable I/O ports, DMA and IRQs.
-           Don't forget to enable (ACT Y) line.
-
-       7c. Add two i/o ports (0xA20 and 0xE20) in WaveTable part.
-           ex)
-               (CONFIGURE CTL0048/58128 (LD 2
-               #     ANSI string -->WaveTable<--
-                 (IO 0 (BASE 0x0620))
-                 (IO 1 (BASE 0x0A20))
-                 (IO 2 (BASE 0x0E20))
-                 (ACT Y)
-               ))
-
-       7d. Load the config file.
-           CAUTION: This will reset all PnP cards!
-
-               # isapnp /etc/isapnp.conf
-
-  8. Load the sound module (if you configured it as a module):
-
-       for 2.0 kernel or OSS/Free monolithic module:
-
-               # modprobe sound.o
-
-       for 2.1 kernel:
-
-               # modprobe sound
-               # insmod uart401
-               # insmod sb io=0x220 irq=5 dma=1 dma16=5 mpu_io=0x330
-               (These values depend on your settings.)
-               # insmod awe_wave
-               (Be sure to load awe_wave after sb!)
-
-               See Documentation/sound/oss/AWE32 for
-               more details.
-
-  9. (only for obsolete systems) If you don't have /dev/sequencer
-     device file, make it according to Readme.linux file on
-     /usr/src/linux/drivers/sound. (Run a shell script included in
-     that file). <-- This file no longer exists in the recent kernels!
-
-  10. OK, load your own soundfont file, and enjoy MIDI!
-
-       % sfxload synthgm.sbk
-       % drvmidi foo.mid
-
-  11. For more advanced use (eg. dynamic loading, virtual bank and
-      etc.), please read the awedrv FAQ or the instructions in awesfx
-      and awemidi packages.
-
-Good luck!
diff --git a/Documentation/sound/oss/MAD16 b/Documentation/sound/oss/MAD16
deleted file mode 100644 (file)
index 865dbd8..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-(This recipe has been edited to update the configuration symbols,
- and change over to modprobe.conf for 2.6)
-
-From: Shaw Carruthers <shaw@shawc.demon.co.uk>
-
-I have been using mad16 sound for some time now with no problems, current
-kernel 2.1.89
-
-lsmod shows:
-
-mad16                   5176   0 
-sb                     22044   0  [mad16]
-uart401                 5576   0  [mad16 sb]
-ad1848                 14176   1  [mad16]
-sound                  61928   0  [mad16 sb uart401 ad1848]
-
-.config has:
-
-CONFIG_SOUND=m
-CONFIG_SOUND_ADLIB=m
-CONFIG_SOUND_MAD16=m
-CONFIG_SOUND_YM3812=m
-
-modprobe.conf has:
-
-alias char-major-14-* mad16
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1  && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-
-To get the built in mixer to work this needs to be:
-
-options adlib_card io=0x388     # FM synthesizer
-options sb mad16=1
-options mad16 io=0x530 irq=7 dma=0 dma16=1 mpu_io=816 mpu_irq=5 && /usr/local/bin/aumix -w 15 -p 20 -m 0 -1 0 -2 0 -3 0 -i 0
-
-The addition of the "mpu_io=816 mpu_irq=5" to the mad16 options line is
-
-------------------------------------------------------------------------
-The mad16 module in addition supports the following options:
-
-option:                        meaning:                        default:
-joystick=0,1           disabled, enabled               disabled
-cdtype=0x00,0x02,0x04, disabled, Sony CDU31A,          disabled
-       0x06,0x08,0x0a   Mitsumi, Panasonic,
-                       Secondary IDE, Primary IDE 
-cdport=0x340,0x320,                                    0x340
-       0x330,0x360
-cdirq=0,3,5,7,9,10,11  disabled, IRQ3, ...             disabled
-cddma=0,5,6,7          disabled, DMA5, ...             DMA5 for Mitsumi or IDE
-cddma=0,1,2,3          disabled, DMA1, ...             DMA3 for Sony or Panasonic
-opl4=0,1               OPL3, OPL4                      OPL3    
-
-for more details see linux/drivers/sound/mad16.c
-
-Rui Sousa
diff --git a/Documentation/sound/oss/Maestro b/Documentation/sound/oss/Maestro
deleted file mode 100644 (file)
index 4a80eb3..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-       An OSS/Lite Driver for the ESS Maestro family of sound cards
-
-                       Zach Brown, December 1999
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-       http://www.zabbo.net/maestro/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-ESS Maestro Chip Family
------------------------
-
-There are 3 main variants of the ESS Maestro PCI sound chip.  The first
-is the Maestro 1.  It was originally produced by Platform Tech as the
-'AGOGO'.  It can be recognized by Platform Tech's PCI ID 0x1285 with
-0x0100 as the device ID.  It was put on some sound boards and a few laptops.  
-ESS bought the design and cleaned it up as the Maestro 2.  This starts
-their marking with the ESS vendor ID 0x125D and the 'year' device IDs.
-The Maestro 2 claims 0x1968 while the Maestro 2e has 0x1978.
-
-The various families of Maestro are mostly identical as far as this 
-driver is concerned.  It doesn't touch the DSP parts that differ (though
-it could for FM synthesis).
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves almost as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, and mmap()ing for playback behaves.  Capture/recording
-is limited due to oddities with the Maestro hardware.  One can only
-record in 16bit stereo.  For recording the maestro uses non interleaved
-stereo buffers so that mmap()ing the incoming data does not result in
-a ring buffer of LRLR data.  mmap()ing of the read buffers is therefore
-disallowed until this can be cleaned up.
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-
-The driver doesn't support MIDI or FM playback at the moment.  Typically
-the Maestro is wired to an MPU MIDI chip, but some hardware implementations
-don't.  We need to assemble a white list of hardware implementations that
-have MIDI wired properly before we can claim to support it safely.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound maestro'
-should also be added to your module configs (typically /etc/conf.modules)
-if you're using modular OSS/Lite sound and want to default to using a
-maestro chip.
-
-As this is a PCI device, the module does not need to be informed of
-any IO or IRQ resources it should use, it devines these from the
-system.  Sometimes, on sucky PCs, the BIOS fails to allocated resources
-for the maestro.  This will result in a message like:
-       maestro: PCI subsystem reports IRQ 0, this might not be correct.
-from the kernel.  Should this happen the sound chip most likely will
-not operate correctly.  To solve this one has to dig through their BIOS
-(typically entered by hitting a hot key at boot time) and figure out
-what magic needs to happen so that the BIOS will reward the maestro with
-an IRQ.  This operation is incredibly system specific, so you're on your
-own.  Sometimes the magic lies in 'PNP Capable Operating System' settings.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-The other, more interesting option, is 'dsps_order'.  Typically at
-install time the driver will only register one available /dev/dsp device
-for its use.  The 'dsps_order' module parameter allows for more devices
-to be allocated, as a power of two.  Up to 4 devices can be registered
-( dsps_order=2 ).  These devices act as fully distinct units and use
-separate channels in the maestro.
-
-Power Management
-----------------
-
-As of version 0.14, this driver has a minimal understanding of PCI
-Power Management.  If it finds a valid power management capability
-on the PCI device it will attempt to use the power management
-functions of the maestro.  It will only do this on Maestro 2Es and
-only on machines that are known to function well.  You can
-force the use of power management by setting the 'use_pm' module
-option to 1, or can disable it entirely by setting it to 0.
-
-When using power management, the driver does a few things
-differently.  It will keep the chip in a lower power mode
-when the module is inserted but /dev/dsp is not open.  This
-allows the mixer to function but turns off the clocks
-on other parts of the chip.  When /dev/dsp is opened the chip
-is brought into full power mode, and brought back down
-when it is closed.  It also powers down the chip entirely
-when the module is removed or the machine is shutdown.  This
-can have nonobvious consequences.  CD audio may not work
-after a power managing driver is removed.  Also, software that
-doesn't understand power management may not be able to talk
-to the powered down chip until the machine goes through a hard
-reboot to bring it back.
-
-.. more details ..
-------------------
-
-drivers/sound/maestro.c contains comments that hopefully explain
-the maestro implementation.
diff --git a/Documentation/sound/oss/Maestro3 b/Documentation/sound/oss/Maestro3
deleted file mode 100644 (file)
index a113718..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-       An OSS/Lite Driver for the ESS Maestro3 family of sound chips
-
-                       Zach Brown, January 2001
-
-Driver Status and Availability
-------------------------------
-
-The most recent version of this driver will hopefully always be available at
-       http://www.zabbo.net/maestro3/
-
-I will try and maintain the most recent stable version of the driver
-in both the stable and development kernel lines.
-
-Historically I've sucked pretty hard at actually doing that, however.
-
-ESS Maestro3 Chip Family
------------------------
-
-The 'Maestro3' is much like the Maestro2 chip.  The noted improvement
-is the removal of the silicon in the '2' that did PCM mixing.  All that
-work is now done through a custom DSP called the ASSP, the Asynchronus
-Specific Signal Processor.
-
-The 'Allegro' is a baby version of the Maestro3.  I'm not entirely clear
-on the extent of the differences, but the driver supports them both :)
-
-The 'Allegro' shows up as PCI ID 0x1988 and the Maestro3 as 0x1998,
-both under ESS's vendor ID of 0x125D.  The Maestro3 can also show up as
-0x199a when hardware strapping is used.
-
-The chip can also act as a multi function device.  The modem IDs follow
-the audio multimedia device IDs.  (so the modem part of an Allegro shows
-up as 0x1989)
-
-Driver OSS Behavior
---------------------
-
-This OSS driver exports /dev/mixer and /dev/dsp to applications, which
-mostly adhere to the OSS spec.   This driver doesn't register itself
-with /dev/sndstat, so don't expect information to appear there.
-
-The /dev/dsp device exported behaves as expected.  Playback is
-supported in all the various lovely formats.  8/16bit stereo/mono from
-8khz to 48khz, with both read()/write(), and mmap().
-
-/dev/mixer is an interface to the AC'97 codec on the Maestro3.  It is
-worth noting that there are a variety of AC'97s that can be wired to
-the Maestro3.  Which is used is entirely up to the hardware implementor.
-This should only be visible to the user by the presence, or lack, of
-'Bass' and 'Treble' sliders in the mixer.  Not all AC'97s have them.
-The Allegro has an onchip AC'97.
-
-The driver doesn't support MIDI or FM playback at the moment.
-
-Compiling and Installing
-------------------------
-
-With the drivers inclusion into the kernel, compiling and installing
-is the same as most OSS/Lite modular sound drivers.  Compilation
-of the driver is enabled through the CONFIG_SOUND_MAESTRO3 variable
-in the config system.  
-
-It may be modular or statically linked.  If it is modular it should be
-installed with the rest of the modules for the kernel on the system.
-Typically this will be in /lib/modules/ somewhere.  'alias sound-slot-0
-maestro3' should also be added to your module configs (typically
-/etc/modprobe.conf) if you're using modular OSS/Lite sound and want to
-default to using a maestro3 chip.
-
-There are very few options to the driver.  One is 'debug' which will 
-tell the driver to print minimal debugging information as it runs.  This
-can be collected with 'dmesg' or through the klogd daemon.
-
-One is 'external_amp', which tells the driver to attempt to enable
-an external amplifier.  This defaults to '1', you can tell the driver
-not to bother enabling such an amplifier by setting it to '0'.
-
-And the last is 'gpio_pin', which tells the driver which GPIO pin number
-the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
-If everything loads correctly and seems to be working but you get no sound, 
-try tweaking this value. 
-
-Systems known to need a different value
-        Panasonic ToughBook CF-72: gpio_pin=13 
-
-Power Management
-----------------
-
-This driver has a minimal understanding of PCI Power Management.  It will
-try and power down the chip when the system is suspended, and power
-it up with it is resumed.  It will also try and power down the chip
-when the machine is shut down.
diff --git a/Documentation/sound/oss/NEWS b/Documentation/sound/oss/NEWS
deleted file mode 100644 (file)
index a81e0ef..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-Linux 2.4 Sound Changes
-2000-September-25
-Christoph Hellwig, <hch@infradead.org>
-
-
-
-=== isapnp support
-
-The Linux 2.4 Kernel does have reliable in-kernel isapnp support.
-Some drivers (sb.o, ad1816.o awe_wave.o) do now support automatically
-detecting and configuring isapnp devices.
-If you have a not yet supported isapnp soundcard, mail me the content
-of '/proc/isapnp' on your system and some information about your card
-and its driver(s) so I can try to get isapnp working for it.
-
-
-
-=== soundcard resources on kernel commandline
-
-Before Linux 2.4 you had to specify the resources for sounddrivers
-statically linked into the kernel at compile time
-(in make config/menuconfig/xconfig). In Linux 2.4 the resources are
-now specified at the boot-time kernel commandline (e.g. the lilo
-'append=' line or everything that's after the kernel name in grub).
-Read the Configure.help entry for your card for the parameters.
-
-
-=== softoss is gone
-
-In Linux 2.4 the softoss in-kernel software synthesizer is no more aviable.
-Use a user space software synthesizer like timidity instead.
-
-
-
-=== /dev/sndstat and /proc/sound are gone
-
-In older Linux versions those files exported some information about the
-OSS/Free configuration to userspace. In Linux 2.3 they were removed because
-they did not support the growing number of pci soundcards and there were
-some general problems with this interface.
-
-
diff --git a/Documentation/sound/oss/OPL3-SA b/Documentation/sound/oss/OPL3-SA
deleted file mode 100644 (file)
index 66a9183..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-OPL3-SA1 sound driver (opl3sa.o)
-
----
-Note: This howto only describes how to setup the OPL3-SA1 chip; this info
-does not apply to the SA2, SA3, or SA4. 
----
-
-The Yamaha OPL3-SA1 sound chip is usually found built into motherboards, and
-it's a decent little chip offering a WSS mode, a SB Pro emulation mode, MPU401
-and OPL3 FM Synth capabilities.
-
-You can enable inclusion of the driver via CONFIG_SOUND_OPL3SA1=m, or
-CONFIG_SOUND_OPL3SA1=y through 'make config/xconfig/menuconfig'.
-
-You'll need to know all of the relevant info (irq, dma, and io port) for the
-chip's WSS mode, since that is the mode the kernel sound driver uses, and of
-course you'll also need to know about where the MPU401 and OPL3 ports and
-IRQs are if you want to use those.
-
-Here's the skinny on how to load it as a module:
-
-       modprobe opl3sa io=0x530 irq=11 dma=0 dma2=1 mpu_io=0x330 mpu_irq=5
-
-Module options in detail:
-
-       io:     This is the WSS's port base.
-       irq:    This is the WSS's IRQ.
-       dma:    This is the WSS's DMA line. In my BIOS setup screen this was
-               listed as "WSS Play DMA"
-       dma2:   This is the WSS's secondary DMA line. My BIOS calls it the
-               "WSS capture DMA"
-       
-       mpu_io: This is the MPU401's port base.
-       mpu_irq: This is the MPU401's IRQ.
-
-If you'd like to use the OPL3 FM Synthesizer, make sure you enable
-CONFIG_SOUND_YM3812 (in 'make config'). That'll build the opl3.o module.
-
-Then a simple 'insmod opl3 io=0x388', and you now have FM Synth.
-
-You can also use the SoftOSS software synthesizer instead of the builtin OPL3.
-Here's how:
-
-Say 'y' or 'm' to "SoftOSS software wave table engine" in make config.
-
-If you said yes, the software synth is available once you boot your new
-kernel.
-
-If you chose to build it as a module, just insmod the resulting softoss2.o
-
-Questions? Comments?
-<stiker@northlink.com>
diff --git a/Documentation/sound/oss/README.awe b/Documentation/sound/oss/README.awe
deleted file mode 100644 (file)
index 80054cd..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-================================================================
-       AWE32 Sound Driver for Linux / FreeBSD
-               version 0.4.3; Nov. 1, 1998
-
-       Takashi Iwai <iwai@ww.uni-erlangen.de>
-================================================================
-
-* GENERAL NOTES
-
-This is a sound driver extension for SoundBlaster AWE32 and other
-compatible cards (AWE32-PnP, SB32, SB32-PnP, AWE64 & etc) to enable
-the wave synth operations.  The driver is provided for Linux 1.2.x
-and 2.[012].x kernels, as well as FreeBSD, on Intel x86 and DEC
-Alpha systems.
-
-This driver was written by Takashi Iwai <iwai@ww.uni-erlangen.de>,
-and provided "as is".  The original source (awedrv-0.4.3.tar.gz) and
-binary packages are available on the following URL:
-       http://bahamut.mm.t.u-tokyo.ac.jp/~iwai/awedrv/
-Note that since the author is apart from this web site, the update is
-not frequent now.
-
-
-* NOTE TO LINUX USERS
-
-To enable this driver on linux-2.[01].x kernels, you need turn on 
-"AWE32 synth" options in sound menu when configure your linux kernel
-and modules.  The precise installation procedure is described in the
-AWE64-Mini-HOWTO and linux-kernel/Documetation/sound/AWE32.
-
-If you're using PnP cards, the card must be initialized before loading
-the sound driver.  There're several options to do this:
-    - Initialize the card via ISA PnP tools, and load the sound module.
-    - Initialize the card on DOS, and load linux by loadlin.exe
-    - Use PnP kernel driver (for Linux-2.x.x)
-The detailed instruction for the solution using isapnp tools is found
-in many documents like above.  A brief instruction is also included in
-the installation document of this package.
-For PnP driver project, please refer to the following URL:
-       http://www-jcr.lmh.ox.ac.uk/~pnp/
-
-
-* USING THE DRIVER
-
-The awedrv has several different playing modes to realize easy channel 
-allocation for MIDI songs.  To hear the exact sound quality, you need
-to obtain the extended sequencer program, drvmidi or playmidi-2.5.
-
-For playing MIDI files, you *MUST* load the soundfont file on the
-driver previously by sfxload utility.  Otherwise you'll here no sounds 
-at all!  All the utilities and driver source packages are found in the
-above URL.  The sfxload program is included in the package
-awesfx-0.4.3.tgz.  Binary packages are available there, too.  See the
-instruction in each package for installation.
-
-Loading a soundfont file is very simple.  Just execute the command
-
-       % sfxload synthgm.sbk
-
-Then, sfxload transfers the file "synthgm.sbk" to the driver.
-Both SF1 and SF2 formats are accepted.
-
-Now you can hear midi musics by a midi player.
-
-       % drvmidi foo.mid
-
-If you run MIDI player after MOD player, you need to load soundfont
-files again, since MOD player programs clear the previous loaded
-samples by their own data.
-
-If you have only 512kb on the sound card, I recommend to use dynamic
-sample loading via -L option of drvmidi.  2MB GM/GS soundfont file is
-available in most midi files.
-
-       % sfxload synthgm
-       % drvmidi -L 2mbgmgs foo.mid
-
-This makes a big difference (believe me)!  For more details, please
-refer to the FAQ list which is available on the URL above.
-
-The current chorus, reverb and equalizer status can be changed by
-aweset utility program (included in awesfx package).  Note that
-some awedrv-native programs (like drvmidi and xmp) will change the
-current settings by themselves.  The aweset program is effective
-only for other programs like playmidi.
-
-Enjoy.
-
-
-* COMPILE FLAGS
-
-Compile conditions are defined in awe_config.h.
-
-[Compatibility Conditions]
-The following flags are defined automatically when using installation
-shell script.
-
-- AWE_MODULE_SUPPORT
-    indicates your Linux kernel supports module for each sound card
-    (in recent 2.1 or 2.2 kernels and unofficial patched 2.0 kernels
-    as distributed in the RH5.0 package).
-    This flag is automatically set when you're using 2.1.x kernels.
-    You can pass the base address and memory size via the following
-    module options,
-       io = base I/O port address (eg. 0x620)
-       memsize = DRAM size in kilobytes (eg. 512)
-    As default, AWE driver probes these values automatically.
-
-
-[Hardware Conditions]
-You DON'T have to define the following two values.
-Define them only when the driver couldn't detect the card properly.
-
-- AWE_DEFAULT_BASE_ADDR                (default: not defined)
-    specifies the base port address of your AWE32 card.
-    0 means to autodetect the address.
-
-- AWE_DEFAULT_MEM_SIZE         (default: not defined)
-    specifies the memory size of your AWE32 card in kilobytes.
-    -1 means to autodetect its size.
-    
-
-[Sample Table Size]
-From ver.0.4.0, sample tables are allocated dynamically (except
-Linux-1.2.x system), so you need NOT to touch these parameters.
-Linux-1.2.x users may need to increase these values to appropriate size 
-if the sound card is equipped with more DRAM.
-
-- AWE_MAX_SF_LISTS, AWE_MAX_SAMPLES, AWE_MAX_INFOS
-
-
-[Other Conditions]
-
-- AWE_ALWAYS_INIT_FM           (default: not defined)
-    indicates the AWE driver always initialize FM passthrough even
-    without DRAM on board.  Emu8000 chip has a restriction for playing
-    samples on DRAM that at least two channels must be occupied as
-    passthrough channels. 
-
-- AWE_DEBUG_ON                 (default: defined)
-    turns on debugging messages if defined.
-
-- AWE_HAS_GUS_COMPATIBILITY    (default: defined)
-    Enables GUS compatibility mode if defined, reading GUS patches and 
-    GUS control commands.  Define this option to use GMOD or other
-    GUS module players.
-
-- CONFIG_AWE32_MIDIEMU         (default: defined)
-    Adds a MIDI emulation device by Emu8000 wavetable.  The emulation
-    device can be accessed as an external MIDI, and sends the MIDI
-    control codes directly.  XG and GS sysex/NRPN are accepted.
-    No MIDI input is supported.
-
-- CONFIG_AWE32_MIXER           (default: not defined)
-    Adds a mixer device for AWE32 bass/treble equalizer control.
-    You can access this device using /dev/mixer?? (usually mixer01).
-
-- AWE_USE_NEW_VOLUME_CALC      (default: defined)
-    Use the new method to calculate the volume change as compatible
-    with DOS/Win drivers.  This option can be toggled via aweset
-    program, or drvmidi player.
-
-- AWE_CHECK_VTARGET            (default: defined)
-    Check the current volume target value when searching for an
-    empty channel to allocate a new voice.  This is experimentally
-    implemented in this version.  (probably, this option doesn't
-    affect the sound quality severely...)
-
-- AWE_ALLOW_SAMPLE_SHARING     (default: defined)
-   Allow sample sharing for differently loaded patches.
-   This function is available only together with awesfx-0.4.3p3.
-   Note that this is still an experimental option.
-
-- DEF_FM_CHORUS_DEPTH          (default: 0x10)
-    The default strength to be sent to the chorus effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-- DEF_FM_REVERB_DEPTH          (default: 0x10)
-    The default strength to be sent to the reverb effect engine.
-    From 0 to 0xff.  Larger numbers may often cause weird sounds.
-
-
-* ACKNOWLEDGMENTS
-
-Thanks to Witold Jachimczyk (witek@xfactor.wpi.edu) for much advice
-on programming of AWE32.  Much code is brought from his AWE32-native 
-MOD player, ALMP.
-The port of awedrv to FreeBSD is done by Randall Hopper
-(rhh@ct.picker.com).
-The new volume calculation routine was derived from Mark Weaver's
-ADIP compatible routines.
-I also thank linux-awe-ml members for their efforts
-to reboot their system many times :-)
-
-
-* TODO'S
-
-- Complete DOS/Win compatibility
-- DSP-like output
-
-
-* COPYRIGHT
-
-Copyright (C) 1996-1998 Takashi Iwai
-
-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., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/Documentation/sound/oss/Wavefront b/Documentation/sound/oss/Wavefront
deleted file mode 100644 (file)
index 16f57ea..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-            An OSS/Free Driver for WaveFront soundcards
-              (Turtle Beach Maui, Tropez, Tropez Plus)
-
-                    Paul Barton-Davis, July 1998
-
-                         VERSION 0.2.5
-
-Driver Status
--------------
-
-Requires: Kernel 2.1.106 or later (the driver is included with kernels
-2.1.109 and above)
-         
-As of 7/22/1998, this driver is currently in *BETA* state. This means
-that it compiles and runs, and that I use it on my system (Linux
-2.1.106) with some reasonably demanding applications and uses.  I
-believe the code is approaching an initial "finished" state that
-provides bug-free support for the Tropez Plus.
-
-Please note that to date, the driver has ONLY been tested on a Tropez
-Plus. I would very much like to hear (and help out) people with Tropez
-and Maui cards, since I think the driver can support those cards as
-well. 
-
-Finally, the driver has not been tested (or even compiled) as a static
-(non-modular) part of the kernel. Alan Cox's good work in modularizing
-OSS/Free for Linux makes this rather unnecessary.
-
-Some Questions
---------------
-
-**********************************************************************
-0) What does this driver do that the maui driver did not ?
-**********************************************************************
-
-* can fully initialize a WaveFront card from cold boot - no DOS 
-          utilities needed
-* working patch/sample/program loading and unloading (the maui
-      driver didn't document how to make this work, and assumed
-      user-level preparation of the patch data for writing
-      to the board. ick.)
-* full user-level access to all WaveFront commands
-* for the Tropez Plus, (primitive) control of the YSS225 FX processor
-* Virtual MIDI mode supported - 2 MIDI devices accessible via the
-          WaveFront's MPU401/UART emulation. One
-         accesses the WaveFront synth, the other accesses the
-         external MIDI connector. Full MIDI read/write semantics
-         for both devices.
-* OSS-compliant /dev/sequencer interface for the WaveFront synth,
-         including native and GUS-format patch downloading.
-* semi-intelligent patch management (prototypical at this point)
-
-**********************************************************************
-1) What to do about MIDI interfaces ?
-**********************************************************************
-
-The Tropez Plus (and perhaps other WF cards) can in theory support up
-to 2 physical MIDI interfaces. One of these is connected to the
-ICS2115 chip (the WaveFront synth itself) and is controlled by
-MPU/UART-401 emulation code running as part of the WaveFront OS.  The
-other is controlled by the CS4232 chip present on the board. However,
-physical access to the CS4232 connector is difficult, and it is
-unlikely (though not impossible) that you will want to use it.
-
-An older version of this driver introduced an additional kernel config
-variable which controlled whether or not the CS4232 MIDI interface was
-configured. Because of Alan Cox's work on modularizing the sound
-drivers, and now backporting them to 2.0.34 kernels, there seems to be
-little reason to support "static" configuration variables, and so this
-has been abandoned in favor of *only* module parameters. Specifying
-"mpuio" and "mpuirq" for the cs4232 parameter will result in the
-CS4232 MIDI interface being configured; leaving them unspecified will
-leave it unconfigured (and thus unusable).
-
-BTW, I have heard from one Tropez+ user that the CS4232 interface is
-more reliable than the ICS2115 one. I have had no problems with the
-latter, and I don't have the right cable to test the former one
-out. Reports welcome.
-
-**********************************************************************
-2) Why does line XXX of the code look like this .... ?
-**********************************************************************
-
-Either because it's not finished yet, or because you're a better coder
-than I am, or because you don't understand some aspect of how the card
-or the code works. 
-
-I absolutely welcome comments, criticisms and suggestions about the
-design and implementation of the driver. 
-
-**********************************************************************
-3) What files are included ?
-**********************************************************************
-
-   drivers/sound/README.wavefront       -- this file
-
-   drivers/sound/wavefront.patch       -- patches for the 2.1.106 sound drivers
-                                          needed to make the rest of this work
-                                          DO NOT USE IF YOU'VE APPLIED THEM 
-                                          BEFORE, OR HAVE 2.1.109 OR ABOVE
-
-   drivers/sound/wavfront.c             -- the driver
-   drivers/sound/ys225.h                -- data declarations for FX config
-   drivers/sound/ys225.c                -- data definitions for FX config
-   drivers/sound/wf_midi.c              -- the "uart401" driver 
-                                             to support virtual MIDI mode.
-   include/wavefront.h                  -- the header file
-   Documentation/sound/oss/Tropez+          -- short docs on configuration
-
-**********************************************************************
-4) How do I compile/install/use it ?
-**********************************************************************
-
-PART ONE: install the source code into your sound driver directory
-
-  cd <top-of-your-2.1.106-code-base-e.g.-/usr/src/linux>
-  tar -zxvf <where-you-put/wavefront.tar.gz>
-
-PART TWO: apply the patches
-
-     DO THIS ONLY IF YOU HAVE A KERNEL VERSION BELOW 2.1.109
-     AND HAVE NOT ALREADY INSTALLED THE PATCH(ES).
-
-  cd drivers/sound
-  patch < wavefront.patch
-
-PART THREE: configure your kernel
-
-  cd <top of your kernel tree>
-  make xconfig (or whichever config option you use)
-
-         - choose YES for Sound Support              
-         - choose MODULE (M) for OSS Sound Modules
-         - choose MODULE(M) to YM3812/OPL3 support
-        - choose MODULE(M) for WaveFront support
-        - choose MODULE(M) for CS4232 support
-
-        - choose "N" for everything else (unless you have other
-             soundcards you want support for)
-
-
-   make boot
-   .
-   .
-   .
-   <whatever you normally do for a kernel install>
-   make modules
-   .
-   .
-   .
-   make modules_install
-
-Here's my autoconf.h SOUND section:
-
-/*
- * Sound
- */
-#define CONFIG_SOUND 1
-#undef  CONFIG_SOUND_OSS
-#define CONFIG_SOUND_OSS_MODULE 1
-#undef  CONFIG_SOUND_PAS
-#undef  CONFIG_SOUND_SB
-#undef  CONFIG_SOUND_ADLIB
-#undef  CONFIG_SOUND_GUS
-#undef  CONFIG_SOUND_MPU401
-#undef  CONFIG_SOUND_PSS
-#undef  CONFIG_SOUND_MSS
-#undef  CONFIG_SOUND_SSCAPE
-#undef  CONFIG_SOUND_TRIX
-#undef  CONFIG_SOUND_MAD16
-#undef  CONFIG_SOUND_WAVEFRONT
-#define CONFIG_SOUND_WAVEFRONT_MODULE 1
-#undef  CONFIG_SOUND_CS4232
-#define CONFIG_SOUND_CS4232_MODULE 1
-#undef  CONFIG_SOUND_MAUI
-#undef  CONFIG_SOUND_SGALAXY
-#undef  CONFIG_SOUND_OPL3SA1
-#undef  CONFIG_SOUND_SOFTOSS
-#undef  CONFIG_SOUND_YM3812
-#define CONFIG_SOUND_YM3812_MODULE 1
-#undef  CONFIG_SOUND_VMIDI
-#undef  CONFIG_SOUND_UART6850
-/*
- * Additional low level sound drivers
- */
-#undef  CONFIG_LOWLEVEL_SOUND
-
-************************************************************
-6) How do I configure my card ?
-************************************************************
-
-You need to edit /etc/modprobe.conf. Here's mine (edited to show the
-relevant details):
-
-  # Sound system
-  alias char-major-14-* wavefront
-  alias synth0 wavefront
-  alias mixer0 cs4232
-  alias audio0 cs4232
-  install wavefront /sbin/modprobe cs4232 && /sbin/modprobe -i wavefront && /sbin/modprobe opl3
-  options wavefront io=0x200 irq=9
-  options cs4232 synthirq=9 synthio=0x200 io=0x530 irq=5 dma=1 dma2=0
-  options opl3 io=0x388
-
-Things to note: 
-
-       the wavefront options "io" and "irq" ***MUST*** match the "synthio"
-       and "synthirq" cs4232 options.
-
-       you can do without the opl3 module if you don't
-       want to use the OPL/[34] FM synth on the soundcard
-
-       the opl3 io parameter is conventionally not adjustable.
-       In theory, any not-in-use IO port address would work, but
-       just use 0x388 and stick with the crowd.
-
-**********************************************************************
-7) What about firmware ?
-**********************************************************************
-
-Turtle Beach have not given me permission to distribute their firmware
-for the ICS2115. However, if you have a WaveFront card, then you
-almost certainly have the firmware, and if not, its freely available
-on their website, at:
-
-   http://www.tbeach.com/tbs/downloads/scardsdown.htm#tropezplus 
-
-The file is called WFOS2001.MOT (for the Tropez+).
-
-This driver, however, doesn't use the pure firmware as distributed,
-but instead relies on a somewhat processed form of it. You can
-generate this very easily. Following an idea from Andrew Veliath's
-Pinnacle driver, the following flex program will generate the
-processed version:
-
----- cut here -------------------------
-%option main
-%%
-^S[28].*\r$ printf ("%c%.*s", yyleng-1,yyleng-1,yytext);
-<<EOF>> { fputc ('\0', stdout); return; }
-\n {} 
-.  {}
----- cut here -------------------------
-
-To use it, put the above in file (say, ws.l) compile it like this:
-
-      shell> flex -ows.c ws.l
-      shell> cc -o ws ws.c
-      
-and then use it like this:
-
-    ws < my-copy-of-the-oswf.mot-file > /etc/sound/wavefront.os
-
-If you put it somewhere else, you'll always have to use the wf_ospath
-module parameter (see below) or alter the source code.
-
-**********************************************************************
-7) How do I get it working ?
-**********************************************************************
-
-Optionally, you can reboot with the "new" kernel (even though the only
-changes have really been made to a module).
-
-Then, as root do:
-
-     modprobe wavefront
-
-You should get something like this in /var/log/messages:
-
-    WaveFront: firmware 1.20 already loaded.
-
-or 
-
-    WaveFront: no response to firmware probe, assume raw.
-
-then:
-
-    WaveFront: waiting for memory configuration ...
-    WaveFront: hardware version 1.64
-    WaveFront: available DRAM 8191k
-    WaveFront: 332 samples used (266 real, 13 aliases, 53 multi), 180 empty
-    WaveFront: 128 programs slots in use
-    WaveFront: 256 patch slots filled, 142 in use
-
-The whole process takes about 16 seconds, the longest waits being
-after reporting the hardware version (during the firmware download),
-and after reporting program status (during patch status inquiry).  Its
-shorter (about 10 secs) if the firmware is already loaded (i.e. only
-warm reboots since the last firmware load).
-
-The "available DRAM" line will vary depending on how much added RAM
-your card has. Mine has 8MB.
-
-To check basically functionality, use play(1) or splay(1) to send a
-.WAV or other audio file through the audio portion. Then use playmidi
-to play a General MIDI file. Try the "-D 0" to hear the
-difference between sending MIDI to the WaveFront and using the OPL/3,
-which is the default (I think ...). If you have an external synth(s)
-hooked to the soundcard, you can use "-e" to route to the
-external synth(s) (in theory, -D 1 should work as well, but I think
-there is a bug in playmidi which prevents this from doing what it
-should). 
-
-**********************************************************************
-8) What are the module parameters ?
-**********************************************************************
-
-Its best to read wavefront.c for this, but here is a summary:
-
-integers: 
-         wf_raw  - if set, ignore apparent presence of firmware
-                   loaded onto the ICS2115, reset the whole
-                   board, and initialize it from scratch. (default = 0)
-
-          fx_raw  - if set, always initialize the YSS225 processor
-                   on the Tropez plus. (default = 1)
-
-          < The next 4 are basically for kernel hackers to allow
-           tweaking the driver for testing purposes. >             
-
-          wait_usecs        -  loop timer used when waiting for
-                              status conditions on the board. 
-                              The default is 150.
-
-          debug_default    - debugging flags. See sound/wavefront.h
-                            for WF_DEBUG_* values. Default is zero.
-                            Setting this allows you to debug the
-                            driver during module installation.
-strings:
-         ospath - path to get to the pre-processed OS firmware.
-                   (default: /etc/sound/wavefront.os)
-
-**********************************************************************
-9) Who should I contact if I have problems?
-**********************************************************************
-
-Just me: Paul Barton-Davis <pbd@op.net>
-
-
diff --git a/Documentation/sound/oss/es1370 b/Documentation/sound/oss/es1370
deleted file mode 100644 (file)
index 7b38b1a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-This soundcard does not have any hardware MIDI synthesizer;
-MIDI synthesis has to be done in software. To allow this
-the driver/soundcard supports two PCM (/dev/dsp) interfaces.
-The second one goes to the mixer "synth" setting and supports
-only a limited set of sampling rates (44100, 22050, 11025, 5512).
-By setting lineout to 1 on the driver command line
-(eg. insmod es1370 lineout=1) it is even possible on some
-cards to convert the LINEIN jack into a second LINEOUT jack, thus
-making it possible to output four independent audio channels!
-
-There is a freely available software package that allows
-MIDI file playback on this soundcard called Timidity.
-See http://www.cgs.fi/~tt/timidity/.
-
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/rme96xx b/Documentation/sound/oss/rme96xx
deleted file mode 100644 (file)
index 87d7b7b..0000000
+++ /dev/null
@@ -1,767 +0,0 @@
-Beta release of the rme96xx (driver for RME 96XX cards like the 
-"Hammerfall" and the "Hammerfall light") 
-
-Important: The driver module has to be installed on a freshly rebooted system, 
-otherwise the driver might not be able to acquire its buffers.
-
-features:
-
- - OSS programming interface (i.e. runs with standard OSS soundsoftware) 
- - OSS/Multichannel interface (OSS multichannel is done by just aquiring
-   more than 2 channels). The driver does not use more than one device 
-   ( yet .. this feature may be implemented later ) 
- - more than one RME card supported
-
-The driver uses a specific multichannel interface, which I will document
-when the driver gets stable. (take a look at the defines in rme96xx.h,
-which adds blocked multichannel formats i.e instead of 
-lrlrlrlr --> llllrrrr  etc.
-
-Use the "rmectrl" programm to look at the status of the card .. 
-or use xrmectrl, a GUI interface for the ctrl program.
-
-What you can do with the rmectrl program is to set the stereo device for
-OSS emulation (e.g. if you use SPDIF out).
-
-You do:
-
-./ctrl offset 24 24
-
-which makes the stereo device use channels 25 and 26.
-
-Guenter Geiger <geiger@epy.co.at>
-
-copy the first part of the attached source code into rmectrl.c
-and the  second part into xrmectrl (or get the program from
-http://gige.xdv.org/pages/soft/pages/rme)
-
-to compile: gcc -o rmectrl rmectrl.c
------------------------------- snip ------------------------------------
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <linux/soundcard.h>
-#include <math.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "rme96xx.h"
-
-/*
-  remctrl.c
-  (C) 2000 Guenter Geiger <geiger@debian.org>
-  HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-*/
-
-/* # define DEVICE_NAME "/dev/mixer" */
-# define DEVICE_NAME "/dev/mixer1"
-
-
-void usage(void)
-{
-     fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
-     fprintf(stderr,"where command is one of:\n");
-     fprintf(stderr,"  help                       show this help\n");
-     fprintf(stderr,"  status                     show status bits\n");
-     fprintf(stderr,"  control                    show control bits\n");
-     fprintf(stderr,"  mix                        show mixer/offset status\n");
-     fprintf(stderr,"  master <n>                 set sync master\n");
-     fprintf(stderr,"  pro <n>                    set spdif out pro\n");
-     fprintf(stderr,"  emphasis <n>               set spdif out emphasis\n");
-     fprintf(stderr,"  dolby <n>                  set spdif out no audio\n");
-     fprintf(stderr,"  optout <n>                 set spdif out optical\n");
-     fprintf(stderr,"  wordclock <n>              set sync wordclock\n");
-     fprintf(stderr,"  spdifin <n>                set spdif in (0=optical,1=coax,2=intern)\n");
-     fprintf(stderr,"  syncref <n>                set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
-     fprintf(stderr,"  adat1cd <n>                set ADAT1 on internal CD\n");
-     fprintf(stderr,"  offset <devnr> <in> <out>  set dev (0..3) offset (0..25)\n");
-     exit(-1);
-}
-
-
-int main(int argc, char* argv[])
-{
-     int cards;
-     int ret;
-     int i;
-     double ft;
-     int fd, fdwr;
-     int param,orig;
-     rme_status_t stat;
-     rme_ctrl_t ctrl;
-     char *device;
-     int argidx;
-
-     if (argc < 2)
-         usage();
-
-     if (*argv[1]=='/') {
-         device = argv[1];
-         argidx = 2;
-     }
-     else {
-         device = DEVICE_NAME;
-         argidx = 1;
-     }
-
-     fprintf(stdout,"mixer device %s\n",device);
-     if ((fd = open(device,O_RDONLY)) < 0) {
-         fprintf(stdout,"opening device failed\n");
-         exit(-1);
-     }
-
-     if ((fdwr = open(device,O_WRONLY)) < 0) {
-         fprintf(stdout,"opening device failed\n");
-         exit(-1);
-     }
-
-     if (argc < argidx+1)
-         usage();
-
-     if (!strcmp(argv[argidx],"help"))
-        usage();
-     if (!strcmp(argv[argidx],"-h"))
-        usage();
-     if (!strcmp(argv[argidx],"--help"))
-        usage();
-
-     if (!strcmp(argv[argidx],"status")) {
-         ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
-         fprintf(stdout,"stat.irq %d\n",stat.irq);
-         fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
-         fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
-         fprintf(stdout,"stat.wclock %d\n",stat.wclock);
-         fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
-         fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
-         fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
-         fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
-         fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
-         fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
-         fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
-         fprintf(stdout,"stat.bufid %d\n",stat.bufid);
-         fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"control")) {
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         fprintf(stdout,"ctrl.start %d\n",ctrl.start);
-         fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
-         fprintf(stdout,"ctrl.master %d\n",ctrl.master);
-         fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
-         fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
-         fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
-         fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
-         fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
-         fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
-         fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
-         fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
-         fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
-         fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
-         fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
-         fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
-         fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
-         fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
-         fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
-         fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"mix")) {
-         rme_mixer mix;
-         int i;
-
-         for (i=0; i<4; i++) {
-              mix.devnr = i;
-              ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
-              if (mix.devnr == i) {
-                   fprintf(stdout,"devnr %d\n",mix.devnr);
-                   fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
-                   fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
-              }
-         }
-         exit (0);
-     }
-
-/* the control flags */
-
-     if (argc < argidx+2)
-         usage();
-
-     if (!strcmp(argv[argidx],"master")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("master = %d\n",val);
-         ctrl.master = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"pro")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("pro = %d\n",val);
-         ctrl.pro = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"emphasis")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("emphasis = %d\n",val);
-         ctrl.emphasis = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"dolby")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("dolby = %d\n",val);
-         ctrl.dolby = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"optout")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("optout = %d\n",val);
-         ctrl.opt_out = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"wordclock")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("wordclock = %d\n",val);
-         ctrl.wordclock = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"spdifin")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("spdifin = %d\n",val);
-         ctrl.spdif_in = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"syncref")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("syncref = %d\n",val);
-         ctrl.sync_ref = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-     if (!strcmp(argv[argidx],"adat1cd")) {
-         int val = atoi(argv[argidx+1]);
-         ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
-         printf("adat1cd = %d\n",val);
-         ctrl.adat1_cd = val;
-         ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
-         exit (0);
-     }
-
-/* setting offset */
-
-     if (argc < argidx+4)
-         usage();
-
-     if (!strcmp(argv[argidx],"offset")) {
-         rme_mixer mix;
-
-         mix.devnr = atoi(argv[argidx+1]);
-
-         mix.i_offset = atoi(argv[argidx+2]);
-         mix.o_offset = atoi(argv[argidx+3]);
-         ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
-         fprintf(stdout,"devnr %d\n",mix.devnr);
-         fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
-         fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
-         exit (0);
-     }
-
-     usage();
-     exit (0); /* to avoid warning */
-}
-
-
----------------------------- <snip> --------------------------------
-#!/usr/bin/wish
-
-# xrmectrl
-# (C) 2000 Guenter Geiger <geiger@debian.org>
-# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-
-#set defaults "-relief ridged"
-set CTRLPROG "./rmectrl"
-if {$argc} {
-    set CTRLPROG "$CTRLPROG $argv"
-}
-puts "CTRLPROG $CTRLPROG"
-
-frame .butts
-button .butts.exit -text "Exit" -command "exit" -relief ridge
-#button .butts.state -text "State" -command "get_all"
-
-pack .butts.exit -side left
-pack .butts -side bottom
-
-
-#
-# STATUS
-#
-
-frame .status
-
-# Sampling Rate
-
-frame .status.sr
-label .status.sr.text -text "Sampling Rate" -justify left
-radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
-radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
-radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
-radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw  -variable srate -value 96000 -font times
-
-pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
-
-# Lock
-
-frame .status.lock
-label .status.lock.text -text "Lock" -justify left
-checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
-checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
-checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
-
-pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
-
-# Sync
-
-frame .status.sync
-label .status.sync.text -text "Sync" -justify left
-checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
-checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
-checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
-
-pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
-
-# Timecode
-
-frame .status.tc
-label .status.tc.text -text "Timecode" -justify left
-checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
-checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
-checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
-
-pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
-
-# SPDIF In
-
-frame .status.spdif
-label .status.spdif.text -text "SPDIF In" -justify left
-label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
-checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
-
-pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
-
-pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
-
-
-#
-# CONTROL 
-#
-
-proc setprof {} {
-    global CTRLPROG
-    global spprof
-    exec $CTRLPROG pro $spprof
-}
-
-proc setemph {} {
-    global CTRLPROG
-    global spemph
-    exec $CTRLPROG emphasis $spemph
-}
-
-proc setnoaud {} {
-    global CTRLPROG
-    global spnoaud
-    exec $CTRLPROG dolby $spnoaud
-}
-
-proc setoptical {} {
-    global CTRLPROG
-    global spoptical
-    exec $CTRLPROG optout $spoptical
-}
-
-proc setspdifin {} {
-    global CTRLPROG
-    global spdifin
-    exec $CTRLPROG spdifin [expr $spdifin - 1]
-}
-
-proc setsyncsource {} {
-    global CTRLPROG
-    global syncsource
-    exec $CTRLPROG syncref [expr $syncsource -1]
-}
-
-
-proc setmaster {} {
-    global CTRLPROG
-    global master
-    exec $CTRLPROG master $master
-}
-
-proc setwordclock {} {
-    global CTRLPROG
-    global wordclock
-    exec $CTRLPROG wordclock $wordclock
-}
-
-proc setadat1cd {} {
-    global CTRLPROG
-    global adat1cd
-    exec $CTRLPROG adat1cd $adat1cd
-}
-
-
-frame .control
-
-# SPDIF In & SPDIF Out
-
-
-frame .control.spdif
-
-frame .control.spdif.in
-label .control.spdif.in.text -text "SPDIF In" -justify left
-radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
-radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
-
-checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
-
-pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
-
-label .control.spdif.space
-
-frame .control.spdif.out
-label .control.spdif.out.text -text "SPDIF Out" -justify left
-checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
-checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
-checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
-checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
-
-pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
-
-pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
-
-# Sync Mode & Sync Source
-
-frame .control.sync
-frame .control.sync.mode
-label .control.sync.mode.text -text "Sync Mode" -justify left
-checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
-checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
-
-pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
-
-label .control.sync.space
-
-frame .control.sync.src
-label .control.sync.src.text -text "Sync Source" -justify left
-radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
-radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
-radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
-
-pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
-
-pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
-
-label .control.space -text "" -width 10
-
-# Buffer Size
-
-frame .control.buf
-label .control.buf.text -text "Buffer Size (Latency)" -justify left
-radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
-radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
-radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
-radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
-radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
-radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
-radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
-radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
-
-pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 
-
-# Offset
-
-frame .control.offset
-
-frame .control.offset.in
-label .control.offset.in.text -text "Offset In" -justify left
-label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
-
-label .control.offset.space
-
-frame .control.offset.out
-label .control.offset.out.text -text "Offset Out" -justify left
-label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
-label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
-label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
-label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
-
-pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
-
-pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
-
-
-pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
-
-
-label .statustext -text Status -justify center -relief ridge
-label .controltext -text Control -justify center -relief ridge
-
-label .statusspace
-label .controlspace
-
-pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
-
-
-proc get_bit {output sstr} {
-    set idx1 [string last [concat $sstr 1] $output]
-    set idx1 [expr $idx1 != -1]
-    return $idx1
-}
-
-proc get_val {output sstr} {
-    set val [string wordend $output [string last $sstr $output]] 
-    set val [string range $output $val [expr $val+1]]
-    return $val
-}
-
-proc get_val2 {output sstr} {
-    set val [string wordend $output [string first $sstr $output]] 
-    set val [string range $output $val [expr $val+2]]
-    return $val
-}
-
-proc get_control {} {
-    global spprof
-    global spemph
-    global spnoaud
-    global spoptical
-    global spdifin
-    global ssrate
-    global master
-    global wordclock
-    global syncsource
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG control" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    set spprof [ get_bit $ooo "pro"]
-    set spemph [ get_bit $ooo "emphasis"]
-    set spnoaud [ get_bit $ooo "dolby"]
-    set spoptical [ get_bit $ooo "opt_out"]
-    set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
-    set ssrate [ expr [ get_val $ooo "latency"] + 1]
-    set master [ expr [ get_val $ooo "master"]]
-    set wordclock [ expr [ get_val $ooo "wordclock"]]
-    set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
-}
-
-proc get_status {} {
-    global srate
-    global ctrlcom
-
-    global adatlock1
-    global adatlock2
-    global adatlock3
-
-    global adatsync1
-    global adatsync2
-    global adatsync3
-
-    global tcbusy
-    global tcout
-    global tcvalid
-
-    global spdiferr
-    global crystal
-    global .status.spdif.text
-    global CTRLPROG
-
-
-    set f [open "| $CTRLPROG status" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-# samplerate
-
-    set idx1 [string last "sr48 1" $ooo]
-    set idx2 [string last "doublespeed 1" $ooo]
-    if {$idx1 >= 0} {
-       set fact1 48000
-    } else {
-       set fact1 44100
-    }
-
-    if {$idx2 >= 0} {
-       set fact2 2
-    } else {
-       set fact2 1
-    }
-    set srate [expr $fact1 * $fact2]
-#   ADAT lock
-
-    set val [get_val $ooo lockmask]
-    set adatlock1 0
-    set adatlock2 0
-    set adatlock3 0
-    if {[expr $val & 1]} {
-       set adatlock3 1
-    }
-    if {[expr $val & 2]} {
-       set adatlock2 1
-    }
-    if {[expr $val & 4]} {
-       set adatlock1 1
-    }
-
-#  ADAT sync
-    set val [get_val $ooo syncmask]
-    set adatsync1 0
-    set adatsync2 0
-    set adatsync3 0
-
-    if {[expr $val & 1]} {
-       set adatsync3 1
-    }
-    if {[expr $val & 2]} {
-       set adatsync2 1
-    }
-    if {[expr $val & 4]} {
-       set adatsync1 1
-    }
-
-# TC busy
-
-    set tcbusy [get_bit $ooo "busy"]
-    set tcout [get_bit $ooo "out"]
-    set tcvalid [get_bit $ooo "valid"]
-    set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
-
-#  000=64kHz, 100=88.2kHz, 011=96kHz
-#  111=32kHz, 110=44.1kHz, 101=48kHz
-
-    set val [get_val $ooo crystalrate]
-
-    set crystal "--.- kHz"
-    if {$val == 0} {
-        set crystal "64 kHz"
-    }
-    if {$val == 4} {
-        set crystal "88.2 kHz"
-    }
-    if {$val == 3} {
-        set crystal "96 kHz"
-    }
-    if {$val == 7} {
-        set crystal "32 kHz"
-    }
-    if {$val == 6} {
-        set crystal "44.1 kHz"
-    }
-    if {$val == 5} {
-        set crystal "48 kHz"
-    }
-    .status.spdif.sr configure -text $crystal
-}
-
-proc get_offset {} {
-    global inoffset
-    global outoffset
-    global CTRLPROG
-
-    set f [open "| $CTRLPROG mix" r+]
-    set ooo [read $f 1000]
-    close $f
-#    puts $ooo
-
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off0 configure -text "dev\#0: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off0 configure -text "dev\#0: $val"
-    } else {
-       .control.offset.in.off0 configure -text "dev\#0: -"
-       .control.offset.out.off0 configure -text "dev\#0: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off1 configure -text "dev\#1: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off1 configure -text "dev\#1: $val"
-    } else {
-       .control.offset.in.off1 configure -text "dev\#1: -"
-       .control.offset.out.off1 configure -text "dev\#1: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off2 configure -text "dev\#2: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off2 configure -text "dev\#2: $val"
-    } else {
-       .control.offset.in.off2 configure -text "dev\#2: -"
-       .control.offset.out.off2 configure -text "dev\#2: -"
-    }
-    if { [string match "*devnr*" $ooo] } {
-       set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
-       set val [get_val2 $ooo i_offset]
-       .control.offset.in.off3 configure -text "dev\#3: $val"
-       set val [get_val2 $ooo o_offset]
-       .control.offset.out.off3 configure -text "dev\#3: $val"
-    } else {
-       .control.offset.in.off3 configure -text "dev\#3: -"
-       .control.offset.out.off3 configure -text "dev\#3: -"
-    }
-}
-
-
-proc get_all {} {
-get_status
-get_control
-get_offset
-}
-
-# main
-while {1} {
-  after 200
-  get_all
-  update
-}
diff --git a/Documentation/sound/oss/solo1 b/Documentation/sound/oss/solo1
deleted file mode 100644 (file)
index 95c4c83..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-Recording
----------
-
-Recording does not work on the author's card, but there
-is at least one report of it working on later silicon.
-The chip behaves differently than described in the data sheet,
-likely due to a chip bug. Working around this would require
-the help of ESS (for example by publishing an errata sheet),
-but ESS has not done so far.
-
-Also, the chip only supports 24 bit addresses for recording,
-which means it cannot work on some Alpha mainboards.
-
-
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (or later, available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card has an OPL compatible FM synthesizer.
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
diff --git a/Documentation/sound/oss/sonicvibes b/Documentation/sound/oss/sonicvibes
deleted file mode 100644 (file)
index 84dee2e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/proc/sound, /dev/sndstat
--------------------------
-
-/proc/sound and /dev/sndstat is not supported by the
-driver. To find out whether the driver succeeded loading,
-check the kernel log (dmesg).
-
-
-ALaw/uLaw sample formats
-------------------------
-
-This driver does not support the ALaw/uLaw sample formats.
-ALaw is the default mode when opening a sound device
-using OSS/Free. The reason for the lack of support is
-that the hardware does not support these formats, and adding
-conversion routines to the kernel would lead to very ugly
-code in the presence of the mmap interface to the driver.
-And since xquake uses mmap, mmap is considered important :-)
-and no sane application uses ALaw/uLaw these days anyway.
-In short, playing a Sun .au file as follows:
-
-cat my_file.au > /dev/dsp
-
-does not work. Instead, you may use the play script from
-Chris Bagwell's sox-12.14 package (available from the URL
-below) to play many different audio file formats.
-The script automatically determines the audio format
-and does do audio conversions if necessary.
-http://home.sprynet.com/sprynet/cbagwell/projects.html
-
-
-Blocking vs. nonblocking IO
----------------------------
-
-Unlike OSS/Free this driver honours the O_NONBLOCK file flag
-not only during open, but also during read and write.
-This is an effort to make the sound driver interface more
-regular. Timidity has problems with this; a patch
-is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html.
-(Timidity patched will also run on OSS/Free).
-
-
-MIDI UART
----------
-
-The driver supports a simple MIDI UART interface, with
-no ioctl's supported.
-
-
-MIDI synthesizer
-----------------
-
-The card both has an OPL compatible FM synthesizer as well as
-a wavetable synthesizer.
-
-I haven't managed so far to get the OPL synth running.
-
-Using the wavetable synthesizer requires allocating
-1-4MB of physically contiguous memory, which isn't possible
-currently on Linux without ugly hacks like the bigphysarea
-patch. Therefore, the driver doesn't support wavetable
-synthesis.
-
-
-No support from S3
-------------------
-
-I do not get any support from S3. Therefore, the driver
-still has many problems. For example, although the manual
-states that the chip should be able to access the sample
-buffer anywhere in 32bit address space, I haven't managed to
-get it working with buffers above 16M. Therefore, the card
-has the same disadvantages as ISA soundcards.
-
-Given that the card is also very noisy, and if you haven't
-already bought it, you should strongly opt for one of the
-comparatively priced Ensoniq products.
-
-
-Thomas Sailer
-t.sailer@alumni.ethz.ch
index fb10f71b8b64dc80a5af8c4a2b64c113ae209a28..8c35b3c503aa842e0258a949f2ef8633e541db01 100644 (file)
@@ -1900,11 +1900,6 @@ M:       rroesler@syskonnect.de
 W:     http://www.syskonnect.com
 S:     Supported
 
-MAESTRO PCI SOUND DRIVERS
-P:     Zach Brown
-M:     zab@zabbo.net
-S:     Odd Fixes
-
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 P: Michael Kerrisk
 M: mtk-manpages@gmx.net
@@ -3402,12 +3397,6 @@ M:       Henk.Vergonet@gmail.com
 L:     usbb2k-api-dev@nongnu.org
 S:     Maintained
 
-YMFPCI YAMAHA PCI SOUND (Use ALSA instead)
-P:     Pete Zaitcev
-M:     zaitcev@yahoo.com
-L:     linux-kernel@vger.kernel.org
-S:     Obsolete
-
 Z8530 DRIVER FOR AX.25
 P:     Joerg Reuter
 M:     jreuter@yaina.de
index 9e8bcb5fa99cb8bb0403b2cf1189f5277f47443f..7d564b6fc98f44a561d4afaf375d4e0f66eda11f 100644 (file)
@@ -160,7 +160,6 @@ header-y += video_decoder.h
 header-y += video_encoder.h
 header-y += videotext.h
 header-y += vt.h
-header-y += wavefront.h
 header-y += wireless.h
 header-y += xattr.h
 header-y += x25.h
index 2ed2fd855133cba6d445a4babdb213e4eb4b2f75..22eb9367235aee14f2e2da4863f450d842287e2b 100644 (file)
@@ -331,8 +331,6 @@ extern int ac97_read_proc (char *page_out, char **start, off_t off,
 extern int ac97_probe_codec(struct ac97_codec *);
 extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
 extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
-extern int ac97_save_state(struct ac97_codec *codec);
-extern int ac97_restore_state(struct ac97_codec *codec);
 
 extern struct ac97_codec *ac97_alloc_codec(void);
 extern void ac97_release_codec(struct ac97_codec *codec);
@@ -346,9 +344,6 @@ struct ac97_driver {
        void (*remove) (struct ac97_codec *codec, struct ac97_driver *driver);
 };
 
-extern int ac97_register_driver(struct ac97_driver *driver);
-extern void ac97_unregister_driver(struct ac97_driver *driver);
-
 /* quirk types */
 enum {
        AC97_TUNE_DEFAULT = -1, /* use default from quirk list (not valid in list) */
index f63d8342ffa342a813c5b2bc10f89a54f00f801a..9e2a94feed6baa519190de1db4521b4eaeeead43 100644 (file)
@@ -35,10 +35,8 @@ extern int register_sound_special_device(const struct file_operations *fops, int
 extern int register_sound_mixer(const struct file_operations *fops, int dev);
 extern int register_sound_midi(const struct file_operations *fops, int dev);
 extern int register_sound_dsp(const struct file_operations *fops, int dev);
-extern int register_sound_synth(const struct file_operations *fops, int dev);
 
 extern void unregister_sound_special(int unit);
 extern void unregister_sound_mixer(int unit);
 extern void unregister_sound_midi(int unit);
 extern void unregister_sound_dsp(int unit);
-extern void unregister_sound_synth(int unit);
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
deleted file mode 100644 (file)
index 51ab3c9..0000000
+++ /dev/null
@@ -1,675 +0,0 @@
-#ifndef __wavefront_h__
-#define __wavefront_h__
-
-/* WaveFront header file.
- *   
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.  
- */
-
-#if (!defined(__GNUC__) && !defined(__GNUG__))
-
-     You will not be able to compile this file correctly without gcc, because
-     it is necessary to pack the "wavefront_alias" structure to a size
-     of 22 bytes, corresponding to 16-bit alignment (as would have been
-     the case on the original platform, MS-DOS). If this is not done,
-     then WavePatch-format files cannot be read/written correctly.
-     The method used to do this here ("__attribute__((packed)") is
-     completely compiler dependent.
-     
-     All other wavefront_* types end up aligned to 32 bit values and
-     still have the same (correct) size.
-
-#else
-
-     /* However, note that as of G++ 2.7.3.2, g++ was unable to
-       correctly parse *type* __attribute__ tags. It will do the
-       right thing if we use the "packed" attribute on each struct
-       member, which has the same semantics anyway. 
-     */
-
-#endif /* __GNUC__ */
-
-/***************************** WARNING ********************************
-  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO 
-  BE USED WITH EITHER C *OR* C++.
- **********************************************************************/
-
-#ifndef NUM_MIDIKEYS 
-#define NUM_MIDIKEYS 128
-#endif  /* NUM_MIDIKEYS */
-
-#ifndef NUM_MIDICHANNELS
-#define NUM_MIDICHANNELS 16
-#endif  /* NUM_MIDICHANNELS */
-
-/* These are very useful/important. the original wavefront interface
-   was developed on a 16 bit system, where sizeof(int) = 2
-   bytes. Defining things like this makes the code much more portable, and
-   easier to understand without having to toggle back and forth
-   between a 16-bit view of the world and a 32-bit one. 
- */   
-
-typedef short INT16;
-typedef unsigned short UINT16;
-typedef int INT32;
-typedef unsigned int UINT32;
-typedef char CHAR8;
-typedef unsigned char UCHAR8;
-
-/* Pseudo-commands not part of the WaveFront command set.
-   These are used for various driver controls and direct
-   hardware control.
- */
-
-#define WFC_DEBUG_DRIVER                0
-#define WFC_FX_IOCTL                    1
-#define WFC_PATCH_STATUS                2
-#define WFC_PROGRAM_STATUS              3
-#define WFC_SAMPLE_STATUS               4
-#define WFC_DISABLE_INTERRUPTS          5
-#define WFC_ENABLE_INTERRUPTS           6
-#define WFC_INTERRUPT_STATUS            7
-#define WFC_ROMSAMPLES_RDONLY           8
-#define WFC_IDENTIFY_SLOT_TYPE          9
-
-/* Wavefront synth commands
- */
-
-#define WFC_DOWNLOAD_SAMPLE            0x80
-#define WFC_DOWNLOAD_BLOCK             0x81
-#define WFC_DOWNLOAD_MULTISAMPLE       0x82
-#define WFC_DOWNLOAD_SAMPLE_ALIAS      0x83
-#define WFC_DELETE_SAMPLE              0x84
-#define WFC_REPORT_FREE_MEMORY         0x85
-#define WFC_DOWNLOAD_PATCH             0x86
-#define WFC_DOWNLOAD_PROGRAM           0x87
-#define WFC_SET_SYNTHVOL               0x89
-#define WFC_SET_NVOICES                        0x8B
-#define WFC_DOWNLOAD_DRUM              0x90
-#define WFC_GET_SYNTHVOL               0x92
-#define WFC_GET_NVOICES                        0x94
-#define WFC_DISABLE_CHANNEL            0x9A
-#define WFC_ENABLE_CHANNEL             0x9B
-#define WFC_MISYNTH_OFF                        0x9D
-#define WFC_MISYNTH_ON                 0x9E
-#define WFC_FIRMWARE_VERSION           0x9F
-#define WFC_GET_NSAMPLES               0xA0
-#define WFC_DISABLE_DRUM_PROGRAM       0xA2
-#define WFC_UPLOAD_PATCH               0xA3
-#define WFC_UPLOAD_PROGRAM             0xA4
-#define WFC_SET_TUNING                 0xA6
-#define WFC_GET_TUNING                 0xA7
-#define WFC_VMIDI_ON                   0xA8
-#define WFC_VMIDI_OFF                  0xA9
-#define WFC_MIDI_STATUS                        0xAA
-#define WFC_GET_CHANNEL_STATUS         0xAB
-#define WFC_DOWNLOAD_SAMPLE_HEADER     0xAC
-#define WFC_UPLOAD_SAMPLE_HEADER       0xAD
-#define WFC_UPLOAD_MULTISAMPLE         0xAE
-#define WFC_UPLOAD_SAMPLE_ALIAS                0xAF
-#define WFC_IDENTIFY_SAMPLE_TYPE       0xB0
-#define WFC_DOWNLOAD_EDRUM_PROGRAM     0xB1
-#define WFC_UPLOAD_EDRUM_PROGRAM       0xB2
-#define WFC_SET_EDRUM_CHANNEL          0xB3
-#define WFC_INSTOUT_LEVELS             0xB4
-#define WFC_PEAKOUT_LEVELS             0xB5
-#define WFC_REPORT_CHANNEL_PROGRAMS    0xB6
-#define WFC_HARDWARE_VERSION           0xCF
-#define WFC_UPLOAD_SAMPLE_PARAMS       0xD7
-#define WFC_DOWNLOAD_OS                        0xF1
-#define WFC_NOOP                        0xFF
-
-#define WF_MAX_SAMPLE   512
-#define WF_MAX_PATCH    256
-#define WF_MAX_PROGRAM  128
-
-#define WF_SECTION_MAX  44   /* longest OS section length */
-
-/* # of bytes we send to the board when sending it various kinds of
-   substantive data, such as samples, patches and programs.
-*/
-
-#define WF_PROGRAM_BYTES 32
-#define WF_PATCH_BYTES 132
-#define WF_SAMPLE_BYTES 27
-#define WF_SAMPLE_HDR_BYTES 25
-#define WF_ALIAS_BYTES 25
-#define WF_DRUM_BYTES 9
-#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
-
-#define WF_ACK     0x80
-#define WF_DMA_ACK 0x81
-
-/* OR-values for MIDI status bits */
-
-#define WF_MIDI_VIRTUAL_ENABLED 0x1
-#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
-#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
-
-/* slot indexes for struct address_info: makes code a little more mnemonic */
-
-#define WF_SYNTH_SLOT         0
-#define WF_INTERNAL_MIDI_SLOT 1
-#define WF_EXTERNAL_MIDI_SLOT 2
-
-/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
-   emulation. Note these NEVER show up in output from the device and
-   should NEVER be used in input unless Virtual MIDI mode has been 
-   disabled. If they do show up as input, the results are unpredictable.
-*/
-
-#define WF_EXTERNAL_SWITCH  0xFD
-#define WF_INTERNAL_SWITCH  0xF9
-
-/* Debugging flags */
-
-#define WF_DEBUG_CMD 0x1
-#define WF_DEBUG_DATA 0x2
-#define WF_DEBUG_LOAD_PATCH 0x4
-#define WF_DEBUG_IO 0x8
-
-/* WavePatch file format stuff */
-
-#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
-#define WF_MAX_COMMENT           64    /*  Comment length */
-#define WF_NUM_LAYERS            4
-#define WF_NAME_LENGTH           32
-#define WF_SOURCE_LENGTH         260
-
-#define BankFileID     "Bank"
-#define DrumkitFileID  "DrumKit"
-#define ProgramFileID  "Program"
-
-struct wf_envelope
-{
-    UCHAR8 attack_time:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 decay1_time:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 decay2_time:7;
-    UCHAR8 Unused3:1;
-
-    UCHAR8 sustain_time:7;
-    UCHAR8 Unused4:1;
-
-    UCHAR8 release_time:7;
-    UCHAR8 Unused5:1;
-
-    UCHAR8 release2_time:7;
-    UCHAR8 Unused6:1;
-
-    CHAR8 attack_level;
-    CHAR8 decay1_level;
-    CHAR8 decay2_level;
-    CHAR8 sustain_level;
-    CHAR8 release_level;
-
-    UCHAR8 attack_velocity:7;
-    UCHAR8 Unused7:1;
-
-    UCHAR8 volume_velocity:7;
-    UCHAR8 Unused8:1;
-
-    UCHAR8 keyboard_scaling:7;
-    UCHAR8 Unused9:1;
-};
-typedef struct wf_envelope wavefront_envelope;
-
-struct wf_lfo
-{
-    UCHAR8 sample_number;
-
-    UCHAR8 frequency:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 am_src:4;
-    UCHAR8 fm_src:4;
-
-    CHAR8 fm_amount;
-    CHAR8 am_amount;
-    CHAR8 start_level;
-    CHAR8 end_level;
-
-    UCHAR8 ramp_delay:7;
-    UCHAR8 wave_restart:1; /* for LFO2 only */
-
-    UCHAR8 ramp_time:7;
-    UCHAR8 Unused2:1;
-};
-typedef struct wf_lfo wavefront_lfo;
-
-struct wf_patch
-{
-    INT16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
-
-    UCHAR8 amplitude_bias:7;
-    UCHAR8 Unused1:1;
-
-    UCHAR8 portamento:7;
-    UCHAR8 Unused2:1;
-
-    UCHAR8 sample_number;
-
-    UCHAR8 pitch_bend:4;
-    UCHAR8 sample_msb:1;
-    UCHAR8 Unused3:3;
-
-    UCHAR8 mono:1;
-    UCHAR8 retrigger:1;
-    UCHAR8 nohold:1;
-    UCHAR8 restart:1;
-    UCHAR8 filterconfig:2; /* SDK says "not used" */
-    UCHAR8 reuse:1;
-    UCHAR8 reset_lfo:1;    
-
-    UCHAR8 fm_src2:4;
-    UCHAR8 fm_src1:4;   
-
-    CHAR8 fm_amount1;
-    CHAR8 fm_amount2;
-
-    UCHAR8 am_src:4;
-    UCHAR8 Unused4:4;
-
-    CHAR8 am_amount;
-
-    UCHAR8 fc1_mode:4;
-    UCHAR8 fc2_mode:4;
-
-    CHAR8 fc1_mod_amount;
-    CHAR8 fc1_keyboard_scaling;
-    CHAR8 fc1_bias;
-    CHAR8 fc2_mod_amount;
-    CHAR8 fc2_keyboard_scaling;
-    CHAR8 fc2_bias;
-
-    UCHAR8 randomizer:7;
-    UCHAR8 Unused5:1;
-
-    struct wf_envelope envelope1;
-    struct wf_envelope envelope2;
-    struct wf_lfo lfo1;
-    struct wf_lfo lfo2;
-};
-typedef struct wf_patch wavefront_patch;
-
-struct wf_layer
-{
-    UCHAR8 patch_number;
-
-    UCHAR8 mix_level:7;
-    UCHAR8 mute:1;
-
-    UCHAR8 split_point:7;
-    UCHAR8 play_below:1;
-
-    UCHAR8 pan_mod_src:2;
-    UCHAR8 pan_or_mod:1;
-    UCHAR8 pan:4;
-    UCHAR8 split_type:1;
-};
-typedef struct wf_layer wavefront_layer;
-
-struct wf_program
-{
-    struct wf_layer layer[WF_NUM_LAYERS];
-};
-typedef struct wf_program wavefront_program;
-
-struct wf_sample_offset
-{
-    INT32 Fraction:4;
-    INT32 Integer:20;
-    INT32 Unused:8;
-};
-typedef struct wf_sample_offset wavefront_sample_offset;          
-     
-/* Sample slot types */
-
-#define WF_ST_SAMPLE      0
-#define WF_ST_MULTISAMPLE 1
-#define WF_ST_ALIAS       2
-#define WF_ST_EMPTY       3
-
-/* pseudo's */
-
-#define WF_ST_DRUM        4
-#define WF_ST_PROGRAM     5
-#define WF_ST_PATCH       6
-#define WF_ST_SAMPLEHDR   7
-
-#define WF_ST_MASK        0xf
-
-/* Flags for slot status. These occupy the upper bits of the same byte
-   as a sample type.
-*/
-
-#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
-#define WF_SLOT_FILLED    0x40
-#define WF_SLOT_ROM       0x20
-
-#define WF_SLOT_MASK      0xf0
-
-/* channel constants */
-
-#define WF_CH_MONO  0
-#define WF_CH_LEFT  1
-#define WF_CH_RIGHT 2
-
-/* Sample formats */
-
-#define LINEAR_16BIT 0
-#define WHITE_NOISE  1
-#define LINEAR_8BIT  2
-#define MULAW_8BIT   3
-
-#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
-
-
-/* 
-
-  Because most/all of the sample data we pass in via pointers has
-  never been copied (just mmap-ed into user space straight from the
-  disk), it would be nice to allow handling of multi-channel sample
-  data without forcing user-level extraction of the relevant bytes.
-  
-  So, we need a way of specifying which channel to use (the WaveFront
-  only handles mono samples in a given slot), and the only way to do
-  this without using some struct other than wavefront_sample as the
-  interface is the awful hack of using the unused bits in a
-  wavefront_sample:
-  
-  Val      Meaning
-  ---      -------
-  0        no channel selection (use channel 1, sample is MONO)
-  1        use first channel, and skip one
-  2        use second channel, and skip one
-  3        use third channel, and skip two
-  4        use fourth channel, skip three
-  5        use fifth channel, skip four
-  6        use six channel, skip five
-
-
-  This can handle up to 4 channels, and anyone downloading >4 channels
-  of sample data just to select one of them needs to find some tools
-  like sox ...
-
-  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is 
-  important.
-
-*/
-
-#define WF_SET_CHANNEL(samp,chn) \
- (samp)->Unused1 = chn & 0x1; \
- (samp)->Unused2 = chn & 0x2; \
- (samp)->Unused3 = chn & 0x4 
-  
-#define WF_GET_CHANNEL(samp) \
-  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
-  
-typedef struct wf_sample {
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset loopEndOffset;
-    struct wf_sample_offset sampleEndOffset;
-    INT16 FrequencyBias;
-    UCHAR8 SampleResolution:2;  /* sample_format */
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-} wavefront_sample;
-
-typedef struct wf_multisample {
-    INT16 NumberOfSamples;   /* log2 of the number of samples */
-    INT16 SampleNumber[NUM_MIDIKEYS];
-} wavefront_multisample;
-
-typedef struct wf_alias {
-    INT16 OriginalSample;
-
-    struct wf_sample_offset sampleStartOffset;
-    struct wf_sample_offset loopStartOffset;
-    struct wf_sample_offset sampleEndOffset;
-    struct wf_sample_offset loopEndOffset;
-
-    INT16  FrequencyBias;
-
-    UCHAR8 SampleResolution:2;
-    UCHAR8 Unused1:1;
-    UCHAR8 Loop:1;
-    UCHAR8 Bidirectional:1;
-    UCHAR8 Unused2:1;
-    UCHAR8 Reverse:1;
-    UCHAR8 Unused3:1;
-    
-    /* This structure is meant to be padded only to 16 bits on their
-       original. Of course, whoever wrote their documentation didn't
-       realize that sizeof(struct) can be >=
-       sum(sizeof(struct-fields)) and so thought that giving a C level
-       description of the structs used in WavePatch files was
-       sufficient. I suppose it was, as long as you remember the 
-       standard 16->32 bit issues.
-    */
-
-    UCHAR8 sixteen_bit_padding;
-} __attribute__((packed)) wavefront_alias;
-
-typedef struct wf_drum {
-    UCHAR8 PatchNumber;
-    UCHAR8 MixLevel:7;
-    UCHAR8 Unmute:1;
-    UCHAR8 Group:4;
-    UCHAR8 Unused1:4;
-    UCHAR8 PanModSource:2;
-    UCHAR8 PanModulated:1;
-    UCHAR8 PanAmount:4;
-    UCHAR8 Unused2:1;
-} wavefront_drum;
-
-typedef struct wf_drumkit {
-    struct wf_drum drum[NUM_MIDIKEYS];
-} wavefront_drumkit;
-
-typedef struct wf_channel_programs {
-    UCHAR8 Program[NUM_MIDICHANNELS];
-} wavefront_channel_programs;
-
-/* How to get MIDI channel status from the data returned by
-   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
-*/
-
-#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
-
-typedef union wf_any {
-    wavefront_sample s;
-    wavefront_multisample ms;
-    wavefront_alias a;
-    wavefront_program pr;
-    wavefront_patch p;
-    wavefront_drum d;
-} wavefront_any;
-
-/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
-   might work for other wave-table based patch loading situations.
-   Alas, his fears were correct. The WaveFront doesn't even come with
-   just "patches", but several different kind of structures that
-   control the sound generation process.
- */
-
-typedef struct wf_patch_info {
-    
-    /* the first two fields are used by the OSS "patch loading" interface
-       only, and are unused by the current user-level library.
-    */
-
-    INT16   key;               /* Use WAVEFRONT_PATCH here */
-    UINT16  devno;             /* fill in when sending */
-    UCHAR8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
-
-#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
-
-    UINT16  number;            /* patch/sample/prog number */
-
-    UINT32  size;              /* size of any data included in 
-                                 one of the fields in `hdrptr', or
-                                 as `dataptr'.
-
-                                 NOTE: for actual samples, this is
-                                 the size of the *SELECTED CHANNEL*
-                                 even if more data is actually available.
-                                 
-                                 So, a stereo sample (2 channels) of
-                                 6000 bytes total has `size' = 3000.
-
-                                 See the macros and comments for
-                                 WF_{GET,SET}_CHANNEL above.
-
-                              */
-    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
-    UINT16 __user *dataptr;            /* actual sample data */
-
-    wavefront_any hdr;          /* kernel-space copy of hdr bytes */         
-} wavefront_patch_info;
-
-/* The maximum number of bytes we will ever move to or from user space
-   in response to a WFC_* command.  This obviously doesn't cover
-   actual sample data.
-*/
-
-#define WF_MAX_READ sizeof(wavefront_multisample)
-#define WF_MAX_WRITE sizeof(wavefront_multisample)
-
-/*
-   This allows us to execute any WF command except the download/upload
-   ones, which are handled differently due to copyin/copyout issues as
-   well as data-nybbling to/from the card.
- */
-
-typedef struct wavefront_control {
-    int cmd;                           /* WFC_* */
-    char status;                       /* return status to user-space */
-    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
-    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
-} wavefront_control;
-
-#define WFCTL_WFCMD    0x1
-#define WFCTL_LOAD_SPP 0x2
-
-/* Modulator table */
-
-#define WF_MOD_LFO1      0
-#define WF_MOD_LFO2      1
-#define WF_MOD_ENV1      2
-#define WF_MOD_ENV2      3
-#define WF_MOD_KEYBOARD  4
-#define WF_MOD_LOGKEY    5
-#define WF_MOD_VELOCITY  6
-#define WF_MOD_LOGVEL    7
-#define WF_MOD_RANDOM    8
-#define WF_MOD_PRESSURE  9
-#define WF_MOD_MOD_WHEEL 10
-#define WF_MOD_1         WF_MOD_MOD_WHEEL 
-#define WF_MOD_BREATH    11
-#define WF_MOD_2         WF_MOD_BREATH
-#define WF_MOD_FOOT      12
-#define WF_MOD_4         WF_MOD_FOOT
-#define WF_MOD_VOLUME    13
-#define WF_MOD_7         WF_MOD_VOLUME
-#define WF_MOD_PAN       14
-#define WF_MOD_10        WF_MOD_PAN
-#define WF_MOD_EXPR      15
-#define WF_MOD_11        WF_MOD_EXPR
-
-/* FX-related material */
-
-typedef struct wf_fx_info {
-    int request;             /* see list below */
-    int data[4];             /* we don't need much */
-} wavefront_fx_info;
-
-/* support for each of these will be forthcoming once I or someone 
-   else has figured out which of the addresses on page 6 and page 7 of 
-   the YSS225 control each parameter. Incidentally, these come from
-   the Windows driver interface, but again, Turtle Beach didn't
-   document the API to use them.
-*/
-
-#define WFFX_SETOUTGAIN                        0
-#define WFFX_SETSTEREOOUTGAIN          1
-#define WFFX_SETREVERBIN1GAIN          2
-#define WFFX_SETREVERBIN2GAIN          3
-#define WFFX_SETREVERBIN3GAIN          4
-#define WFFX_SETCHORUSINPORT           5
-#define WFFX_SETREVERBIN1PORT          6
-#define WFFX_SETREVERBIN2PORT          7
-#define WFFX_SETREVERBIN3PORT          8
-#define WFFX_SETEFFECTPORT             9
-#define WFFX_SETAUXPORT                        10
-#define WFFX_SETREVERBTYPE             11
-#define WFFX_SETREVERBDELAY            12
-#define WFFX_SETCHORUSLFO              13
-#define WFFX_SETCHORUSPMD              14
-#define WFFX_SETCHORUSAMD              15
-#define WFFX_SETEFFECT                 16
-#define WFFX_SETBASEALL                        17
-#define WFFX_SETREVERBALL              18
-#define WFFX_SETCHORUSALL              20
-#define WFFX_SETREVERBDEF              22
-#define WFFX_SETCHORUSDEF              23
-#define WFFX_DELAYSETINGAIN            24
-#define WFFX_DELAYSETFBGAIN            25
-#define WFFX_DELAYSETFBLPF             26
-#define WFFX_DELAYSETGAIN              27
-#define WFFX_DELAYSETTIME              28
-#define WFFX_DELAYSETFBTIME            29
-#define WFFX_DELAYSETALL               30
-#define WFFX_DELAYSETDEF               32
-#define WFFX_SDELAYSETINGAIN           33
-#define WFFX_SDELAYSETFBGAIN           34
-#define WFFX_SDELAYSETFBLPF            35
-#define WFFX_SDELAYSETGAIN             36
-#define WFFX_SDELAYSETTIME             37
-#define WFFX_SDELAYSETFBTIME           38
-#define WFFX_SDELAYSETALL              39
-#define WFFX_SDELAYSETDEF              41
-#define WFFX_DEQSETINGAIN              42
-#define WFFX_DEQSETFILTER              43
-#define WFFX_DEQSETALL                 44
-#define WFFX_DEQSETDEF                 46
-#define WFFX_MUTE                      47
-#define WFFX_FLANGESETBALANCE          48      
-#define WFFX_FLANGESETDELAY            49
-#define WFFX_FLANGESETDWFFX_TH         50
-#define WFFX_FLANGESETFBGAIN           51
-#define WFFX_FLANGESETINGAIN           52
-#define WFFX_FLANGESETLFO              53
-#define WFFX_FLANGESETALL              54
-#define WFFX_FLANGESETDEF              56
-#define WFFX_PITCHSETSHIFT             57
-#define WFFX_PITCHSETBALANCE           58
-#define WFFX_PITCHSETALL               59
-#define WFFX_PITCHSETDEF               61
-#define WFFX_SRSSETINGAIN              62
-#define WFFX_SRSSETSPACE               63
-#define WFFX_SRSSETCENTER              64
-#define WFFX_SRSSETGAIN                        65
-#define WFFX_SRSSETMODE                        66
-#define WFFX_SRSSETDEF                 68
-
-/* Allow direct user-space control over FX memory/coefficient data.
-   In theory this could be used to download the FX microprogram,
-   but it would be a little slower, and involve some weird code.
- */
-
-#define WFFX_MEMSET              69
-
-#endif /* __wavefront_h__ */
index 86811792002f82194783d8e191528ad49e34360c..8313757b6487aed32c30de4b64746c9363475373 100644 (file)
@@ -15,71 +15,42 @@ obj-$(CONFIG_SOUND_HAL2)    += hal2.o
 obj-$(CONFIG_SOUND_AEDSP16)    += aedsp16.o
 obj-$(CONFIG_SOUND_PSS)                += pss.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_TRIX)       += trix.o ad1848.o sb_lib.o uart401.o
-obj-$(CONFIG_SOUND_OPL3SA1)    += opl3sa.o ad1848.o uart401.o
 obj-$(CONFIG_SOUND_SSCAPE)     += sscape.o ad1848.o mpu401.o
-obj-$(CONFIG_SOUND_MAD16)      += mad16.o ad1848.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_CS4232)     += cs4232.o uart401.o
 obj-$(CONFIG_SOUND_MSS)                += ad1848.o
 obj-$(CONFIG_SOUND_OPL3SA2)    += opl3sa2.o ad1848.o mpu401.o
 obj-$(CONFIG_SOUND_PAS)                += pas2.o sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_SB)         += sb.o sb_lib.o uart401.o
 obj-$(CONFIG_SOUND_KAHLUA)     += kahlua.o
-obj-$(CONFIG_SOUND_WAVEFRONT)  += wavefront.o
-obj-$(CONFIG_SOUND_MAUI)       += maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)     += mpu401.o
 obj-$(CONFIG_SOUND_UART6850)   += uart6850.o
-obj-$(CONFIG_SOUND_GUS)                += gus.o ad1848.o
 obj-$(CONFIG_SOUND_ADLIB)      += adlib_card.o opl3.o
 obj-$(CONFIG_SOUND_YM3812)     += opl3.o
 obj-$(CONFIG_SOUND_VMIDI)      += v_midi.o
 obj-$(CONFIG_SOUND_VIDC)       += vidc_mod.o
 obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o
-obj-$(CONFIG_SOUND_SGALAXY)    += sgalaxy.o ad1848.o
 obj-$(CONFIG_SOUND_AD1816)     += ad1816.o
 obj-$(CONFIG_SOUND_AD1889)     += ad1889.o ac97_codec.o
 obj-$(CONFIG_SOUND_ACI_MIXER)  += aci.o
-obj-$(CONFIG_SOUND_AWE32_SYNTH)        += awe_wave.o
 
 obj-$(CONFIG_SOUND_VIA82CXXX)  += via82cxxx_audio.o ac97_codec.o
 ifeq ($(CONFIG_MIDI_VIA82CXXX),y)
   obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o
 endif
-obj-$(CONFIG_SOUND_YMFPCI)     += ymfpci.o ac97_codec.o
-ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y)
-  obj-$(CONFIG_SOUND_YMFPCI)    += opl3.o uart401.o
-endif
 obj-$(CONFIG_SOUND_MSNDCLAS)   += msnd.o msnd_classic.o
 obj-$(CONFIG_SOUND_MSNDPIN)    += msnd.o msnd_pinnacle.o
 obj-$(CONFIG_SOUND_VWSND)      += vwsnd.o
 obj-$(CONFIG_SOUND_NM256)      += nm256_audio.o ac97.o
 obj-$(CONFIG_SOUND_ICH)                += i810_audio.o ac97_codec.o
-obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o
-obj-$(CONFIG_SOUND_CMPCI)      += cmpci.o
-ifeq ($(CONFIG_SOUND_CMPCI_FM),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o opl3.o
-endif
-ifeq ($(CONFIG_SOUND_CMPCI_MIDI),y)
-  obj-$(CONFIG_SOUND_CMPCI)     += sound.o mpu401.o
-endif
-obj-$(CONFIG_SOUND_ES1370)     += es1370.o
 obj-$(CONFIG_SOUND_ES1371)     += es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)    += nec_vrc5477.o ac97_codec.o
-obj-$(CONFIG_SOUND_AU1000)     += au1000.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1550_AC97)        += au1550_ac97.o ac97_codec.o
-obj-$(CONFIG_SOUND_ESSSOLO1)   += esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)     += cs46xx.o ac97_codec.o
-obj-$(CONFIG_SOUND_MAESTRO)    += maestro.o
-obj-$(CONFIG_SOUND_MAESTRO3)   += maestro3.o ac97_codec.o
 obj-$(CONFIG_SOUND_TRIDENT)    += trident.o ac97_codec.o
-obj-$(CONFIG_SOUND_HARMONY)    += harmony.o
 obj-$(CONFIG_SOUND_EMU10K1)    += ac97_codec.o
 obj-$(CONFIG_SOUND_BCM_CS4297A)        += swarm_cs4297a.o
-obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
 obj-$(CONFIG_SOUND_BT878)      += btaudio.o
-obj-$(CONFIG_SOUND_ALI5455)    += ali5455.o ac97_codec.o
-obj-$(CONFIG_SOUND_FORTE)      += forte.o ac97_codec.o
 
-obj-$(CONFIG_SOUND_AD1980)     += ac97_plugin_ad1980.o ac97_codec.o
 obj-$(CONFIG_SOUND_WM97XX)     += ac97_plugin_wm97xx.o
 
 ifeq ($(CONFIG_MIDI_EMU10K1),y)
@@ -87,7 +58,6 @@ ifeq ($(CONFIG_MIDI_EMU10K1),y)
 endif
 
 obj-$(CONFIG_SOUND_EMU10K1)    += emu10k1/
-obj-$(CONFIG_SOUND_CS4281)     += cs4281/
 obj-$(CONFIG_DMASOUND)         += dmasound/
 
 # Declare multi-part drivers.
@@ -98,17 +68,15 @@ sound-objs  :=                                                      \
     midi_syms.o midi_synth.o midibuf.o                                 \
     sequencer.o sequencer_syms.o sound_timer.o sys_timer.o
 
-gus-objs       := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o
 pas2-objs      := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
 sb-objs                := sb_card.o
 sb_lib-objs    := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
 vidc_mod-objs  := vidc.o vidc_fill.o
-wavefront-objs  := wavfront.o wf_midi.o yss225.o
 
 hostprogs-y    := bin2hex hex2hex
 
 # Files generated that shall be removed upon make clean
-clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \
+clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \
                pss_boot.h trix_boot.h
 
 # Firmware files that need translation
@@ -118,21 +86,6 @@ clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \
 # will be forced to be remade.
 #
 
-# Turtle Beach Maui / Tropez
-
-$(obj)/maui.o: $(obj)/maui_boot.h
-
-ifeq ($(CONFIG_MAUI_HAVE_BOOT),y)
-    $(obj)/maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) $(obj)/bin2hex
-       $(obj)/bin2hex -i maui_os < $< > $@
-else
-    $(obj)/maui_boot.h:
-       (                                                       \
-           echo 'static unsigned char * maui_os = NULL;';      \
-           echo 'static int maui_osLen = 0;';                  \
-       ) > $@
-endif
-
 # Turtle Beach MultiSound
 
 ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y)
index 3ba6d91e891d2aba0b87c48d4eda3f1c6011bdae..72cf4ed77937dac96bcda281c2b9a4470b4a2c8a 100644 (file)
@@ -112,25 +112,6 @@ ac97_init (struct ac97_hwint *dev)
     return 0;
 }
 
-/* Reset the mixer to the currently saved settings.  */
-int
-ac97_reset (struct ac97_hwint *dev)
-{
-    int x;
-
-    if (dev->reset_device (dev))
-       return -1;
-
-    /* Now set the registers back to their last-written values. */
-    for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) {
-       int regnum = mixerRegs[x].ac97_regnum;
-       int value = dev->last_written_mixer_values [regnum / 2];
-       if (value >= 0)
-           ac97_put_register (dev, regnum, value);
-    }
-    return 0;
-}
-
 /* Return the contents of register REG; use the cache if the value in it
    is valid.  Returns a negative error code on failure. */
 static int
@@ -441,7 +422,6 @@ EXPORT_SYMBOL(ac97_init);
 EXPORT_SYMBOL(ac97_set_values);
 EXPORT_SYMBOL(ac97_put_register);
 EXPORT_SYMBOL(ac97_mixer_ioctl);
-EXPORT_SYMBOL(ac97_reset);
 MODULE_LICENSE("GPL");
 
 \f
index 77d454ea3202e1d231f1b94e808c0e9cff331638..01837a9d7d6eff2baa6d9daea9f864c826f238ee 100644 (file)
@@ -192,9 +192,6 @@ extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value);
 extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd,
                             void __user * arg);
 
-/* Do a complete reset on the AC97 mixer, restoring all mixer registers to
-   the current values.  Normally used after an APM resume event.  */
-extern int ac97_reset (struct ac97_hwint *dev);
 #endif
 \f
 /*
index 972327c97644f29bd37c09d0de4639ea3f9fb56f..602db497929abd70d048d1d5215b0d869651ab5f 100644 (file)
@@ -1399,95 +1399,6 @@ unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
 
 EXPORT_SYMBOL(ac97_set_adc_rate);
 
-int ac97_save_state(struct ac97_codec *codec)
-{
-       return 0;       
-}
-
-EXPORT_SYMBOL(ac97_save_state);
-
-int ac97_restore_state(struct ac97_codec *codec)
-{
-       int i;
-       unsigned int left, right, val;
-
-       for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-               if (!supported_mixer(codec, i)) 
-                       continue;
-
-               val = codec->mixer_state[i];
-               right = val >> 8;
-               left = val  & 0xff;
-               codec->write_mixer(codec, i, left, right);
-       }
-       return 0;
-}
-
-EXPORT_SYMBOL(ac97_restore_state);
-
-/**
- *     ac97_register_driver    -       register a codec helper
- *     @driver: Driver handler
- *
- *     Register a handler for codecs matching the codec id. The handler
- *     attach function is called for all present codecs and will be 
- *     called when new codecs are discovered.
- */
-int ac97_register_driver(struct ac97_driver *driver)
-{
-       struct list_head *l;
-       struct ac97_codec *c;
-       
-       mutex_lock(&codec_mutex);
-       INIT_LIST_HEAD(&driver->list);
-       list_add(&driver->list, &codec_drivers);
-       
-       list_for_each(l, &codecs)
-       {
-               c = list_entry(l, struct ac97_codec, list);
-               if(c->driver != NULL || ((c->model ^ driver->codec_id) & driver->codec_mask))
-                       continue;
-               if(driver->probe(c, driver))
-                       continue;
-               c->driver = driver;
-       }
-       mutex_unlock(&codec_mutex);
-       return 0;
-}
-
-EXPORT_SYMBOL_GPL(ac97_register_driver);
-
-/**
- *     ac97_unregister_driver  -       unregister a codec helper
- *     @driver: Driver handler
- *
- *     Unregister a handler for codecs matching the codec id. The handler
- *     remove function is called for all matching codecs.
- */
-void ac97_unregister_driver(struct ac97_driver *driver)
-{
-       struct list_head *l;
-       struct ac97_codec *c;
-       
-       mutex_lock(&codec_mutex);
-       list_del_init(&driver->list);
-
-       list_for_each(l, &codecs)
-       {
-               c = list_entry(l, struct ac97_codec, list);
-               if (c->driver == driver) {
-                       driver->remove(c, driver);
-                       c->driver = NULL;
-               }
-       }
-       
-       mutex_unlock(&codec_mutex);
-}
-
-EXPORT_SYMBOL_GPL(ac97_unregister_driver);
-
 static int swap_headphone(int remove_master)
 {
        struct list_head *l;
diff --git a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c
deleted file mode 100644 (file)
index 24a9acd..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-    ac97_plugin_ad1980.c  Copyright (C) 2003 Red Hat, Inc. All rights reserved.
-
-   The contents of this file are subject to the Open Software License version 1.1
-   that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is 
-   included herein by reference. 
-   
-   Alternatively, the contents of this file may be used under the
-   terms of the GNU General Public License version 2 (the "GPL") as 
-   distributed in the kernel source COPYING file, in which
-   case the provisions of the GPL are applicable instead of the
-   above.  If you wish to allow the use of your version of this file
-   only under the terms of the GPL and not to allow others to use
-   your version of this file under the OSL, indicate your decision
-   by deleting the provisions above and replace them with the notice
-   and other provisions required by the GPL.  If you do not delete
-   the provisions above, a recipient may use your version of this
-   file under either the OSL or the GPL.
-   
-   Authors:    Alan Cox <alan@redhat.com>
-
-   This is an example codec plugin. This one switches the connections
-   around to match the setups some vendors use with audio switched to
-   non standard front connectors not the normal rear ones
-
-   This code primarily exists to demonstrate how to use the codec
-   interface
-
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/ac97_codec.h>
-
-/**
- *     ad1980_remove           -       codec remove callback
- *     @codec: The codec that is being removed
- *
- *     This callback occurs when an AC97 codec is being removed. A
- *     codec remove call will not occur for a codec during that codec
- *     probe callback.
- *
- *     Most drivers will need to lock their remove versus their 
- *     use of the codec after the probe function.
- */
-static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-       /* Nothing to do in the simple example */
-}
-
-
-/**
- *     ad1980_probe            -       codec found callback
- *     @codec: ac97 codec matching the idents
- *     @driver: ac97_driver it matched
- *
- *     This entry point is called when a codec is found which matches
- *     the driver. At the point it is called the codec is basically
- *     operational, mixer operations have been initialised and can
- *     be overriden. Called in process context. The field driver_private
- *     is available for the driver to use to store stuff.
- *
- *     The caller can claim the device by returning zero, or return
- *     a negative error code. 
- */
-static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver)
-{
-       u16 control;
-
-#define AC97_AD_MISC   0x76
-
-       /* Switch the inputs/outputs over (from Dell code) */
-       control = codec->codec_read(codec, AC97_AD_MISC);
-       codec->codec_write(codec, AC97_AD_MISC, control | 0x4420);
-       
-       /* We could refuse the device since we dont need to hang around,
-          but we will claim it */
-       return 0;
-}
-       
-static struct ac97_driver ad1980_driver = {
-       .codec_id       = 0x41445370,
-       .codec_mask     = 0xFFFFFFFF,
-       .name           = "AD1980 example",
-       .probe          = ad1980_probe,
-       .remove         = __devexit_p(ad1980_remove),
-};
-
-/**
- *     ad1980_exit             -       module exit path
- *
- *     Our module is being unloaded. At this point unregister_driver
- *     will call back our remove handler for any existing codecs. You
- *     may not unregister_driver from interrupt context or from a 
- *     probe/remove callback.
- */
-
-static void ad1980_exit(void)
-{
-       ac97_unregister_driver(&ad1980_driver);
-}
-
-/**
- *     ad1980_init             -       set up ad1980 handlers
- *
- *     After we call the register function it will call our probe
- *     function for each existing matching device before returning to us.
- *     Any devices appearing afterwards whose id's match the codec_id
- *     will also cause the probe function to be called.
- *     You may not register_driver from interrupt context or from a 
- *     probe/remove callback.
- */
-static int ad1980_init(void)
-{
-       return ac97_register_driver(&ad1980_driver);
-}
-
-module_init(ad1980_init);
-module_exit(ad1980_exit);
-MODULE_LICENSE("GPL");
index f6b6b886c2adcdcc4f199670da294bc126760bcd..257b7536fb18b505033e3a4233aa67187309f3cb 100644 (file)
@@ -195,6 +195,7 @@ static void     ad1848_halt(int dev);
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
@@ -2195,7 +2196,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
                printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);
 }
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        unsigned char status;
        ad1848_info *devc;
@@ -2802,7 +2803,6 @@ EXPORT_SYMBOL(ad1848_detect);
 EXPORT_SYMBOL(ad1848_init);
 EXPORT_SYMBOL(ad1848_unload);
 EXPORT_SYMBOL(ad1848_control);
-EXPORT_SYMBOL(adintr);
 EXPORT_SYMBOL(probe_ms_sound);
 EXPORT_SYMBOL(attach_ms_sound);
 EXPORT_SYMBOL(unload_ms_sound);
index d0573b0239732edf59608863ef504523074544b8..b95ebe28d42609a15b78f96a26461278f334c8ab 100644 (file)
@@ -18,7 +18,6 @@ void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int
 int ad1848_detect (struct resource *ports, int *flags, int *osp);
 int ad1848_control(int cmd, int arg);
 
-irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy);
 void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner);
 
 int probe_ms_sound(struct address_info *hw_config, struct resource *ports);
diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c
deleted file mode 100644 (file)
index 70dcd70..0000000
+++ /dev/null
@@ -1,3735 +0,0 @@
-/*
- *     ALI  ali5455 and friends ICH driver for Linux
- *     LEI HU <Lei_Hu@ali.com.tw>
- *
- *  Built from:
- *     drivers/sound/i810_audio
- *
- *     The ALi 5455 is similar but not quite identical to the Intel ICH
- *     series of controllers. Its easier to keep the driver separated from
- *     the i810 driver.
- *
- *     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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- *     ALi 5455 theory of operation
- *
- *     The chipset provides three DMA channels that talk to an AC97
- *     CODEC (AC97 is a digital/analog mixer standard). At its simplest
- *     you get 48Khz audio with basic volume and mixer controls. At the
- *     best you get rate adaption in the codec. We set the card up so
- *     that we never take completion interrupts but instead keep the card
- *     chasing its tail around a ring buffer. This is needed for mmap
- *     mode audio and happens to work rather well for non-mmap modes too.
- *
- *     The board has one output channel for PCM audio (supported) and
- *     a stereo line in and mono microphone input. Again these are normally
- *     locked to 48Khz only. Right now recording is not finished.
- *
- *     There is no midi support, no synth support. Use timidity. To get
- *     esd working you need to use esd -r 48000 as it won't probe 48KHz
- *     by default. mpg123 can't handle 48Khz only audio so use xmms.
- *
- *     If you need to force a specific rate set the clocking= option
- *
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-
-#ifndef PCI_DEVICE_ID_ALI_5455
-#define PCI_DEVICE_ID_ALI_5455 0x5455
-#endif
-
-#ifndef PCI_VENDOR_ID_ALI
-#define PCI_VENDOR_ID_ALI      0x10b9
-#endif
-
-static int strict_clocking = 0;
-static unsigned int clocking = 0;
-static unsigned int codec_pcmout_share_spdif_locked = 0;
-static unsigned int codec_independent_spdif_locked = 0;
-static unsigned int controller_pcmout_share_spdif_locked = 0;
-static unsigned int controller_independent_spdif_locked = 0;
-static unsigned int globel = 0;
-
-#define ADC_RUNNING    1
-#define DAC_RUNNING    2
-#define CODEC_SPDIFOUT_RUNNING 8
-#define CONTROLLER_SPDIFOUT_RUNNING 4
-
-#define SPDIF_ENABLE_OUTPUT    4       /* bits 0,1 are PCM */
-
-#define ALI5455_FMT_16BIT      1
-#define ALI5455_FMT_STEREO     2
-#define ALI5455_FMT_MASK       3
-
-#define SPDIF_ON       0x0004
-#define SURR_ON                0x0010
-#define CENTER_LFE_ON  0x0020
-#define VOL_MUTED      0x8000
-
-
-#define ALI_SPDIF_OUT_CH_STATUS 0xbf
-/* the 810's array of pointers to data buffers */
-
-struct sg_item {
-#define BUSADDR_MASK   0xFFFFFFFE
-       u32 busaddr;
-#define CON_IOC        0x80000000      /* interrupt on completion */
-#define CON_BUFPAD     0x40000000      /* pad underrun with last sample, else 0 */
-#define CON_BUFLEN_MASK        0x0000ffff      /* buffer length in samples */
-       u32 control;
-};
-
-/* an instance of the ali channel */
-#define SG_LEN 32
-struct ali_channel {
-       /* these sg guys should probably be allocated
-          separately as nocache. Must be 8 byte aligned */
-       struct sg_item sg[SG_LEN];      /* 32*8 */
-       u32 offset;             /* 4 */
-       u32 port;               /* 4 */
-       u32 used;
-       u32 num;
-};
-
-/*
- * we have 3 separate dma engines.  pcm in, pcm out, and mic.
- * each dma engine has controlling registers.  These goofy
- * names are from the datasheet, but make it easy to write
- * code while leafing through it.
- */
-
-#define ENUM_ENGINE(PRE,DIG)                                                                   \
-enum {                                                                                         \
-       PRE##_BDBAR =   0x##DIG##0,             /* Buffer Descriptor list Base Address */       \
-       PRE##_CIV =     0x##DIG##4,             /* Current Index Value */                       \
-       PRE##_LVI =     0x##DIG##5,             /* Last Valid Index */                          \
-       PRE##_SR =      0x##DIG##6,             /* Status Register */                           \
-       PRE##_PICB =    0x##DIG##8,             /* Position In Current Buffer */                \
-       PRE##_CR =      0x##DIG##b              /* Control Register */                          \
-}
-
-ENUM_ENGINE(OFF, 0);           /* Offsets */
-ENUM_ENGINE(PI, 4);            /* PCM In */
-ENUM_ENGINE(PO, 5);            /* PCM Out */
-ENUM_ENGINE(MC, 6);            /* Mic In */
-ENUM_ENGINE(CODECSPDIFOUT, 7); /* CODEC SPDIF OUT  */
-ENUM_ENGINE(CONTROLLERSPDIFIN, A);     /* CONTROLLER SPDIF In */
-ENUM_ENGINE(CONTROLLERSPDIFOUT, B);    /* CONTROLLER SPDIF OUT */
-
-
-enum {
-       ALI_SCR = 0x00,         /* System Control Register */
-       ALI_SSR = 0x04,         /* System Status Register  */
-       ALI_DMACR = 0x08,       /* DMA Control Register    */
-       ALI_FIFOCR1 = 0x0c,     /* FIFO Control Register 1  */
-       ALI_INTERFACECR = 0x10, /* Interface Control Register */
-       ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */
-       ALI_INTERRUPTSR = 0x18, /* Interrupt  Status Register */
-       ALI_FIFOCR2 = 0x1c,     /* FIFO Control Register 2   */
-       ALI_CPR = 0x20,         /* Command Port Register     */
-       ALI_SPR = 0x24,         /* Status Port Register      */
-       ALI_FIFOCR3 = 0x2c,     /* FIFO Control Register 3  */
-       ALI_TTSR = 0x30,        /* Transmit Tag Slot Register */
-       ALI_RTSR = 0x34,        /* Receive Tag Slot  Register */
-       ALI_CSPSR = 0x38,       /* Command/Status Port Status Register */
-       ALI_CAS = 0x3c,         /* Codec Write Semaphore Register */
-       ALI_SPDIFCSR = 0xf8,    /* spdif channel status register  */
-       ALI_SPDIFICS = 0xfc     /* spdif interface control/status  */
-};
-
-// x-status register(x:pcm in ,pcm out, mic in,)
-/* interrupts for a dma engine */
-#define DMA_INT_FIFO           (1<<4)  /* fifo under/over flow */
-#define DMA_INT_COMPLETE       (1<<3)  /* buffer read/write complete and ioc set */
-#define DMA_INT_LVI            (1<<2)  /* last valid done */
-#define DMA_INT_CELV           (1<<1)  /* last valid is current */
-#define DMA_INT_DCH            (1)     /* DMA Controller Halted (happens on LVI interrupts) */ //not eqult intel
-#define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI)
-
-/* interrupts for the whole chip */// by interrupt status register finish
-
-#define INT_SPDIFOUT   (1<<23) /* controller spdif out INTERRUPT */
-#define INT_SPDIFIN   (1<<22)
-#define INT_CODECSPDIFOUT   (1<<19)
-#define INT_MICIN   (1<<18)
-#define INT_PCMOUT   (1<<17)
-#define INT_PCMIN   (1<<16)
-#define INT_CPRAIS   (1<<7)
-#define INT_SPRAIS   (1<<5)
-#define INT_GPIO    (1<<1)
-#define INT_MASK   (INT_SPDIFOUT|INT_CODECSPDIFOUT|INT_MICIN|INT_PCMOUT|INT_PCMIN)
-
-#define DRIVER_VERSION "0.02ac"
-
-/* magic numbers to protect our data structures */
-#define ALI5455_CARD_MAGIC             0x5072696E      /* "Prin" */
-#define ALI5455_STATE_MAGIC            0x63657373      /* "cess" */
-#define ALI5455_DMA_MASK               0xffffffff      /* DMA buffer mask for pci_alloc_consist */
-#define NR_HW_CH                       5       //I think 5 channel
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97                2
-
-/* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */
-/* stream at a minimum for this card to be happy */
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-/* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */
-/* values are one less than might be expected */
-static const unsigned sample_shift[] = { -1, 0, 0, 1 };
-
-#define ALI5455
-static char *card_names[] = {
-       "ALI 5455"
-};
-
-static struct pci_device_id ali_pci_tbl[] = {
-       {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5455,
-        PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI5455},
-       {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, ali_pci_tbl);
-
-#ifdef CONFIG_PM
-#define PM_SUSPENDED(card) (card->pm_suspended)
-#else
-#define PM_SUSPENDED(card) (0)
-#endif
-
-/* "software" or virtual channel, an instance of opened /dev/dsp */
-struct ali_state {
-       unsigned int magic;
-       struct ali_card *card;  /* Card info */
-
-       /* single open lock mechanism, only used for recording */
-       struct mutex open_mutex;
-       wait_queue_head_t open_wait;
-
-       /* file mode */
-       mode_t open_mode;
-
-       /* virtual channel number */
-       int virt;
-
-#ifdef CONFIG_PM
-       unsigned int pm_saved_dac_rate, pm_saved_adc_rate;
-#endif
-       struct dmabuf {
-               /* wave sample stuff */
-               unsigned int rate;
-               unsigned char fmt, enable, trigger;
-
-               /* hardware channel */
-               struct ali_channel *read_channel;
-               struct ali_channel *write_channel;
-               struct ali_channel *codec_spdifout_channel;
-               struct ali_channel *controller_spdifout_channel;
-
-               /* OSS buffer management stuff */
-               void *rawbuf;
-               dma_addr_t dma_handle;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-
-               /* our buffer acts like a circular ring */
-               unsigned hwptr; /* where dma last started, updated by update_ptr */
-               unsigned swptr; /* where driver last clear/filled, updated by read/write */
-               int count;      /* bytes to be consumed or been generated by dma machine */
-               unsigned total_bytes;   /* total bytes dmaed by hardware */
-
-               unsigned error; /* number of over/underruns */
-               wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */
-
-               /* redundant, but makes calculations easier */
-               /* what the hardware uses */
-               unsigned dmasize;
-               unsigned fragsize;
-               unsigned fragsamples;
-
-               /* what we tell the user to expect */
-               unsigned userfrags;
-               unsigned userfragsize;
-
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned update_flag;
-               unsigned ossfragsize;
-               unsigned ossmaxfrags;
-               unsigned subdivision;
-       } dmabuf;
-};
-
-
-struct ali_card {
-       struct ali_channel channel[5];
-       unsigned int magic;
-
-       /* We keep ali5455 cards in a linked list */
-       struct ali_card *next;
-
-       /* The ali has a certain amount of cross channel interaction
-          so we use a single per card lock */
-       spinlock_t lock;
-       spinlock_t ac97_lock;
-
-       /* PCI device stuff */
-       struct pci_dev *pci_dev;
-       u16 pci_id;
-#ifdef CONFIG_PM
-       u16 pm_suspended;
-       int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97];
-#endif
-       /* soundcore stuff */
-       int dev_audio;
-
-       /* structures for abstraction of hardware facilities, codecs, banks and channels */
-       struct ac97_codec *ac97_codec[NR_AC97];
-       struct ali_state *states[NR_HW_CH];
-
-       u16 ac97_features;
-       u16 ac97_status;
-       u16 channels;
-
-       /* hardware resources */
-       unsigned long iobase;
-
-       u32 irq;
-
-       /* Function support */
-       struct ali_channel *(*alloc_pcm_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_rec_pcm_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_rec_mic_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_codec_spdifout_channel) (struct ali_card *);
-       struct ali_channel *(*alloc_controller_spdifout_channel) (struct  ali_card *);
-       void (*free_pcm_channel) (struct ali_card *, int chan);
-
-       /* We have a *very* long init time possibly, so use this to block */
-       /* attempts to open our devices before we are ready (stops oops'es) */
-       int initializing;
-};
-
-
-static struct ali_card *devs = NULL;
-
-static int ali_open_mixdev(struct inode *inode, struct file *file);
-static int ali_ioctl_mixdev(struct inode *inode, struct file *file,
-                           unsigned int cmd, unsigned long arg);
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg);
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data);
-
-static struct ali_channel *ali_alloc_pcm_channel(struct ali_card *card)
-{
-       if (card->channel[1].used == 1)
-               return NULL;
-       card->channel[1].used = 1;
-       return &card->channel[1];
-}
-
-static struct ali_channel *ali_alloc_rec_pcm_channel(struct ali_card *card)
-{
-       if (card->channel[0].used == 1)
-               return NULL;
-       card->channel[0].used = 1;
-       return &card->channel[0];
-}
-
-static struct ali_channel *ali_alloc_rec_mic_channel(struct ali_card *card)
-{
-       if (card->channel[2].used == 1)
-               return NULL;
-       card->channel[2].used = 1;
-       return &card->channel[2];
-}
-
-static struct ali_channel *ali_alloc_codec_spdifout_channel(struct ali_card *card)
-{
-       if (card->channel[3].used == 1)
-               return NULL;
-       card->channel[3].used = 1;
-       return &card->channel[3];
-}
-
-static struct ali_channel *ali_alloc_controller_spdifout_channel(struct ali_card *card)
-{
-       if (card->channel[4].used == 1)
-               return NULL;
-       card->channel[4].used = 1;
-       return &card->channel[4];
-}
-static void ali_free_pcm_channel(struct ali_card *card, int channel)
-{
-       card->channel[channel].used = 0;
-}
-
-
-//add support  codec spdif out 
-static int ali_valid_spdif_rate(struct ac97_codec *codec, int rate)
-{
-       unsigned long id = 0L;
-
-       id = (ali_ac97_get(codec, AC97_VENDOR_ID1) << 16);
-       id |= ali_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff;
-       switch (id) {
-       case 0x41445361:        /* AD1886 */
-               if (rate == 48000) {
-                       return 1;
-               }
-               break;
-       case 0x414c4720:        /* ALC650 */
-               if (rate == 48000) {
-                       return 1;
-               }
-               break;
-       default:                /* all other codecs, until we know otherwiae */
-               if (rate == 48000 || rate == 44100 || rate == 32000) {
-                       return 1;
-               }
-               break;
-       }
-       return (0);
-}
-
-/* ali_set_spdif_output
- * 
- *  Configure the S/PDIF output transmitter. When we turn on
- *  S/PDIF, we turn off the analog output. This may not be
- *  the right thing to do.
- *
- *  Assumptions:
- *     The DSP sample rate must already be set to a supported
- *     S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort.
- */
-static void ali_set_spdif_output(struct ali_state *state, int slots,
-                                int rate)
-{
-       int vol;
-       int aud_reg;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 4)) {
-               state->card->ac97_status &= ~SPDIF_ON;
-       } else {
-               if (slots == -1) {      /* Turn off S/PDIF */
-                       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-
-                       /* If the volume wasn't muted before we turned on S/PDIF, unmute it */
-                       if (!(state->card->ac97_status & VOL_MUTED)) {
-                               aud_reg = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-                               ali_ac97_set(codec, AC97_MASTER_VOL_STEREO,
-                                            (aud_reg & ~VOL_MUTED));
-                       }
-                       state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON);
-                       return;
-               }
-
-               vol = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO);
-               state->card->ac97_status = vol & VOL_MUTED;
-
-               /* Set S/PDIF transmitter sample rate */
-               aud_reg = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-               switch (rate) {
-               case 32000:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K;
-                       break;
-               case 44100:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K;
-                       break;
-               case 48000:
-                       aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K;
-                       break;
-               default:
-                       /* turn off S/PDIF */
-                       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-                       state->card->ac97_status &= ~SPDIF_ON;
-                       return;
-               }
-
-               ali_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg);
-
-               aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-               aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_SPDIF;
-               ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-               aud_reg = ali_ac97_get(codec, AC97_POWER_CONTROL);
-               aud_reg |= 0x0002;
-               ali_ac97_set(codec, AC97_POWER_CONTROL, aud_reg);
-               udelay(1);
-
-               state->card->ac97_status |= SPDIF_ON;
-
-               /* Check to make sure the configuration is valid */
-               aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-               if (!(aud_reg & 0x0400)) {
-                       /* turn off S/PDIF */
-                       ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF));
-                       state->card->ac97_status &= ~SPDIF_ON;
-                       return;
-               }
-               if (codec_independent_spdif_locked > 0) {
-                       aud_reg = ali_ac97_get(codec, 0x6a);
-                       ali_ac97_set(codec, 0x6a, (aud_reg & 0xefff));
-               }
-               /* Mute the analog output */
-               /* Should this only mute the PCM volume??? */
-       }
-}
-
-/* ali_set_dac_channels
- *
- *  Configure the codec's multi-channel DACs
- *
- *  The logic is backwards. Setting the bit to 1 turns off the DAC. 
- *
- *  What about the ICH? We currently configure it using the
- *  SNDCTL_DSP_CHANNELS ioctl.  If we're turnning on the DAC, 
- *  does that imply that we want the ICH set to support
- *  these channels?
- *  
- *  TODO:
- *    vailidate that the codec really supports these DACs
- *    before turning them on. 
- */
-static void ali_set_dac_channels(struct ali_state *state, int channel)
-{
-       int aud_reg;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS);
-       aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK;
-       state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON);
-
-       switch (channel) {
-       case 2:         /* always enabled */
-               break;
-       case 4:
-               aud_reg &= ~AC97_EA_PRJ;
-               state->card->ac97_status |= SURR_ON;
-               break;
-       case 6:
-               aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK);
-               state->card->ac97_status |= SURR_ON | CENTER_LFE_ON;
-               break;
-       default:
-               break;
-       }
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg);
-
-}
-
-/* set playback sample rate */
-static unsigned int ali_set_dac_rate(struct ali_state *state,
-                                    unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       u32 new_rate;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       /*
-        *      Adjust for misclocked crap
-        */
-
-       rate = (rate * clocking) / 48000;
-
-       if (strict_clocking && rate < 8000) {
-               rate = 8000;
-               dmabuf->rate = (rate * 48000) / clocking;
-       }
-
-       new_rate = ac97_set_dac_rate(codec, rate);
-       if (new_rate != rate) {
-               dmabuf->rate = (new_rate * 48000) / clocking;
-       }
-       rate = new_rate;
-       return dmabuf->rate;
-}
-
-/* set recording sample rate */
-static unsigned int ali_set_adc_rate(struct ali_state *state,
-                                    unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       u32 new_rate;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       /*
-        *      Adjust for misclocked crap
-        */
-
-       rate = (rate * clocking) / 48000;
-       if (strict_clocking && rate < 8000) {
-               rate = 8000;
-               dmabuf->rate = (rate * 48000) / clocking;
-       }
-
-       new_rate = ac97_set_adc_rate(codec, rate);
-
-       if (new_rate != rate) {
-               dmabuf->rate = (new_rate * 48000) / clocking;
-               rate = new_rate;
-       }
-       return dmabuf->rate;
-}
-
-/* set codec independent spdifout sample rate */
-static unsigned int ali_set_codecspdifout_rate(struct ali_state *state,
-                                              unsigned int rate)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-
-       if (!(state->card->ac97_features & 0x0001)) {
-               dmabuf->rate = clocking;
-               return clocking;
-       }
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       dmabuf->rate = rate;
-
-       return dmabuf->rate;
-}
-
-/* set  controller independent spdif out function sample rate */
-static void ali_set_spdifout_rate(struct ali_state *state,
-                                 unsigned int rate)
-{
-       unsigned char ch_st_sel;
-       unsigned short status_rate;
-
-       switch (rate) {
-       case 44100:
-               status_rate = 0;
-               break;
-       case 32000:
-               status_rate = 0x300;
-               break;
-       case 48000:
-       default:
-               status_rate = 0x200;
-               break;
-       }
-
-       ch_st_sel = inb(state->card->iobase + ALI_SPDIFICS) & ALI_SPDIF_OUT_CH_STATUS;  //select spdif_out
-
-       ch_st_sel |= 0x80;      //select right
-       outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-       outb(status_rate | 0x20, (state->card->iobase + ALI_SPDIFCSR + 2));
-
-       ch_st_sel &= (~0x80);   //select left
-       outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS));
-       outw(status_rate | 0x10, (state->card->iobase + ALI_SPDIFCSR + 2));
-}
-
-/* get current playback/recording dma buffer pointer (byte offset from LBA),
-   called with spinlock held! */
-
-static inline unsigned ali_get_dma_addr(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned int civ, offset, port, port_picb;
-       unsigned int data;
-
-       if (!dmabuf->enable)
-               return 0;
-
-       if (rec == 1)
-               port = state->card->iobase + dmabuf->read_channel->port;
-       else if (rec == 2)
-               port = state->card->iobase + dmabuf->codec_spdifout_channel->port;
-       else if (rec == 3)
-               port = state->card->iobase + dmabuf->controller_spdifout_channel->port;
-       else
-               port = state->card->iobase + dmabuf->write_channel->port;
-
-       port_picb = port + OFF_PICB;
-
-       do {
-               civ = inb(port + OFF_CIV) & 31;
-               offset = inw(port_picb);
-               /* Must have a delay here! */
-               if (offset == 0)
-                       udelay(1);
-
-               /* Reread both registers and make sure that that total
-                * offset from the first reading to the second is 0.
-                * There is an issue with SiS hardware where it will count
-                * picb down to 0, then update civ to the next value,
-                * then set the new picb to fragsize bytes.  We can catch
-                * it between the civ update and the picb update, making
-                * it look as though we are 1 fragsize ahead of where we
-                * are.  The next to we get the address though, it will
-                * be back in thdelay is more than long enough
-                * that we won't have to worry about the chip still being
-                * out of sync with reality ;-)
-                */
-       } while (civ != (inb(port + OFF_CIV) & 31) || offset != inw(port_picb));
-
-       data = ((civ + 1) * dmabuf->fragsize - (2 * offset)) % dmabuf->dmasize;
-       if (inw(port_picb) == 0)
-               data -= 2048;
-
-       return data;
-}
-
-/* Stop recording (lock held) */
-static inline void __stop_adc(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       dmabuf->enable &= ~ADC_RUNNING;
-
-       outl((1 << 18) | (1 << 16), card->iobase + ALI_DMACR);
-       udelay(1);
-
-       outb(0, card->iobase + PI_CR);
-       while (inb(card->iobase + PI_CR) != 0);
-
-       // now clear any latent interrupt bits (like the halt bit)
-       outb(inb(card->iobase + PI_SR) | 0x001e, card->iobase + PI_SR);
-       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMIN, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_adc(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_adc(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_adc(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-
-       if (dmabuf->count < dmabuf->dmasize && dmabuf->ready
-           && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-               dmabuf->enable |= ADC_RUNNING;
-               outb((1 << 4) | (1 << 2), state->card->iobase + PI_CR);
-               if (state->card->channel[0].used == 1)
-                       outl(1, state->card->iobase + ALI_DMACR);       // DMA CONTROL REGISTRER
-               udelay(100);
-               if (state->card->channel[2].used == 1)
-                       outl((1 << 2), state->card->iobase + ALI_DMACR);        //DMA CONTROL REGISTER
-               udelay(100);
-       }
-}
-
-static void start_adc(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-
-       spin_lock_irqsave(&card->lock, flags);
-       __start_adc(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop playback (lock held) */
-static inline void __stop_dac(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       dmabuf->enable &= ~DAC_RUNNING;
-       outl(0x00020000, card->iobase + 0x08);
-       outb(0, card->iobase + PO_CR);
-       while (inb(card->iobase + PO_CR) != 0)
-               cpu_relax();
-
-       outb(inb(card->iobase + PO_SR) | 0x001e, card->iobase + PO_SR);
-
-       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMOUT, card->iobase + ALI_INTERRUPTSR);
-}
-
-static void stop_dac(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_dac(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_dac(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-           (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-               dmabuf->enable |= DAC_RUNNING;
-               outb((1 << 4) | (1 << 2), state->card->iobase + PO_CR);
-               outl((1 << 1), state->card->iobase + 0x08);     //dma control register
-       }
-}
-
-static void start_dac(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __start_dac(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* stop codec and controller spdif out  (lock held) */
-static inline void __stop_spdifout(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_card *card = state->card;
-
-       if (codec_independent_spdif_locked > 0) {
-               dmabuf->enable &= ~CODEC_SPDIFOUT_RUNNING;
-               outl((1 << 19), card->iobase + 0x08);
-               outb(0, card->iobase + CODECSPDIFOUT_CR);
-
-               while (inb(card->iobase + CODECSPDIFOUT_CR) != 0)
-                       cpu_relax();
-
-               outb(inb(card->iobase + CODECSPDIFOUT_SR) | 0x001e, card->iobase + CODECSPDIFOUT_SR);
-               outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_CODECSPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       dmabuf->enable &= ~CONTROLLER_SPDIFOUT_RUNNING;
-                       outl((1 << 23), card->iobase + 0x08);
-                       outb(0, card->iobase + CONTROLLERSPDIFOUT_CR);
-                       while (inb(card->iobase + CONTROLLERSPDIFOUT_CR) != 0)
-                               cpu_relax();
-                       outb(inb(card->iobase + CONTROLLERSPDIFOUT_SR) | 0x001e, card->iobase + CONTROLLERSPDIFOUT_SR);
-                       outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_SPDIFOUT, card->iobase + ALI_INTERRUPTSR);
-               }
-       }
-}
-
-static void stop_spdifout(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __stop_spdifout(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static inline void __start_spdifout(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable &&
-           (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-               if (codec_independent_spdif_locked > 0) {
-                       dmabuf->enable |= CODEC_SPDIFOUT_RUNNING;
-                       outb((1 << 4) | (1 << 2), state->card->iobase + CODECSPDIFOUT_CR);
-                       outl((1 << 3), state->card->iobase + 0x08);     //dma control register
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               dmabuf->enable |= CONTROLLER_SPDIFOUT_RUNNING;
-                               outb((1 << 4) | (1 << 2), state->card->iobase + CONTROLLERSPDIFOUT_CR);
-                               outl((1 << 7), state->card->iobase + 0x08);     //dma control register
-                       }
-               }
-       }
-}
-
-static void start_spdifout(struct ali_state *state)
-{
-       struct ali_card *card = state->card;
-       unsigned long flags;
-       spin_lock_irqsave(&card->lock, flags);
-       __start_spdifout(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-}
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/* allocate DMA buffer, playback , recording,spdif out  buffer should be allocated separately */
-static int alloc_dmabuf(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       void *rawbuf = NULL;
-       int order, size;
-       struct page *page, *pend;
-
-       /* If we don't have any oss frag params, then use our default ones */
-       if (dmabuf->ossmaxfrags == 0)
-               dmabuf->ossmaxfrags = 4;
-       if (dmabuf->ossfragsize == 0)
-               dmabuf->ossfragsize = (PAGE_SIZE << DMABUF_DEFAULTORDER) / dmabuf->ossmaxfrags;
-       size = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-
-       if (dmabuf->rawbuf && (PAGE_SIZE << dmabuf->buforder) == size)
-               return 0;
-       /* alloc enough to satisfy the oss params */
-       for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-               if ((PAGE_SIZE << order) > size)
-                       continue;
-               if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
-                                                  PAGE_SIZE << order,
-                                                  &dmabuf->dma_handle)))
-                       break;
-       }
-       if (!rawbuf)
-               return -ENOMEM;
-
-       dmabuf->ready = dmabuf->mapped = 0;
-       dmabuf->rawbuf = rawbuf;
-       dmabuf->buforder = order;
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (page = virt_to_page(rawbuf); page <= pend; page++)
-               SetPageReserved(page);
-       return 0;
-}
-
-/* free DMA buffer */
-static void dealloc_dmabuf(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct page *page, *pend;
-
-       if (dmabuf->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-               for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(state->card->pci_dev,
-                                   PAGE_SIZE << dmabuf->buforder,
-                                   dmabuf->rawbuf, dmabuf->dma_handle);
-       }
-       dmabuf->rawbuf = NULL;
-       dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ali_state *state, unsigned rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       struct ali_channel *c = NULL;
-       struct sg_item *sg;
-       unsigned long flags;
-       int ret;
-       unsigned fragint;
-       int i;
-
-       spin_lock_irqsave(&state->card->lock, flags);
-       if (dmabuf->enable & DAC_RUNNING)
-               __stop_dac(state);
-       if (dmabuf->enable & ADC_RUNNING)
-               __stop_adc(state);
-       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-               __stop_spdifout(state);
-       if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-               __stop_spdifout(state);
-
-       dmabuf->total_bytes = 0;
-       dmabuf->count = dmabuf->error = 0;
-       dmabuf->swptr = dmabuf->hwptr = 0;
-       spin_unlock_irqrestore(&state->card->lock, flags);
-
-       /* allocate DMA buffer, let alloc_dmabuf determine if we are already
-        * allocated well enough or if we should replace the current buffer
-        * (assuming one is already allocated, if it isn't, then allocate it).
-        */
-       if ((ret = alloc_dmabuf(state)))
-               return ret;
-
-       /* FIXME: figure out all this OSS fragment stuff */
-       /* I did, it now does what it should according to the OSS API.  DL */
-       /* We may not have realloced our dmabuf, but the fragment size to
-        * fragment number ratio may have changed, so go ahead and reprogram
-        * things
-        */
-
-       dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder;
-       dmabuf->numfrag = SG_LEN;
-       dmabuf->fragsize = dmabuf->dmasize / dmabuf->numfrag;
-       dmabuf->fragsamples = dmabuf->fragsize >> 1;
-       dmabuf->userfragsize = dmabuf->ossfragsize;
-       dmabuf->userfrags = dmabuf->dmasize / dmabuf->ossfragsize;
-
-       memset(dmabuf->rawbuf, 0, dmabuf->dmasize);
-
-       if (dmabuf->ossmaxfrags == 4) {
-               fragint = 8;
-               dmabuf->fragshift = 2;
-       } else if (dmabuf->ossmaxfrags == 8) {
-               fragint = 4;
-               dmabuf->fragshift = 3;
-       } else if (dmabuf->ossmaxfrags == 16) {
-               fragint = 2;
-               dmabuf->fragshift = 4;
-       } else {
-               fragint = 1;
-               dmabuf->fragshift = 5;
-       }
-       /*
-        *      Now set up the ring 
-        */
-
-       if (rec == 1)
-               c = dmabuf->read_channel;
-       else if (rec == 2)
-               c = dmabuf->codec_spdifout_channel;
-       else if (rec == 3)
-               c = dmabuf->controller_spdifout_channel;
-       else if (rec == 0)
-               c = dmabuf->write_channel;
-       if (c != NULL) {
-               sg = &c->sg[0];
-               /*
-                *      Load up 32 sg entries and take an interrupt at half
-                *      way (we might want more interrupts later..) 
-                */
-               for (i = 0; i < dmabuf->numfrag; i++) {
-                       sg->busaddr =
-                           virt_to_bus(dmabuf->rawbuf +
-                                       dmabuf->fragsize * i);
-                       // the card will always be doing 16bit stereo
-                       sg->control = dmabuf->fragsamples;
-                       sg->control |= CON_BUFPAD;      //I modify
-                       // set us up to get IOC interrupts as often as needed to
-                       // satisfy numfrag requirements, no more
-                       if (((i + 1) % fragint) == 0) {
-                               sg->control |= CON_IOC;
-                       }
-                       sg++;
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               outb(2, state->card->iobase + c->port + OFF_CR);        /* reset DMA machine */
-               outl(virt_to_bus(&c->sg[0]), state->card->iobase + c->port + OFF_BDBAR);
-               outb(0, state->card->iobase + c->port + OFF_CIV);
-               outb(0, state->card->iobase + c->port + OFF_LVI);
-               spin_unlock_irqrestore(&state->card->lock, flags);
-       }
-       /* set the ready flag for the dma buffer */
-       dmabuf->ready = 1;
-       return 0;
-}
-
-static void __ali_update_lvi(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int x, port;
-       port = state->card->iobase;
-       if (rec == 1)
-               port += dmabuf->read_channel->port;
-       else if (rec == 2)
-               port += dmabuf->codec_spdifout_channel->port;
-       else if (rec == 3)
-               port += dmabuf->controller_spdifout_channel->port;
-       else if (rec == 0)
-               port += dmabuf->write_channel->port;
-       /* if we are currently stopped, then our CIV is actually set to our
-        * *last* sg segment and we are ready to wrap to the next.  However,
-        * if we set our LVI to the last sg segment, then it won't wrap to
-        * the next sg segment, it won't even get a start.  So, instead, when
-        * we are stopped, we set both the LVI value and also we increment
-        * the CIV value to the next sg segment to be played so that when
-        * we call start_{dac,adc}, things will operate properly
-        */
-       if (!dmabuf->enable && dmabuf->ready) {
-               if (rec && dmabuf->count < dmabuf->dmasize && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                       __start_adc(state);
-                       while (! (inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                               cpu_relax();
-               } else if (!rec && dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                       __start_dac(state);
-                       while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                               cpu_relax();
-               } else if (rec && dmabuf->count && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                       if (codec_independent_spdif_locked > 0) {
-                               // outb((inb(port+OFF_CIV))&31, port+OFF_LVI);
-                               outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                               __start_spdifout(state);
-                               while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                                       cpu_relax();
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI);
-                                       __start_spdifout(state);
-                                       while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2))))
-                                               cpu_relax();
-                               }
-                       }
-               }
-       }
-
-       /* swptr - 1 is the tail of our transfer */
-       x = (dmabuf->dmasize + dmabuf->swptr - 1) % dmabuf->dmasize;
-       x /= dmabuf->fragsize;
-       outb(x, port + OFF_LVI);
-}
-
-static void ali_update_lvi(struct ali_state *state, int rec)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       if (!dmabuf->ready)
-               return;
-       spin_lock_irqsave(&state->card->lock, flags);
-       __ali_update_lvi(state, rec);
-       spin_unlock_irqrestore(&state->card->lock, flags);
-}
-
-/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
-static void ali_update_ptr(struct ali_state *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned hwptr;
-       int diff;
-       
-       /* error handling and process wake up for DAC */
-       if (dmabuf->enable == ADC_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 1);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count += diff;
-               if (dmabuf->count > dmabuf->dmasize) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a read */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + PI_CIV) & 31) != (inb(state->card->iobase + PI_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on read\n");
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count > dmabuf->userfragsize)
-                       wake_up(&dmabuf->wait);
-       }
-       /* error handling and process wake up for DAC */
-       if (dmabuf->enable == DAC_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 0);
-               diff =
-                   (dmabuf->dmasize + hwptr -
-                    dmabuf->hwptr) % dmabuf->dmasize;
-#if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP)
-               printk("DAC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff);
-#endif
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + PO_CIV) & 31) != (inb(state->card->iobase + PO_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-                               printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n",
-                                                       inb(state->card->iobase + PO_CIV) & 31,
-                                                       inb(state->card->iobase + PO_LVI) & 31, 
-                                                       dmabuf->hwptr,
-                                                       dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-
-       /* error handling and process wake up for CODEC SPDIF OUT */
-       if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 2);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31)) {
-                               printk(KERN_WARNING "ali_audio: DMA overrun on write\n");
-                               printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n", 
-                                       inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31,
-                                       inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31,
-                                       dmabuf->hwptr, dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-       /* error handling and process wake up for CONTROLLER SPDIF OUT */
-       if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-               /* update hardware pointer */
-               hwptr = ali_get_dma_addr(state, 3);
-               diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
-               dmabuf->hwptr = hwptr;
-               dmabuf->total_bytes += diff;
-               dmabuf->count -= diff;
-               if (dmabuf->count < 0) {
-                       /* buffer underrun or buffer overrun */
-                       /* this is normal for the end of a write */
-                       /* only give an error if we went past the */
-                       /* last valid sg entry */
-                       if ((inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31)) {
-                               printk(KERN_WARNING
-                                      "ali_audio: DMA overrun on write\n");
-                               printk("ali_audio: CIV %d, LVI %d, hwptr %x, "
-                                       "count %d\n",
-                                               inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31,
-                                               inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31,
-                                               dmabuf->hwptr, dmabuf->count);
-                               dmabuf->error++;
-                       }
-               }
-               if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize))
-                       wake_up(&dmabuf->wait);
-       }
-}
-
-static inline int ali_get_free_write_space(struct
-                                          ali_state
-                                          *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int free;
-
-       if (dmabuf->count < 0) {
-               dmabuf->count = 0;
-               dmabuf->swptr = dmabuf->hwptr;
-       }
-       free = dmabuf->dmasize - dmabuf->swptr;
-       if ((dmabuf->count + free) > dmabuf->dmasize){
-               free = dmabuf->dmasize - dmabuf->count;
-       }
-       return free;
-}
-
-static inline int ali_get_available_read_data(struct
-                                             ali_state
-                                             *state)
-{
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int avail;
-       ali_update_ptr(state);
-       // catch overruns during record
-       if (dmabuf->count > dmabuf->dmasize) {
-               dmabuf->count = dmabuf->dmasize;
-               dmabuf->swptr = dmabuf->hwptr;
-       }
-       avail = dmabuf->count;
-       avail -= (dmabuf->hwptr % dmabuf->fragsize);
-       if (avail < 0)
-               return (0);
-       return (avail);
-}
-
-static int drain_dac(struct ali_state *state, int signals_allowed)
-{
-
-       DECLARE_WAITQUEUE(wait, current);
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned long tmo;
-       int count;
-       if (!dmabuf->ready)
-               return 0;
-       if (dmabuf->mapped) {
-               stop_dac(state);
-               return 0;
-       }
-       add_wait_queue(&dmabuf->wait, &wait);
-       for (;;) {
-
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               count = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               if (count <= 0)
-                       break;
-               /* 
-                * This will make sure that our LVI is correct, that our
-                * pointer is updated, and that the DAC is running.  We
-                * have to force the setting of dmabuf->trigger to avoid
-                * any possible deadlocks.
-                */
-               if (!dmabuf->enable) {
-                       dmabuf->trigger = PCM_ENABLE_OUTPUT;
-                       ali_update_lvi(state, 0);
-               }
-               if (signal_pending(current) && signals_allowed) {
-                       break;
-               }
-
-               /* It seems that we have to set the current state to
-                * TASK_INTERRUPTIBLE every time to make the process
-                * really go to sleep.  This also has to be *after* the
-                * update_ptr() call because update_ptr is likely to
-                * do a wake_up() which will unset this before we ever
-                * try to sleep, resuling in a tight loop in this code
-                * instead of actually sleeping and waiting for an
-                * interrupt to wake us up!
-                */
-               set_current_state(TASK_INTERRUPTIBLE);
-               /*
-                * set the timeout to significantly longer than it *should*
-                * take for the DAC to drain the DMA buffer
-                */
-               tmo = (count * HZ) / (dmabuf->rate);
-               if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                       printk(KERN_ERR "ali_audio: drain_dac, dma timeout?\n");
-                       count = 0;
-                       break;
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &wait);
-       if (count > 0 && signal_pending(current) && signals_allowed)
-               return -ERESTARTSYS;
-       stop_dac(state);
-       return 0;
-}
-
-
-static int drain_spdifout(struct ali_state *state, int signals_allowed)
-{
-
-       DECLARE_WAITQUEUE(wait, current);
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned long tmo;
-       int count;
-       if (!dmabuf->ready)
-               return 0;
-       if (dmabuf->mapped) {
-               stop_spdifout(state);
-               return 0;
-       }
-       add_wait_queue(&dmabuf->wait, &wait);
-       for (;;) {
-
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               count = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               if (count <= 0)
-                       break;
-               /* 
-                * This will make sure that our LVI is correct, that our
-                * pointer is updated, and that the DAC is running.  We
-                * have to force the setting of dmabuf->trigger to avoid
-                * any possible deadlocks.
-                */
-               if (!dmabuf->enable) {
-                       if (codec_independent_spdif_locked > 0) {
-                               dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                               ali_update_lvi(state, 2);
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 3);
-                               }
-                       }
-               }
-               if (signal_pending(current) && signals_allowed) {
-                       break;
-               }
-
-               /* It seems that we have to set the current state to
-                * TASK_INTERRUPTIBLE every time to make the process
-                * really go to sleep.  This also has to be *after* the
-                * update_ptr() call because update_ptr is likely to
-                * do a wake_up() which will unset this before we ever
-                * try to sleep, resuling in a tight loop in this code
-                * instead of actually sleeping and waiting for an
-                * interrupt to wake us up!
-                */
-               set_current_state(TASK_INTERRUPTIBLE);
-               /*
-                * set the timeout to significantly longer than it *should*
-                * take for the DAC to drain the DMA buffer
-                */
-               tmo = (count * HZ) / (dmabuf->rate);
-               if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                       printk(KERN_ERR "ali_audio: drain_spdifout, dma timeout?\n");
-                       count = 0;
-                       break;
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &wait);
-       if (count > 0 && signal_pending(current) && signals_allowed)
-               return -ERESTARTSYS;
-       stop_spdifout(state);
-       return 0;
-}
-
-static void ali_channel_interrupt(struct ali_card *card)
-{
-       int i, count;
-       
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               struct ali_channel *c = NULL;
-               struct dmabuf *dmabuf;
-               unsigned long port = card->iobase;
-               u16 status;
-               if (!state)
-                       continue;
-               if (!state->dmabuf.ready)
-                       continue;
-               dmabuf = &state->dmabuf;
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                               c = dmabuf->codec_spdifout_channel;
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       c = dmabuf->controller_spdifout_channel;
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING) {
-                                       c = dmabuf->write_channel;
-                               } else if (dmabuf->enable & ADC_RUNNING) {
-                                       c = dmabuf->read_channel;
-                               } else
-                                       continue;
-                       }
-               }
-               port += c->port;
-
-               status = inw(port + OFF_SR);
-
-               if (status & DMA_INT_COMPLETE) {
-                       /* only wake_up() waiters if this interrupt signals
-                        * us being beyond a userfragsize of data open or
-                        * available, and ali_update_ptr() does that for
-                        * us
-                        */
-                       ali_update_ptr(state);
-               }
-
-               if (status & DMA_INT_LVI) {
-                       ali_update_ptr(state);
-                       wake_up(&dmabuf->wait);
-
-                       if (dmabuf->enable & DAC_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & ADC_RUNNING)
-                               count = dmabuf->dmasize - dmabuf->count;
-                       else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else count = 0;
-
-                       if (count > 0) {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       outl((1 << 1), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                               outl((1 << 3), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       outl((1 << 7), state->card->iobase + ALI_DMACR);
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       __stop_dac(state);
-                               if (dmabuf->enable & ADC_RUNNING)
-                                       __stop_adc(state);
-                               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               dmabuf->enable = 0;
-                               wake_up(&dmabuf->wait);
-                       }
-
-               }
-               if (!(status & DMA_INT_DCH)) {
-                       ali_update_ptr(state);
-                       wake_up(&dmabuf->wait);
-                       if (dmabuf->enable & DAC_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & ADC_RUNNING)
-                               count = dmabuf->dmasize - dmabuf->count;
-                       else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                               count = dmabuf->count;
-                       else
-                               count = 0;
-
-                       if (count > 0) {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       outl((1 << 1), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       outl((1 << 3), state->card->iobase + ALI_DMACR);
-                               else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       outl((1 << 7), state->card->iobase + ALI_DMACR);
-                       } else {
-                               if (dmabuf->enable & DAC_RUNNING)
-                                       __stop_dac(state);
-                               if (dmabuf->enable & ADC_RUNNING)
-                                       __stop_adc(state);
-                               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)
-                                       __stop_spdifout(state);
-                               dmabuf->enable = 0;
-                               wake_up(&dmabuf->wait);
-                       }
-               }
-               outw(status & DMA_INT_MASK, port + OFF_SR);
-       }
-}
-
-static irqreturn_t ali_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct ali_card *card = (struct ali_card *) dev_id;
-       u32 status;
-       u16 status2;
-
-       spin_lock(&card->lock);
-       status = inl(card->iobase + ALI_INTERRUPTSR);
-       if (!(status & INT_MASK)) {
-               spin_unlock(&card->lock);
-               return IRQ_NONE;                /* not for us */
-       }
-
-       if (codec_independent_spdif_locked > 0) {
-               if (globel == 0) {
-                       globel += 1;
-                       status2 = inw(card->iobase + 0x76);
-                       outw(status2 | 0x000c, card->iobase + 0x76);
-               } else {
-                       if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-                               ali_channel_interrupt(card);
-               }
-       } else {
-               if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT))
-                       ali_channel_interrupt(card);
-       }
-
-       /* clear 'em */
-       outl(status & INT_MASK, card->iobase + ALI_INTERRUPTSR);
-       spin_unlock(&card->lock);
-       return IRQ_HANDLED;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is
-   waiting to be copied to the user's buffer.  It is filled by the dma
-   machine and drained by this loop. */
-
-static ssize_t ali_read(struct file *file, char __user *buffer,
-                       size_t count, loff_t * ppos)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state ? state->card : NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;
-       DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-       printk("ali_audio: ali_read called, count = %d\n", count);
-#endif
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (dmabuf->enable & DAC_RUNNING)
-               return -ENODEV;
-       if (!dmabuf->read_channel) {
-               dmabuf->ready = 0;
-               dmabuf->read_channel = card->alloc_rec_pcm_channel(card);
-               if (!dmabuf->read_channel) {
-                       return -EBUSY;
-               }
-       }
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&dmabuf->wait, &waita);
-       while (count > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               swptr = dmabuf->swptr;
-               cnt = ali_get_available_read_data(state);
-               // this is to make the copy_to_user simpler below
-               if (cnt > (dmabuf->dmasize - swptr))
-                       cnt = dmabuf->dmasize - swptr;
-               spin_unlock_irqrestore(&card->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               /* Lop off the last two bits to force the code to always
-                * write in full samples.  This keeps software that sets
-                * O_NONBLOCK but doesn't check the return value of the
-                * write call from getting things out of state where they
-                * think a full 4 byte sample was written when really only
-                * a portion was, resulting in odd sound and stereo
-                * hysteresis.
-                */
-               cnt &= ~0x3;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       /*
-                        * Don't let us deadlock.  The ADC won't start if
-                        * dmabuf->trigger isn't set.  A call to SETTRIGGER
-                        * could have turned it off after we set it to on
-                        * previously.
-                        */
-                       dmabuf->trigger = PCM_ENABLE_INPUT;
-                       /*
-                        * This does three things.  Updates LVI to be correct,
-                        * makes sure the ADC is running, and updates the
-                        * hwptr.
-                        */
-                       ali_update_lvi(state, 1);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto done;
-                       }
-                       /* Set the timeout to how long it would take to fill
-                        * two of our buffers.  If we haven't been woke up
-                        * by then, then we know something is wrong.
-                        */
-                       tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-                           
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer overrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       if (!schedule_timeout(tmo >= 2 ? tmo : 2)) {
-                               printk(KERN_ERR
-                                      "ali_audio: recording schedule timeout, "
-                                      "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      dmabuf->dmasize, dmabuf->fragsize,
-                                      dmabuf->count, dmabuf->hwptr,
-                                      dmabuf->swptr);
-                               /* a buffer overrun, we delay the recovery until next time the
-                                  while loop begin and we REALLY have space to record */
-                       }
-                       if (signal_pending(current)) {
-                               ret = ret ? ret : -ERESTARTSYS;
-                               goto done;
-                       }
-                       continue;
-               }
-
-               if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto done;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-               spin_lock_irqsave(&card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       continue;
-               }
-               dmabuf->swptr = swptr;
-               dmabuf->count -= cnt;
-               spin_unlock_irqrestore(&card->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-done:
-       ali_update_lvi(state, 1);
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-       return ret;
-}
-
-/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
-   the soundcard.  it is drained by the dma machine and filled by this loop. */
-static ssize_t ali_write(struct file *file,
-                        const char __user *buffer, size_t count, loff_t * ppos)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state ? state->card : NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr = 0;
-       int cnt, x;
-       DECLARE_WAITQUEUE(waita, current);
-#ifdef DEBUG2
-       printk("ali_audio: ali_write called, count = %d\n", count);
-#endif
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (dmabuf->enable & ADC_RUNNING)
-               return -ENODEV;
-       if (codec_independent_spdif_locked > 0) {
-               if (!dmabuf->codec_spdifout_channel) {
-                       dmabuf->ready = 0;
-                       dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card);
-                       if (!dmabuf->codec_spdifout_channel)
-                               return -EBUSY;
-               }
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       if (!dmabuf->controller_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card);
-                               if (!dmabuf->controller_spdifout_channel)
-                                       return -EBUSY;
-                       }
-               } else {
-                       if (!dmabuf->write_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->write_channel =
-                                   card->alloc_pcm_channel(card);
-                               if (!dmabuf->write_channel)
-                                       return -EBUSY;
-                       }
-               }
-       }
-
-       if (codec_independent_spdif_locked > 0) {
-               if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-                       return ret;
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-                               return ret;
-               } else {
-
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-                               return ret;
-               }
-       }
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&dmabuf->wait, &waita);
-       while (count > 0) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-
-               swptr = dmabuf->swptr;
-               cnt = ali_get_free_write_space(state);
-               /* Bound the maximum size to how much we can copy to the
-                * dma buffer before we hit the end.  If we have more to
-                * copy then it will get done in a second pass of this
-                * loop starting from the beginning of the buffer.
-                */
-               if (cnt > (dmabuf->dmasize - swptr))
-                       cnt = dmabuf->dmasize - swptr;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG2
-               printk(KERN_INFO
-                      "ali_audio: ali_write: %d bytes available space\n",
-                      cnt);
-#endif
-               if (cnt > count)
-                       cnt = count;
-               /* Lop off the last two bits to force the code to always
-                * write in full samples.  This keeps software that sets
-                * O_NONBLOCK but doesn't check the return value of the
-                * write call from getting things out of state where they
-                * think a full 4 byte sample was written when really only
-                * a portion was, resulting in odd sound and stereo
-                * hysteresis.
-                */
-               cnt &= ~0x3;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       // There is data waiting to be played
-                       /*
-                        * Force the trigger setting since we would
-                        * deadlock with it set any other way
-                        */
-                       if (codec_independent_spdif_locked > 0) {
-                               dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                               ali_update_lvi(state, 2);
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       dmabuf->trigger = SPDIF_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 3);
-                               } else {
-
-                                       dmabuf->trigger = PCM_ENABLE_OUTPUT;
-                                       ali_update_lvi(state, 0);
-                               }
-                       }
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto ret;
-                       }
-                       /* Not strictly correct but works */
-                       tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4);
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer underrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                          
-                       /* FIXME - do timeout handling here !! */
-                       schedule_timeout(tmo >= 2 ? tmo : 2);
-
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto ret;
-                       }
-                       continue;
-               }
-               if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto ret;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (PM_SUSPENDED(card)) {
-                       spin_unlock_irqrestore(&card->lock, flags);
-                       continue;
-               }
-
-               dmabuf->swptr = swptr;
-               dmabuf->count += cnt;
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-       }
-       if (swptr % dmabuf->fragsize) {
-               x = dmabuf->fragsize - (swptr % dmabuf->fragsize);
-               memset(dmabuf->rawbuf + swptr, '\0', x);
-       }
-ret:
-       if (codec_independent_spdif_locked > 0) {
-               ali_update_lvi(state, 2);
-       } else {
-               if (controller_independent_spdif_locked > 0) {
-                       ali_update_lvi(state, 3);
-               } else {
-                       ali_update_lvi(state, 0);
-               }
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ali_poll(struct file *file, struct poll_table_struct
-                            *wait)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       unsigned int mask = 0;
-       if (!dmabuf->ready)
-               return 0;
-       poll_wait(file, &dmabuf->wait, wait);
-       spin_lock_irqsave(&state->card->lock, flags);
-       ali_update_ptr(state);
-       if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) {
-               if (dmabuf->count >= (signed) dmabuf->fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE  && (dmabuf->enable & (DAC_RUNNING|CODEC_SPDIFOUT_RUNNING|CONTROLLER_SPDIFOUT_RUNNING))) {
-               if ((signed) dmabuf->dmasize >= dmabuf->count + (signed) dmabuf->fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&state->card->lock, flags);
-       return mask;
-}
-
-static int ali_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       int ret = -EINVAL;
-       unsigned long size;
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-       }
-       if (vma->vm_flags & VM_READ) {
-               if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL) {
-                       ret = -EBUSY;
-                       goto out;
-               }
-       }
-       if ((ret = prog_dmabuf(state, 0)) != 0)
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << dmabuf->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       dmabuf->mapped = 1;
-       dmabuf->trigger = 0;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_channel *c = NULL;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       unsigned int i_scr;
-       int val = 0, ret;
-       struct ac97_codec *codec = state->card->ac97_codec[0];
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-#ifdef DEBUG
-       printk("ali_audio: ali_ioctl, arg=0x%x, cmd=",
-              arg ? *p : 0);
-#endif
-       switch (cmd) {
-       case OSS_GETVERSION:
-#ifdef DEBUG
-               printk("OSS_GETVERSION\n");
-#endif
-               return put_user(SOUND_VERSION, p);
-       case SNDCTL_DSP_RESET:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_RESET\n");
-#endif
-               spin_lock_irqsave(&state->card->lock, flags);
-               if (dmabuf->enable == DAC_RUNNING) {
-                       c = dmabuf->write_channel;
-                       __stop_dac(state);
-               }
-               if (dmabuf->enable == ADC_RUNNING) {
-                       c = dmabuf->read_channel;
-                       __stop_adc(state);
-               }
-               if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-                       c = dmabuf->codec_spdifout_channel;
-                       __stop_spdifout(state);
-               }
-               if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-                       c = dmabuf->controller_spdifout_channel;
-                       __stop_spdifout(state);
-               }
-               if (c != NULL) {
-                       outb(2, state->card->iobase + c->port + OFF_CR);        /* reset DMA machine */
-                       outl(virt_to_bus(&c->sg[0]),
-                            state->card->iobase + c->port + OFF_BDBAR);
-                       outb(0, state->card->iobase + c->port + OFF_CIV);
-                       outb(0, state->card->iobase + c->port + OFF_LVI);
-               }
-
-               spin_unlock_irqrestore(&state->card->lock, flags);
-               synchronize_irq(state->card->pci_dev->irq);
-               dmabuf->ready = 0;
-               dmabuf->swptr = dmabuf->hwptr = 0;
-               dmabuf->count = dmabuf->total_bytes = 0;
-               return 0;
-       case SNDCTL_DSP_SYNC:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SYNC\n");
-#endif
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->enable != CODEC_SPDIFOUT_RUNNING
-                           || file->f_flags & O_NONBLOCK)
-                               return 0;
-                       if ((val = drain_spdifout(state, 1)))
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->enable !=
-                                   CONTROLLER_SPDIFOUT_RUNNING
-                                   || file->f_flags & O_NONBLOCK)
-                                       return 0;
-                               if ((val = drain_spdifout(state, 1)))
-                                       return val;
-                       } else {
-                               if (dmabuf->enable != DAC_RUNNING
-                                   || file->f_flags & O_NONBLOCK)
-                                       return 0;
-                               if ((val = drain_dac(state, 1)))
-                                       return val;
-                       }
-               }
-               dmabuf->total_bytes = 0;
-               return 0;
-       case SNDCTL_DSP_SPEED:  /* set smaple rate */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SPEED\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               if ((state->card->ac97_status & SPDIF_ON)) {    /* S/PDIF Enabled */
-                                       /* RELTEK ALC650 only support 48000, need to check that */
-                                       if (ali_valid_spdif_rate(codec, val)) {
-                                               if (codec_independent_spdif_locked > 0) {
-                                                       ali_set_spdif_output(state, -1, 0);
-                                                       stop_spdifout(state);
-                                                       dmabuf->ready = 0;
-                                                       /* I add test codec independent spdif out */
-                                                       spin_lock_irqsave(&state->card->lock, flags);
-                                                       ali_set_codecspdifout_rate(state, val); // I modified
-                                                       spin_unlock_irqrestore(&state->card->lock, flags);
-                                                       /* Set S/PDIF transmitter rate. */
-                                                       i_scr = inl(state->card->iobase + ALI_SCR);
-                                                       if ((i_scr & 0x00300000) == 0x00100000) {
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                                       } else {
-                                                               if ((i_scr&0x00300000)  == 0x00200000)
-                                                               {
-                                                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                                                               } else {
-                                                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                                                       } else {
-                                                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                                                       }
-                                                               }
-                                                       }
-
-                                                       if (!(state->card->ac97_status & SPDIF_ON)) {
-                                                               val = dmabuf->rate;
-                                                       }
-                                               } else {
-                                                       if (controller_independent_spdif_locked > 0) 
-                                                       {
-                                                               stop_spdifout(state);
-                                                               dmabuf->ready = 0;
-                                                               spin_lock_irqsave(&state->card->lock, flags);
-                                                               ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-                                                               spin_unlock_irqrestore(&state->card->lock, flags);
-                                                       } else {
-                                                               /* Set DAC rate */
-                                                               ali_set_spdif_output(state, -1, 0);
-                                                               stop_dac(state);
-                                                               dmabuf->ready = 0;
-                                                               spin_lock_irqsave(&state->card->lock, flags);
-                                                               ali_set_dac_rate(state, val);
-                                                               spin_unlock_irqrestore(&state->card->lock, flags);
-                                                               /* Set S/PDIF transmitter rate. */
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_3_4, val);
-                                                               if (!(state->card->ac97_status & SPDIF_ON))
-                                                               {
-                                                                       val = dmabuf->rate;
-                                                               }
-                                                       }
-                                               }
-                                       } else {        /* Not a valid rate for S/PDIF, ignore it */
-                                               val = dmabuf->rate;
-                                       }
-                               } else {
-                                       stop_dac(state);
-                                       dmabuf->ready = 0;
-                                       spin_lock_irqsave(&state->card->lock, flags);
-                                       ali_set_dac_rate(state, val);
-                                       spin_unlock_irqrestore(&state->card->lock, flags);
-                               }
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(state);
-                               dmabuf->ready = 0;
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_set_adc_rate(state, val);
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       }
-               }
-               return put_user(dmabuf->rate, p);
-       case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_STEREO\n");
-#endif
-               if (dmabuf->enable & DAC_RUNNING) {
-                       stop_dac(state);
-               }
-               if (dmabuf->enable & ADC_RUNNING) {
-                       stop_adc(state);
-               }
-               if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               return put_user(1, p);
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if (codec_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 2)))
-                                       return val;
-                       } else {
-                               if (controller_independent_spdif_locked > 0) {
-                                       if (!dmabuf->ready && (val = prog_dmabuf(state, 3)))
-                                               return val;
-                               } else {
-                                       if (!dmabuf->ready && (val = prog_dmabuf(state, 0)))
-                                               return val;
-                               }
-                       }
-               }
-
-               if (file->f_mode & FMODE_READ) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 1)))
-                               return val;
-               }
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize);
-#endif
-               return put_user(dmabuf->userfragsize, p);
-       case SNDCTL_DSP_GETFMTS:        /* Returns a mask of supported sample format */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETFMTS\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_SETFMT: /* Select sample format */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETFMT\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_CHANNELS:       // add support 4,6 channel 
-#ifdef DEBUG
-               printk("SNDCTL_DSP_CHANNELS\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val > 0) {
-                       if (dmabuf->enable & DAC_RUNNING) {
-                               stop_dac(state);
-                       }
-                       if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) {
-                               stop_spdifout(state);
-                       }
-                       if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) {
-                               stop_spdifout(state);
-                       }
-                       if (dmabuf->enable & ADC_RUNNING) {
-                               stop_adc(state);
-                       }
-               } else {
-                       return put_user(state->card->channels, p);
-               }
-
-               i_scr = inl(state->card->iobase + ALI_SCR);
-               /* Current # of channels enabled */
-               if (i_scr & 0x00000100)
-                       ret = 4;
-               else if (i_scr & 0x00000200)
-                       ret = 6;
-               else
-                       ret = 2;
-               switch (val) {
-               case 2: /* 2 channels is always supported */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00100000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl((i_scr & 0xfffffcff), (state->card->iobase + ALI_SCR));
-                       /* Do we need to change mixer settings????  */
-                       break;
-               case 4: /* Supported on some chipsets, better check first */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00000100 | 0x00200000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl(((i_scr & 0xfffffcff) | 0x00000100), (state->card->iobase + ALI_SCR));
-                       break;
-               case 6: /* Supported on some chipsets, better check first */
-                       if (codec_independent_spdif_locked > 0) {
-                               outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000 | 0x00300000), (state->card->iobase + ALI_SCR));
-                       } else
-                               outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000), (state->card->iobase + ALI_SCR));
-                       break;
-               default:        /* nothing else is ever supported by the chipset */
-                       val = ret;
-                       break;
-               }
-               return put_user(val, p);
-       case SNDCTL_DSP_POST:   /* the user has sent all data and is notifying us */
-               /* we update the swptr to the end of the last sg segment then return */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_POST\n");
-#endif
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready || (dmabuf->enable != CODEC_SPDIFOUT_RUNNING))
-                               return 0;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready || (dmabuf->enable != CONTROLLER_SPDIFOUT_RUNNING))
-                                       return 0;
-                       } else {
-                               if (!dmabuf->ready || (dmabuf->enable != DAC_RUNNING))
-                                       return 0;
-                       }
-               }
-               if ((dmabuf->swptr % dmabuf->fragsize) != 0) {
-                       val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize);
-                       dmabuf->swptr += val;
-                       dmabuf->count += val;
-               }
-               return 0;
-       case SNDCTL_DSP_SUBDIVIDE:
-               if (dmabuf->subdivision)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SUBDIVIDE %d\n", val);
-#endif
-               dmabuf->subdivision = val;
-               dmabuf->ready = 0;
-               return 0;
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               dmabuf->ossfragsize = 1 << (val & 0xffff);
-               dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-               if (!dmabuf->ossfragsize || !dmabuf->ossmaxfrags)
-                       return -EINVAL;
-               /*
-                * Bound the frag size into our allowed range of 256 - 4096
-                */
-               if (dmabuf->ossfragsize < 256)
-                       dmabuf->ossfragsize = 256;
-               else if (dmabuf->ossfragsize > 4096)
-                       dmabuf->ossfragsize = 4096;
-               /*
-                * The numfrags could be something reasonable, or it could
-                * be 0xffff meaning "Give me as much as possible".  So,
-                * we check the numfrags * fragsize doesn't exceed our
-                * 64k buffer limit, nor is it less than our 8k minimum.
-                * If it fails either one of these checks, then adjust the
-                * number of fragments, not the size of them.  It's OK if
-                * our number of fragments doesn't equal 32 or anything
-                * like our hardware based number now since we are using
-                * a different frag count for the hardware.  Before we get
-                * into this though, bound the maxfrags to avoid overflow
-                * issues.  A reasonable bound would be 64k / 256 since our
-                * maximum buffer size is 64k and our minimum frag size is
-                * 256.  On the other end, our minimum buffer size is 8k and
-                * our maximum frag size is 4k, so the lower bound should
-                * be 2.
-                */
-               if (dmabuf->ossmaxfrags > 256)
-                       dmabuf->ossmaxfrags = 256;
-               else if (dmabuf->ossmaxfrags < 2)
-                       dmabuf->ossmaxfrags = 2;
-               val = dmabuf->ossfragsize * dmabuf->ossmaxfrags;
-               while (val < 8192) {
-                       val <<= 1;
-                       dmabuf->ossmaxfrags <<= 1;
-               }
-               while (val > 65536) {
-                       val >>= 1;
-                       dmabuf->ossmaxfrags >>= 1;
-               }
-               dmabuf->ready = 0;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val,
-                      dmabuf->ossfragsize, dmabuf->ossmaxfrags);
-#endif
-               return 0;
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-                                       return val;
-                       } else {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                                       return val;
-                       }
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               abinfo.fragsize = dmabuf->userfragsize;
-               abinfo.fragstotal = dmabuf->userfrags;
-               if (dmabuf->mapped)
-                       abinfo.bytes = dmabuf->dmasize;
-               else
-                       abinfo.bytes = ali_get_free_write_space(state);
-               abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n",
-                      abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-                      abinfo.fragstotal);
-#endif
-               return copy_to_user(argp, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (codec_independent_spdif_locked > 0) {
-                       if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0)
-                               return val;
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0)
-                                       return val;
-                       } else {
-                               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                                       return val;
-                       }
-               }
-               spin_lock_irqsave(&state->card->lock, flags);
-               val = ali_get_free_write_space(state);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.ptr = dmabuf->hwptr;
-               cinfo.blocks = val / dmabuf->userfragsize;
-               if (codec_independent_spdif_locked > 0) {
-                       if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                               dmabuf->count += val;
-                               dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 2);
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) {
-                                       dmabuf->count += val;
-                                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                                       __ali_update_lvi(state, 3);
-                               }
-                       } else {
-                               if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) {
-                                       dmabuf->count += val;
-                                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                                       __ali_update_lvi(state, 0);
-                               }
-                       }
-               }
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
-                      cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0;
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->card->lock, flags);
-               abinfo.bytes = ali_get_available_read_data(state);
-               abinfo.fragsize = dmabuf->userfragsize;
-               abinfo.fragstotal = dmabuf->userfrags;
-               abinfo.fragments = abinfo.bytes / dmabuf->userfragsize;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n",
-                      abinfo.bytes, abinfo.fragsize, abinfo.fragments,
-                      abinfo.fragstotal);
-#endif
-               return copy_to_user(argp, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->card->lock, flags);
-               val = ali_get_available_read_data(state);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = val / dmabuf->userfragsize;
-               cinfo.ptr = dmabuf->hwptr;
-               if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_INPUT)) {
-                       dmabuf->count -= val;
-                       dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize;
-                       __ali_update_lvi(state, 1);
-               }
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
-                      cinfo.blocks, cinfo.ptr, dmabuf->count);
-#endif
-               return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0;
-       case SNDCTL_DSP_NONBLOCK:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_NONBLOCK\n");
-#endif
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-       case SNDCTL_DSP_GETCAPS:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETCAPS\n");
-#endif
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER |
-                               DSP_CAP_MMAP | DSP_CAP_BIND, p);
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger);
-#endif
-               return put_user(dmabuf->trigger, p);
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-#if defined(DEBUG) || defined(DEBUG_MMAP)
-               printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val);
-#endif
-               if (!(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) {
-                       stop_adc(state);
-               }
-               if (!(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) {
-                       stop_dac(state);
-               }
-               if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CODEC_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) {
-                       stop_spdifout(state);
-               }
-               dmabuf->trigger = val;
-               if (val & PCM_ENABLE_OUTPUT && !(dmabuf->enable & DAC_RUNNING)) {
-                       if (!dmabuf->write_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->write_channel = state->card->alloc_pcm_channel(state->card);
-                               if (!dmabuf->write_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 0);
-                               spin_unlock_irqrestore(&state->card->lock,
-                                                      flags);
-                       } else
-                               start_dac(state);
-               }
-               if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CODEC_SPDIFOUT_RUNNING)) {
-                       if (!dmabuf->codec_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->codec_spdifout_channel = state->card->alloc_codec_spdifout_channel(state->card);
-                               if (!dmabuf->codec_spdifout_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 2)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 2);
-                               spin_unlock_irqrestore(&state->card->lock,
-                                                      flags);
-                       } else
-                               start_spdifout(state);
-               }
-               if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)) {
-                       if (!dmabuf->controller_spdifout_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->controller_spdifout_channel = state->card->alloc_controller_spdifout_channel(state->card);
-                               if (!dmabuf->controller_spdifout_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 3)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock, flags);
-                               ali_update_ptr(state);
-                               dmabuf->count = 0;
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = ali_get_free_write_space(state);
-                               dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize;
-                               __ali_update_lvi(state, 3);
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       } else
-                               start_spdifout(state);
-               }
-               if (val & PCM_ENABLE_INPUT && !(dmabuf->enable & ADC_RUNNING)) {
-                       if (!dmabuf->read_channel) {
-                               dmabuf->ready = 0;
-                               dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card);
-                               if (!dmabuf->read_channel)
-                                       return -EBUSY;
-                       }
-                       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-                               return ret;
-                       if (dmabuf->mapped) {
-                               spin_lock_irqsave(&state->card->lock,
-                                                 flags);
-                               ali_update_ptr(state);
-                               dmabuf->swptr = dmabuf->hwptr;
-                               dmabuf->count = 0;
-                               spin_unlock_irqrestore(&state->card->lock, flags);
-                       }
-                       ali_update_lvi(state, 1);
-                       start_adc(state);
-               }
-               return 0;
-       case SNDCTL_DSP_SETDUPLEX:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETDUPLEX\n");
-#endif
-               return -EINVAL;
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&state->card->lock, flags);
-               ali_update_ptr(state);
-               val = dmabuf->count;
-               spin_unlock_irqrestore(&state->card->lock, flags);
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count);
-#endif
-               return put_user(val, p);
-       case SOUND_PCM_READ_RATE:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate);
-#endif
-               return put_user(dmabuf->rate, p);
-       case SOUND_PCM_READ_CHANNELS:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_CHANNELS\n");
-#endif
-               return put_user(2, p);
-       case SOUND_PCM_READ_BITS:
-#ifdef DEBUG
-               printk("SOUND_PCM_READ_BITS\n");
-#endif
-               return put_user(AFMT_S16_LE, p);
-       case SNDCTL_DSP_SETSPDIF:       /* Set S/PDIF Control register */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_SETSPDIF\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Check to make sure the codec supports S/PDIF transmitter */
-               if ((state->card->ac97_features & 4)) {
-                       /* mask out the transmitter speed bits so the user can't set them */
-                       val &= ~0x3000;
-                       /* Add the current transmitter speed bits to the passed value */
-                       ret = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-                       val |= (ret & 0x3000);
-                       ali_ac97_set(codec, AC97_SPDIF_CONTROL, val);
-                       if (ali_ac97_get(codec, AC97_SPDIF_CONTROL) != val) {
-                               printk(KERN_ERR "ali_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val);
-                               return -EFAULT;
-                       }
-               }
-#ifdef DEBUG
-               else
-                       printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-               return put_user(val, p);
-       case SNDCTL_DSP_GETSPDIF:       /* Get S/PDIF Control register */
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETSPDIF\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Check to make sure the codec supports S/PDIF transmitter */
-               if (!(state->card->ac97_features & 4)) {
-#ifdef DEBUG
-                       printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n");
-#endif
-                       val = 0;
-               } else {
-                       val = ali_ac97_get(codec, AC97_SPDIF_CONTROL);
-               }
-
-               return put_user(val, p);
-//end add support spdif out
-//add support 4,6 channel
-       case SNDCTL_DSP_GETCHANNELMASK:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_GETCHANNELMASK\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               /* Based on AC'97 DAC support, not ICH hardware */
-               val = DSP_BIND_FRONT;
-               if (state->card->ac97_features & 0x0004)
-                       val |= DSP_BIND_SPDIF;
-               if (state->card->ac97_features & 0x0080)
-                       val |= DSP_BIND_SURR;
-               if (state->card->ac97_features & 0x0140)
-                       val |= DSP_BIND_CENTER_LFE;
-               return put_user(val, p);
-       case SNDCTL_DSP_BIND_CHANNEL:
-#ifdef DEBUG
-               printk("SNDCTL_DSP_BIND_CHANNEL\n");
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val == DSP_BIND_QUERY) {
-                       val = DSP_BIND_FRONT;   /* Always report this as being enabled */
-                       if (state->card->ac97_status & SPDIF_ON)
-                               val |= DSP_BIND_SPDIF;
-                       else {
-                               if (state->card->ac97_status & SURR_ON)
-                                       val |= DSP_BIND_SURR;
-                               if (state->card->
-                                   ac97_status & CENTER_LFE_ON)
-                                       val |= DSP_BIND_CENTER_LFE;
-                       }
-               } else {        /* Not a query, set it */
-                       if (!(file->f_mode & FMODE_WRITE))
-                               return -EINVAL;
-                       if (dmabuf->enable == DAC_RUNNING) {
-                               stop_dac(state);
-                       }
-                       if (val & DSP_BIND_SPDIF) {     /* Turn on SPDIF */
-                               /*  Ok, this should probably define what slots
-                                *  to use. For now, we'll only set it to the
-                                *  defaults:
-                                * 
-                                *   non multichannel codec maps to slots 3&4
-                                *   2 channel codec maps to slots 7&8
-                                *   4 channel codec maps to slots 6&9
-                                *   6 channel codec maps to slots 10&11
-                                *
-                                *  there should be some way for the app to
-                                *  select the slot assignment.
-                                */
-                               i_scr = inl(state->card->iobase + ALI_SCR);
-                               if (codec_independent_spdif_locked > 0) {
-
-                                       if ((i_scr & 0x00300000) == 0x00100000) {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                       } else {
-                                               if ((i_scr & 0x00300000) == 0x00200000) {
-                                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                                               } else {
-                                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                                       }
-                                               }
-                                       }
-                               } else {        /* codec spdif out (pcm out share ) */
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_3_4, dmabuf->rate);    //I do not modify
-                               }
-
-                               if (!(state->card->ac97_status & SPDIF_ON))
-                                       val &= ~DSP_BIND_SPDIF;
-                       } else {
-                               int mask;
-                               int channels;
-                               /* Turn off S/PDIF if it was on */
-                               if (state->card->ac97_status & SPDIF_ON)
-                                       ali_set_spdif_output(state, -1, 0);
-                               mask =
-                                   val & (DSP_BIND_FRONT | DSP_BIND_SURR |
-                                          DSP_BIND_CENTER_LFE);
-                               switch (mask) {
-                               case DSP_BIND_FRONT:
-                                       channels = 2;
-                                       break;
-                               case DSP_BIND_FRONT | DSP_BIND_SURR:
-                                       channels = 4;
-                                       break;
-                               case DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE:
-                                       channels = 6;
-                                       break;
-                               default:
-                                       val = DSP_BIND_FRONT;
-                                       channels = 2;
-                                       break;
-                               }
-                               ali_set_dac_channels(state, channels);
-                               /* check that they really got turned on */
-                               if (!state->card->ac97_status & SURR_ON)
-                                       val &= ~DSP_BIND_SURR;
-                               if (!state->card->
-                                   ac97_status & CENTER_LFE_ON)
-                                       val &= ~DSP_BIND_CENTER_LFE;
-                       }
-               }
-               return put_user(val, p);
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_WRITE_FILTER:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-       return -EINVAL;
-}
-
-static int ali_open(struct inode *inode, struct file *file)
-{
-       int i = 0;
-       struct ali_card *card = devs;
-       struct ali_state *state = NULL;
-       struct dmabuf *dmabuf = NULL;
-       unsigned int i_scr;
-       
-       /* find an available virtual channel (instance of /dev/dsp) */
-       
-       while (card != NULL) {
-
-               /*
-                * If we are initializing and then fail, card could go
-                * away unuexpectedly while we are in the for() loop.
-                * So, check for card on each iteration before we check
-                * for card->initializing to avoid a possible oops.
-                * This usually only matters for times when the driver is
-                * autoloaded by kmod.
-                */
-               for (i = 0; i < 50 && card && card->initializing; i++) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ / 20);
-               }
-
-               for (i = 0; i < NR_HW_CH && card && !card->initializing; i++) {
-                       if (card->states[i] == NULL) {
-                               state = card->states[i] = (struct ali_state *) kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-                               if (state == NULL)
-                                       return -ENOMEM;
-                               memset(state, 0, sizeof(struct ali_state));
-                               dmabuf = &state->dmabuf;
-                               goto found_virt;
-                       }
-               }
-               card = card->next;
-       }
-
-       /* no more virtual channel avaiable */
-       if (!state)
-               return -ENODEV;
-found_virt:
-       /* initialize the virtual channel */
-
-       state->virt = i;
-       state->card = card;
-       state->magic = ALI5455_STATE_MAGIC;
-       init_waitqueue_head(&dmabuf->wait);
-       mutex_init(&state->open_mutex);
-       file->private_data = state;
-       dmabuf->trigger = 0;
-       /* allocate hardware channels */
-       if (file->f_mode & FMODE_READ) {
-               if ((dmabuf->read_channel =
-                    card->alloc_rec_pcm_channel(card)) == NULL) {
-                       kfree(card->states[i]);
-                       card->states[i] = NULL;
-                       return -EBUSY;
-               }
-               dmabuf->trigger |= PCM_ENABLE_INPUT;
-               ali_set_adc_rate(state, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (codec_independent_spdif_locked > 0) {
-                       if ((dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card)) == NULL) {
-                               kfree(card->states[i]);
-                               card->states[i] = NULL;
-                               return -EBUSY;
-                       }
-                       dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-                       ali_set_codecspdifout_rate(state, codec_independent_spdif_locked);      //It must add
-                       i_scr = inl(state->card->iobase + ALI_SCR);
-                       if ((i_scr & 0x00300000) == 0x00100000) {
-                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                       } else {
-                               if ((i_scr & 0x00300000) == 0x00200000) {
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked);
-                               } else {
-                                       if ((i_scr & 0x00300000) == 0x00300000) {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked);
-                                       } else {
-                                               ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked);
-                                       }
-                               }
-
-                       }
-               } else {
-                       if (controller_independent_spdif_locked > 0) {
-                               if ((dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card)) == NULL) {
-                                       kfree(card->states[i]);
-                                       card->states[i] = NULL;
-                                       return -EBUSY;
-                               }
-                               dmabuf->trigger |= SPDIF_ENABLE_OUTPUT;
-                               ali_set_spdifout_rate(state, controller_independent_spdif_locked);
-                       } else {
-                               if ((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) {
-                                       kfree(card->states[i]);
-                                       card->states[i] = NULL;
-                                       return -EBUSY;
-                               }
-                               /* Initialize to 8kHz?  What if we don't support 8kHz? */
-                               /*  Let's change this to check for S/PDIF stuff */
-
-                               dmabuf->trigger |= PCM_ENABLE_OUTPUT;
-                               if (codec_pcmout_share_spdif_locked) {
-                                       ali_set_dac_rate(state, codec_pcmout_share_spdif_locked);
-                                       ali_set_spdif_output(state, AC97_EA_SPSA_3_4, codec_pcmout_share_spdif_locked);
-                               } else {
-                                       ali_set_dac_rate(state, 8000);
-                               }
-                       }
-
-               }
-       }
-
-       /* set default sample format. According to OSS Programmer's Guide  /dev/dsp
-          should be default to unsigned 8-bits, mono, with sample rate 8kHz and
-          /dev/dspW will accept 16-bits sample, but we don't support those so we
-          set it immediately to stereo and 16bit, which is all we do support */
-       dmabuf->fmt |= ALI5455_FMT_16BIT | ALI5455_FMT_STEREO;
-       dmabuf->ossfragsize = 0;
-       dmabuf->ossmaxfrags = 0;
-       dmabuf->subdivision = 0;
-       state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-       return nonseekable_open(inode, file);
-}
-
-static int ali_release(struct inode *inode, struct file *file)
-{
-       struct ali_state *state = (struct ali_state *) file->private_data;
-       struct ali_card *card = state->card;
-       struct dmabuf *dmabuf = &state->dmabuf;
-       unsigned long flags;
-       lock_kernel();
-       
-       /* stop DMA state machine and free DMA buffers/channels */
-       if (dmabuf->trigger & PCM_ENABLE_OUTPUT)
-               drain_dac(state, 0);
-
-       if (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)
-               drain_spdifout(state, 0);
-       
-       if (dmabuf->trigger & PCM_ENABLE_INPUT)
-               stop_adc(state);
-       
-       spin_lock_irqsave(&card->lock, flags);
-       dealloc_dmabuf(state);
-       if (file->f_mode & FMODE_WRITE) {
-               if (codec_independent_spdif_locked > 0) {
-                       state->card->free_pcm_channel(state->card, dmabuf->codec_spdifout_channel->num);
-               } else {
-                       if (controller_independent_spdif_locked > 0)
-                               state->card->free_pcm_channel(state->card,
-                                                             dmabuf->controller_spdifout_channel->num);
-                       else state->card->free_pcm_channel(state->card,
-                                                             dmabuf->write_channel->num);
-               }
-       }
-       if (file->f_mode & FMODE_READ)
-               state->card->free_pcm_channel(state->card, dmabuf->read_channel->num);
-
-       state->card->states[state->virt] = NULL;
-       kfree(state);
-       spin_unlock_irqrestore(&card->lock, flags);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const */ struct file_operations ali_audio_fops = {
-       .owner          = THIS_MODULE, 
-       .llseek         = no_llseek, 
-       .read           = ali_read,
-       .write          = ali_write, 
-       .poll           = ali_poll,
-       .ioctl          = ali_ioctl,
-       .mmap           = ali_mmap,
-       .open           = ali_open,
-       .release        = ali_release,
-};
-
-/* Read AC97 codec registers */
-static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg)
-{
-       struct ali_card *card = dev->private_data;
-       int count1 = 100;
-       char val;
-       unsigned short int data = 0, count, addr1, addr2 = 0;
-
-       spin_lock(&card->ac97_lock);
-       while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-               udelay(1);
-
-       addr1 = reg;
-       reg |= 0x0080;
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x08)
-                       break;
-       }
-       if (count == 0x7f)
-       {
-               spin_unlock(&card->ac97_lock);
-               return -1;
-       }
-       outw(reg, (card->iobase + ALI_CPR) + 2);
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x02) {
-                       data = inw(card->iobase + ALI_SPR);
-                       addr2 = inw((card->iobase + ALI_SPR) + 2);
-                       break;
-               }
-       }
-       spin_unlock(&card->ac97_lock);
-       if (count == 0x7f)
-               return -1;
-       if (addr2 != addr1)
-               return -1;
-       return ((u16) data);
-}
-
-/* write ac97 codec register   */
-
-static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
-{
-       struct ali_card *card = dev->private_data;
-       int count1 = 100;
-       char val;
-       unsigned short int count;
-
-       spin_lock(&card->ac97_lock);
-       while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000))
-               udelay(1);
-
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x08)
-                       break;
-       }
-       if (count == 0x7f) {
-               printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-               spin_unlock(&card->ac97_lock);
-               return;
-       }
-       outw(data, (card->iobase + ALI_CPR));
-       outb(reg, (card->iobase + ALI_CPR) + 2);
-       for (count = 0; count < 0x7f; count++) {
-               val = inb(card->iobase + ALI_CSPSR);
-               if (val & 0x01)
-                       break;
-       }
-       spin_unlock(&card->ac97_lock);
-       if (count == 0x7f)
-               printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n");
-       return;
-}
-
-/* OSS /dev/mixer file operation methods */
-
-static int ali_open_mixdev(struct inode *inode, struct file *file)
-{
-       int i;
-       int minor = iminor(inode);
-       struct ali_card *card = devs;
-       for (card = devs; card != NULL; card = card->next) {
-               /*
-                * If we are initializing and then fail, card could go
-                * away unuexpectedly while we are in the for() loop.
-                * So, check for card on each iteration before we check
-                * for card->initializing to avoid a possible oops.
-                * This usually only matters for times when the driver is
-                * autoloaded by kmod.
-                */
-               for (i = 0; i < 50 && card && card->initializing; i++) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HZ / 20);
-               }
-               for (i = 0; i < NR_AC97 && card && !card->initializing; i++)
-                       if (card->ac97_codec[i] != NULL
-                           && card->ac97_codec[i]->dev_mixer == minor) {
-                               file->private_data = card->ac97_codec[i];
-                               return nonseekable_open(inode, file);
-                       }
-       }
-       return -ENODEV;
-}
-
-static int ali_ioctl_mixdev(struct inode *inode,
-                           struct file *file,
-                           unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations ali_mixer_fops = {
-       .owner  = THIS_MODULE, 
-       .llseek = no_llseek, 
-       .ioctl  = ali_ioctl_mixdev,
-       .open   = ali_open_mixdev,
-};
-
-/* AC97 codec initialisation.  These small functions exist so we don't
-   duplicate code between module init and apm resume */
-
-static inline int ali_ac97_exists(struct ali_card *card, int ac97_number)
-{
-       unsigned int i = 1;
-       u32 reg = inl(card->iobase + ALI_RTSR);
-       if (ac97_number) {
-               while (i < 100) {
-
-                       reg = inl(card->iobase + ALI_RTSR);
-                       if (reg & 0x40) {
-                               break;
-                       } else {
-                               outl(reg | 0x00000040,
-                                    card->iobase + 0x34);
-                               udelay(1);
-                       }
-                       i++;
-               }
-
-       } else {
-               while (i < 100) {
-                       reg = inl(card->iobase + ALI_RTSR);
-                       if (reg & 0x80) {
-                               break;
-                       } else {
-                               outl(reg | 0x00000080,
-                                    card->iobase + 0x34);
-                               udelay(1);
-                       }
-                       i++;
-               }
-       }
-
-       if (ac97_number)
-               return reg & 0x40;
-       else
-               return reg & 0x80;
-}
-
-static inline int ali_ac97_enable_variable_rate(struct ac97_codec *codec)
-{
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
-       ali_ac97_set(codec, AC97_EXTENDED_STATUS, ali_ac97_get(codec, AC97_EXTENDED_STATUS) | 0xE800);
-       return (ali_ac97_get(codec, AC97_EXTENDED_STATUS) & 1);
-}
-
-
-static int ali_ac97_probe_and_powerup(struct ali_card *card, struct ac97_codec *codec)
-{
-       /* Returns 0 on failure */
-       int i;
-       u16 addr;
-       if (ac97_probe_codec(codec) == 0)
-               return 0;
-       /* ac97_probe_codec is success ,then begin to init codec */
-       ali_ac97_set(codec, AC97_RESET, 0xffff);
-       if (card->channel[0].used == 1) {
-               ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-               ali_ac97_set(codec, AC97_LINEIN_VOL, 0x0808);
-               ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-       }
-
-       if (card->channel[2].used == 1) //if MICin then init codec
-       {
-               ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000);
-               ali_ac97_set(codec, AC97_MIC_VOL, 0x8808);
-               ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F);
-               ali_ac97_set(codec, AC97_RECORD_GAIN_MIC, 0x0000);
-       }
-
-       ali_ac97_set(codec, AC97_MASTER_VOL_STEREO, 0x0000);
-       ali_ac97_set(codec, AC97_HEADPHONE_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_PCMOUT_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_CD_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_VIDEO_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_AUX_VOL, 0x0808);
-       ali_ac97_set(codec, AC97_PHONE_VOL, 0x8048);
-       ali_ac97_set(codec, AC97_PCBEEP_VOL, 0x0000);
-       ali_ac97_set(codec, AC97_GENERAL_PURPOSE, AC97_GP_MIX);
-       ali_ac97_set(codec, AC97_MASTER_VOL_MONO, 0x0000);
-       ali_ac97_set(codec, 0x38, 0x0000);
-       addr = ali_ac97_get(codec, 0x2a);
-       ali_ac97_set(codec, 0x2a, addr | 0x0001);
-       addr = ali_ac97_get(codec, 0x2a);
-       addr = ali_ac97_get(codec, 0x28);
-       ali_ac97_set(codec, 0x2c, 0xbb80);
-       addr = ali_ac97_get(codec, 0x2c);
-       /* power it all up */
-       ali_ac97_set(codec, AC97_POWER_CONTROL,
-                    ali_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00);
-       /* wait for analog ready */
-       for (i = 10; i && ((ali_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(HZ / 20);
-       }
-       /* FIXME !! */
-       i++;
-       return i;
-}
-
-
-/* I clone ali5455(2.4.7 )  not clone i810_audio(2.4.18)  */
-
-static int ali_reset_5455(struct ali_card *card)
-{
-       outl(0x80000003, card->iobase + ALI_SCR);
-       outl(0x83838383, card->iobase + ALI_FIFOCR1);
-       outl(0x83838383, card->iobase + ALI_FIFOCR2);
-       if (controller_pcmout_share_spdif_locked > 0) {
-               outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-                    card->iobase + ALI_SPDIFICS);
-               outl(0x0408000a, card->iobase + ALI_INTERFACECR);
-       } else {
-               if (codec_independent_spdif_locked > 0) {
-                       outl((inl(card->iobase + ALI_SCR) | 0x00100000), card->iobase + ALI_SCR);       // now I select slot 7 & 8
-                       outl(0x00200000, card->iobase + ALI_INTERFACECR);       //enable codec independent spdifout 
-               } else
-                       outl(0x04080002, card->iobase + ALI_INTERFACECR);
-       }
-
-       outl(0x00000000, card->iobase + ALI_INTERRUPTCR);
-       outl(0x00000000, card->iobase + ALI_INTERRUPTSR);
-       if (controller_independent_spdif_locked > 0)
-               outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001),
-                    card->iobase + ALI_SPDIFICS);
-       return 1;
-}
-
-
-static int ali_ac97_random_init_stuff(struct ali_card
-                                     *card)
-{
-       u32 reg = inl(card->iobase + ALI_SCR);
-       int i = 0;
-       reg = inl(card->iobase + ALI_SCR);
-       if ((reg & 2) == 0)     /* Cold required */
-               reg |= 2;
-       else
-               reg |= 1;       /* Warm */
-       reg &= ~0x80000000;     /* ACLink on */
-       outl(reg, card->iobase + ALI_SCR);
-
-       while (i < 10) {
-               if ((inl(card->iobase + 0x18) & (1 << 1)) == 0)
-                       break;
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout(HZ / 20);
-               i++;
-       }
-       if (i == 10) {
-               printk(KERN_ERR "ali_audio: AC'97 reset failed.\n");
-               return 0;
-       }
-
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 2);
-       return 1;
-}
-
-/* AC97 codec initialisation. */
-
-static int __devinit ali_ac97_init(struct ali_card *card)
-{
-       int num_ac97 = 0;
-       int total_channels = 0;
-       struct ac97_codec *codec;
-       u16 eid;
-
-       if (!ali_ac97_random_init_stuff(card))
-               return 0;
-
-       /* Number of channels supported */
-       /* What about the codec?  Just because the ICH supports */
-       /* multiple channels doesn't mean the codec does.       */
-       /* we'll have to modify this in the codec section below */
-       /* to reflect what the codec has.                       */
-       /* ICH and ICH0 only support 2 channels so don't bother */
-       /* to check....                                         */
-       inl(card->iobase + ALI_CPR);
-       card->channels = 2;
-
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-
-               /* Assume codec isn't available until we go through the
-                * gauntlet below */
-               card->ac97_codec[num_ac97] = NULL;
-               /* The ICH programmer's reference says you should   */
-               /* check the ready status before probing. So we chk */
-               /*   What do we do if it's not ready?  Wait and try */
-               /*   again, or abort?                               */
-               if (!ali_ac97_exists(card, num_ac97)) {
-                       if (num_ac97 == 0)
-                               printk(KERN_ERR "ali_audio: Primary codec not ready.\n");
-                       break;
-               }
-
-               if ((codec = ac97_alloc_codec()) == NULL)
-                       return -ENOMEM;
-               /* initialize some basic codec information, other fields will be filled
-                  in ac97_probe_codec */
-               codec->private_data = card;
-               codec->id = num_ac97;
-               codec->codec_read = ali_ac97_get;
-               codec->codec_write = ali_ac97_set;
-               if (!ali_ac97_probe_and_powerup(card, codec)) {
-                       printk(KERN_ERR "ali_audio: timed out waiting for codec %d analog ready",
-                            num_ac97);
-                       kfree(codec);
-                       break;  /* it didn't work */
-               }
-               
-               /* Store state information about S/PDIF transmitter */
-               card->ac97_status = 0;
-               /* Don't attempt to get eid until powerup is complete */
-               eid = ali_ac97_get(codec, AC97_EXTENDED_ID);
-               if (eid == 0xFFFF) {
-                       printk(KERN_ERR "ali_audio: no codec attached ?\n");
-                       kfree(codec);
-                       break;
-               }
-
-               card->ac97_features = eid;
-               /* Now check the codec for useful features to make up for
-                  the dumbness of the ali5455 hardware engine */
-               if (!(eid & 0x0001))
-                       printk(KERN_WARNING
-                              "ali_audio: only 48Khz playback available.\n");
-               else {
-                       if (!ali_ac97_enable_variable_rate(codec)) {
-                               printk(KERN_WARNING
-                                      "ali_audio: Codec refused to allow VRA, using 48Khz only.\n");
-                               card->ac97_features &= ~1;
-                       }
-               }
-
-               /* Determine how many channels the codec(s) support   */
-               /*   - The primary codec always supports 2            */
-               /*   - If the codec supports AMAP, surround DACs will */
-               /*     automaticlly get assigned to slots.            */
-               /*     * Check for surround DACs and increment if     */
-               /*       found.                                       */
-               /*   - Else check if the codec is revision 2.2        */
-               /*     * If surround DACs exist, assign them to slots */
-               /*       and increment channel count.                 */
-
-               /* All of this only applies to ICH2 and above. ICH    */
-               /* and ICH0 only support 2 channels.  ICH2 will only  */
-               /* support multiple codecs in a "split audio" config. */
-               /* as described above.                                */
-
-               /* TODO: Remove all the debugging messages!           */
-
-               if ((eid & 0xc000) == 0)        /* primary codec */
-                       total_channels += 2;
-               if ((codec->dev_mixer = register_sound_mixer(&ali_mixer_fops, -1)) < 0) {
-                       printk(KERN_ERR "ali_audio: couldn't register mixer!\n");
-                       kfree(codec);
-                       break;
-               }
-               card->ac97_codec[num_ac97] = codec;
-       }
-       /* pick the minimum of channels supported by ICHx or codec(s) */
-       card->channels = (card->channels > total_channels) ? total_channels : card->channels;
-       return num_ac97;
-}
-
-static void __devinit ali_configure_clocking(void)
-{
-       struct ali_card *card;
-       struct ali_state *state;
-       struct dmabuf *dmabuf;
-       unsigned int i, offset, new_offset;
-       unsigned long flags;
-       card = devs;
-
-       /* We could try to set the clocking for multiple cards, but can you even have
-        * more than one ali in a machine?  Besides, clocking is global, so unless
-        * someone actually thinks more than one ali in a machine is possible and
-        * decides to rewrite that little bit, setting the rate for more than one card
-        * is a waste of time.
-        */
-       if (card != NULL) {
-               state = card->states[0] = (struct ali_state *)
-                   kmalloc(sizeof(struct ali_state), GFP_KERNEL);
-               if (state == NULL)
-                       return;
-               memset(state, 0, sizeof(struct ali_state));
-               dmabuf = &state->dmabuf;
-               dmabuf->write_channel = card->alloc_pcm_channel(card);
-               state->virt = 0;
-               state->card = card;
-               state->magic = ALI5455_STATE_MAGIC;
-               init_waitqueue_head(&dmabuf->wait);
-               mutex_init(&state->open_mutex);
-               dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT;
-               dmabuf->trigger = PCM_ENABLE_OUTPUT;
-               ali_set_dac_rate(state, 48000);
-               if (prog_dmabuf(state, 0) != 0)
-                       goto config_out_nodmabuf;
-               
-               if (dmabuf->dmasize < 16384)
-                       goto config_out;
-               
-               dmabuf->count = dmabuf->dmasize;
-               outb(31, card->iobase + dmabuf->write_channel->port + OFF_LVI);
-
-               local_irq_save(flags);
-               start_dac(state);
-               offset = ali_get_dma_addr(state, 0);
-               mdelay(50);
-               new_offset = ali_get_dma_addr(state, 0);
-               stop_dac(state);
-               
-               outb(2, card->iobase + dmabuf->write_channel->port + OFF_CR);
-               local_irq_restore(flags);
-
-               i = new_offset - offset;
-
-               if (i == 0)
-                       goto config_out;
-               i = i / 4 * 20;
-               if (i > 48500 || i < 47500) {
-                       clocking = clocking * clocking / i;
-               }
-config_out:
-               dealloc_dmabuf(state);
-config_out_nodmabuf:
-               state->card->free_pcm_channel(state->card, state->dmabuf. write_channel->num);
-               kfree(state);
-               card->states[0] = NULL;
-       }
-}
-
-/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
-   until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
-
-static int __devinit ali_probe(struct pci_dev *pci_dev,
-                              const struct pci_device_id *pci_id)
-{
-       struct ali_card *card;
-       if (pci_enable_device(pci_dev))
-               return -EIO;
-       if (pci_set_dma_mask(pci_dev, ALI5455_DMA_MASK)) {
-               printk(KERN_ERR "ali5455: architecture does not support"
-                      " 32bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-
-       if ((card = kmalloc(sizeof(struct ali_card), GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "ali_audio: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(card, 0, sizeof(*card));
-       card->initializing = 1;
-       card->iobase = pci_resource_start(pci_dev, 0);
-       card->pci_dev = pci_dev;
-       card->pci_id = pci_id->device;
-       card->irq = pci_dev->irq;
-       card->next = devs;
-       card->magic = ALI5455_CARD_MAGIC;
-#ifdef CONFIG_PM
-       card->pm_suspended = 0;
-#endif
-       spin_lock_init(&card->lock);
-       spin_lock_init(&card->ac97_lock);
-       devs = card;
-       pci_set_master(pci_dev);
-       printk(KERN_INFO "ali: %s found at IO 0x%04lx, IRQ %d\n",
-              card_names[pci_id->driver_data], card->iobase, card->irq);
-       card->alloc_pcm_channel = ali_alloc_pcm_channel;
-       card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel;
-       card->alloc_rec_mic_channel = ali_alloc_rec_mic_channel;
-       card->alloc_codec_spdifout_channel = ali_alloc_codec_spdifout_channel;
-       card->alloc_controller_spdifout_channel = ali_alloc_controller_spdifout_channel;
-       card->free_pcm_channel = ali_free_pcm_channel;
-       card->channel[0].offset = 0;
-       card->channel[0].port = 0x40;
-       card->channel[0].num = 0;
-       card->channel[1].offset = 0;
-       card->channel[1].port = 0x50;
-       card->channel[1].num = 1;
-       card->channel[2].offset = 0;
-       card->channel[2].port = 0x60;
-       card->channel[2].num = 2;
-       card->channel[3].offset = 0;
-       card->channel[3].port = 0x70;
-       card->channel[3].num = 3;
-       card->channel[4].offset = 0;
-       card->channel[4].port = 0xb0;
-       card->channel[4].num = 4;
-       /* claim our iospace and irq */
-       request_region(card->iobase, 256, card_names[pci_id->driver_data]);
-       if (request_irq(card->irq, &ali_interrupt, IRQF_SHARED,
-                       card_names[pci_id->driver_data], card)) {
-               printk(KERN_ERR "ali_audio: unable to allocate irq %d\n",
-                      card->irq);
-               release_region(card->iobase, 256);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       if (ali_reset_5455(card) <= 0) {
-               unregister_sound_dsp(card->dev_audio);
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
-       }
-
-       /* initialize AC97 codec and register /dev/mixer */
-       if (ali_ac97_init(card) < 0) {
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               kfree(card);
-               return -ENODEV;
-       }
-       
-       pci_set_drvdata(pci_dev, card);
-       
-       if (clocking == 0) {
-               clocking = 48000;
-               ali_configure_clocking();
-       }
-
-       /* register /dev/dsp */
-       if ((card->dev_audio = register_sound_dsp(&ali_audio_fops, -1)) < 0) {
-               int i;
-               printk(KERN_ERR"ali_audio: couldn't register DSP device!\n");
-               release_region(card->iobase, 256);
-               free_irq(card->irq, card);
-               for (i = 0; i < NR_AC97; i++)
-                       if (card->ac97_codec[i] != NULL) {
-                               unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-                               kfree(card->ac97_codec[i]);
-                       }
-               kfree(card);
-               return -ENODEV;
-       }
-       card->initializing = 0;
-       return 0;
-}
-
-static void __devexit ali_remove(struct pci_dev *pci_dev)
-{
-       int i;
-       struct ali_card *card = pci_get_drvdata(pci_dev);
-       /* free hardware resources */
-       free_irq(card->irq, devs);
-       release_region(card->iobase, 256);
-       /* unregister audio devices */
-       for (i = 0; i < NR_AC97; i++)
-               if (card->ac97_codec[i] != NULL) {
-                       unregister_sound_mixer(card->ac97_codec[i]->
-                                              dev_mixer);
-                       ac97_release_codec(card->ac97_codec[i]);
-                       card->ac97_codec[i] = NULL;
-               }
-       unregister_sound_dsp(card->dev_audio);
-       kfree(card);
-}
-
-#ifdef CONFIG_PM
-static int ali_pm_suspend(struct pci_dev *dev, pm_message_t pm_state)
-{
-       struct ali_card *card = pci_get_drvdata(dev);
-       struct ali_state *state;
-       unsigned long flags;
-       struct dmabuf *dmabuf;
-       int i, num_ac97;
-
-       if (!card)
-               return 0;
-       spin_lock_irqsave(&card->lock, flags);
-       card->pm_suspended = 1;
-       for (i = 0; i < NR_HW_CH; i++) {
-               state = card->states[i];
-               if (!state)
-                       continue;
-               /* this happens only if there are open files */
-               dmabuf = &state->dmabuf;
-               if (dmabuf->enable & DAC_RUNNING ||
-                   (dmabuf->count
-                    && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) {
-                       state->pm_saved_dac_rate = dmabuf->rate;
-                       stop_dac(state);
-               } else {
-                       state->pm_saved_dac_rate = 0;
-               }
-               if (dmabuf->enable & ADC_RUNNING) {
-                       state->pm_saved_adc_rate = dmabuf->rate;
-                       stop_adc(state);
-               } else {
-                       state->pm_saved_adc_rate = 0;
-               }
-               dmabuf->ready = 0;
-               dmabuf->swptr = dmabuf->hwptr = 0;
-               dmabuf->count = dmabuf->total_bytes = 0;
-       }
-
-       spin_unlock_irqrestore(&card->lock, flags);
-       /* save mixer settings */
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-               struct ac97_codec *codec = card->ac97_codec[num_ac97];
-               if (!codec)
-                       continue;
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if ((supported_mixer(codec, i)) && (codec->read_mixer)) {
-                               card->pm_saved_mixer_settings[i][num_ac97] = codec->read_mixer(codec, i);
-                       }
-               }
-       }
-       pci_save_state(dev);    /* XXX do we need this? */
-       pci_disable_device(dev);        /* disable busmastering */
-       pci_set_power_state(dev, 3);    /* Zzz. */
-       return 0;
-}
-
-
-static int ali_pm_resume(struct pci_dev *dev)
-{
-       int num_ac97, i = 0;
-       struct ali_card *card = pci_get_drvdata(dev);
-       pci_enable_device(dev);
-       pci_restore_state(dev);
-       /* observation of a toshiba portege 3440ct suggests that the 
-          hardware has to be more or less completely reinitialized from
-          scratch after an apm suspend.  Works For Me.   -dan */
-       ali_ac97_random_init_stuff(card);
-       for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-               struct ac97_codec *codec = card->ac97_codec[num_ac97];
-               /* check they haven't stolen the hardware while we were
-                  away */
-               if (!codec || !ali_ac97_exists(card, num_ac97)) {
-                       if (num_ac97)
-                               continue;
-                       else
-                               BUG();
-               }
-               if (!ali_ac97_probe_and_powerup(card, codec))
-                       BUG();
-               if ((card->ac97_features & 0x0001)) {
-                       /* at probe time we found we could do variable
-                          rates, but APM suspend has made it forget
-                          its magical powers */
-                       if (!ali_ac97_enable_variable_rate(codec))
-                               BUG();
-               }
-               /* we lost our mixer settings, so restore them */
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (supported_mixer(codec, i)) {
-                               int val = card->pm_saved_mixer_settings[i][num_ac97];
-                               codec->mixer_state[i] = val;
-                               codec->write_mixer(codec, i,
-                                                  (val & 0xff),
-                                                  ((val >> 8) & 0xff));
-                       }
-               }
-       }
-
-       /* we need to restore the sample rate from whatever it was */
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               if (state) {
-                       if (state->pm_saved_adc_rate)
-                               ali_set_adc_rate(state, state->pm_saved_adc_rate);
-                       if (state->pm_saved_dac_rate)
-                               ali_set_dac_rate(state, state->pm_saved_dac_rate);
-               }
-       }
-
-       card->pm_suspended = 0;
-       /* any processes that were reading/writing during the suspend
-          probably ended up here */
-       for (i = 0; i < NR_HW_CH; i++) {
-               struct ali_state *state = card->states[i];
-               if (state)
-                       wake_up(&state->dmabuf.wait);
-       }
-       return 0;
-}
-#endif                         /* CONFIG_PM */
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("ALI 5455 audio support");
-MODULE_LICENSE("GPL");
-module_param(clocking, int, 0);
-/* FIXME: bool? */
-module_param(strict_clocking, uint, 0);
-module_param(codec_pcmout_share_spdif_locked, uint, 0);
-module_param(codec_independent_spdif_locked, uint, 0);
-module_param(controller_pcmout_share_spdif_locked, uint, 0);
-module_param(controller_independent_spdif_locked, uint, 0);
-#define ALI5455_MODULE_NAME "ali5455"
-static struct pci_driver ali_pci_driver = {
-       .name           = ALI5455_MODULE_NAME,
-       .id_table       = ali_pci_tbl,
-       .probe          = ali_probe,
-       .remove         = __devexit_p(ali_remove),
-#ifdef CONFIG_PM
-       .suspend        = ali_pm_suspend,
-       .resume         = ali_pm_resume,
-#endif                         /* CONFIG_PM */
-};
-
-static int __init ali_init_module(void)
-{
-       printk(KERN_INFO "ALI 5455 + AC97 Audio, version "
-              DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
-
-       if (codec_independent_spdif_locked > 0) {
-               if (codec_independent_spdif_locked == 32000
-                   || codec_independent_spdif_locked == 44100
-                   || codec_independent_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_independent_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       codec_independent_spdif_locked = 0;
-               }
-       }
-       if (controller_independent_spdif_locked > 0) {
-               if (controller_independent_spdif_locked == 32000
-                   || controller_independent_spdif_locked == 44100
-                   || controller_independent_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", controller_independent_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       controller_independent_spdif_locked = 0;
-               }
-       }
-
-       if (codec_pcmout_share_spdif_locked > 0) {
-               if (codec_pcmout_share_spdif_locked == 32000
-                   || codec_pcmout_share_spdif_locked == 44100
-                   || codec_pcmout_share_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_pcmout_share_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       codec_pcmout_share_spdif_locked = 0;
-               }
-       }
-       if (controller_pcmout_share_spdif_locked > 0) {
-               if (controller_pcmout_share_spdif_locked == 32000
-                   || controller_pcmout_share_spdif_locked == 44100
-                   || controller_pcmout_share_spdif_locked == 48000) {
-                       printk(KERN_INFO "ali_audio: Enabling controller S/PDIF at sample rate %dHz.\n", controller_pcmout_share_spdif_locked);
-               } else {
-                       printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n");
-                       controller_pcmout_share_spdif_locked = 0;
-               }
-       }
-       return pci_register_driver(&ali_pci_driver);
-}
-
-static void __exit ali_cleanup_module(void)
-{
-       pci_unregister_driver(&ali_pci_driver);
-}
-
-module_init(ali_init_module);
-module_exit(ali_cleanup_module);
-/*
-Local Variables:
-c-basic-offset: 8
-End:
-*/
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
deleted file mode 100644 (file)
index e379623..0000000
+++ /dev/null
@@ -1,2216 +0,0 @@
-/*
- *      au1000.c  --  Sound driver for Alchemy Au1000 MIPS Internet Edge
- *                    Processor.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *             stevel@mvista.com or source@mvista.com
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  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.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- * Module command line parameters:
- *
- *  Supported devices:
- *  /dev/dsp    standard OSS /dev/dsp device
- *  /dev/mixer  standard OSS /dev/mixer device
- *
- * Notes:
- *
- *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
- *     taken, slightly modified or not at all, from the ES1371 driver,
- *     so refer to the credits in es1371.c for those. The rest of the
- *     code (probe, open, read, write, the ISR, etc.) is new.
- *
- *  Revision history
- *    06.27.2001  Initial version
- *    03.20.2002  Added mutex locks around read/write methods, to prevent
- *                simultaneous access on SMP or preemptible kernels. Also
- *                removed the counter/pointer fragment aligning at the end
- *                of read/write methods [stevel].
- *    03.21.2002  Add support for coherent DMA on the audio read/write DMA
- *                channels [stevel].
- *
- */
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/init.h>
-#include <linux/page-flags.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef AU1000_DEBUG
-#undef AU1000_VERBOSE_DEBUG
-
-#define AU1000_MODULE_NAME "Au1000 audio"
-#define PFX AU1000_MODULE_NAME
-
-#ifdef AU1000_DEBUG
-#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
-#else
-#define dbg(format, arg...) do {} while (0)
-#endif
-#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
-
-
-/* misc stuff */
-#define POLL_COUNT   0x5000
-#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
-
-/* Boot options */
-static int      vra = 0;       // 0 = no VRA, 1 = use VRA if codec supports it
-module_param(vra, bool, 0);
-MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
-
-
-/* --------------------------------------------------------------------- */
-
-struct au1000_state {
-       /* soundcore stuff */
-       int             dev_audio;
-
-#ifdef AU1000_DEBUG
-       /* debug /proc entry */
-       struct proc_dir_entry *ps;
-       struct proc_dir_entry *ac97_ps;
-#endif                         /* AU1000_DEBUG */
-
-       struct ac97_codec codec;
-       unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
-       unsigned        codec_ext_caps; // AC'97 reg 28h, "Extended Audio ID"
-       int             no_vra; // do not use VRA
-
-       spinlock_t      lock;
-       struct mutex open_mutex;
-       struct mutex sem;
-       mode_t          open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               unsigned int    dmanr;  // DMA Channel number
-               unsigned        sample_rate;    // Hz
-               unsigned src_factor;     // SRC interp/decimation (no vra)
-               unsigned        sample_size;    // 8 or 16
-               int             num_channels;   // 1 = mono, 2 = stereo, 4, 6
-               int dma_bytes_per_sample;// DMA bytes per audio sample frame
-               int user_bytes_per_sample;// User bytes per audio sample frame
-               int cnt_factor;          // user-to-DMA bytes per audio
-               //  sample frame
-               void           *rawbuf;
-               dma_addr_t      dmaaddr;
-               unsigned        buforder;
-               unsigned numfrag;        // # of DMA fragments in DMA buffer
-               unsigned        fragshift;
-               void           *nextIn; // ptr to next-in to DMA buffer
-               void           *nextOut;// ptr to next-out from DMA buffer
-               int             count;  // current byte count in DMA buffer
-               unsigned        total_bytes;    // total bytes written or read
-               unsigned        error;  // over/underrun
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;       // user perception of fragment size
-               unsigned dma_fragsize;   // DMA (real) fragment size
-               unsigned dmasize;        // Total DMA buffer size
-               //   (mult. of DMA fragsize)
-               /* OSS stuff */
-               unsigned        mapped:1;
-               unsigned        ready:1;
-               unsigned        stopped:1;
-               unsigned        ossfragshift;
-               int             ossmaxfrags;
-               unsigned        subdivision;
-       } dma_dac      , dma_adc;
-} au1000_state;
-
-/* --------------------------------------------------------------------- */
-
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned        r = 0;
-
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void au1000_delay(int msec)
-{
-       unsigned long   tmo;
-       signed long     tmo2;
-
-       if (in_interrupt())
-               return;
-
-       tmo = jiffies + (msec * HZ) / 1000;
-       for (;;) {
-               tmo2 = tmo - jiffies;
-               if (tmo2 <= 0)
-                       break;
-               schedule_timeout(tmo2);
-       }
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static u16 rdcodec(struct ac97_codec *codec, u8 addr)
-{
-       struct au1000_state *s = (struct au1000_state *)codec->private_data;
-       unsigned long   flags;
-       u32             cmd;
-       u16             data;
-       int             i;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT)
-               err("rdcodec: codec cmd pending expired!");
-
-       cmd = (u32) addr & AC97C_INDEX_MASK;
-       cmd |= AC97C_READ;      // read command
-       au_writel(cmd, AC97C_CMD);
-
-       /* now wait for the data */
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT) {
-               err("rdcodec: read poll expired!");
-               return 0;
-       }
-
-       data = au_readl(AC97C_CMD) & 0xffff;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       return data;
-}
-
-
-static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
-{
-       struct au1000_state *s = (struct au1000_state *)codec->private_data;
-       unsigned long   flags;
-       u32             cmd;
-       int             i;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       for (i = 0; i < POLL_COUNT; i++)
-               if (!(au_readl(AC97C_STATUS) & AC97C_CP))
-                       break;
-       if (i == POLL_COUNT)
-               err("wrcodec: codec cmd pending expired!");
-
-       cmd = (u32) addr & AC97C_INDEX_MASK;
-       cmd &= ~AC97C_READ;     // write command
-       cmd |= ((u32) data << AC97C_WD_BIT);    // OR in the data word
-       au_writel(cmd, AC97C_CMD);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void waitcodec(struct ac97_codec *codec)
-{
-       u16             temp;
-       int             i;
-
-       /* codec_wait is used to wait for a ready state after
-          an AC97C_RESET. */
-       au1000_delay(10);
-
-       // first poll the CODEC_READY tag bit
-       for (i = 0; i < POLL_COUNT; i++)
-               if (au_readl(AC97C_STATUS) & AC97C_READY)
-                       break;
-       if (i == POLL_COUNT) {
-               err("waitcodec: CODEC_READY poll expired!");
-               return;
-       }
-       // get AC'97 powerdown control/status register
-       temp = rdcodec(codec, AC97_POWER_CONTROL);
-
-       // If anything is powered down, power'em up
-       if (temp & 0x7f00) {
-               // Power on
-               wrcodec(codec, AC97_POWER_CONTROL, 0);
-               au1000_delay(100);
-               // Reread
-               temp = rdcodec(codec, AC97_POWER_CONTROL);
-       }
-    
-       // Check if Codec REF,ANL,DAC,ADC ready
-       if ((temp & 0x7f0f) != 0x000f)
-               err("codec reg 26 status (0x%x) not ready!!", temp);
-}
-
-
-/* --------------------------------------------------------------------- */
-
-/* stop the ADC before calling */
-static void set_adc_rate(struct au1000_state *s, unsigned rate)
-{
-       struct dmabuf  *adc = &s->dma_adc;
-       struct dmabuf  *dac = &s->dma_dac;
-       unsigned        adc_rate, dac_rate;
-       u16             ac97_extstat;
-
-       if (s->no_vra) {
-               // calc SRC factor
-               adc->src_factor = ((96000 / rate) + 1) >> 1;
-               adc->sample_rate = 48000 / adc->src_factor;
-               return;
-       }
-
-       adc->src_factor = 1;
-
-       ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-       rate = rate > 48000 ? 48000 : rate;
-
-       // enable VRA
-       wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-               ac97_extstat | AC97_EXTSTAT_VRA);
-       // now write the sample rate
-       wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
-       // read it back for actual supported rate
-       adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("%s: set to %d Hz", __FUNCTION__, adc_rate);
-#endif
-
-       // some codec's don't allow unequal DAC and ADC rates, in which case
-       // writing one rate reg actually changes both.
-       dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-       if (dac->num_channels > 2)
-               wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
-       if (dac->num_channels > 4)
-               wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
-
-       adc->sample_rate = adc_rate;
-       dac->sample_rate = dac_rate;
-}
-
-/* stop the DAC before calling */
-static void set_dac_rate(struct au1000_state *s, unsigned rate)
-{
-       struct dmabuf  *dac = &s->dma_dac;
-       struct dmabuf  *adc = &s->dma_adc;
-       unsigned        adc_rate, dac_rate;
-       u16             ac97_extstat;
-
-       if (s->no_vra) {
-               // calc SRC factor
-               dac->src_factor = ((96000 / rate) + 1) >> 1;
-               dac->sample_rate = 48000 / dac->src_factor;
-               return;
-       }
-
-       dac->src_factor = 1;
-
-       ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-
-       rate = rate > 48000 ? 48000 : rate;
-
-       // enable VRA
-       wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-               ac97_extstat | AC97_EXTSTAT_VRA);
-       // now write the sample rate
-       wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
-       // I don't support different sample rates for multichannel,
-       // so make these channels the same.
-       if (dac->num_channels > 2)
-               wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
-       if (dac->num_channels > 4)
-               wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
-       // read it back for actual supported rate
-       dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("%s: set to %d Hz", __FUNCTION__, dac_rate);
-#endif
-
-       // some codec's don't allow unequal DAC and ADC rates, in which case
-       // writing one rate reg actually changes both.
-       adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
-
-       dac->sample_rate = dac_rate;
-       adc->sample_rate = adc_rate;
-}
-
-static void stop_dac(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_dac;
-       unsigned long   flags;
-
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       disable_dma(db->dmanr);
-
-       db->stopped = 1;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void  stop_adc(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_adc;
-       unsigned long   flags;
-
-       if (db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       disable_dma(db->dmanr);
-
-       db->stopped = 1;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void set_xmit_slots(int num_channels)
-{
-       u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_XMIT_SLOTS_MASK;
-
-       switch (num_channels) {
-       case 1:         // mono
-       case 2:         // stereo, slots 3,4
-               ac97_config |= (0x3 << AC97C_XMIT_SLOTS_BIT);
-               break;
-       case 4:         // stereo with surround, slots 3,4,7,8
-               ac97_config |= (0x33 << AC97C_XMIT_SLOTS_BIT);
-               break;
-       case 6:         // stereo with surround and center/LFE, slots 3,4,6,7,8,9
-               ac97_config |= (0x7b << AC97C_XMIT_SLOTS_BIT);
-               break;
-       }
-
-       au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void     set_recv_slots(int num_channels)
-{
-       u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_RECV_SLOTS_MASK;
-
-       /*
-        * Always enable slots 3 and 4 (stereo). Slot 6 is
-        * optional Mic ADC, which I don't support yet.
-        */
-       ac97_config |= (0x3 << AC97C_RECV_SLOTS_BIT);
-
-       au_writel(ac97_config, AC97C_CONFIG);
-}
-
-static void start_dac(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_dac;
-       unsigned long   flags;
-       unsigned long   buf1, buf2;
-
-       if (!db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       au_readl(AC97C_STATUS); // read status to clear sticky bits
-
-       // reset Buffer 1 and 2 pointers to nextOut and nextOut+dma_fragsize
-       buf1 = virt_to_phys(db->nextOut);
-       buf2 = buf1 + db->dma_fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-
-       set_xmit_slots(db->num_channels);
-
-       init_dma(db->dmanr);
-       if (get_dma_active_buffer(db->dmanr) == 0) {
-               clear_dma_done0(db->dmanr);     // clear DMA done bit
-               set_dma_addr0(db->dmanr, buf1);
-               set_dma_addr1(db->dmanr, buf2);
-       } else {
-               clear_dma_done1(db->dmanr);     // clear DMA done bit
-               set_dma_addr1(db->dmanr, buf1);
-               set_dma_addr0(db->dmanr, buf2);
-       }
-       set_dma_count(db->dmanr, db->dma_fragsize>>1);
-       enable_dma_buffers(db->dmanr);
-
-       start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dump_au1000_dma_channel(db->dmanr);
-#endif
-
-       db->stopped = 0;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct au1000_state *s)
-{
-       struct dmabuf  *db = &s->dma_adc;
-       unsigned long   flags;
-       unsigned long   buf1, buf2;
-
-       if (!db->stopped)
-               return;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       au_readl(AC97C_STATUS); // read status to clear sticky bits
-
-       // reset Buffer 1 and 2 pointers to nextIn and nextIn+dma_fragsize
-       buf1 = virt_to_phys(db->nextIn);
-       buf2 = buf1 + db->dma_fragsize;
-       if (buf2 >= db->dmaaddr + db->dmasize)
-               buf2 -= db->dmasize;
-
-       set_recv_slots(db->num_channels);
-
-       init_dma(db->dmanr);
-       if (get_dma_active_buffer(db->dmanr) == 0) {
-               clear_dma_done0(db->dmanr);     // clear DMA done bit
-               set_dma_addr0(db->dmanr, buf1);
-               set_dma_addr1(db->dmanr, buf2);
-       } else {
-               clear_dma_done1(db->dmanr);     // clear DMA done bit
-               set_dma_addr1(db->dmanr, buf1);
-               set_dma_addr0(db->dmanr, buf2);
-       }
-       set_dma_count(db->dmanr, db->dma_fragsize>>1);
-       enable_dma_buffers(db->dmanr);
-
-       start_dma(db->dmanr);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dump_au1000_dma_channel(db->dmanr);
-#endif
-
-       db->stopped = 0;
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-       struct page    *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf +
-                                   (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               dma_free_noncoherent(NULL,
-                               PAGE_SIZE << db->buforder,
-                               db->rawbuf,
-                               db->dmaaddr);
-       }
-       db->rawbuf = db->nextIn = db->nextOut = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db)
-{
-       int             order;
-       unsigned user_bytes_per_sec;
-       unsigned        bufs;
-       struct page    *page, *pend;
-       unsigned        rate = db->sample_rate;
-
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER;
-                    order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = dma_alloc_noncoherent(NULL,
-                                               PAGE_SIZE << order,
-                                               &db->dmaaddr,
-                                               0)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved;
-                  otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf +
-                                   (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-
-       db->cnt_factor = 1;
-       if (db->sample_size == 8)
-               db->cnt_factor *= 2;
-       if (db->num_channels == 1)
-               db->cnt_factor *= 2;
-       db->cnt_factor *= db->src_factor;
-
-       db->count = 0;
-       db->nextIn = db->nextOut = db->rawbuf;
-
-       db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
-       db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
-                                       2 : db->num_channels);
-
-       user_bytes_per_sec = rate * db->user_bytes_per_sample;
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < user_bytes_per_sec)
-                       db->fragshift = ld2(user_bytes_per_sec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(user_bytes_per_sec / 100 /
-                                   (db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-
-       db->fragsize = 1 << db->fragshift;
-       db->dma_fragsize = db->fragsize * db->cnt_factor;
-       db->numfrag = bufs / db->dma_fragsize;
-
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->fragsize = 1 << db->fragshift;
-               db->dma_fragsize = db->fragsize * db->cnt_factor;
-               db->numfrag = bufs / db->dma_fragsize;
-       }
-
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-
-       db->dmasize = db->dma_fragsize * db->numfrag;
-       memset(db->rawbuf, 0, bufs);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("rate=%d, samplesize=%d, channels=%d",
-           rate, db->sample_size, db->num_channels);
-       dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
-           db->fragsize, db->cnt_factor, db->dma_fragsize);
-       dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
-#endif
-
-       db->ready = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct au1000_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc);
-
-}
-
-static inline int prog_dmabuf_dac(struct au1000_state *s)
-{
-       stop_dac(s);
-       return prog_dmabuf(s, &s->dma_dac);
-}
-
-
-/* hold spinlock for the following */
-static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct au1000_state *s = (struct au1000_state *) dev_id;
-       struct dmabuf  *dac = &s->dma_dac;
-       unsigned long   newptr;
-       u32 ac97c_stat, buff_done;
-
-       ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-       if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
-               dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-       if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
-               /* fastpath out, to ease interrupt sharing */
-               return IRQ_HANDLED;
-       }
-
-       spin_lock(&s->lock);
-       
-       if (buff_done != (DMA_D0 | DMA_D1)) {
-               dac->nextOut += dac->dma_fragsize;
-               if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-                       dac->nextOut -= dac->dmasize;
-
-               /* update playback pointers */
-               newptr = virt_to_phys(dac->nextOut) + dac->dma_fragsize;
-               if (newptr >= dac->dmaaddr + dac->dmasize)
-                       newptr -= dac->dmasize;
-
-               dac->count -= dac->dma_fragsize;
-               dac->total_bytes += dac->dma_fragsize;
-
-               if (dac->count <= 0) {
-#ifdef AU1000_VERBOSE_DEBUG
-                       dbg("dac underrun");
-#endif
-                       spin_unlock(&s->lock);
-                       stop_dac(s);
-                       spin_lock(&s->lock);
-                       dac->count = 0;
-                       dac->nextIn = dac->nextOut;
-               } else if (buff_done == DMA_D0) {
-                       clear_dma_done0(dac->dmanr);    // clear DMA done bit
-                       set_dma_count0(dac->dmanr, dac->dma_fragsize>>1);
-                       set_dma_addr0(dac->dmanr, newptr);
-                       enable_dma_buffer0(dac->dmanr); // reenable
-               } else {
-                       clear_dma_done1(dac->dmanr);    // clear DMA done bit
-                       set_dma_count1(dac->dmanr, dac->dma_fragsize>>1);
-                       set_dma_addr1(dac->dmanr, newptr);
-                       enable_dma_buffer1(dac->dmanr); // reenable
-               }
-       } else {
-               // both done bits set, we missed an interrupt
-               spin_unlock(&s->lock);
-               stop_dac(s);
-               spin_lock(&s->lock);
-
-               dac->nextOut += 2*dac->dma_fragsize;
-               if (dac->nextOut >= dac->rawbuf + dac->dmasize)
-                       dac->nextOut -= dac->dmasize;
-
-               dac->count -= 2*dac->dma_fragsize;
-               dac->total_bytes += 2*dac->dma_fragsize;
-
-               if (dac->count > 0) {
-                       spin_unlock(&s->lock);
-                       start_dac(s);
-                       spin_lock(&s->lock);
-               }
-       }
-
-       /* wake up anybody listening */
-       if (waitqueue_active(&dac->wait))
-               wake_up(&dac->wait);
-
-       spin_unlock(&s->lock);
-
-       return IRQ_HANDLED;
-}
-
-
-static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct au1000_state *s = (struct au1000_state *) dev_id;
-       struct dmabuf  *adc = &s->dma_adc;
-       unsigned long   newptr;
-       u32 ac97c_stat, buff_done;
-
-       ac97c_stat = au_readl(AC97C_STATUS);
-#ifdef AU1000_VERBOSE_DEBUG
-       if (ac97c_stat & (AC97C_RU | AC97C_RO))
-               dbg("AC97C status = 0x%08x", ac97c_stat);
-#endif
-
-       if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
-               /* fastpath out, to ease interrupt sharing */
-               return IRQ_HANDLED;
-       }
-
-       spin_lock(&s->lock);
-       
-       if (buff_done != (DMA_D0 | DMA_D1)) {
-               if (adc->count + adc->dma_fragsize > adc->dmasize) {
-                       // Overrun. Stop ADC and log the error
-                       spin_unlock(&s->lock);
-                       stop_adc(s);
-                       adc->error++;
-                       err("adc overrun");
-                       return IRQ_NONE;
-               }
-
-               adc->nextIn += adc->dma_fragsize;
-               if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-                       adc->nextIn -= adc->dmasize;
-
-               /* update capture pointers */
-               newptr = virt_to_phys(adc->nextIn) + adc->dma_fragsize;
-               if (newptr >= adc->dmaaddr + adc->dmasize)
-                       newptr -= adc->dmasize;
-
-               adc->count += adc->dma_fragsize;
-               adc->total_bytes += adc->dma_fragsize;
-
-               if (buff_done == DMA_D0) {
-                       clear_dma_done0(adc->dmanr);    // clear DMA done bit
-                       set_dma_count0(adc->dmanr, adc->dma_fragsize>>1);
-                       set_dma_addr0(adc->dmanr, newptr);
-                       enable_dma_buffer0(adc->dmanr); // reenable
-               } else {
-                       clear_dma_done1(adc->dmanr);    // clear DMA done bit
-                       set_dma_count1(adc->dmanr, adc->dma_fragsize>>1);
-                       set_dma_addr1(adc->dmanr, newptr);
-                       enable_dma_buffer1(adc->dmanr); // reenable
-               }
-       } else {
-               // both done bits set, we missed an interrupt
-               spin_unlock(&s->lock);
-               stop_adc(s);
-               spin_lock(&s->lock);
-               
-               if (adc->count + 2*adc->dma_fragsize > adc->dmasize) {
-                       // Overrun. Log the error
-                       adc->error++;
-                       err("adc overrun");
-                       spin_unlock(&s->lock);
-                       return IRQ_NONE;
-               }
-
-               adc->nextIn += 2*adc->dma_fragsize;
-               if (adc->nextIn >= adc->rawbuf + adc->dmasize)
-                       adc->nextIn -= adc->dmasize;
-
-               adc->count += 2*adc->dma_fragsize;
-               adc->total_bytes += 2*adc->dma_fragsize;
-               
-               spin_unlock(&s->lock);
-               start_adc(s);
-               spin_lock(&s->lock);
-       }
-
-       /* wake up anybody listening */
-       if (waitqueue_active(&adc->wait))
-               wake_up(&adc->wait);
-
-       spin_unlock(&s->lock);
-
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static loff_t au1000_llseek(struct file *file, loff_t offset, int origin)
-{
-       return -ESPIPE;
-}
-
-
-static int au1000_open_mixdev(struct inode *inode, struct file *file)
-{
-       file->private_data = &au1000_state;
-       return nonseekable_open(inode, file);
-}
-
-static int au1000_release_mixdev(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
-                        unsigned long arg)
-{
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int au1000_ioctl_mixdev(struct inode *inode, struct file *file,
-                              unsigned int cmd, unsigned long arg)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct ac97_codec *codec = &s->codec;
-
-       return mixdev_ioctl(codec, cmd, arg);
-}
-
-static /*const */ struct file_operations au1000_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = au1000_llseek,
-       .ioctl          = au1000_ioctl_mixdev,
-       .open           = au1000_open_mixdev,
-       .release        = au1000_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct au1000_state *s, int nonblock)
-{
-       unsigned long   flags;
-       int             count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
-               return 0;
-
-       for (;;) {
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                       break;
-               if (nonblock)
-                       return -EBUSY;
-               tmo = 1000 * count / (s->no_vra ?
-                                     48000 : s->dma_dac.sample_rate);
-               tmo /= s->dma_dac.dma_bytes_per_sample;
-               au1000_delay(tmo);
-       }
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline u8 S16_TO_U8(s16 ch)
-{
-       return (u8) (ch >> 8) + 0x80;
-}
-static inline s16 U8_TO_S16(u8 ch)
-{
-       return (s16) (ch - 0x80) << 8;
-}
-
-/*
- * Translates user samples to dma buffer suitable for AC'97 DAC data:
- *     If mono, copy left channel to right channel in dma buffer.
- *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
- *     If interpolating (no VRA), duplicate every audio frame src_factor times.
- */
-static int translate_from_user(struct dmabuf *db,
-                              char* dmabuf,
-                              char* userbuf,
-                              int dmacount)
-{
-       int             sample, i;
-       int             interp_bytes_per_sample;
-       int             num_samples;
-       int             mono = (db->num_channels == 1);
-       char            usersample[12];
-       s16             ch, dmasample[6];
-
-       if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-               // no translation necessary, just copy
-               if (copy_from_user(dmabuf, userbuf, dmacount))
-                       return -EFAULT;
-               return dmacount;
-       }
-
-       interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-       num_samples = dmacount / interp_bytes_per_sample;
-
-       for (sample = 0; sample < num_samples; sample++) {
-               if (copy_from_user(usersample, userbuf,
-                                  db->user_bytes_per_sample)) {
-                       dbg("%s: fault", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               for (i = 0; i < db->num_channels; i++) {
-                       if (db->sample_size == 8)
-                               ch = U8_TO_S16(usersample[i]);
-                       else
-                               ch = *((s16 *) (&usersample[i * 2]));
-                       dmasample[i] = ch;
-                       if (mono)
-                               dmasample[i + 1] = ch;  // right channel
-               }
-
-               // duplicate every audio frame src_factor times
-               for (i = 0; i < db->src_factor; i++)
-                       memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
-
-               userbuf += db->user_bytes_per_sample;
-               dmabuf += interp_bytes_per_sample;
-       }
-
-       return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Translates AC'97 ADC samples to user buffer:
- *     If mono, send only left channel to user buffer.
- *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
- *     If decimating (no VRA), skip over src_factor audio frames.
- */
-static int translate_to_user(struct dmabuf *db,
-                            char* userbuf,
-                            char* dmabuf,
-                            int dmacount)
-{
-       int             sample, i;
-       int             interp_bytes_per_sample;
-       int             num_samples;
-       int             mono = (db->num_channels == 1);
-       char            usersample[12];
-
-       if (db->sample_size == 16 && !mono && db->src_factor == 1) {
-               // no translation necessary, just copy
-               if (copy_to_user(userbuf, dmabuf, dmacount))
-                       return -EFAULT;
-               return dmacount;
-       }
-
-       interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
-       num_samples = dmacount / interp_bytes_per_sample;
-
-       for (sample = 0; sample < num_samples; sample++) {
-               for (i = 0; i < db->num_channels; i++) {
-                       if (db->sample_size == 8)
-                               usersample[i] =
-                                       S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
-                       else
-                               *((s16 *) (&usersample[i * 2])) =
-                                       *((s16 *) (&dmabuf[i * 2]));
-               }
-
-               if (copy_to_user(userbuf, usersample,
-                                db->user_bytes_per_sample)) {
-                       dbg("%s: fault", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               userbuf += db->user_bytes_per_sample;
-               dmabuf += interp_bytes_per_sample;
-       }
-
-       return num_samples * interp_bytes_per_sample;
-}
-
-/*
- * Copy audio data to/from user buffer from/to dma buffer, taking care
- * that we wrap when reading/writing the dma buffer. Returns actual byte
- * count written to or read from the dma buffer.
- */
-static int copy_dmabuf_user(struct dmabuf *db, char* userbuf,
-                           int count, int to_user)
-{
-       char           *bufptr = to_user ? db->nextOut : db->nextIn;
-       char           *bufend = db->rawbuf + db->dmasize;
-       int             cnt, ret;
-
-       if (bufptr + count > bufend) {
-               int             partial = (int) (bufend - bufptr);
-               if (to_user) {
-                       if ((cnt = translate_to_user(db, userbuf,
-                                                    bufptr, partial)) < 0)
-                               return cnt;
-                       ret = cnt;
-                       if ((cnt = translate_to_user(db, userbuf + partial,
-                                                    db->rawbuf,
-                                                    count - partial)) < 0)
-                               return cnt;
-                       ret += cnt;
-               } else {
-                       if ((cnt = translate_from_user(db, bufptr, userbuf,
-                                                      partial)) < 0)
-                               return cnt;
-                       ret = cnt;
-                       if ((cnt = translate_from_user(db, db->rawbuf,
-                                                      userbuf + partial,
-                                                      count - partial)) < 0)
-                               return cnt;
-                       ret += cnt;
-               }
-       } else {
-               if (to_user)
-                       ret = translate_to_user(db, userbuf, bufptr, count);
-               else
-                       ret = translate_from_user(db, bufptr, userbuf, count);
-       }
-
-       return ret;
-}
-
-
-static ssize_t au1000_read(struct file *file, char *buffer,
-                          size_t count, loff_t *ppos)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db = &s->dma_adc;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t         ret;
-       unsigned long   flags;
-       int             cnt, usercnt, avail;
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-       count *= db->cnt_factor;
-
-       mutex_lock(&s->sem);
-       add_wait_queue(&db->wait, &wait);
-
-       while (count > 0) {
-               // wait for samples in ADC dma buffer
-               do {
-                       if (db->stopped)
-                               start_adc(s);
-                       spin_lock_irqsave(&s->lock, flags);
-                       avail = db->count;
-                       if (avail <= 0)
-                               __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       goto out;
-                               }
-                               mutex_unlock(&s->sem);
-                               schedule();
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       goto out2;
-                               }
-                               mutex_lock(&s->sem);
-                       }
-               } while (avail <= 0);
-
-               // copy from nextOut to user
-               if ((cnt = copy_dmabuf_user(db, buffer,
-                                           count > avail ?
-                                           avail : count, 1)) < 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count -= cnt;
-               db->nextOut += cnt;
-               if (db->nextOut >= db->rawbuf + db->dmasize)
-                       db->nextOut -= db->dmasize;
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               count -= cnt;
-               usercnt = cnt / db->cnt_factor;
-               buffer += usercnt;
-               ret += usercnt;
-       }                       // while (count > 0)
-
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&db->wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t au1000_write(struct file *file, const char *buffer,
-                           size_t count, loff_t * ppos)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db = &s->dma_dac;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t         ret = 0;
-       unsigned long   flags;
-       int             cnt, usercnt, avail;
-
-#ifdef AU1000_VERBOSE_DEBUG
-       dbg("write: count=%d", count);
-#endif
-
-       if (db->mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-
-       count *= db->cnt_factor;
-
-       mutex_lock(&s->sem);
-       add_wait_queue(&db->wait, &wait);
-
-       while (count > 0) {
-               // wait for space in playback buffer
-               do {
-                       spin_lock_irqsave(&s->lock, flags);
-                       avail = (int) db->dmasize - db->count;
-                       if (avail <= 0)
-                               __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (avail <= 0) {
-                               if (file->f_flags & O_NONBLOCK) {
-                                       if (!ret)
-                                               ret = -EAGAIN;
-                                       goto out;
-                               }
-                               mutex_unlock(&s->sem);
-                               schedule();
-                               if (signal_pending(current)) {
-                                       if (!ret)
-                                               ret = -ERESTARTSYS;
-                                       goto out2;
-                               }
-                               mutex_lock(&s->sem);
-                       }
-               } while (avail <= 0);
-
-               // copy from user to nextIn
-               if ((cnt = copy_dmabuf_user(db, (char *) buffer,
-                                           count > avail ?
-                                           avail : count, 0)) < 0) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-
-               spin_lock_irqsave(&s->lock, flags);
-               db->count += cnt;
-               db->nextIn += cnt;
-               if (db->nextIn >= db->rawbuf + db->dmasize)
-                       db->nextIn -= db->dmasize;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (db->stopped)
-                       start_dac(s);
-
-               count -= cnt;
-               usercnt = cnt / db->cnt_factor;
-               buffer += usercnt;
-               ret += usercnt;
-       }                       // while (count > 0)
-
-out:
-       mutex_unlock(&s->sem);
-out2:
-       remove_wait_queue(&db->wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int au1000_poll(struct file *file,
-                               struct poll_table_struct *wait)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       unsigned long   flags;
-       unsigned int    mask = 0;
-
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready)
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready)
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-
-       spin_lock_irqsave(&s->lock, flags);
-       
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >=
-                           (signed)s->dma_dac.dma_fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed) s->dma_dac.dmasize >=
-                           s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       struct dmabuf  *db;
-       unsigned long   size;
-       int ret = 0;
-
-       dbg("%s", __FUNCTION__);
-    
-       lock_kernel();
-       mutex_lock(&s->sem);
-       if (vma->vm_flags & VM_WRITE)
-               db = &s->dma_dac;
-       else if (vma->vm_flags & VM_READ)
-               db = &s->dma_adc;
-       else {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
-                            size, vma->vm_page_prot)) {
-               ret = -EAGAIN;
-               goto out;
-       }
-       vma->vm_flags &= ~VM_IO;
-       db->mapped = 1;
-out:
-       mutex_unlock(&s->sem);
-       unlock_kernel();
-       return ret;
-}
-
-
-#ifdef AU1000_VERBOSE_DEBUG
-static struct ioctl_str_t {
-       unsigned int    cmd;
-       const char     *str;
-} ioctl_str[] = {
-       {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
-       {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
-       {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
-       {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
-       {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
-       {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
-       {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
-       {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
-       {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
-       {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
-       {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
-       {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
-       {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
-       {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
-       {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
-       {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
-       {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
-       {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
-       {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
-       {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
-       {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
-       {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
-       {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
-       {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
-       {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
-       {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
-       {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
-       {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
-       {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
-       {OSS_GETVERSION, "OSS_GETVERSION"},
-       {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
-       {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
-       {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
-       {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
-};
-#endif
-
-// Need to hold a spin-lock before calling this!
-static int dma_count_done(struct dmabuf *db)
-{
-       if (db->stopped)
-               return 0;
-
-       return db->dma_fragsize - get_dma_residue(db->dmanr);
-}
-
-
-static int au1000_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-       unsigned long   flags;
-       audio_buf_info  abinfo;
-       count_info      cinfo;
-       int             count;
-       int             val, mapped, ret, diff;
-
-       mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-#ifdef AU1000_VERBOSE_DEBUG
-       for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
-               if (ioctl_str[count].cmd == cmd)
-                       break;
-       }
-       if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
-               dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
-       else
-               dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
-#endif
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *) arg);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, file->f_flags & O_NONBLOCK);
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-                               DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
-
-       case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq();
-                       s->dma_dac.count = s->dma_dac.total_bytes = 0;
-                       s->dma_dac.nextIn = s->dma_dac.nextOut =
-                               s->dma_dac.rawbuf;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq();
-                       s->dma_adc.count = s->dma_adc.total_bytes = 0;
-                       s->dma_adc.nextIn = s->dma_adc.nextOut =
-                               s->dma_adc.rawbuf;
-               }
-               return 0;
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               set_dac_rate(s, val);
-                       }
-                       if (s->open_mode & FMODE_READ)
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       if (s->open_mode & FMODE_WRITE)
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-               }
-               return put_user((file->f_mode & FMODE_READ) ?
-                               s->dma_adc.sample_rate :
-                               s->dma_dac.sample_rate,
-                               (int *)arg);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.num_channels = val ? 2 : 1;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.num_channels = val ? 2 : 1;
-                       if (s->codec_ext_caps & AC97_EXT_DACS) {
-                               // disable surround and center/lfe in AC'97
-                               u16 ext_stat = rdcodec(&s->codec,
-                                                      AC97_EXTENDED_STATUS);
-                               wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-                                       ext_stat | (AC97_EXTSTAT_PRI |
-                                                   AC97_EXTSTAT_PRJ |
-                                                   AC97_EXTSTAT_PRK));
-                       }
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               if (val < 0 || val > 2)
-                                       return -EINVAL;
-                               stop_adc(s);
-                               s->dma_adc.num_channels = val;
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               switch (val) {
-                               case 1:
-                               case 2:
-                                       break;
-                               case 3:
-                               case 5:
-                                       return -EINVAL;
-                               case 4:
-                                       if (!(s->codec_ext_caps &
-                                             AC97_EXTID_SDAC))
-                                               return -EINVAL;
-                                       break;
-                               case 6:
-                                       if ((s->codec_ext_caps &
-                                            AC97_EXT_DACS) != AC97_EXT_DACS)
-                                               return -EINVAL;
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
-
-                               stop_dac(s);
-                               if (val <= 2 &&
-                                   (s->codec_ext_caps & AC97_EXT_DACS)) {
-                                       // disable surround and center/lfe
-                                       // channels in AC'97
-                                       u16             ext_stat =
-                                               rdcodec(&s->codec,
-                                                       AC97_EXTENDED_STATUS);
-                                       wrcodec(&s->codec,
-                                               AC97_EXTENDED_STATUS,
-                                               ext_stat | (AC97_EXTSTAT_PRI |
-                                                           AC97_EXTSTAT_PRJ |
-                                                           AC97_EXTSTAT_PRK));
-                               } else if (val >= 4) {
-                                       // enable surround, center/lfe
-                                       // channels in AC'97
-                                       u16             ext_stat =
-                                               rdcodec(&s->codec,
-                                                       AC97_EXTENDED_STATUS);
-                                       ext_stat &= ~AC97_EXTSTAT_PRJ;
-                                       if (val == 6)
-                                               ext_stat &=
-                                                       ~(AC97_EXTSTAT_PRI |
-                                                         AC97_EXTSTAT_PRK);
-                                       wrcodec(&s->codec,
-                                               AC97_EXTENDED_STATUS,
-                                               ext_stat);
-                               }
-
-                               s->dma_dac.num_channels = val;
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               }
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_GETFMTS:        /* Returns a mask */
-               return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               if (val == AFMT_S16_LE)
-                                       s->dma_adc.sample_size = 16;
-                               else {
-                                       val = AFMT_U8;
-                                       s->dma_adc.sample_size = 8;
-                               }
-                               if ((ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               if (val == AFMT_S16_LE)
-                                       s->dma_dac.sample_size = 16;
-                               else {
-                                       val = AFMT_U8;
-                                       s->dma_dac.sample_size = 8;
-                               }
-                               if ((ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                       }
-               } else {
-                       if (file->f_mode & FMODE_READ)
-                               val = (s->dma_adc.sample_size == 16) ?
-                                       AFMT_S16_LE : AFMT_U8;
-                       else
-                               val = (s->dma_dac.sample_size == 16) ?
-                                       AFMT_S16_LE : AFMT_U8;
-               }
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_POST:
-               return 0;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               spin_lock_irqsave(&s->lock, flags);
-               if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
-                       val |= PCM_ENABLE_OUTPUT;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, (int *) arg);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT)
-                               start_adc(s);
-                       else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT)
-                               start_dac(s);
-                       else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               abinfo.fragsize = s->dma_dac.fragsize;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               count -= dma_count_done(&s->dma_dac);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               abinfo.bytes = (s->dma_dac.dmasize - count) /
-                       s->dma_dac.cnt_factor;
-               abinfo.fragstotal = s->dma_dac.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-#ifdef AU1000_VERBOSE_DEBUG
-               dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
-#endif
-               return copy_to_user((void *) arg, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               abinfo.fragsize = s->dma_adc.fragsize;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_adc.count;
-               count += dma_count_done(&s->dma_adc);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               abinfo.bytes = count / s->dma_adc.cnt_factor;
-               abinfo.fragstotal = s->dma_adc.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-               return copy_to_user((void *) arg, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               count -= dma_count_done(&s->dma_dac);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               count /= s->dma_dac.cnt_factor;
-               return put_user(count, (int *) arg);
-
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (!s->dma_adc.stopped) {
-                       diff = dma_count_done(&s->dma_adc);
-                       count += diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
-                               s->dma_adc.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
-                               s->dma_adc.dmaaddr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_adc.fragshift;
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (!s->dma_dac.stopped) {
-                       diff = dma_count_done(&s->dma_dac);
-                       count -= diff;
-                       cinfo.bytes += diff;
-                       cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
-                               s->dma_dac.dmaaddr;
-               } else
-                       cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
-                               s->dma_dac.dmaaddr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               cinfo.blocks = count >> s->dma_dac.fragshift;
-               return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->dma_dac.fragsize, (int *) arg);
-               else
-                       return put_user(s->dma_adc.fragsize, (int *) arg);
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-               if (get_user(val, (int *) arg))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.subdivision = val;
-                       if ((ret = prog_dmabuf_adc(s)))
-                               return ret;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.subdivision = val;
-                       if ((ret = prog_dmabuf_dac(s)))
-                               return ret;
-               }
-               return 0;
-
-       case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ?
-                               s->dma_adc.sample_rate :
-                               s->dma_dac.sample_rate,
-                               (int *)arg);
-
-       case SOUND_PCM_READ_CHANNELS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->dma_adc.num_channels, (int *)arg);
-               else
-                       return put_user(s->dma_dac.num_channels, (int *)arg);
-
-       case SOUND_PCM_READ_BITS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->dma_adc.sample_size, (int *)arg);
-               else
-                       return put_user(s->dma_dac.sample_size, (int *)arg);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-
-       return mixdev_ioctl(&s->codec, cmd, arg);
-}
-
-
-static int  au1000_open(struct inode *inode, struct file *file)
-{
-       int             minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct au1000_state *s = &au1000_state;
-       int             ret;
-
-#ifdef AU1000_VERBOSE_DEBUG
-       if (file->f_flags & O_NONBLOCK)
-               dbg("%s: non-blocking", __FUNCTION__);
-       else
-               dbg("%s: blocking", __FUNCTION__);
-#endif
-       
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-
-       stop_dac(s);
-       stop_adc(s);
-
-       if (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-                       s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
-               s->dma_adc.num_channels = 1;
-               s->dma_adc.sample_size = 8;
-               set_adc_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->dma_adc.sample_size = 16;
-       }
-
-       if (file->f_mode & FMODE_WRITE) {
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-                       s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
-               s->dma_dac.num_channels = 1;
-               s->dma_dac.sample_size = 8;
-               set_dac_rate(s, 8000);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->dma_dac.sample_size = 16;
-       }
-
-       if (file->f_mode & FMODE_READ) {
-               if ((ret = prog_dmabuf_adc(s)))
-                       return ret;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)))
-                       return ret;
-       }
-
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       mutex_init(&s->sem);
-       return nonseekable_open(inode, file);
-}
-
-static int au1000_release(struct inode *inode, struct file *file)
-{
-       struct au1000_state *s = (struct au1000_state *)file->private_data;
-
-       lock_kernel();
-       
-       if (file->f_mode & FMODE_WRITE) {
-               unlock_kernel();
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-               lock_kernel();
-       }
-
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const */ struct file_operations au1000_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = au1000_llseek,
-       .read           = au1000_read,
-       .write          = au1000_write,
-       .poll           = au1000_poll,
-       .ioctl          = au1000_ioctl,
-       .mmap           = au1000_mmap,
-       .open           = au1000_open,
-       .release        = au1000_release,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-
-/* --------------------------------------------------------------------- */
-
-/*
- * for debugging purposes, we'll create a proc device that dumps the
- * CODEC chipstate
- */
-
-#ifdef AU1000_DEBUG
-static int proc_au1000_dump(char *buf, char **start, off_t fpos,
-                           int length, int *eof, void *data)
-{
-       struct au1000_state *s = &au1000_state;
-       int             cnt, len = 0;
-
-       /* print out header */
-       len += sprintf(buf + len, "\n\t\tAU1000 Audio Debug\n\n");
-
-       // print out digital controller state
-       len += sprintf(buf + len, "AU1000 Audio Controller registers\n");
-       len += sprintf(buf + len, "---------------------------------\n");
-       len += sprintf (buf + len, "AC97C_CONFIG = %08x\n",
-                       au_readl(AC97C_CONFIG));
-       len += sprintf (buf + len, "AC97C_STATUS = %08x\n",
-                       au_readl(AC97C_STATUS));
-       len += sprintf (buf + len, "AC97C_CNTRL  = %08x\n",
-                       au_readl(AC97C_CNTRL));
-
-       /* print out CODEC state */
-       len += sprintf(buf + len, "\nAC97 CODEC registers\n");
-       len += sprintf(buf + len, "----------------------\n");
-       for (cnt = 0; cnt <= 0x7e; cnt += 2)
-               len += sprintf(buf + len, "reg %02x = %04x\n",
-                              cnt, rdcodec(&s->codec, cnt));
-
-       if (fpos >= len) {
-               *start = buf;
-               *eof = 1;
-               return 0;
-       }
-       *start = buf + fpos;
-       if ((len -= fpos) > length)
-               return length;
-       *eof = 1;
-       return len;
-
-}
-#endif /* AU1000_DEBUG */
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
-MODULE_DESCRIPTION("Au1000 Audio Driver");
-
-/* --------------------------------------------------------------------- */
-
-static int __devinit au1000_probe(void)
-{
-       struct au1000_state *s = &au1000_state;
-       int             val;
-#ifdef AU1000_DEBUG
-       char            proc_str[80];
-#endif
-
-       memset(s, 0, sizeof(struct au1000_state));
-
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->codec.private_data = s;
-       s->codec.id = 0;
-       s->codec.codec_read = rdcodec;
-       s->codec.codec_write = wrcodec;
-       s->codec.codec_wait = waitcodec;
-
-       if (!request_mem_region(CPHYSADDR(AC97C_CONFIG),
-                           0x14, AU1000_MODULE_NAME)) {
-               err("AC'97 ports in use");
-               return -1;
-       }
-       // Allocate the DMA Channels
-       if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
-                                                  "audio DAC",
-                                                  dac_dma_interrupt,
-                                                  IRQF_DISABLED, s)) < 0) {
-               err("Can't get DAC DMA");
-               goto err_dma1;
-       }
-       if ((s->dma_adc.dmanr = request_au1000_dma(DMA_ID_AC97C_RX,
-                                                  "audio ADC",
-                                                  adc_dma_interrupt,
-                                                  IRQF_DISABLED, s)) < 0) {
-               err("Can't get ADC DMA");
-               goto err_dma2;
-       }
-
-       info("DAC: DMA%d/IRQ%d, ADC: DMA%d/IRQ%d",
-            s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
-            s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
-
-       // enable DMA coherency in read/write DMA channels
-       set_dma_mode(s->dma_dac.dmanr,
-                    get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
-       set_dma_mode(s->dma_adc.dmanr,
-                    get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
-
-       /* register devices */
-
-       if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
-               goto err_dev1;
-       if ((s->codec.dev_mixer =
-            register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
-               goto err_dev2;
-
-#ifdef AU1000_DEBUG
-       /* intialize the debug proc device */
-       s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
-                                      proc_au1000_dump, NULL);
-#endif /* AU1000_DEBUG */
-
-       // configure pins for AC'97
-       au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
-
-       // Assert reset for 10msec to the AC'97 controller, and enable clock
-       au_writel(AC97C_RS | AC97C_CE, AC97C_CNTRL);
-       au1000_delay(10);
-       au_writel(AC97C_CE, AC97C_CNTRL);
-       au1000_delay(10);       // wait for clock to stabilize
-
-       /* cold reset the AC'97 */
-       au_writel(AC97C_RESET, AC97C_CONFIG);
-       au1000_delay(10);
-       au_writel(0, AC97C_CONFIG);
-       /* need to delay around 500msec(bleech) to give
-          some CODECs enough time to wakeup */
-       au1000_delay(500);
-
-       /* warm reset the AC'97 to start the bitclk */
-       au_writel(AC97C_SG | AC97C_SYNC, AC97C_CONFIG);
-       udelay(100);
-       au_writel(0, AC97C_CONFIG);
-
-       /* codec init */
-       if (!ac97_probe_codec(&s->codec))
-               goto err_dev3;
-
-       s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
-       s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
-       info("AC'97 Base/Extended ID = %04x/%04x",
-            s->codec_base_caps, s->codec_ext_caps);
-
-       /*
-        * On the Pb1000, audio playback is on the AUX_OUT
-        * channel (which defaults to LNLVL_OUT in AC'97
-        * rev 2.2) so make sure this channel is listed
-        * as supported (soundcard.h calls this channel
-        * ALTPCM). ac97_codec.c does not handle detection
-        * of this channel correctly.
-        */
-       s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
-       /*
-        * Now set AUX_OUT's default volume.
-        */
-       val = 0x4343;
-       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
-                    (unsigned long) &val);
-       
-       if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
-               // codec does not support VRA
-               s->no_vra = 1;
-       } else if (!vra) {
-               // Boot option says disable VRA
-               u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
-               wrcodec(&s->codec, AC97_EXTENDED_STATUS,
-                       ac97_extstat & ~AC97_EXTSTAT_VRA);
-               s->no_vra = 1;
-       }
-       if (s->no_vra)
-               info("no VRA, interpolating and decimating");
-
-       /* set mic to be the recording source */
-       val = SOUND_MASK_MIC;
-       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
-                    (unsigned long) &val);
-
-#ifdef AU1000_DEBUG
-       sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
-               s->codec.id);
-       s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
-                                            ac97_read_proc, &s->codec);
-#endif
-
-#ifdef CONFIG_MIPS_XXS1500
-       /* deassert eapd */
-       wrcodec(&s->codec, AC97_POWER_CONTROL,
-                       rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000);
-       /* mute a number of signals which seem to be causing problems
-        * if not muted.
-        */
-       wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000);
-       wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008);
-       wrcodec(&s->codec, AC97_MIC_VOL, 0x8008);
-       wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_CD_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_AUX_VOL, 0x8808);
-       wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808);
-       wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000);
-#endif
-
-       return 0;
-
- err_dev3:
-       unregister_sound_mixer(s->codec.dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       free_au1000_dma(s->dma_adc.dmanr);
- err_dma2:
-       free_au1000_dma(s->dma_dac.dmanr);
- err_dma1:
-       release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-       return -1;
-}
-
-static void au1000_remove(void)
-{
-       struct au1000_state *s = &au1000_state;
-
-       if (!s)
-               return;
-#ifdef AU1000_DEBUG
-       if (s->ps)
-               remove_proc_entry(AU1000_MODULE_NAME, NULL);
-#endif /* AU1000_DEBUG */
-       synchronize_irq();
-       free_au1000_dma(s->dma_adc.dmanr);
-       free_au1000_dma(s->dma_dac.dmanr);
-       release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->codec.dev_mixer);
-}
-
-static int __init init_au1000(void)
-{
-       info("stevel@mvista.com, built " __TIME__ " on " __DATE__);
-       return au1000_probe();
-}
-
-static void __exit cleanup_au1000(void)
-{
-       info("unloading");
-       au1000_remove();
-}
-
-module_init(init_au1000);
-module_exit(cleanup_au1000);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-static int __init au1000_setup(char *options)
-{
-       char           *this_opt;
-
-       if (!options || !*options)
-               return 0;
-
-       while ((this_opt = strsep(&options, ","))) {
-               if (!*this_opt)
-                       continue;
-               if (!strncmp(this_opt, "vra", 3)) {
-                       vra = 1;
-               }
-       }
-
-       return 1;
-}
-
-__setup("au1000_audio=", au1000_setup);
-
-#endif /* MODULE */
index 5da217fcbedde28e0041e3c1395eda922e17299d..3919e4d6b3f38adf70d70a405b8db6aab0ec90ed 100644 (file)
@@ -10,7 +10,5 @@ char audio_syms_symbol;
 #include "sound_calls.h"
 
 EXPORT_SYMBOL(DMAbuf_start_dma);
-EXPORT_SYMBOL(DMAbuf_open_dma);
-EXPORT_SYMBOL(DMAbuf_close_dma);
 EXPORT_SYMBOL(DMAbuf_inputintr);
 EXPORT_SYMBOL(DMAbuf_outputintr);
diff --git a/sound/oss/awe_hw.h b/sound/oss/awe_hw.h
deleted file mode 100644 (file)
index ab00c3c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * sound/oss/awe_hw.h
- *
- * Access routines and definitions for the low level driver for the 
- * Creative AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AWE_HW_H_DEF
-#define AWE_HW_H_DEF
-
-/*
- * Emu-8000 control registers
- * name(channel)       reg, port
- */
-
-#define awe_cmd_idx(reg,ch)    (((reg)<< 5) | (ch))
-
-#define Data0    0             /* 0x620: doubleword r/w */
-#define Data1    1             /* 0xA20: doubleword r/w */
-#define Data2    2             /* 0xA22: word r/w */
-#define Data3    3             /* 0xE20: word r/w */
-#define Pointer  4             /* 0xE22 register pointer r/w */
-
-#define AWE_CPF(ch)    awe_cmd_idx(0,ch), Data0        /* DW: current pitch and fractional address */
-#define AWE_PTRX(ch)   awe_cmd_idx(1,ch), Data0        /* DW: pitch target and reverb send */
-#define AWE_CVCF(ch)   awe_cmd_idx(2,ch), Data0        /* DW: current volume and filter cutoff */
-#define AWE_VTFT(ch)   awe_cmd_idx(3,ch), Data0        /* DW: volume and filter cutoff targets */
-#define AWE_0080(ch)   awe_cmd_idx(4,ch), Data0        /* DW: ?? */
-#define AWE_00A0(ch)   awe_cmd_idx(5,ch), Data0        /* DW: ?? */
-#define AWE_PSST(ch)   awe_cmd_idx(6,ch), Data0        /* DW: pan send and loop start address */
-#define AWE_CSL(ch)    awe_cmd_idx(7,ch), Data0        /* DW: chorus send and loop end address */
-#define AWE_CCCA(ch)   awe_cmd_idx(0,ch), Data1        /* DW: Q, control bits, and current address */
-#define AWE_HWCF4      awe_cmd_idx(1,9),  Data1        /* DW: config dw 4 */
-#define AWE_HWCF5      awe_cmd_idx(1,10), Data1        /* DW: config dw 5 */
-#define AWE_HWCF6      awe_cmd_idx(1,13), Data1        /* DW: config dw 6 */
-#define AWE_HWCF7      awe_cmd_idx(1,14), Data1        /* DW: config dw 7? (not documented) */
-#define AWE_SMALR      awe_cmd_idx(1,20), Data1        /* DW: sound memory address for left read */
-#define AWE_SMARR      awe_cmd_idx(1,21), Data1        /* DW:    for right read */
-#define AWE_SMALW      awe_cmd_idx(1,22), Data1        /* DW: sound memory address for left write */
-#define AWE_SMARW      awe_cmd_idx(1,23), Data1        /* DW:    for right write */
-#define AWE_SMLD       awe_cmd_idx(1,26), Data1        /* W: sound memory left data */
-#define AWE_SMRD       awe_cmd_idx(1,26), Data2        /* W:    right data */
-#define AWE_WC         awe_cmd_idx(1,27), Data2        /* W: sample counter */
-#define AWE_WC_Cmd     awe_cmd_idx(1,27)
-#define AWE_WC_Port    Data2
-#define AWE_HWCF1      awe_cmd_idx(1,29), Data1        /* W: config w 1 */
-#define AWE_HWCF2      awe_cmd_idx(1,30), Data1        /* W: config w 2 */
-#define AWE_HWCF3      awe_cmd_idx(1,31), Data1        /* W: config w 3 */
-#define AWE_INIT1(ch)  awe_cmd_idx(2,ch), Data1        /* W: init array 1 */
-#define AWE_INIT2(ch)  awe_cmd_idx(2,ch), Data2        /* W: init array 2 */
-#define AWE_INIT3(ch)  awe_cmd_idx(3,ch), Data1        /* W: init array 3 */
-#define AWE_INIT4(ch)  awe_cmd_idx(3,ch), Data2        /* W: init array 4 */
-#define AWE_ENVVOL(ch) awe_cmd_idx(4,ch), Data1        /* W: volume envelope delay */
-#define AWE_DCYSUSV(ch)        awe_cmd_idx(5,ch), Data1        /* W: volume envelope sustain and decay */
-#define AWE_ENVVAL(ch) awe_cmd_idx(6,ch), Data1        /* W: modulation envelope delay */
-#define AWE_DCYSUS(ch) awe_cmd_idx(7,ch), Data1        /* W: modulation envelope sustain and decay */
-#define AWE_ATKHLDV(ch)        awe_cmd_idx(4,ch), Data2        /* W: volume envelope attack and hold */
-#define AWE_LFO1VAL(ch)        awe_cmd_idx(5,ch), Data2        /* W: LFO#1 Delay */
-#define AWE_ATKHLD(ch) awe_cmd_idx(6,ch), Data2        /* W: modulation envelope attack and hold */
-#define AWE_LFO2VAL(ch)        awe_cmd_idx(7,ch), Data2        /* W: LFO#2 Delay */
-#define AWE_IP(ch)     awe_cmd_idx(0,ch), Data3        /* W: initial pitch */
-#define AWE_IFATN(ch)  awe_cmd_idx(1,ch), Data3        /* W: initial filter cutoff and attenuation */
-#define AWE_PEFE(ch)   awe_cmd_idx(2,ch), Data3        /* W: pitch and filter envelope heights */
-#define AWE_FMMOD(ch)  awe_cmd_idx(3,ch), Data3        /* W: vibrato and filter modulation freq */
-#define AWE_TREMFRQ(ch)        awe_cmd_idx(4,ch), Data3        /* W: LFO#1 tremolo amount and freq */
-#define AWE_FM2FRQ2(ch)        awe_cmd_idx(5,ch), Data3        /* W: LFO#2 vibrato amount and freq */
-
-/* used during detection (returns ROM version?; not documented in ADIP) */
-#define AWE_U1         0xE0, Data3       /* (R)(W) used in initialization */
-#define AWE_U2(ch)     0xC0+(ch), Data3  /* (W)(W) used in init envelope  */
-
-
-#define AWE_MAX_VOICES         32
-#define AWE_NORMAL_VOICES      30      /*30&31 are reserved for DRAM refresh*/
-
-#define AWE_MAX_CHANNELS       32      /* max midi channels (must >= voices) */
-#define AWE_MAX_LAYERS AWE_MAX_VOICES  /* maximum number of multiple layers */
-
-#define AWE_DRAM_OFFSET                0x200000
-#define AWE_MAX_DRAM_SIZE      (28 * 1024)     /* 28 MB is max onboard memory */
-
-#endif
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
deleted file mode 100644 (file)
index 01c592c..0000000
+++ /dev/null
@@ -1,6149 +0,0 @@
-/*
- * sound/oss/awe_wave.c
- *
- * The low level driver for the AWE32/SB32/AWE64 wave table synth.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-2000 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Changelog:
- * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
- * - detection code rewrite
- */
-
-#include <linux/awe_voice.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/pnp.h>
-
-#include "sound_config.h"
-
-#include "awe_wave.h"
-#include "awe_hw.h"
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-#include "tuning.h"
-#include <linux/ultrasound.h>
-#endif
-
-/*
- * debug message
- */
-
-#ifdef AWE_DEBUG_ON
-#define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
-#define ERRMSG(XXX)    {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
-#define FATALERR(XXX)  XXX
-#else
-#define DEBUG(LVL,XXX) /**/
-#define ERRMSG(XXX)    XXX
-#define FATALERR(XXX)  XXX
-#endif
-
-/*
- * bank and voice record
- */
-
-typedef struct _sf_list sf_list;
-typedef struct _awe_voice_list awe_voice_list;
-typedef struct _awe_sample_list awe_sample_list;
-
-/* soundfont record */
-struct _sf_list {
-       unsigned short sf_id;   /* id number */
-       unsigned short type;    /* lock & shared flags */
-       int num_info;           /* current info table index */
-       int num_sample;         /* current sample table index */
-       int mem_ptr;            /* current word byte pointer */
-       awe_voice_list *infos, *last_infos;     /* instruments */
-       awe_sample_list *samples, *last_samples;        /* samples */
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       sf_list *shared;        /* shared list */
-       unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
-#endif
-       sf_list *next, *prev;
-};
-
-/* instrument list */
-struct _awe_voice_list {
-       awe_voice_info v;       /* instrument information */
-       sf_list *holder;        /* parent sf_list of this record */
-       unsigned char bank, instr;      /* preset number information */
-       char type, disabled;    /* type=normal/mapped, disabled=boolean */
-       awe_voice_list *next;   /* linked list with same sf_id */
-       awe_voice_list *next_instr;     /* instrument list */
-       awe_voice_list *next_bank;      /* hash table list */
-};
-
-/* voice list type */
-#define V_ST_NORMAL    0
-#define V_ST_MAPPED    1
-
-/* sample list */
-struct _awe_sample_list {
-       awe_sample_info v;      /* sample information */
-       sf_list *holder;        /* parent sf_list of this record */
-       awe_sample_list *next;  /* linked list with same sf_id */
-};
-
-/* sample and information table */
-static int current_sf_id;      /* current number of fonts */
-static int locked_sf_id;       /* locked position */
-static sf_list *sfhead, *sftail;       /* linked-lists */
-
-#define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
-#define awe_free_info() (sftail ? sftail->num_info : 0)
-#define awe_free_sample() (sftail ? sftail->num_sample : 0)
-
-#define AWE_MAX_PRESETS                256
-#define AWE_DEFAULT_PRESET     0
-#define AWE_DEFAULT_BANK       0
-#define AWE_DEFAULT_DRUM       0
-#define AWE_DRUM_BANK          128
-
-#define MAX_LAYERS     AWE_MAX_VOICES
-
-/* preset table index */
-static awe_voice_list *preset_table[AWE_MAX_PRESETS];
-
-/*
- * voice table
- */
-
-/* effects table */
-typedef        struct FX_Rec { /* channel effects */
-       unsigned char flags[AWE_FX_END];
-       short val[AWE_FX_END];
-} FX_Rec;
-
-
-/* channel parameters */
-typedef struct _awe_chan_info {
-       int channel;            /* channel number */
-       int bank;               /* current tone bank */
-       int instr;              /* current program */
-       int bender;             /* midi pitchbend (-8192 - 8192) */
-       int bender_range;       /* midi bender range (x100) */
-       int panning;            /* panning (0-127) */
-       int main_vol;           /* channel volume (0-127) */
-       int expression_vol;     /* midi expression (0-127) */
-       int chan_press;         /* channel pressure */
-       int sustained;          /* sustain status in MIDI */
-       FX_Rec fx;              /* effects */
-       FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
-} awe_chan_info;
-
-/* voice parameters */
-typedef struct _voice_info {
-       int state;
-#define AWE_ST_OFF             (1<<0)  /* no sound */
-#define AWE_ST_ON              (1<<1)  /* playing */
-#define AWE_ST_STANDBY         (1<<2)  /* stand by for playing */
-#define AWE_ST_SUSTAINED       (1<<3)  /* sustained */
-#define AWE_ST_MARK            (1<<4)  /* marked for allocation */
-#define AWE_ST_DRAM            (1<<5)  /* DRAM read/write */
-#define AWE_ST_FM              (1<<6)  /* reserved for FM */
-#define AWE_ST_RELEASED                (1<<7)  /* released */
-
-       int ch;                 /* midi channel */
-       int key;                /* internal key for search */
-       int layer;              /* layer number (for channel mode only) */
-       int time;               /* allocated time */
-       awe_chan_info   *cinfo; /* channel info */
-
-       int note;               /* midi key (0-127) */
-       int velocity;           /* midi velocity (0-127) */
-       int sostenuto;          /* sostenuto on/off */
-       awe_voice_info *sample; /* assigned voice */
-
-       /* EMU8000 parameters */
-       int apitch;             /* pitch parameter */
-       int avol;               /* volume parameter */
-       int apan;               /* panning parameter */
-       int acutoff;            /* cutoff parameter */
-       short aaux;             /* aux word */
-} voice_info;
-
-/* voice information */
-static voice_info voices[AWE_MAX_VOICES];
-
-#define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
-#define IS_NO_EFFECT(v)        (voices[v].state != AWE_ST_ON)
-#define IS_PLAYING(v)  (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
-#define IS_EMPTY(v)    (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
-
-
-/* MIDI channel effects information (for hw control) */
-static awe_chan_info channels[AWE_MAX_CHANNELS];
-
-
-/*
- * global variables
- */
-
-#ifndef AWE_DEFAULT_BASE_ADDR
-#define AWE_DEFAULT_BASE_ADDR  0       /* autodetect */
-#endif
-
-#ifndef AWE_DEFAULT_MEM_SIZE
-#define AWE_DEFAULT_MEM_SIZE   -1      /* autodetect */
-#endif
-
-static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
-static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
-#ifdef CONFIG_PNP
-static int isapnp = -1;
-#else
-static int isapnp;
-#endif
-
-MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
-MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "base i/o port of Emu8000");
-module_param(memsize, int, 0);
-MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
-module_param(isapnp, bool, 0);
-MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
-
-/* DRAM start offset */
-static int awe_mem_start = AWE_DRAM_OFFSET;
-
-/* maximum channels for playing */
-static int awe_max_voices = AWE_MAX_VOICES;
-
-static int patch_opened;               /* sample already loaded? */
-
-static char atten_relative = FALSE;
-static short atten_offset;
-
-static int awe_present = FALSE;                /* awe device present? */
-static int awe_busy = FALSE;           /* awe device opened? */
-
-static int my_dev = -1;
-
-#define DEFAULT_DRUM_FLAGS     ((1 << 9) | (1 << 25))
-#define IS_DRUM_CHANNEL(c)     (drum_flags & (1 << (c)))
-#define DRUM_CHANNEL_ON(c)     (drum_flags |= (1 << (c)))
-#define DRUM_CHANNEL_OFF(c)    (drum_flags &= ~(1 << (c)))
-static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
-
-static int playing_mode = AWE_PLAY_INDIRECT;
-#define SINGLE_LAYER_MODE()    (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
-#define MULTI_LAYER_MODE()     (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
-
-static int current_alloc_time;         /* voice allocation index for channel mode */
-
-static struct synth_info awe_info = {
-       "AWE32 Synth",          /* name */
-       0,                      /* device */
-       SYNTH_TYPE_SAMPLE,      /* synth_type */
-       SAMPLE_TYPE_AWE32,      /* synth_subtype */
-       0,                      /* perc_mode (obsolete) */
-       AWE_MAX_VOICES,         /* nr_voices */
-       0,                      /* nr_drums (obsolete) */
-       400                     /* instr_bank_size */
-};
-
-
-static struct voice_alloc_info *voice_alloc;   /* set at initialization */
-
-
-/*
- * function prototypes
- */
-
-static int awe_request_region(void);
-static void awe_release_region(void);
-
-static void awe_reset_samples(void);
-/* emu8000 chip i/o access */
-static void setup_ports(int p1, int p2, int p3);
-static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
-static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
-static unsigned short awe_peek(unsigned short cmd, unsigned short port);
-static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
-static void awe_wait(unsigned short delay);
-
-/* initialize emu8000 chip */
-static void awe_initialize(void);
-
-/* set voice parameters */
-static void awe_init_ctrl_parms(int init_all);
-static void awe_init_voice_info(awe_voice_info *vp);
-static void awe_init_voice_parm(awe_voice_parm *pp);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int freq_to_note(int freq);
-static int calc_rate_offset(int Hz);
-/*static int calc_parm_delay(int msec);*/
-static int calc_parm_hold(int msec);
-static int calc_parm_attack(int msec);
-static int calc_parm_decay(int msec);
-static int calc_parm_search(int msec, short *table);
-#endif /* gus compat */
-
-/* turn on/off note */
-static void awe_note_on(int voice);
-static void awe_note_off(int voice);
-static void awe_terminate(int voice);
-static void awe_exclusive_off(int voice);
-static void awe_note_off_all(int do_sustain);
-
-/* calculate voice parameters */
-typedef void (*fx_affect_func)(int voice, int forced);
-static void awe_set_pitch(int voice, int forced);
-static void awe_set_voice_pitch(int voice, int forced);
-static void awe_set_volume(int voice, int forced);
-static void awe_set_voice_vol(int voice, int forced);
-static void awe_set_pan(int voice, int forced);
-static void awe_fx_fmmod(int voice, int forced);
-static void awe_fx_tremfrq(int voice, int forced);
-static void awe_fx_fm2frq2(int voice, int forced);
-static void awe_fx_filterQ(int voice, int forced);
-static void awe_calc_pitch(int voice);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_calc_pitch_from_freq(int voice, int freq);
-#endif
-static void awe_calc_volume(int voice);
-static void awe_update_volume(void);
-static void awe_change_master_volume(short val);
-static void awe_voice_init(int voice, int init_all);
-static void awe_channel_init(int ch, int init_all);
-static void awe_fx_init(int ch);
-static void awe_send_effect(int voice, int layer, int type, int val);
-static void awe_modwheel_change(int voice, int value);
-
-/* sequencer interface */
-static int awe_open(int dev, int mode);
-static void awe_close(int dev);
-static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
-static int awe_kill_note(int dev, int voice, int note, int velocity);
-static int awe_start_note(int dev, int v, int note_num, int volume);
-static int awe_set_instr(int dev, int voice, int instr_no);
-static int awe_set_instr_2(int dev, int voice, int instr_no);
-static void awe_reset(int dev);
-static void awe_hw_control(int dev, unsigned char *event);
-static int awe_load_patch(int dev, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag);
-static void awe_aftertouch(int dev, int voice, int pressure);
-static void awe_controller(int dev, int voice, int ctrl_num, int value);
-static void awe_panning(int dev, int voice, int value);
-static void awe_volume_method(int dev, int mode);
-static void awe_bender(int dev, int voice, int value);
-static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
-static void awe_setup_voice(int dev, int voice, int chn);
-
-#define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
-
-/* hardware controls */
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
-#endif
-static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
-static void awe_voice_change(int voice, fx_affect_func func);
-static void awe_sostenuto_on(int voice, int forced);
-static void awe_sustain_off(int voice, int forced);
-static void awe_terminate_and_init(int voice, int forced);
-
-/* voice search */
-static int awe_search_key(int bank, int preset, int note);
-static awe_voice_list *awe_search_instr(int bank, int preset, int note);
-static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
-static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
-static void awe_alloc_one_voice(int voice, int note, int velocity);
-static int awe_clear_voice(void);
-
-/* load / remove patches */
-static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
-static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag);
-#endif
-/*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/
-static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
-static sf_list *check_patch_opened(int type, char *name);
-static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
-static int awe_create_sf(int type, char *name);
-static void awe_free_sf(sf_list *sf);
-static void add_sf_info(sf_list *sf, awe_voice_list *rec);
-static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
-static void add_info_list(awe_voice_list *rec);
-static void awe_remove_samples(int sf_id);
-static void rebuild_preset_list(void);
-static short awe_set_sample(awe_voice_list *rec);
-static awe_sample_list *search_sample_index(sf_list *sf, int sample);
-
-static int is_identical_holder(sf_list *sf1, sf_list *sf2);
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-static int is_identical_name(unsigned char *name, sf_list *p);
-static int is_shared_sf(unsigned char *name);
-static int info_duplicated(sf_list *sf, awe_voice_list *rec);
-#endif /* allow sharing */
-
-/* lowlevel functions */
-static void awe_init_audio(void);
-static void awe_init_dma(void);
-static void awe_init_array(void);
-static void awe_send_array(unsigned short *data);
-static void awe_tweak_voice(int voice);
-static void awe_tweak(void);
-static void awe_init_fm(void);
-static int awe_open_dram_for_write(int offset, int channels);
-static void awe_open_dram_for_check(void);
-static void awe_close_dram(void);
-/*static void awe_write_dram(unsigned short c);*/
-static int awe_detect_base(int addr);
-static int awe_detect(void);
-static void awe_check_dram(void);
-static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_chorus_mode(int mode);
-static void awe_update_chorus_mode(void);
-static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
-static void awe_set_reverb_mode(int mode);
-static void awe_update_reverb_mode(void);
-static void awe_equalizer(int bass, int treble);
-static void awe_update_equalizer(void);
-
-#ifdef CONFIG_AWE32_MIXER
-static void attach_mixer(void);
-static void unload_mixer(void);
-#endif
-
-#ifdef CONFIG_AWE32_MIDIEMU
-static void attach_midiemu(void);
-static void unload_midiemu(void);
-#endif
-
-#define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
-
-/*
- * control parameters
- */
-
-
-#ifdef AWE_USE_NEW_VOLUME_CALC
-#define DEF_VOLUME_CALC        TRUE
-#else
-#define DEF_VOLUME_CALC        FALSE
-#endif /* new volume */
-
-#define DEF_ZERO_ATTEN         32      /* 12dB below */
-#define DEF_MOD_SENSE          18
-#define DEF_CHORUS_MODE                2
-#define DEF_REVERB_MODE                4
-#define DEF_BASS_LEVEL         5
-#define DEF_TREBLE_LEVEL       9
-
-static struct CtrlParmsDef {
-       int value;
-       int init_each_time;
-       void (*update)(void);
-} ctrl_parms[AWE_MD_END] = {
-       {0,0, NULL}, {0,0, NULL}, /* <-- not used */
-       {AWE_VERSION_NUMBER, FALSE, NULL},
-       {TRUE, FALSE, NULL}, /* exclusive */
-       {TRUE, FALSE, NULL}, /* realpan */
-       {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
-       {FALSE, TRUE, NULL}, /* keep effect */
-       {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
-       {FALSE, FALSE, NULL}, /* chn_prior */
-       {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
-       {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
-       {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
-       {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
-       {FALSE, FALSE, NULL}, /* toggle_drum_bank */
-       {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
-       {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
-       {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
-       {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
-       {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
-       {0, FALSE, NULL},       /* debug mode */
-       {FALSE, FALSE, NULL}, /* pan exchange */
-};
-
-static int ctrls[AWE_MD_END];
-
-
-/*
- * synth operation table
- */
-
-static struct synth_operations awe_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "EMU8K",
-       .info           = &awe_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_AWE32,
-       .open           = awe_open,
-       .close          = awe_close,
-       .ioctl          = awe_ioctl,
-       .kill_note      = awe_kill_note,
-       .start_note     = awe_start_note,
-       .set_instr      = awe_set_instr_2,
-       .reset          = awe_reset,
-       .hw_control     = awe_hw_control,
-       .load_patch     = awe_load_patch,
-       .aftertouch     = awe_aftertouch,
-       .controller     = awe_controller,
-       .panning        = awe_panning,
-       .volume_method  = awe_volume_method,
-       .bender         = awe_bender,
-       .alloc_voice    = awe_alloc,
-       .setup_voice    = awe_setup_voice
-};
-
-static void free_tables(void)
-{
-       if (sftail) {
-               sf_list *p, *prev;
-               for (p = sftail; p; p = prev) {
-                       prev = p->prev;
-                       awe_free_sf(p);
-               }
-       }
-       sfhead = sftail = NULL;
-}
-
-/*
- * clear sample tables 
- */
-
-static void
-awe_reset_samples(void)
-{
-       /* free all bank tables */
-       memset(preset_table, 0, sizeof(preset_table));
-       free_tables();
-
-       current_sf_id = 0;
-       locked_sf_id = 0;
-       patch_opened = 0;
-}
-
-
-/*
- * EMU register access
- */
-
-/* select a given AWE32 pointer */
-static int awe_ports[5];
-static int port_setuped = FALSE;
-static int awe_cur_cmd = -1;
-#define awe_set_cmd(cmd) \
-if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
-
-/* write 16bit data */
-static void
-awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
-{
-       awe_set_cmd(cmd);
-       outw(data, awe_ports[port]);
-}
-
-/* write 32bit data */
-static void
-awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
-{
-       unsigned short addr = awe_ports[port];
-       awe_set_cmd(cmd);
-       outw(data, addr);               /* write lower 16 bits */
-       outw(data >> 16, addr + 2);     /* write higher 16 bits */
-}
-
-/* read 16bit data */
-static unsigned short
-awe_peek(unsigned short cmd, unsigned short port)
-{
-       unsigned short k;
-       awe_set_cmd(cmd);
-       k = inw(awe_ports[port]);
-       return k;
-}
-
-/* read 32bit data */
-static unsigned int
-awe_peek_dw(unsigned short cmd, unsigned short port)
-{
-       unsigned int k1, k2;
-       unsigned short addr = awe_ports[port];
-       awe_set_cmd(cmd);
-       k1 = inw(addr);
-       k2 = inw(addr + 2);
-       k1 |= k2 << 16;
-       return k1;
-}
-
-/* wait delay number of AWE32 44100Hz clocks */
-#ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
-static void
-awe_wait(unsigned short delay)
-{
-       unsigned short clock, target;
-       unsigned short port = awe_ports[AWE_WC_Port];
-       int counter;
-  
-       /* sample counter */
-       awe_set_cmd(AWE_WC_Cmd);
-       clock = (unsigned short)inw(port);
-       target = clock + delay;
-       counter = 0;
-       if (target < clock) {
-               for (; (unsigned short)inw(port) > target; counter++)
-                       if (counter > 65536)
-                               break;
-       }
-       for (; (unsigned short)inw(port) < target; counter++)
-               if (counter > 65536)
-                       break;
-}
-#else
-
-static void awe_wait(unsigned short delay)
-{
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
-}
-/*
-static void awe_wait(unsigned short delay)
-{
-       udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
-}
-*/
-#endif /* wait by loop */
-
-/* write a word data */
-#define awe_write_dram(c)      awe_poke(AWE_SMLD, c)
-
-/*
- * AWE32 voice parameters
- */
-
-/* initialize voice_info record */
-static void
-awe_init_voice_info(awe_voice_info *vp)
-{
-       vp->sample = 0;
-       vp->rate_offset = 0;
-
-       vp->start = 0;
-       vp->end = 0;
-       vp->loopstart = 0;
-       vp->loopend = 0;
-       vp->mode = 0;
-       vp->root = 60;
-       vp->tune = 0;
-       vp->low = 0;
-       vp->high = 127;
-       vp->vellow = 0;
-       vp->velhigh = 127;
-
-       vp->fixkey = -1;
-       vp->fixvel = -1;
-       vp->fixpan = -1;
-       vp->pan = -1;
-
-       vp->exclusiveClass = 0;
-       vp->amplitude = 127;
-       vp->attenuation = 0;
-       vp->scaleTuning = 100;
-
-       awe_init_voice_parm(&vp->parm);
-}
-
-/* initialize voice_parm record:
- * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
- * Vibrato and Tremolo effects are zero.
- * Cutoff is maximum.
- * Chorus and Reverb effects are zero.
- */
-static void
-awe_init_voice_parm(awe_voice_parm *pp)
-{
-       pp->moddelay = 0x8000;
-       pp->modatkhld = 0x7f7f;
-       pp->moddcysus = 0x7f7f;
-       pp->modrelease = 0x807f;
-       pp->modkeyhold = 0;
-       pp->modkeydecay = 0;
-
-       pp->voldelay = 0x8000;
-       pp->volatkhld = 0x7f7f;
-       pp->voldcysus = 0x7f7f;
-       pp->volrelease = 0x807f;
-       pp->volkeyhold = 0;
-       pp->volkeydecay = 0;
-
-       pp->lfo1delay = 0x8000;
-       pp->lfo2delay = 0x8000;
-       pp->pefe = 0;
-
-       pp->fmmod = 0;
-       pp->tremfrq = 0;
-       pp->fm2frq2 = 0;
-
-       pp->cutoff = 0xff;
-       pp->filterQ = 0;
-
-       pp->chorus = 0;
-       pp->reverb = 0;
-}      
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* convert frequency mHz to abstract cents (= midi key * 100) */
-static int
-freq_to_note(int mHz)
-{
-       /* abscents = log(mHz/8176) / log(2) * 1200 */
-       unsigned int max_val = (unsigned int)0xffffffff / 10000;
-       int i, times;
-       unsigned int base;
-       unsigned int freq;
-       int note, tune;
-
-       if (mHz == 0)
-               return 0;
-       if (mHz < 0)
-               return 12799; /* maximum */
-
-       freq = mHz;
-       note = 0;
-       for (base = 8176 * 2; freq >= base; base *= 2) {
-               note += 12;
-               if (note >= 128) /* over maximum */
-                       return 12799;
-       }
-       base /= 2;
-
-       /* to avoid overflow... */
-       times = 10000;
-       while (freq > max_val) {
-               max_val *= 10;
-               times /= 10;
-               base /= 10;
-       }
-
-       freq = freq * times / base;
-       for (i = 0; i < 12; i++) {
-               if (freq < semitone_tuning[i+1])
-                       break;
-               note++;
-       }
-
-       tune = 0;
-       freq = freq * 10000 / semitone_tuning[i];
-       for (i = 0; i < 100; i++) {
-               if (freq < cent_tuning[i+1])
-                       break;
-               tune++;
-       }
-
-       return note * 100 + tune;
-}
-
-
-/* convert Hz to AWE32 rate offset:
- * sample pitch offset for the specified sample rate
- * rate=44100 is no offset, each 4096 is 1 octave (twice).
- * eg, when rate is 22050, this offset becomes -4096.
- */
-static int
-calc_rate_offset(int Hz)
-{
-       /* offset = log(Hz / 44100) / log(2) * 4096 */
-       int freq, base, i;
-
-       /* maybe smaller than max (44100Hz) */
-       if (Hz <= 0 || Hz >= 44100) return 0;
-
-       base = 0;
-       for (freq = Hz * 2; freq < 44100; freq *= 2)
-               base++;
-       base *= 1200;
-
-       freq = 44100 * 10000 / (freq/2);
-       for (i = 0; i < 12; i++) {
-               if (freq < semitone_tuning[i+1])
-                       break;
-               base += 100;
-       }
-       freq = freq * 10000 / semitone_tuning[i];
-       for (i = 0; i < 100; i++) {
-               if (freq < cent_tuning[i+1])
-                       break;
-               base++;
-       }
-       return -base * 4096 / 1200;
-}
-
-
-/*
- * convert envelope time parameter to AWE32 raw parameter
- */
-
-/* attack & decay/release time table (msec) */
-static short attack_time_tbl[128] = {
-32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
-707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
-361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
-180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
-90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
-45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
-22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
-11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
-};
-
-static short decay_time_tbl[128] = {
-32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
-2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
-1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
-691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
-345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
-172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
-86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
-43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
-};
-
-#define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
-
-/* delay time = 0x8000 - msec/92 */
-static int
-calc_parm_hold(int msec)
-{
-       int val = (0x7f * 92 - msec) / 92;
-       if (val < 1) val = 1;
-       if (val > 127) val = 127;
-       return val;
-}
-
-/* attack time: search from time table */
-static int
-calc_parm_attack(int msec)
-{
-       return calc_parm_search(msec, attack_time_tbl);
-}
-
-/* decay/release time: search from time table */
-static int
-calc_parm_decay(int msec)
-{
-       return calc_parm_search(msec, decay_time_tbl);
-}
-
-/* search an index for specified time from given time table */
-static int
-calc_parm_search(int msec, short *table)
-{
-       int left = 1, right = 127, mid;
-       while (left < right) {
-               mid = (left + right) / 2;
-               if (msec < (int)table[mid])
-                       left = mid + 1;
-               else
-                       right = mid;
-       }
-       return left;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * effects table
- */
-
-/* set an effect value */
-#define FX_FLAG_OFF    0
-#define FX_FLAG_SET    1
-#define FX_FLAG_ADD    2
-
-#define FX_SET(rec,type,value) \
-       ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
-#define FX_ADD(rec,type,value) \
-       ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
-#define FX_UNSET(rec,type) \
-       ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
-
-/* check the effect value is set */
-#define FX_ON(rec,type)        ((rec)->flags[type])
-
-#define PARM_BYTE      0
-#define PARM_WORD      1
-#define PARM_SIGN      2
-
-static struct PARM_DEFS {
-       int type;       /* byte or word */
-       int low, high;  /* value range */
-       fx_affect_func realtime;        /* realtime paramater change */
-} parm_defs[] = {
-       {PARM_WORD, 0, 0x8000, NULL},   /* env1 delay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 attack */
-       {PARM_BYTE, 0, 0x7e, NULL},     /* env1 hold */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 decay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env1 release */
-       {PARM_BYTE, 0, 0x7f, NULL},     /* env1 sustain */
-       {PARM_BYTE, 0, 0xff, NULL},     /* env1 pitch */
-       {PARM_BYTE, 0, 0xff, NULL},     /* env1 cutoff */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* env2 delay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 attack */
-       {PARM_BYTE, 0, 0x7e, NULL},     /* env2 hold */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 decay */
-       {PARM_BYTE, 1, 0x7f, NULL},     /* env2 release */
-       {PARM_BYTE, 0, 0x7f, NULL},     /* env2 sustain */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* lfo1 delay */
-       {PARM_BYTE, 0, 0xff, awe_fx_tremfrq},   /* lfo1 freq */
-       {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
-       {PARM_SIGN, -128, 127, awe_fx_fmmod},   /* lfo1 pitch */
-       {PARM_BYTE, 0, 0xff, awe_fx_fmmod},     /* lfo1 cutoff */
-
-       {PARM_WORD, 0, 0x8000, NULL},   /* lfo2 delay */
-       {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2},   /* lfo2 freq */
-       {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
-
-       {PARM_WORD, 0, 0xffff, awe_set_voice_pitch},    /* initial pitch */
-       {PARM_BYTE, 0, 0xff, NULL},     /* chorus */
-       {PARM_BYTE, 0, 0xff, NULL},     /* reverb */
-       {PARM_BYTE, 0, 0xff, awe_set_volume},   /* initial cutoff */
-       {PARM_BYTE, 0, 15, awe_fx_filterQ},     /* initial resonance */
-
-       {PARM_WORD, 0, 0xffff, NULL},   /* sample start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* loop start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* loop end */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse sample start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse loop start */
-       {PARM_WORD, 0, 0xffff, NULL},   /* coarse loop end */
-       {PARM_BYTE, 0, 0xff, awe_set_volume},   /* initial attenuation */
-};
-
-
-static unsigned char
-FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
-{
-       int effect = 0;
-       int on = 0;
-       if (lay && (on = FX_ON(lay, type)) != 0)
-               effect = lay->val[type];
-       if (!on && (on = FX_ON(rec, type)) != 0)
-               effect = rec->val[type];
-       if (on == FX_FLAG_ADD) {
-               if (parm_defs[type].type == PARM_SIGN) {
-                       if (value > 0x7f)
-                               effect += (int)value - 0x100;
-                       else
-                               effect += (int)value;
-               } else {
-                       effect += (int)value;
-               }
-       }
-       if (on) {
-               if (effect < parm_defs[type].low)
-                       effect = parm_defs[type].low;
-               else if (effect > parm_defs[type].high)
-                       effect = parm_defs[type].high;
-               return (unsigned char)effect;
-       }
-       return value;
-}
-
-/* get word effect value */
-static unsigned short
-FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
-{
-       int effect = 0;
-       int on = 0;
-       if (lay && (on = FX_ON(lay, type)) != 0)
-               effect = lay->val[type];
-       if (!on && (on = FX_ON(rec, type)) != 0)
-               effect = rec->val[type];
-       if (on == FX_FLAG_ADD)
-               effect += (int)value;
-       if (on) {
-               if (effect < parm_defs[type].low)
-                       effect = parm_defs[type].low;
-               else if (effect > parm_defs[type].high)
-                       effect = parm_defs[type].high;
-               return (unsigned short)effect;
-       }
-       return value;
-}
-
-/* get word (upper=type1/lower=type2) effect value */
-static unsigned short
-FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
-{
-       unsigned short tmp;
-       tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
-       tmp <<= 8;
-       tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
-       return tmp;
-}
-
-/* address offset */
-static int
-FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
-{
-       int addr = 0;
-       if (lay && FX_ON(lay, hi))
-               addr = (short)lay->val[hi];
-       else if (FX_ON(rec, hi))
-               addr = (short)rec->val[hi];
-       addr = addr << 15;
-       if (lay && FX_ON(lay, lo))
-               addr += (short)lay->val[lo];
-       else if (FX_ON(rec, lo))
-               addr += (short)rec->val[lo];
-       if (!(mode & AWE_SAMPLE_8BITS))
-               addr /= 2;
-       return addr;
-}
-
-
-/*
- * turn on/off sample
- */
-
-/* table for volume target calculation */
-static unsigned short voltarget[16] = { 
-   0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
-   0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
-};
-
-static void
-awe_note_on(int voice)
-{
-       unsigned int temp;
-       int addr;
-       int vtarget, ftarget, ptarget, pitch;
-       awe_voice_info *vp;
-       awe_voice_parm_block *parm;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       /* A voice sample must assigned before calling */
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       parm = (awe_voice_parm_block*)&vp->parm;
-
-       /* channel to be silent and idle */
-       awe_poke(AWE_DCYSUSV(voice), 0x0080);
-       awe_poke(AWE_VTFT(voice), 0x0000FFFF);
-       awe_poke(AWE_CVCF(voice), 0x0000FFFF);
-       awe_poke(AWE_PTRX(voice), 0);
-       awe_poke(AWE_CPF(voice), 0);
-
-       /* set pitch offset */
-       awe_set_pitch(voice, TRUE);
-
-       /* modulation & volume envelope */
-       if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
-               awe_poke(AWE_ENVVAL(voice), 0xBFFF);
-               pitch = (parm->env1pit<<4) + voices[voice].apitch;
-               if (pitch > 0xffff) pitch = 0xffff;
-               /* calculate filter target */
-               ftarget = parm->cutoff + parm->env1fc;
-               limitvalue(ftarget, 0, 255);
-               ftarget <<= 8;
-       } else {
-               awe_poke(AWE_ENVVAL(voice),
-                        FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
-               ftarget = parm->cutoff;
-               ftarget <<= 8;
-               pitch = voices[voice].apitch;
-       }
-
-       /* calcualte pitch target */
-       if (pitch != 0xffff) {
-               ptarget = 1 << (pitch >> 12);
-               if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
-               if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
-               if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
-               ptarget += (ptarget>>1);
-               if (ptarget > 0xffff) ptarget = 0xffff;
-
-       } else ptarget = 0xffff;
-       if (parm->modatk >= 0x80)
-               awe_poke(AWE_ATKHLD(voice),
-                        FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
-       else
-               awe_poke(AWE_ATKHLD(voice),
-                        FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
-                                vp->parm.modatkhld));
-       awe_poke(AWE_DCYSUS(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
-                         vp->parm.moddcysus));
-
-       if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
-               awe_poke(AWE_ENVVOL(voice), 0xBFFF);
-               vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
-       } else {
-               awe_poke(AWE_ENVVOL(voice),
-                        FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
-               vtarget = 0;
-       }
-       if (parm->volatk >= 0x80)
-               awe_poke(AWE_ATKHLDV(voice),
-                        FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
-       else
-               awe_poke(AWE_ATKHLDV(voice),
-                        FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
-                        vp->parm.volatkhld));
-       /* decay/sustain parameter for volume envelope must be set at last */
-
-       /* cutoff and volume */
-       awe_set_volume(voice, TRUE);
-
-       /* modulation envelope heights */
-       awe_poke(AWE_PEFE(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
-                        vp->parm.pefe));
-
-       /* lfo1/2 delay */
-       awe_poke(AWE_LFO1VAL(voice),
-                FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
-       awe_poke(AWE_LFO2VAL(voice),
-                FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
-
-       /* lfo1 pitch & cutoff shift */
-       awe_fx_fmmod(voice, TRUE);
-       /* lfo1 volume & freq */
-       awe_fx_tremfrq(voice, TRUE);
-       /* lfo2 pitch & freq */
-       awe_fx_fm2frq2(voice, TRUE);
-       /* pan & loop start */
-       awe_set_pan(voice, TRUE);
-
-       /* chorus & loop end (chorus 8bit, MSB) */
-       addr = vp->loopend - 1;
-       addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
-                         AWE_FX_COARSE_LOOP_END, vp->mode);
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
-       temp = (temp <<24) | (unsigned int)addr;
-       awe_poke_dw(AWE_CSL(voice), temp);
-       DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
-
-       /* Q & current address (Q 4bit value, MSB) */
-       addr = vp->start - 1;
-       addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
-                         AWE_FX_COARSE_SAMPLE_START, vp->mode);
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
-       temp = (temp<<28) | (unsigned int)addr;
-       awe_poke_dw(AWE_CCCA(voice), temp);
-       DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
-
-       /* clear unknown registers */
-       awe_poke_dw(AWE_00A0(voice), 0);
-       awe_poke_dw(AWE_0080(voice), 0);
-
-       /* reset volume */
-       awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
-       awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
-
-       /* set reverb */
-       temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
-       temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
-       awe_poke_dw(AWE_PTRX(voice), temp);
-       awe_poke_dw(AWE_CPF(voice), ptarget << 16);
-       /* turn on envelope */
-       awe_poke(AWE_DCYSUSV(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
-                         vp->parm.voldcysus));
-
-       voices[voice].state = AWE_ST_ON;
-
-       /* clear voice position for the next note on this channel */
-       if (SINGLE_LAYER_MODE()) {
-               FX_UNSET(fx, AWE_FX_SAMPLE_START);
-               FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
-       }
-}
-
-
-/* turn off the voice */
-static void
-awe_note_off(int voice)
-{
-       awe_voice_info *vp;
-       unsigned short tmp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if ((vp = voices[voice].sample) == NULL) {
-               voices[voice].state = AWE_ST_OFF;
-               return;
-       }
-
-       tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
-                              (unsigned char)vp->parm.modrelease);
-       awe_poke(AWE_DCYSUS(voice), tmp);
-       tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
-                              (unsigned char)vp->parm.volrelease);
-       awe_poke(AWE_DCYSUSV(voice), tmp);
-       voices[voice].state = AWE_ST_RELEASED;
-}
-
-/* force to terminate the voice (no releasing echo) */
-static void
-awe_terminate(int voice)
-{
-       awe_poke(AWE_DCYSUSV(voice), 0x807F);
-       awe_tweak_voice(voice);
-       voices[voice].state = AWE_ST_OFF;
-}
-
-/* turn off other voices with the same exclusive class (for drums) */
-static void
-awe_exclusive_off(int voice)
-{
-       int i, exclass;
-
-       if (voices[voice].sample == NULL)
-               return;
-       if ((exclass = voices[voice].sample->exclusiveClass) == 0)
-               return; /* not exclusive */
-
-       /* turn off voices with the same class */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (i != voice && IS_PLAYING(i) &&
-                   voices[i].sample && voices[i].ch == voices[voice].ch &&
-                   voices[i].sample->exclusiveClass == exclass) {
-                       DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
-                       awe_terminate(i);
-                       awe_voice_init(i, TRUE);
-               }
-       }
-}
-
-
-/*
- * change the parameters of an audible voice
- */
-
-/* change pitch */
-static void
-awe_set_pitch(int voice, int forced)
-{
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       awe_poke(AWE_IP(voice), voices[voice].apitch);
-       DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
-}
-
-/* calculate & change pitch */
-static void
-awe_set_voice_pitch(int voice, int forced)
-{
-       awe_calc_pitch(voice);
-       awe_set_pitch(voice, forced);
-}
-
-/* change volume & cutoff */
-static void
-awe_set_volume(int voice, int forced)
-{
-       awe_voice_info *vp;
-       unsigned short tmp2;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (!IS_PLAYING(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
-                      (unsigned char)voices[voice].acutoff);
-       tmp2 = (tmp2 << 8);
-       tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
-                       (unsigned char)voices[voice].avol);
-       awe_poke(AWE_IFATN(voice), tmp2);
-}
-
-/* calculate & change volume */
-static void
-awe_set_voice_vol(int voice, int forced)
-{
-       if (IS_EMPTY(voice))
-               return;
-       awe_calc_volume(voice);
-       awe_set_volume(voice, forced);
-}
-
-
-/* change pan; this could make a click noise.. */
-static void
-awe_set_pan(int voice, int forced)
-{
-       unsigned int temp;
-       int addr;
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
-       if (vp->fixpan > 0)     /* 0-127 */
-               temp = 255 - (int)vp->fixpan * 2;
-       else {
-               int pos = 0;
-               if (vp->pan >= 0) /* 0-127 */
-                       pos = (int)vp->pan * 2 - 128;
-               pos += voices[voice].cinfo->panning; /* -128 - 127 */
-               temp = 127 - pos;
-       }
-       limitvalue(temp, 0, 255);
-       if (ctrls[AWE_MD_PAN_EXCHANGE]) {
-               temp = 255 - temp;
-       }
-       if (forced || temp != voices[voice].apan) {
-               voices[voice].apan = temp;
-               if (temp == 0)
-                       voices[voice].aaux = 0xff;
-               else
-                       voices[voice].aaux = (-temp) & 0xff;
-               addr = vp->loopstart - 1;
-               addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
-                                 AWE_FX_COARSE_LOOP_START, vp->mode);
-               temp = (temp<<24) | (unsigned int)addr;
-               awe_poke_dw(AWE_PSST(voice), temp);
-               DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
-       }
-}
-
-/* effects change during playing */
-static void
-awe_fx_fmmod(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_FMMOD(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
-                        vp->parm.fmmod));
-}
-
-/* set tremolo (lfo1) volume & frequency */
-static void
-awe_fx_tremfrq(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_TREMFRQ(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
-                        vp->parm.tremfrq));
-}
-
-/* set lfo2 pitch & frequency */
-static void
-awe_fx_fm2frq2(int voice, int forced)
-{
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-       awe_poke(AWE_FM2FRQ2(voice),
-                FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
-                        vp->parm.fm2frq2));
-}
-
-
-/* Q & current address (Q 4bit value, MSB) */
-static void
-awe_fx_filterQ(int voice, int forced)
-{
-       unsigned int addr;
-       awe_voice_info *vp;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       if ((vp = voices[voice].sample) == NULL || vp->index == 0)
-               return;
-
-       addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
-       addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
-       awe_poke_dw(AWE_CCCA(voice), addr);
-}
-
-/*
- * calculate pitch offset
- *
- * 0xE000 is no pitch offset at 44100Hz sample.
- * Every 4096 is one octave.
- */
-
-static void
-awe_calc_pitch(int voice)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       awe_chan_info *cp = voices[voice].cinfo;
-       int offset;
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-                       return;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-
-       /* calculate offset */
-       if (ap->fixkey >= 0) {
-               DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
-               offset = (ap->fixkey - ap->root) * 4096 / 12;
-       } else {
-               DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
-               offset = (vp->note - ap->root) * 4096 / 12;
-               DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
-       }
-       offset = (offset * ap->scaleTuning) / 100;
-       DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
-       offset += ap->tune * 4096 / 1200;
-       DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
-       if (cp->bender != 0) {
-               DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
-               /* (819200: 1 semitone) ==> (4096: 12 semitones) */
-               offset += cp->bender * cp->bender_range / 2400;
-       }
-
-       /* add initial pitch correction */
-       if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
-               offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
-       else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
-               offset += cp->fx.val[AWE_FX_INIT_PITCH];
-
-       /* 0xe000: root pitch */
-       vp->apitch = 0xe000 + ap->rate_offset + offset;
-       DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
-       if (vp->apitch > 0xffff)
-               vp->apitch = 0xffff;
-       if (vp->apitch < 0)
-               vp->apitch = 0;
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-/* calculate MIDI key and semitone from the specified frequency */
-static void
-awe_calc_pitch_from_freq(int voice, int freq)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       FX_Rec *fx = &voices[voice].cinfo->fx;
-       FX_Rec *fx_lay = NULL;
-       int offset;
-       int note;
-
-       if (voices[voice].layer < MAX_LAYERS)
-               fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-               return;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-       note = freq_to_note(freq);
-       offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
-       offset = (offset * ap->scaleTuning) / 100;
-       if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
-               offset += fx_lay->val[AWE_FX_INIT_PITCH];
-       else if (FX_ON(fx, AWE_FX_INIT_PITCH))
-               offset += fx->val[AWE_FX_INIT_PITCH];
-       vp->apitch = 0xe000 + ap->rate_offset + offset;
-       if (vp->apitch > 0xffff)
-               vp->apitch = 0xffff;
-       if (vp->apitch < 0)
-               vp->apitch = 0;
-}
-#endif /* AWE_HAS_GUS_COMPATIBILITY */
-
-
-/*
- * calculate volume attenuation
- *
- * Voice volume is controlled by volume attenuation parameter.
- * So volume becomes maximum when avol is 0 (no attenuation), and
- * minimum when 255 (-96dB or silence).
- */
-
-static int vol_table[128] = {
-       255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
-       47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
-       31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
-       22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
-       15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
-       10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
-       6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
-       2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
-};
-
-/* tables for volume->attenuation calculation */
-static unsigned char voltab1[128] = {
-   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
-   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
-   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
-   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
-   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
-   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
-   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
-   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char voltab2[128] = {
-   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
-   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
-   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
-   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
-   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
-   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
-   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
-   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
-   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
-   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
-   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char expressiontab[128] = {
-   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
-   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
-   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
-   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
-   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
-   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
-   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
-   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
-   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
-   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
-   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
-   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
-   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static void
-awe_calc_volume(int voice)
-{
-       voice_info *vp = &voices[voice];
-       awe_voice_info *ap;
-       awe_chan_info *cp = voices[voice].cinfo;
-       int vol;
-
-       /* search voice information */
-       if ((ap = vp->sample) == NULL)
-               return;
-
-       ap = vp->sample;
-       if (ap->index == 0) {
-               DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
-               if (awe_set_sample((awe_voice_list*)ap) == 0)
-                       return;
-       }
-       
-       if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
-               int main_vol = cp->main_vol * ap->amplitude / 127;
-               limitvalue(vp->velocity, 0, 127);
-               limitvalue(main_vol, 0, 127);
-               limitvalue(cp->expression_vol, 0, 127);
-
-               vol = voltab1[main_vol] + voltab2[vp->velocity];
-               vol = (vol * 8) / 3;
-               vol += ap->attenuation;
-               if (cp->expression_vol < 127)
-                       vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
-               vol += atten_offset;
-               if (atten_relative)
-                       vol += ctrls[AWE_MD_ZERO_ATTEN];
-               limitvalue(vol, 0, 255);
-               vp->avol = vol;
-               
-       } else {
-               /* 0 - 127 */
-               vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
-               vol = vol * ap->amplitude / 127;
-
-               if (vol < 0) vol = 0;
-               if (vol > 127) vol = 127;
-
-               /* calc to attenuation */
-               vol = vol_table[vol];
-               vol += (int)ap->attenuation;
-               vol += atten_offset;
-               if (atten_relative)
-                       vol += ctrls[AWE_MD_ZERO_ATTEN];
-               if (vol > 255) vol = 255;
-
-               vp->avol = vol;
-       }
-       if (cp->bank !=  AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
-               int atten;
-               if (vp->velocity < 70) atten = 70;
-               else atten = vp->velocity;
-               vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
-       } else {
-               vp->acutoff = ap->parm.cutoff;
-       }
-       DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
-}
-
-/* change master volume */
-static void
-awe_change_master_volume(short val)
-{
-       limitvalue(val, 0, 127);
-       atten_offset = vol_table[val];
-       atten_relative = TRUE;
-       awe_update_volume();
-}
-
-/* update volumes of all available channels */
-static void awe_update_volume(void)
-{
-       int i;
-       for (i = 0; i < awe_max_voices; i++)
-               awe_set_voice_vol(i, TRUE);
-}
-
-/* set sostenuto on */
-static void awe_sostenuto_on(int voice, int forced)
-{
-       if (IS_NO_EFFECT(voice) && !forced) return;
-       voices[voice].sostenuto = 127;
-}
-
-
-/* drop sustain */
-static void awe_sustain_off(int voice, int forced)
-{
-       if (voices[voice].state == AWE_ST_SUSTAINED) {
-               awe_note_off(voice);
-               awe_fx_init(voices[voice].ch);
-               awe_voice_init(voice, FALSE);
-       }
-}
-
-
-/* terminate and initialize voice */
-static void awe_terminate_and_init(int voice, int forced)
-{
-       awe_terminate(voice);
-       awe_fx_init(voices[voice].ch);
-       awe_voice_init(voice, TRUE);
-}
-
-
-/*
- * synth operation routines
- */
-
-#define AWE_VOICE_KEY(v)       (0x8000 | (v))
-#define AWE_CHAN_KEY(c,n)      (((c) << 8) | ((n) + 1))
-#define KEY_CHAN_MATCH(key,c)  (((key) >> 8) == (c))
-
-/* initialize the voice */
-static void
-awe_voice_init(int voice, int init_all)
-{
-       voice_info *vp = &voices[voice];
-
-       /* reset voice search key */
-       if (playing_mode == AWE_PLAY_DIRECT)
-               vp->key = AWE_VOICE_KEY(voice);
-       else
-               vp->key = 0;
-
-       /* clear voice mapping */
-       voice_alloc->map[voice] = 0;
-
-       /* touch the timing flag */
-       vp->time = current_alloc_time;
-
-       /* initialize other parameters if necessary */
-       if (init_all) {
-               vp->note = -1;
-               vp->velocity = 0;
-               vp->sostenuto = 0;
-
-               vp->sample = NULL;
-               vp->cinfo = &channels[voice];
-               vp->ch = voice;
-               vp->state = AWE_ST_OFF;
-
-               /* emu8000 parameters */
-               vp->apitch = 0;
-               vp->avol = 255;
-               vp->apan = -1;
-       }
-}
-
-/* clear effects */
-static void awe_fx_init(int ch)
-{
-       if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
-               memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
-               memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
-       }
-}
-
-/* initialize channel info */
-static void awe_channel_init(int ch, int init_all)
-{
-       awe_chan_info *cp = &channels[ch];
-       cp->channel = ch;
-       if (init_all) {
-               cp->panning = 0; /* zero center */
-               cp->bender_range = 200; /* sense * 100 */
-               cp->main_vol = 127;
-               if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
-                       cp->instr = ctrls[AWE_MD_DEF_DRUM];
-                       cp->bank = AWE_DRUM_BANK;
-               } else {
-                       cp->instr = ctrls[AWE_MD_DEF_PRESET];
-                       cp->bank = ctrls[AWE_MD_DEF_BANK];
-               }
-       }
-
-       cp->bender = 0; /* zero tune skew */
-       cp->expression_vol = 127;
-       cp->chan_press = 0;
-       cp->sustained = 0;
-
-       if (! ctrls[AWE_MD_KEEP_EFFECT]) {
-               memset(&cp->fx, 0, sizeof(cp->fx));
-               memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
-       }
-}
-
-
-/* change the voice parameters; voice = channel */
-static void awe_voice_change(int voice, fx_affect_func func)
-{
-       int i; 
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-               func(voice, FALSE);
-               break;
-       case AWE_PLAY_INDIRECT:
-               for (i = 0; i < awe_max_voices; i++)
-                       if (voices[i].key == AWE_VOICE_KEY(voice))
-                               func(i, FALSE);
-               break;
-       default:
-               for (i = 0; i < awe_max_voices; i++)
-                       if (KEY_CHAN_MATCH(voices[i].key, voice))
-                               func(i, FALSE);
-               break;
-       }
-}
-
-
-/*
- * device open / close
- */
-
-/* open device:
- *   reset status of all voices, and clear sample position flag
- */
-static int
-awe_open(int dev, int mode)
-{
-       if (awe_busy)
-               return -EBUSY;
-
-       awe_busy = TRUE;
-
-       /* set default mode */
-       awe_init_ctrl_parms(FALSE);
-       atten_relative = TRUE;
-       atten_offset = 0;
-       drum_flags = DEFAULT_DRUM_FLAGS;
-       playing_mode = AWE_PLAY_INDIRECT;
-
-       /* reset voices & channels */
-       awe_reset(dev);
-
-       patch_opened = 0;
-
-       return 0;
-}
-
-
-/* close device:
- *   reset all voices again (terminate sounds)
- */
-static void
-awe_close(int dev)
-{
-       awe_reset(dev);
-       awe_busy = FALSE;
-}
-
-
-/* set miscellaneous mode parameters
- */
-static void
-awe_init_ctrl_parms(int init_all)
-{
-       int i;
-       for (i = 0; i < AWE_MD_END; i++) {
-               if (init_all || ctrl_parms[i].init_each_time)
-                       ctrls[i] = ctrl_parms[i].value;
-       }
-}
-
-
-/* sequencer I/O control:
- */
-static int
-awe_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       switch (cmd) {
-       case SNDCTL_SYNTH_INFO:
-               if (playing_mode == AWE_PLAY_DIRECT)
-                       awe_info.nr_voices = awe_max_voices;
-               else
-                       awe_info.nr_voices = AWE_MAX_CHANNELS;
-               if (copy_to_user(arg, &awe_info, sizeof(awe_info)))
-                       return -EFAULT;
-               return 0;
-               break;
-
-       case SNDCTL_SEQ_RESETSAMPLES:
-               awe_reset(dev);
-               awe_reset_samples();
-               return 0;
-               break;
-
-       case SNDCTL_SEQ_PERCMODE:
-               /* what's this? */
-               return 0;
-               break;
-
-       case SNDCTL_SYNTH_MEMAVL:
-               return memsize - awe_free_mem_ptr() * 2;
-               break;
-
-       default:
-               printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
-               return -EINVAL;
-               break;
-       }
-}
-
-
-static int voice_in_range(int voice)
-{
-       if (playing_mode == AWE_PLAY_DIRECT) {
-               if (voice < 0 || voice >= awe_max_voices)
-                       return FALSE;
-       } else {
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static void release_voice(int voice, int do_sustain)
-{
-       if (IS_NO_SOUND(voice))
-               return;
-       if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
-                           voices[voice].sostenuto == 127))
-               voices[voice].state = AWE_ST_SUSTAINED;
-       else {
-               awe_note_off(voice);
-               awe_fx_init(voices[voice].ch);
-               awe_voice_init(voice, FALSE);
-       }
-}
-
-/* release all notes */
-static void awe_note_off_all(int do_sustain)
-{
-       int i;
-       for (i = 0; i < awe_max_voices; i++)
-               release_voice(i, do_sustain);
-}
-
-/* kill a voice:
- *   not terminate, just release the voice.
- */
-static int
-awe_kill_note(int dev, int voice, int note, int velocity)
-{
-       int i, v2, key;
-
-       DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
-       if (! voice_in_range(voice))
-               return -EINVAL;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               key = AWE_VOICE_KEY(voice);
-               break;
-
-       case AWE_PLAY_MULTI2:
-               v2 = voice_alloc->map[voice] >> 8;
-               voice_alloc->map[voice] = 0;
-               voice = v2;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-               /* continue to below */
-       default:
-               key = AWE_CHAN_KEY(voice, note);
-               break;
-       }
-
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key)
-                       release_voice(i, TRUE);
-       }
-       return 0;
-}
-
-
-static void start_or_volume_change(int voice, int velocity)
-{
-       voices[voice].velocity = velocity;
-       awe_calc_volume(voice);
-       if (voices[voice].state == AWE_ST_STANDBY)
-               awe_note_on(voice);
-       else if (voices[voice].state == AWE_ST_ON)
-               awe_set_volume(voice, FALSE);
-}
-
-static void set_and_start_voice(int voice, int state)
-{
-       /* calculate pitch & volume parameters */
-       voices[voice].state = state;
-       awe_calc_pitch(voice);
-       awe_calc_volume(voice);
-       if (state == AWE_ST_ON)
-               awe_note_on(voice);
-}
-
-/* start a voice:
- *   if note is 255, identical with aftertouch function.
- *   Otherwise, start a voice with specified not and volume.
- */
-static int
-awe_start_note(int dev, int voice, int note, int velocity)
-{
-       int i, key, state, volonly;
-
-       DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
-       if (! voice_in_range(voice))
-               return -EINVAL;
-           
-       if (velocity == 0)
-               state = AWE_ST_STANDBY; /* stand by for playing */
-       else
-               state = AWE_ST_ON;      /* really play */
-       volonly = FALSE;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               key = AWE_VOICE_KEY(voice);
-               if (note == 255)
-                       volonly = TRUE;
-               break;
-
-       case AWE_PLAY_MULTI2:
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-               /* continue to below */
-       default:
-               if (note >= 128) { /* key volume mode */
-                       note -= 128;
-                       volonly = TRUE;
-               }
-               key = AWE_CHAN_KEY(voice, note);
-               break;
-       }
-
-       /* dynamic volume change */
-       if (volonly) {
-               for (i = 0; i < awe_max_voices; i++) {
-                       if (voices[i].key == key)
-                               start_or_volume_change(i, velocity);
-               }
-               return 0;
-       }
-
-       /* if the same note still playing, stop it */
-       if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
-               for (i = 0; i < awe_max_voices; i++)
-                       if (voices[i].key == key) {
-                               if (voices[i].state == AWE_ST_ON) {
-                                       awe_note_off(i);
-                                       awe_voice_init(i, FALSE);
-                               } else if (voices[i].state == AWE_ST_STANDBY)
-                                       awe_voice_init(i, TRUE);
-                       }
-       }
-
-       /* allocate voices */
-       if (playing_mode == AWE_PLAY_DIRECT)
-               awe_alloc_one_voice(voice, note, velocity);
-       else
-               awe_alloc_multi_voices(voice, note, velocity, key);
-
-       /* turn off other voices exlusively (for drums) */
-       for (i = 0; i < awe_max_voices; i++)
-               if (voices[i].key == key)
-                       awe_exclusive_off(i);
-
-       /* set up pitch and volume parameters */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
-                       set_and_start_voice(i, state);
-       }
-
-       return 0;
-}
-
-
-/* calculate hash key */
-static int
-awe_search_key(int bank, int preset, int note)
-{
-       unsigned int key;
-
-#if 1 /* new hash table */
-       if (bank == AWE_DRUM_BANK)
-               key = preset + note + 128;
-       else
-               key = bank + preset;
-#else
-       key = preset;
-#endif
-       key %= AWE_MAX_PRESETS;
-
-       return (int)key;
-}
-
-
-/* search instrument from hash table */
-static awe_voice_list *
-awe_search_instr(int bank, int preset, int note)
-{
-       awe_voice_list *p;
-       int key, key2;
-
-       key = awe_search_key(bank, preset, note);
-       for (p = preset_table[key]; p; p = p->next_bank) {
-               if (p->instr == preset && p->bank == bank)
-                       return p;
-       }
-       key2 = awe_search_key(bank, preset, 0); /* search default */
-       if (key == key2)
-               return NULL;
-       for (p = preset_table[key2]; p; p = p->next_bank) {
-               if (p->instr == preset && p->bank == bank)
-                       return p;
-       }
-       return NULL;
-}
-
-
-/* assign the instrument to a voice */
-static int
-awe_set_instr_2(int dev, int voice, int instr_no)
-{
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return -EINVAL;
-       }
-       return awe_set_instr(dev, voice, instr_no);
-}
-
-/* assign the instrument to a channel; voice is the channel number */
-static int
-awe_set_instr(int dev, int voice, int instr_no)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return -EINVAL;
-
-       if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
-               return -EINVAL;
-
-       cinfo = &channels[voice];
-       cinfo->instr = instr_no;
-       DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
-
-       return 0;
-}
-
-
-/* reset all voices; terminate sounds and initialize parameters */
-static void
-awe_reset(int dev)
-{
-       int i;
-       current_alloc_time = 0;
-       /* don't turn off voice 31 and 32.  they are used also for FM voices */
-       for (i = 0; i < awe_max_voices; i++) {
-               awe_terminate(i);
-               awe_voice_init(i, TRUE);
-       }
-       for (i = 0; i < AWE_MAX_CHANNELS; i++)
-               awe_channel_init(i, TRUE);
-       for (i = 0; i < 16; i++) {
-               awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
-               awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
-       }
-       awe_init_fm();
-       awe_tweak();
-}
-
-
-/* hardware specific control:
- *   GUS specific and AWE32 specific controls are available.
- */
-static void
-awe_hw_control(int dev, unsigned char *event)
-{
-       int cmd = event[2];
-       if (cmd & _AWE_MODE_FLAG)
-               awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-       else
-               awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
-#endif
-}
-
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* GUS compatible controls */
-static void
-awe_hw_gus_control(int dev, int cmd, unsigned char *event)
-{
-       int voice, i, key;
-       unsigned short p1;
-       short p2;
-       int plong;
-
-       if (MULTI_LAYER_MODE())
-               return;
-       if (cmd == _GUS_NUMVOICES)
-               return;
-
-       voice = event[3];
-       if (! voice_in_range(voice))
-               return;
-
-       p1 = *(unsigned short *) &event[4];
-       p2 = *(short *) &event[6];
-       plong = *(int*) &event[4];
-
-       switch (cmd) {
-       case _GUS_VOICESAMPLE:
-               awe_set_instr(dev, voice, p1);
-               return;
-
-       case _GUS_VOICEBALA:
-               /* 0 to 15 --> -128 to 127 */
-               awe_panning(dev, voice, ((int)p1 << 4) - 128);
-               return;
-
-       case _GUS_VOICEVOL:
-       case _GUS_VOICEVOL2:
-               /* not supported yet */
-               return;
-
-       case _GUS_RAMPRANGE:
-       case _GUS_RAMPRATE:
-       case _GUS_RAMPMODE:
-       case _GUS_RAMPON:
-       case _GUS_RAMPOFF:
-               /* volume ramping not supported */
-               return;
-
-       case _GUS_VOLUME_SCALE:
-               return;
-
-       case _GUS_VOICE_POS:
-               FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
-                      (short)(plong & 0x7fff));
-               FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
-                      (plong >> 15) & 0xffff);
-               return;
-       }
-
-       key = AWE_VOICE_KEY(voice);
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].key == key) {
-                       switch (cmd) {
-                       case _GUS_VOICEON:
-                               awe_note_on(i);
-                               break;
-
-                       case _GUS_VOICEOFF:
-                               awe_terminate(i);
-                               awe_fx_init(voices[i].ch);
-                               awe_voice_init(i, TRUE);
-                               break;
-
-                       case _GUS_VOICEFADE:
-                               awe_note_off(i);
-                               awe_fx_init(voices[i].ch);
-                               awe_voice_init(i, FALSE);
-                               break;
-
-                       case _GUS_VOICEFREQ:
-                               awe_calc_pitch_from_freq(i, plong);
-                               break;
-                       }
-               }
-       }
-}
-
-#endif /* gus_compat */
-
-
-/* AWE32 specific controls */
-static void
-awe_hw_awe_control(int dev, int cmd, unsigned char *event)
-{
-       int voice;
-       unsigned short p1;
-       short p2;
-       int i;
-
-       voice = event[3];
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       p1 = *(unsigned short *) &event[4];
-       p2 = *(short *) &event[6];
-
-       switch (cmd) {
-       case _AWE_DEBUG_MODE:
-               ctrls[AWE_MD_DEBUG_MODE] = p1;
-               printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
-               break;
-       case _AWE_REVERB_MODE:
-               ctrls[AWE_MD_REVERB_MODE] = p1;
-               awe_update_reverb_mode();
-               break;
-
-       case _AWE_CHORUS_MODE:
-               ctrls[AWE_MD_CHORUS_MODE] = p1;
-               awe_update_chorus_mode();
-               break;
-                     
-       case _AWE_REMOVE_LAST_SAMPLES:
-               DEBUG(0,printk("AWE32: remove last samples\n"));
-               awe_reset(0);
-               if (locked_sf_id > 0)
-                       awe_remove_samples(locked_sf_id);
-               break;
-
-       case _AWE_INITIALIZE_CHIP:
-               awe_initialize();
-               break;
-
-       case _AWE_SEND_EFFECT:
-               i = -1;
-               if (p1 >= 0x100) {
-                       i = (p1 >> 8);
-                       if (i < 0 || i >= MAX_LAYERS)
-                               break;
-               }
-               awe_send_effect(voice, i, p1, p2);
-               break;
-
-       case _AWE_RESET_CHANNEL:
-               awe_channel_init(voice, !p1);
-               break;
-               
-       case _AWE_TERMINATE_ALL:
-               awe_reset(0);
-               break;
-
-       case _AWE_TERMINATE_CHANNEL:
-               awe_voice_change(voice, awe_terminate_and_init);
-               break;
-
-       case _AWE_RELEASE_ALL:
-               awe_note_off_all(FALSE);
-               break;
-       case _AWE_NOTEOFF_ALL:
-               awe_note_off_all(TRUE);
-               break;
-
-       case _AWE_INITIAL_VOLUME:
-               DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
-               atten_relative = (char)p2;
-               atten_offset = (short)p1;
-               awe_update_volume();
-               break;
-
-       case _AWE_CHN_PRESSURE:
-               channels[voice].chan_press = p1;
-               awe_modwheel_change(voice, p1);
-               break;
-
-       case _AWE_CHANNEL_MODE:
-               DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
-               playing_mode = p1;
-               awe_reset(0);
-               break;
-
-       case _AWE_DRUM_CHANNELS:
-               DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
-               drum_flags = *(unsigned int*)&event[4];
-               break;
-
-       case _AWE_MISC_MODE:
-               DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
-               if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
-                       ctrls[p1] = p2;
-                       if (ctrl_parms[p1].update)
-                               ctrl_parms[p1].update();
-               }
-               break;
-
-       case _AWE_EQUALIZER:
-               ctrls[AWE_MD_BASS_LEVEL] = p1;
-               ctrls[AWE_MD_TREBLE_LEVEL] = p2;
-               awe_update_equalizer();
-               break;
-
-       default:
-               DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
-               break;
-       }
-}
-
-
-/* change effects */
-static void
-awe_send_effect(int voice, int layer, int type, int val)
-{
-       awe_chan_info *cinfo;
-       FX_Rec *fx;
-       int mode;
-
-       cinfo = &channels[voice];
-       if (layer >= 0 && layer < MAX_LAYERS)
-               fx = &cinfo->fx_layer[layer];
-       else
-               fx = &cinfo->fx;
-
-       if (type & 0x40)
-               mode = FX_FLAG_OFF;
-       else if (type & 0x80)
-               mode = FX_FLAG_ADD;
-       else
-               mode = FX_FLAG_SET;
-       type &= 0x3f;
-
-       if (type >= 0 && type < AWE_FX_END) {
-               DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
-               if (mode == FX_FLAG_SET)
-                       FX_SET(fx, type, val);
-               else if (mode == FX_FLAG_ADD)
-                       FX_ADD(fx, type, val);
-               else
-                       FX_UNSET(fx, type);
-               if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
-                       DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
-                       awe_voice_change(voice, parm_defs[type].realtime);
-               }
-       }
-}
-
-
-/* change modulation wheel; voice is already mapped on multi2 mode */
-static void
-awe_modwheel_change(int voice, int value)
-{
-       int i;
-       awe_chan_info *cinfo;
-
-       cinfo = &channels[voice];
-       i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
-       FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
-       awe_voice_change(voice, awe_fx_fmmod);
-       FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
-       awe_voice_change(voice, awe_fx_fm2frq2);
-}
-
-
-/* voice pressure change */
-static void
-awe_aftertouch(int dev, int voice, int pressure)
-{
-       int note;
-
-       DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
-       if (! voice_in_range(voice))
-               return;
-
-       switch (playing_mode) {
-       case AWE_PLAY_DIRECT:
-       case AWE_PLAY_INDIRECT:
-               awe_start_note(dev, voice, 255, pressure);
-               break;
-       case AWE_PLAY_MULTI2:
-               note = (voice_alloc->map[voice] & 0xff) - 1;
-               awe_key_pressure(dev, voice, note + 0x80, pressure);
-               break;
-       }
-}
-
-
-/* voice control change */
-static void
-awe_controller(int dev, int voice, int ctrl_num, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       cinfo = &channels[voice];
-
-       switch (ctrl_num) {
-       case CTL_BANK_SELECT: /* MIDI control #0 */
-               DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
-               if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
-                   !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
-                       break;
-               if (value < 0 || value > 255)
-                       break;
-               cinfo->bank = value;
-               if (cinfo->bank == AWE_DRUM_BANK)
-                       DRUM_CHANNEL_ON(cinfo->channel);
-               else
-                       DRUM_CHANNEL_OFF(cinfo->channel);
-               awe_set_instr(dev, voice, cinfo->instr);
-               break;
-
-       case CTL_MODWHEEL: /* MIDI control #1 */
-               DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
-               awe_modwheel_change(voice, value);
-               break;
-
-       case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
-               DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
-               /* zero centered */
-               cinfo->bender = value;
-               awe_voice_change(voice, awe_set_voice_pitch);
-               break;
-
-       case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
-               /* value = sense x 100 */
-               cinfo->bender_range = value;
-               /* no audible pitch change yet.. */
-               break;
-
-       case CTL_EXPRESSION: /* MIDI control #11 */
-               if (SINGLE_LAYER_MODE())
-                       value /= 128;
-       case CTRL_EXPRESSION: /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
-               /* 0 - 127 */
-               cinfo->expression_vol = value;
-               awe_voice_change(voice, awe_set_voice_vol);
-               break;
-
-       case CTL_PAN:   /* MIDI control #10 */
-               DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
-               /* (0-127) -> signed 8bit */
-               cinfo->panning = value * 2 - 128;
-               if (ctrls[AWE_MD_REALTIME_PAN])
-                       awe_voice_change(voice, awe_set_pan);
-               break;
-
-       case CTL_MAIN_VOLUME:   /* MIDI control #7 */
-               if (SINGLE_LAYER_MODE())
-                       value = (value * 100) / 16383;
-       case CTRL_MAIN_VOLUME:  /* SEQ1 V2 control */
-               DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
-               /* 0 - 127 */
-               cinfo->main_vol = value;
-               awe_voice_change(voice, awe_set_voice_vol);
-               break;
-
-       case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
-               DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
-               FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
-               break;
-
-       case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
-               DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
-               FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
-               break;
-
-       case 120:  /* all sounds off */
-               awe_note_off_all(FALSE);
-               break;
-       case 123:  /* all notes off */
-               awe_note_off_all(TRUE);
-               break;
-
-       case CTL_SUSTAIN: /* MIDI control #64 */
-               cinfo->sustained = value;
-               if (value != 127)
-                       awe_voice_change(voice, awe_sustain_off);
-               break;
-
-       case CTL_SOSTENUTO: /* MIDI control #66 */
-               if (value == 127)
-                       awe_voice_change(voice, awe_sostenuto_on);
-               else
-                       awe_voice_change(voice, awe_sustain_off);
-               break;
-
-       default:
-               DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
-                          voice, ctrl_num, value));
-               break;
-       }
-}
-
-
-/* voice pan change (value = -128 - 127) */
-static void
-awe_panning(int dev, int voice, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       cinfo = &channels[voice];
-       cinfo->panning = value;
-       DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
-       if (ctrls[AWE_MD_REALTIME_PAN])
-               awe_voice_change(voice, awe_set_pan);
-}
-
-
-/* volume mode change */
-static void
-awe_volume_method(int dev, int mode)
-{
-       /* not impremented */
-       DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
-}
-
-
-/* pitch wheel change: 0-16384 */
-static void
-awe_bender(int dev, int voice, int value)
-{
-       awe_chan_info *cinfo;
-
-       if (! voice_in_range(voice))
-               return;
-
-       if (playing_mode == AWE_PLAY_MULTI2) {
-               voice = voice_alloc->map[voice] >> 8;
-               if (voice < 0 || voice >= AWE_MAX_CHANNELS)
-                       return;
-       }
-
-       /* convert to zero centered value */
-       cinfo = &channels[voice];
-       cinfo->bender = value - 8192;
-       DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
-       awe_voice_change(voice, awe_set_voice_pitch);
-}
-
-
-/*
- * load a sound patch:
- *   three types of patches are accepted: AWE, GUS, and SYSEX.
- */
-
-static int
-awe_load_patch(int dev, int format, const char __user *addr,
-              int offs, int count, int pmgr_flag)
-{
-       awe_patch_info patch;
-       int rc = 0;
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-       if (format == GUS_PATCH) {
-               return awe_load_guspatch(addr, offs, count, pmgr_flag);
-       } else
-#endif
-       if (format == SYSEX_PATCH) {
-               /* no system exclusive message supported yet */
-               return 0;
-       } else if (format != AWE_PATCH) {
-               printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
-               return -EINVAL;
-       }
-       
-       if (count < AWE_PATCH_INFO_SIZE) {
-               printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(((char*)&patch) + offs, addr + offs, 
-                          AWE_PATCH_INFO_SIZE - offs))
-               return -EFAULT;
-
-       count -= AWE_PATCH_INFO_SIZE;
-       if (count < patch.len) {
-               printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
-                      count, patch.len);
-               return -EINVAL;
-       }
-       
-       switch (patch.type) {
-       case AWE_LOAD_INFO:
-               rc = awe_load_info(&patch, addr, count);
-               break;
-       case AWE_LOAD_DATA:
-               rc = awe_load_data(&patch, addr, count);
-               break;
-       case AWE_OPEN_PATCH:
-               rc = awe_open_patch(&patch, addr, count);
-               break;
-       case AWE_CLOSE_PATCH:
-               rc = awe_close_patch(&patch, addr, count);
-               break;
-       case AWE_UNLOAD_PATCH:
-               rc = awe_unload_patch(&patch, addr, count);
-               break;
-       case AWE_REPLACE_DATA:
-               rc = awe_replace_data(&patch, addr, count);
-               break;
-       case AWE_MAP_PRESET:
-               rc = awe_load_map(&patch, addr, count);
-               break;
-       /* case AWE_PROBE_INFO:
-               rc = awe_probe_info(&patch, addr, count);
-               break;*/
-       case AWE_PROBE_DATA:
-               rc = awe_probe_data(&patch, addr, count);
-               break;
-       case AWE_REMOVE_INFO:
-               rc = awe_remove_info(&patch, addr, count);
-               break;
-       case AWE_LOAD_CHORUS_FX:
-               rc = awe_load_chorus_fx(&patch, addr, count);
-               break;
-       case AWE_LOAD_REVERB_FX:
-               rc = awe_load_reverb_fx(&patch, addr, count);
-               break;
-
-       default:
-               printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
-                      patch.type);
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
-
-
-/* create an sf list record */
-static int
-awe_create_sf(int type, char *name)
-{
-       sf_list *rec;
-
-       /* terminate sounds */
-       awe_reset(0);
-       rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
-       if (rec == NULL)
-               return 1; /* no memory */
-       rec->sf_id = current_sf_id + 1;
-       rec->type = type;
-       if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
-               locked_sf_id = current_sf_id + 1;
-       rec->num_info = awe_free_info();
-       rec->num_sample = awe_free_sample();
-       rec->mem_ptr = awe_free_mem_ptr();
-       rec->infos = rec->last_infos = NULL;
-       rec->samples = rec->last_samples = NULL;
-
-       /* add to linked-list */
-       rec->next = NULL;
-       rec->prev = sftail;
-       if (sftail)
-               sftail->next = rec;
-       else
-               sfhead = rec;
-       sftail = rec;
-       current_sf_id++;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       rec->shared = NULL;
-       if (name)
-               memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
-       else
-               strcpy(rec->name, "*TEMPORARY*");
-       if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
-               /* is the current font really a shared font? */
-               if (is_shared_sf(rec->name)) {
-                       /* check if the shared font is already installed */
-                       sf_list *p;
-                       for (p = rec->prev; p; p = p->prev) {
-                               if (is_identical_name(rec->name, p)) {
-                                       rec->shared = p;
-                                       break;
-                               }
-                       }
-               }
-       }
-#endif /* allow sharing */
-
-       return 0;
-}
-
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-
-/* check if the given name is a valid shared name */
-#define ASC_TO_KEY(c) ((c) - 'A' + 1)
-static int is_shared_sf(unsigned char *name)
-{
-       static unsigned char id_head[4] = {
-               ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
-               AWE_MAJOR_VERSION,
-       };
-       if (memcmp(name, id_head, 4) == 0)
-               return TRUE;
-       return FALSE;
-}
-
-/* check if the given name matches to the existing list */
-static int is_identical_name(unsigned char *name, sf_list *p) 
-{
-       char *id = p->name;
-       if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
-               return TRUE;
-       return FALSE;
-}
-
-/* check if the given voice info exists */
-static int info_duplicated(sf_list *sf, awe_voice_list *rec)
-{
-       /* search for all sharing lists */
-       for (; sf; sf = sf->shared) {
-               awe_voice_list *p;
-               for (p = sf->infos; p; p = p->next) {
-                       if (p->type == V_ST_NORMAL &&
-                           p->bank == rec->bank &&
-                           p->instr == rec->instr &&
-                           p->v.low == rec->v.low &&
-                           p->v.high == rec->v.high &&
-                           p->v.sample == rec->v.sample)
-                               return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-#endif /* AWE_ALLOW_SAMPLE_SHARING */
-
-
-/* free sf_list record */
-/* linked-list in this function is not cared */
-static void
-awe_free_sf(sf_list *sf)
-{
-       if (sf->infos) {
-               awe_voice_list *p, *next;
-               for (p = sf->infos; p; p = next) {
-                       next = p->next;
-                       kfree(p);
-               }
-       }
-       if (sf->samples) {
-               awe_sample_list *p, *next;
-               for (p = sf->samples; p; p = next) {
-                       next = p->next;
-                       kfree(p);
-               }
-       }
-       kfree(sf);
-}
-
-
-/* open patch; create sf list and set opened flag */
-static int
-awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       awe_open_parm parm;
-       int shared;
-
-       if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
-               return -EFAULT;
-       shared = FALSE;
-
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
-               /* is the previous font the same font? */
-               if (is_identical_name(parm.name, sftail)) {
-                       /* then append to the previous */
-                       shared = TRUE;
-                       awe_reset(0);
-                       if (parm.type & AWE_PAT_LOCKED)
-                               locked_sf_id = current_sf_id;
-               }
-       }
-#endif /* allow sharing */
-       if (! shared) {
-               if (awe_create_sf(parm.type, parm.name)) {
-                       printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
-                       return -ENOMEM;
-               }
-       }
-       patch_opened = TRUE;
-       return current_sf_id;
-}
-
-/* check if the patch is already opened */
-static sf_list *
-check_patch_opened(int type, char *name)
-{
-       if (! patch_opened) {
-               if (awe_create_sf(type, name)) {
-                       printk(KERN_ERR "AWE32: failed to alloc new list\n");
-                       return NULL;
-               }
-               patch_opened = TRUE;
-               return sftail;
-       }
-       return sftail;
-}
-
-/* close the patch; if no voice is loaded, remove the patch */
-static int
-awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch_opened && sftail) {
-               /* if no voice is loaded, release the current patch */
-               if (sftail->infos == NULL) {
-                       awe_reset(0);
-                       awe_remove_samples(current_sf_id - 1);
-               }
-       }
-       patch_opened = 0;
-       return 0;
-}
-
-
-/* remove the latest patch */
-static int
-awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
-               awe_reset(0);
-               awe_remove_samples(current_sf_id - 1);
-       }
-       return 0;
-}
-
-/* allocate voice info list records */
-static awe_voice_list *
-alloc_new_info(void)
-{
-       awe_voice_list *newlist;
-       
-       newlist = kmalloc(sizeof(*newlist), GFP_KERNEL);
-       if (newlist == NULL) {
-               printk(KERN_ERR "AWE32: can't alloc info table\n");
-               return NULL;
-       }
-       return newlist;
-}
-
-/* allocate sample info list records */
-static awe_sample_list *
-alloc_new_sample(void)
-{
-       awe_sample_list *newlist;
-       
-       newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
-       if (newlist == NULL) {
-               printk(KERN_ERR "AWE32: can't alloc sample table\n");
-               return NULL;
-       }
-       return newlist;
-}
-
-/* load voice map */
-static int
-awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
-{
-       awe_voice_map map;
-       awe_voice_list *rec, *p;
-       sf_list *sf;
-
-       /* get the link info */
-       if (count < sizeof(map)) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-               return -EFAULT;
-       
-       /* check if the identical mapping already exists */
-       p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
-       for (; p; p = p->next_instr) {
-               if (p->type == V_ST_MAPPED &&
-                   p->v.start == map.src_instr &&
-                   p->v.end == map.src_bank &&
-                   p->v.fixkey == map.src_key)
-                       return 0; /* already present! */
-       }
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
-               return -ENOMEM;
-
-       if ((rec = alloc_new_info()) == NULL)
-               return -ENOMEM;
-
-       rec->bank = map.map_bank;
-       rec->instr = map.map_instr;
-       rec->type = V_ST_MAPPED;
-       rec->disabled = FALSE;
-       awe_init_voice_info(&rec->v);
-       if (map.map_key >= 0) {
-               rec->v.low = map.map_key;
-               rec->v.high = map.map_key;
-       }
-       rec->v.start = map.src_instr;
-       rec->v.end = map.src_bank;
-       rec->v.fixkey = map.src_key;
-       add_sf_info(sf, rec);
-       add_info_list(rec);
-
-       return 0;
-}
-
-#if 0
-/* probe preset in the current list -- nothing to be loaded */
-static int
-awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       awe_voice_map map;
-       awe_voice_list *p;
-
-       if (! patch_opened)
-               return -EINVAL;
-
-       /* get the link info */
-       if (count < sizeof(map)) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
-               return -EFAULT;
-       
-       /* check if the identical mapping already exists */
-       if (sftail == NULL)
-               return -EINVAL;
-       p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
-       for (; p; p = p->next_instr) {
-               if (p->type == V_ST_NORMAL &&
-                   is_identical_holder(p->holder, sftail) &&
-                   p->v.low <= map.src_key &&
-                   p->v.high >= map.src_key)
-                       return 0; /* already present! */
-       }
-#endif /* allow sharing */
-       return -EINVAL;
-}
-#endif
-
-/* probe sample in the current list -- nothing to be loaded */
-static int
-awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       if (! patch_opened)
-               return -EINVAL;
-
-       /* search the specified sample by optarg */
-       if (search_sample_index(sftail, patch->optarg) != NULL)
-               return 0;
-#endif /* allow sharing */
-       return -EINVAL;
-}
-
-               
-/* remove the present instrument layers */
-static int
-remove_info(sf_list *sf, int bank, int instr)
-{
-       awe_voice_list *prev, *next, *p;
-       int removed = 0;
-
-       prev = NULL;
-       for (p = sf->infos; p; p = next) {
-               next = p->next;
-               if (p->type == V_ST_NORMAL &&
-                   p->bank == bank && p->instr == instr) {
-                       /* remove this layer */
-                       if (prev)
-                               prev->next = next;
-                       else
-                               sf->infos = next;
-                       if (p == sf->last_infos)
-                               sf->last_infos = prev;
-                       sf->num_info--;
-                       removed++;
-                       kfree(p);
-               } else
-                       prev = p;
-       }
-       if (removed)
-               rebuild_preset_list();
-       return removed;
-}
-
-/* load voice information data */
-static int
-awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset;
-       awe_voice_rec_hdr hdr;
-       int i;
-       int total_size;
-       sf_list *sf;
-       awe_voice_list *rec;
-
-       if (count < AWE_VOICE_REC_SIZE) {
-               printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
-               return -EINVAL;
-       }
-
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
-               return -EFAULT;
-       offset += AWE_VOICE_REC_SIZE;
-
-       if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
-               printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
-               return -EINVAL;
-       }
-       total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
-       if (count < total_size) {
-               printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
-                      count, hdr.nvoices);
-               return -EINVAL;
-       }
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-               return -ENOMEM;
-
-       switch (hdr.write_mode) {
-       case AWE_WR_EXCLUSIVE:
-               /* exclusive mode - if the instrument already exists,
-                  return error */
-               for (rec = sf->infos; rec; rec = rec->next) {
-                       if (rec->type == V_ST_NORMAL &&
-                           rec->bank == hdr.bank &&
-                           rec->instr == hdr.instr)
-                               return -EINVAL;
-               }
-               break;
-       case AWE_WR_REPLACE:
-               /* replace mode - remove the instrument if it already exists */
-               remove_info(sf, hdr.bank, hdr.instr);
-               break;
-       }
-
-       /* append new layers */
-       for (i = 0; i < hdr.nvoices; i++) {
-               rec = alloc_new_info();
-               if (rec == NULL)
-                       return -ENOMEM;
-
-               rec->bank = hdr.bank;
-               rec->instr = hdr.instr;
-               rec->type = V_ST_NORMAL;
-               rec->disabled = FALSE;
-
-               /* copy awe_voice_info parameters */
-               if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
-                       kfree(rec);
-                       return -EFAULT;
-               }
-               offset += AWE_VOICE_INFO_SIZE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-               if (sf && sf->shared) {
-                       if (info_duplicated(sf, rec)) {
-                               kfree(rec);
-                               continue;
-                       }
-               }
-#endif /* allow sharing */
-               if (rec->v.mode & AWE_MODE_INIT_PARM)
-                       awe_init_voice_parm(&rec->v.parm);
-               add_sf_info(sf, rec);
-               awe_set_sample(rec);
-               add_info_list(rec);
-       }
-
-       return 0;
-}
-
-
-/* remove instrument layers */
-static int
-awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
-{
-       unsigned char bank, instr;
-       sf_list *sf;
-
-       if (! patch_opened || (sf = sftail) == NULL) {
-               printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
-               return -EINVAL;
-       }
-
-       bank = ((unsigned short)patch->optarg >> 8) & 0xff;
-       instr = (unsigned short)patch->optarg & 0xff;
-       if (! remove_info(sf, bank, instr))
-               return -EINVAL;
-       return 0;
-}
-
-
-/* load wave sample data */
-static int
-awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset, size;
-       int rc;
-       awe_sample_info tmprec;
-       awe_sample_list *rec;
-       sf_list *sf;
-
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
-               return -ENOMEM;
-
-       size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
-               return -EFAULT;
-       offset += AWE_SAMPLE_INFO_SIZE;
-       if (size != tmprec.size) {
-               printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
-                      tmprec.size, size);
-               return -EINVAL;
-       }
-
-       if (search_sample_index(sf, tmprec.sample) != NULL) {
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-               /* if shared sample, skip this data */
-               if (sf->type & AWE_PAT_SHARED)
-                       return 0;
-#endif /* allow sharing */
-               DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
-               return -EINVAL;
-       }
-
-       if ((rec = alloc_new_sample()) == NULL)
-               return -ENOMEM;
-
-       memcpy(&rec->v, &tmprec, sizeof(tmprec));
-
-       if (rec->v.size > 0) {
-               if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
-                       kfree(rec);
-                       return rc;
-               }
-               sf->mem_ptr += rc;
-       }
-
-       add_sf_sample(sf, rec);
-       return 0;
-}
-
-
-/* replace wave sample data */
-static int
-awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
-{
-       int offset;
-       int size;
-       int rc;
-       int channels;
-       awe_sample_info cursmp;
-       int save_mem_ptr;
-       sf_list *sf;
-       awe_sample_list *rec;
-
-       if (! patch_opened || (sf = sftail) == NULL) {
-               printk(KERN_WARNING "AWE32: replace: patch not opened\n");
-               return -EINVAL;
-       }
-
-       size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
-       offset = AWE_PATCH_INFO_SIZE;
-       if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
-               return -EFAULT;
-       offset += AWE_SAMPLE_INFO_SIZE;
-       if (cursmp.size == 0 || size != cursmp.size) {
-               printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
-                      cursmp.size, size);
-               return -EINVAL;
-       }
-       channels = patch->optarg;
-       if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
-               printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
-               return -EINVAL;
-       }
-
-       for (rec = sf->samples; rec; rec = rec->next) {
-               if (rec->v.sample == cursmp.sample)
-                       break;
-       }
-       if (rec == NULL) {
-               printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
-                      cursmp.sample);
-               return -EINVAL;
-       }
-               
-       if (rec->v.size != cursmp.size) {
-               printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
-                      rec->v.size, cursmp.size);
-               return -EINVAL;
-       }
-
-       save_mem_ptr = awe_free_mem_ptr();
-       sftail->mem_ptr = rec->v.start - awe_mem_start;
-       memcpy(&rec->v, &cursmp, sizeof(cursmp));
-       rec->v.sf_id = current_sf_id;
-       if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
-               return rc;
-       sftail->mem_ptr = save_mem_ptr;
-
-       return 0;
-}
-
-
-/*----------------------------------------------------------------*/
-
-static const char __user *readbuf_addr;
-static int readbuf_offs;
-static int readbuf_flags;
-
-/* initialize read buffer */
-static int
-readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
-{
-       readbuf_addr = addr;
-       readbuf_offs = offset;
-       readbuf_flags = sp->mode_flags;
-       return 0;
-}
-
-/* read directly from user buffer */
-static unsigned short
-readbuf_word(int pos)
-{
-       unsigned short c;
-       /* read from user buffer */
-       if (readbuf_flags & AWE_SAMPLE_8BITS) {
-               unsigned char cc;
-               get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
-               c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
-       } else {
-               get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
-       }
-       if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
-               c ^= 0x8000; /* unsigned -> signed */
-       return c;
-}
-
-#define readbuf_word_cache     readbuf_word
-#define readbuf_end()          /**/
-
-/*----------------------------------------------------------------*/
-
-#define BLANK_LOOP_START       8
-#define BLANK_LOOP_END         40
-#define BLANK_LOOP_SIZE                48
-
-/* loading onto memory - return the actual written size */
-static int 
-awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
-{
-       int i, truesize, dram_offset;
-       awe_sample_info *sp = &list->v;
-       int rc;
-
-       /* be sure loop points start < end */
-       if (sp->loopstart > sp->loopend) {
-               int tmp = sp->loopstart;
-               sp->loopstart = sp->loopend;
-               sp->loopend = tmp;
-       }
-
-       /* compute true data size to be loaded */
-       truesize = sp->size;
-       if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
-               truesize += sp->loopend - sp->loopstart;
-       if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
-               truesize += BLANK_LOOP_SIZE;
-       if (awe_free_mem_ptr() + truesize >= memsize/2) {
-               DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
-               return -ENOSPC;
-       }
-
-       /* recalculate address offset */
-       sp->end -= sp->start;
-       sp->loopstart -= sp->start;
-       sp->loopend -= sp->start;
-
-       dram_offset = awe_free_mem_ptr() + awe_mem_start;
-       sp->start = dram_offset;
-       sp->end += dram_offset;
-       sp->loopstart += dram_offset;
-       sp->loopend += dram_offset;
-
-       /* set the total size (store onto obsolete checksum value) */
-       if (sp->size == 0)
-               sp->checksum = 0;
-       else
-               sp->checksum = truesize;
-
-       if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
-               return rc;
-
-       if (readbuf_init(addr, offset, sp) < 0)
-               return -ENOSPC;
-
-       for (i = 0; i < sp->size; i++) {
-               unsigned short c;
-               c = readbuf_word(i);
-               awe_write_dram(c);
-               if (i == sp->loopend &&
-                   (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
-                       int looplen = sp->loopend - sp->loopstart;
-                       /* copy reverse loop */
-                       int k;
-                       for (k = 1; k <= looplen; k++) {
-                               c = readbuf_word_cache(i - k);
-                               awe_write_dram(c);
-                       }
-                       if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
-                               sp->end += looplen;
-                       } else {
-                               sp->start += looplen;
-                               sp->end += looplen;
-                       }
-               }
-       }
-       readbuf_end();
-
-       /* if no blank loop is attached in the sample, add it */
-       if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
-               for (i = 0; i < BLANK_LOOP_SIZE; i++)
-                       awe_write_dram(0);
-               if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
-                       sp->loopstart = sp->end + BLANK_LOOP_START;
-                       sp->loopend = sp->end + BLANK_LOOP_END;
-               }
-       }
-
-       awe_close_dram();
-
-       /* initialize FM */
-       awe_init_fm();
-
-       return truesize;
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef AWE_HAS_GUS_COMPATIBILITY
-
-/* calculate GUS envelope time:
- * is this correct?  i have no idea..
- */
-static int
-calc_gus_envelope_time(int rate, int start, int end)
-{
-       int r, p, t;
-       r = (3 - ((rate >> 6) & 3)) * 3;
-       p = rate & 0x3f;
-       t = end - start;
-       if (t < 0) t = -t;
-       if (13 > r)
-               t = t << (13 - r);
-       else
-               t = t >> (r - 13);
-       return (t * 10) / (p * 441);
-}
-
-#define calc_gus_sustain(val)  (0x7f - vol_table[(val)/2])
-#define calc_gus_attenuation(val)      vol_table[(val)/2]
-
-/* load GUS patch */
-static int
-awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
-{
-       struct patch_info patch;
-       awe_voice_info *rec;
-       awe_sample_info *smp;
-       awe_voice_list *vrec;
-       awe_sample_list *smprec;
-       int sizeof_patch;
-       int note, rc;
-       sf_list *sf;
-
-       sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
-       if (size < sizeof_patch) {
-               printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
-               return -EFAULT;
-       size -= sizeof_patch;
-       if (size < patch.len) {
-               printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
-                      size, patch.len);
-               return -EINVAL;
-       }
-       if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
-               return -ENOMEM;
-       if ((smprec = alloc_new_sample()) == NULL)
-               return -ENOMEM;
-       if ((vrec = alloc_new_info()) == NULL) {
-               kfree(smprec);
-               return -ENOMEM;
-       }
-
-       smp = &smprec->v;
-       smp->sample = sf->num_sample;
-       smp->start = 0;
-       smp->end = patch.len;
-       smp->loopstart = patch.loop_start;
-       smp->loopend = patch.loop_end;
-       smp->size = patch.len;
-
-       /* set up mode flags */
-       smp->mode_flags = 0;
-       if (!(patch.mode & WAVE_16_BITS))
-               smp->mode_flags |= AWE_SAMPLE_8BITS;
-       if (patch.mode & WAVE_UNSIGNED)
-               smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
-       smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
-       if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
-               smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
-       if (patch.mode & WAVE_BIDIR_LOOP)
-               smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
-       if (patch.mode & WAVE_LOOP_BACK)
-               smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
-
-       DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
-       if (patch.mode & WAVE_16_BITS) {
-               /* convert to word offsets */
-               smp->size /= 2;
-               smp->end /= 2;
-               smp->loopstart /= 2;
-               smp->loopend /= 2;
-       }
-       smp->checksum_flag = 0;
-       smp->checksum = 0;
-
-       if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) {
-               kfree(vrec);
-               return rc;
-       }
-       sf->mem_ptr += rc;
-       add_sf_sample(sf, smprec);
-
-       /* set up voice info */
-       rec = &vrec->v;
-       awe_init_voice_info(rec);
-       rec->sample = sf->num_info; /* the last sample */
-       rec->rate_offset = calc_rate_offset(patch.base_freq);
-       note = freq_to_note(patch.base_note);
-       rec->root = note / 100;
-       rec->tune = -(note % 100);
-       rec->low = freq_to_note(patch.low_note) / 100;
-       rec->high = freq_to_note(patch.high_note) / 100;
-       DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
-                      rec->rate_offset, note,
-                      rec->low, rec->high,
-             patch.low_note, patch.high_note));
-       /* panning position; -128 - 127 => 0-127 */
-       rec->pan = (patch.panning + 128) / 2;
-
-       /* detuning is ignored */
-       /* 6points volume envelope */
-       if (patch.mode & WAVE_ENVELOPES) {
-               int attack, hold, decay, release;
-               attack = calc_gus_envelope_time
-                       (patch.env_rate[0], 0, patch.env_offset[0]);
-               hold = calc_gus_envelope_time
-                       (patch.env_rate[1], patch.env_offset[0],
-                        patch.env_offset[1]);
-               decay = calc_gus_envelope_time
-                       (patch.env_rate[2], patch.env_offset[1],
-                        patch.env_offset[2]);
-               release = calc_gus_envelope_time
-                       (patch.env_rate[3], patch.env_offset[1],
-                        patch.env_offset[4]);
-               release += calc_gus_envelope_time
-                       (patch.env_rate[4], patch.env_offset[3],
-                        patch.env_offset[4]);
-               release += calc_gus_envelope_time
-                       (patch.env_rate[5], patch.env_offset[4],
-                        patch.env_offset[5]);
-               rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
-                       calc_parm_attack(attack);
-               rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
-                       calc_parm_decay(decay);
-               rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
-               DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
-               rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
-       }
-
-       /* tremolo effect */
-       if (patch.mode & WAVE_TREMOLO) {
-               int rate = (patch.tremolo_rate * 1000 / 38) / 42;
-               rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
-               DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
-                              patch.tremolo_rate, patch.tremolo_depth,
-                              rec->parm.tremfrq));
-       }
-       /* vibrato effect */
-       if (patch.mode & WAVE_VIBRATO) {
-               int rate = (patch.vibrato_rate * 1000 / 38) / 42;
-               rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
-               DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
-                              patch.tremolo_rate, patch.tremolo_depth,
-                              rec->parm.tremfrq));
-       }
-       
-       /* scale_freq, scale_factor, volume, and fractions not implemented */
-
-       /* append to the tail of the list */
-       vrec->bank = ctrls[AWE_MD_GUS_BANK];
-       vrec->instr = patch.instr_no;
-       vrec->disabled = FALSE;
-       vrec->type = V_ST_NORMAL;
-
-       add_sf_info(sf, vrec);
-       add_info_list(vrec);
-
-       /* set the voice index */
-       awe_set_sample(vrec);
-
-       return 0;
-}
-
-#endif  /* AWE_HAS_GUS_COMPATIBILITY */
-
-/*
- * sample and voice list handlers
- */
-
-/* append this to the current sf list */
-static void add_sf_info(sf_list *sf, awe_voice_list *rec)
-{
-       if (sf == NULL)
-               return;
-       rec->holder = sf;
-       rec->v.sf_id = sf->sf_id;
-       if (sf->last_infos)
-               sf->last_infos->next = rec;
-       else
-               sf->infos = rec;
-       sf->last_infos = rec;
-       rec->next = NULL;
-       sf->num_info++;
-}
-
-/* prepend this sample to sf list */
-static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
-{
-       if (sf == NULL)
-               return;
-       rec->holder = sf;
-       rec->v.sf_id = sf->sf_id;
-       if (sf->last_samples)
-               sf->last_samples->next = rec;
-       else
-               sf->samples = rec;
-       sf->last_samples = rec;
-       rec->next = NULL;
-       sf->num_sample++;
-}
-
-/* purge the old records which don't belong with the same file id */
-static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
-{
-       rec->next_instr = next;
-       if (rec->bank == AWE_DRUM_BANK) {
-               /* remove samples with the same note range */
-               awe_voice_list *cur, *prev = rec;
-               int low = rec->v.low;
-               int high = rec->v.high;
-               for (cur = next; cur; cur = cur->next_instr) {
-                       if (cur->v.low == low &&
-                           cur->v.high == high &&
-                           ! is_identical_holder(cur->holder, rec->holder))
-                               prev->next_instr = cur->next_instr;
-                       else
-                               prev = cur;
-               }
-       } else {
-               if (! is_identical_holder(next->holder, rec->holder))
-                       /* remove all samples */
-                       rec->next_instr = NULL;
-       }
-}
-
-/* prepend to top of the preset table */
-static void add_info_list(awe_voice_list *rec)
-{
-       awe_voice_list *prev, *cur;
-       int key;
-
-       if (rec->disabled)
-               return;
-
-       key = awe_search_key(rec->bank, rec->instr, rec->v.low);
-       prev = NULL;
-       for (cur = preset_table[key]; cur; cur = cur->next_bank) {
-               /* search the first record with the same bank number */
-               if (cur->instr == rec->instr && cur->bank == rec->bank) {
-                       /* replace the list with the new record */
-                       rec->next_bank = cur->next_bank;
-                       if (prev)
-                               prev->next_bank = rec;
-                       else
-                               preset_table[key] = rec;
-                       purge_old_list(rec, cur);
-                       return;
-               }
-               prev = cur;
-       }
-
-       /* this is the first bank record.. just add this */
-       rec->next_instr = NULL;
-       rec->next_bank = preset_table[key];
-       preset_table[key] = rec;
-}
-
-/* remove samples later than the specified sf_id */
-static void
-awe_remove_samples(int sf_id)
-{
-       sf_list *p, *prev;
-
-       if (sf_id <= 0) {
-               awe_reset_samples();
-               return;
-       }
-       /* already removed? */
-       if (current_sf_id <= sf_id)
-               return;
-
-       for (p = sftail; p; p = prev) {
-               if (p->sf_id <= sf_id)
-                       break;
-               prev = p->prev;
-               awe_free_sf(p);
-       }
-       sftail = p;
-       if (sftail) {
-               sf_id = sftail->sf_id;
-               sftail->next = NULL;
-       } else {
-               sf_id = 0;
-               sfhead = NULL;
-       }
-       current_sf_id = sf_id;
-       if (locked_sf_id > sf_id)
-               locked_sf_id = sf_id;
-
-       rebuild_preset_list();
-}
-
-/* rebuild preset search list */
-static void rebuild_preset_list(void)
-{
-       sf_list *p;
-       awe_voice_list *rec;
-
-       memset(preset_table, 0, sizeof(preset_table));
-
-       for (p = sfhead; p; p = p->next) {
-               for (rec = p->infos; rec; rec = rec->next)
-                       add_info_list(rec);
-       }
-}
-
-/* compare the given sf_id pair */
-static int is_identical_holder(sf_list *sf1, sf_list *sf2)
-{
-       if (sf1 == NULL || sf2 == NULL)
-               return FALSE;
-       if (sf1 == sf2)
-               return TRUE;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       {
-               /* compare with the sharing id */
-               sf_list *p;
-               int counter = 0;
-               if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
-                       sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
-               }
-               for (p = sf1->shared; p; p = p->shared) {
-                       if (counter++ > current_sf_id)
-                               break; /* strange sharing loop.. quit */
-                       if (p == sf2)
-                               return TRUE;
-               }
-       }
-#endif /* allow sharing */
-       return FALSE;
-}
-
-/* search the sample index matching with the given sample id */
-static awe_sample_list *
-search_sample_index(sf_list *sf, int sample)
-{
-       awe_sample_list *p;
-#ifdef AWE_ALLOW_SAMPLE_SHARING
-       int counter = 0;
-       while (sf) {
-               for (p = sf->samples; p; p = p->next) {
-                       if (p->v.sample == sample)
-                               return p;
-               }
-               sf = sf->shared;
-               if (counter++ > current_sf_id)
-                       break; /* strange sharing loop.. quit */
-       }
-#else
-       if (sf) {
-               for (p = sf->samples; p; p = p->next) {
-                       if (p->v.sample == sample)
-                               return p;
-               }
-       }
-#endif
-       return NULL;
-}
-
-/* search the specified sample */
-/* non-zero = found */
-static short
-awe_set_sample(awe_voice_list *rec)
-{
-       awe_sample_list *smp;
-       awe_voice_info *vp = &rec->v;
-
-       vp->index = 0;
-       if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
-               return 0;
-
-       /* set the actual sample offsets */
-       vp->start += smp->v.start;
-       vp->end += smp->v.end;
-       vp->loopstart += smp->v.loopstart;
-       vp->loopend += smp->v.loopend;
-       /* copy mode flags */
-       vp->mode = smp->v.mode_flags;
-       /* set flag */
-       vp->index = 1;
-
-       return 1;
-}
-
-
-/*
- * voice allocation
- */
-
-/* look for all voices associated with the specified note & velocity */
-static int
-awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
-                       awe_voice_info **vlist)
-{
-       int nvoices;
-
-       nvoices = 0;
-       for (; rec; rec = rec->next_instr) {
-               if (note >= rec->v.low &&
-                   note <= rec->v.high &&
-                   velocity >= rec->v.vellow &&
-                   velocity <= rec->v.velhigh) {
-                       if (rec->type == V_ST_MAPPED) {
-                               /* mapper */
-                               vlist[0] = &rec->v;
-                               return -1;
-                       }
-                       vlist[nvoices++] = &rec->v;
-                       if (nvoices >= AWE_MAX_VOICES)
-                               break;
-               }
-       }
-       return nvoices; 
-}
-
-/* store the voice list from the specified note and velocity.
-   if the preset is mapped, seek for the destination preset, and rewrite
-   the note number if necessary.
-   */
-static int
-really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
-{
-       int nvoices;
-       awe_voice_list *vrec;
-       int level = 0;
-
-       for (;;) {
-               vrec = awe_search_instr(bank, instr, *note);
-               nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               if (nvoices == 0) {
-                       if (bank == AWE_DRUM_BANK)
-                               /* search default drumset */
-                               vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
-                       else
-                               /* search default preset */
-                               vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
-                       nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               }
-               if (nvoices == 0) {
-                       if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
-                               /* search default drumset */
-                               vrec = awe_search_instr(bank, 0, *note);
-                       else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
-                               /* search default preset */
-                               vrec = awe_search_instr(0, instr, *note);
-                       nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
-               }
-               if (nvoices < 0) { /* mapping */
-                       int key = vlist[0]->fixkey;
-                       instr = vlist[0]->start;
-                       bank = vlist[0]->end;
-                       if (level++ > 5) {
-                               printk(KERN_ERR "AWE32: too deep mapping level\n");
-                               return 0;
-                       }
-                       if (key >= 0)
-                               *note = key;
-               } else
-                       break;
-       }
-
-       return nvoices;
-}
-
-/* allocate voices corresponding note and velocity; supports multiple insts. */
-static void
-awe_alloc_multi_voices(int ch, int note, int velocity, int key)
-{
-       int i, v, nvoices, bank;
-       awe_voice_info *vlist[AWE_MAX_VOICES];
-
-       if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
-               bank = AWE_DRUM_BANK; /* always search drumset */
-       else
-               bank = channels[ch].bank;
-
-       /* check the possible voices; note may be changeable if mapped */
-       nvoices = really_alloc_voices(bank, channels[ch].instr,
-                                     &note, velocity, vlist);
-
-       /* set the voices */
-       current_alloc_time++;
-       for (i = 0; i < nvoices; i++) {
-               v = awe_clear_voice();
-               voices[v].key = key;
-               voices[v].ch = ch;
-               voices[v].note = note;
-               voices[v].velocity = velocity;
-               voices[v].time = current_alloc_time;
-               voices[v].cinfo = &channels[ch];
-               voices[v].sample = vlist[i];
-               voices[v].state = AWE_ST_MARK;
-               voices[v].layer = nvoices - i - 1;  /* in reverse order */
-       }
-
-       /* clear the mark in allocated voices */
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].state == AWE_ST_MARK)
-                       voices[i].state = AWE_ST_OFF;
-                       
-       }
-}
-
-
-/* search an empty voice.
-   if no empty voice is found, at least terminate a voice
-   */
-static int
-awe_clear_voice(void)
-{
-       enum {
-               OFF=0, RELEASED, SUSTAINED, PLAYING, END
-       };
-       struct voice_candidate_t {
-               int best;
-               int time;
-               int vtarget;
-       } candidate[END];
-       int i, type, vtarget;
-
-       vtarget = 0xffff;
-       for (type = OFF; type < END; type++) {
-               candidate[type].best = -1;
-               candidate[type].time = current_alloc_time + 1;
-               candidate[type].vtarget = vtarget;
-       }
-
-       for (i = 0; i < awe_max_voices; i++) {
-               if (voices[i].state & AWE_ST_OFF)
-                       type = OFF;
-               else if (voices[i].state & AWE_ST_RELEASED)
-                       type = RELEASED;
-               else if (voices[i].state & AWE_ST_SUSTAINED)
-                       type = SUSTAINED;
-               else if (voices[i].state & ~AWE_ST_MARK)
-                       type = PLAYING;
-               else
-                       continue;
-#ifdef AWE_CHECK_VTARGET
-               /* get current volume */
-               vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
-#endif
-               if (candidate[type].best < 0 ||
-                   vtarget < candidate[type].vtarget ||
-                   (vtarget == candidate[type].vtarget &&
-                    voices[i].time < candidate[type].time)) {
-                       candidate[type].best = i;
-                       candidate[type].time = voices[i].time;
-                       candidate[type].vtarget = vtarget;
-               }
-       }
-
-       for (type = OFF; type < END; type++) {
-               if ((i = candidate[type].best) >= 0) {
-                       if (voices[i].state != AWE_ST_OFF)
-                               awe_terminate(i);
-                       awe_voice_init(i, TRUE);
-                       return i;
-               }
-       }
-       return 0;
-}
-
-
-/* search sample for the specified note & velocity and set it on the voice;
- * note that voice is the voice index (not channel index)
- */
-static void
-awe_alloc_one_voice(int voice, int note, int velocity)
-{
-       int ch, nvoices, bank;
-       awe_voice_info *vlist[AWE_MAX_VOICES];
-
-       ch = voices[voice].ch;
-       if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
-               bank = AWE_DRUM_BANK; /* always search drumset */
-       else
-               bank = voices[voice].cinfo->bank;
-
-       nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
-                                     &note, velocity, vlist);
-       if (nvoices > 0) {
-               voices[voice].time = ++current_alloc_time;
-               voices[voice].sample = vlist[0]; /* use the first one */
-               voices[voice].layer = 0;
-               voices[voice].note = note;
-               voices[voice].velocity = velocity;
-       }
-}
-
-
-/*
- * sequencer2 functions
- */
-
-/* search an empty voice; used by sequencer2 */
-static int
-awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-       playing_mode = AWE_PLAY_MULTI2;
-       awe_info.nr_voices = AWE_MAX_CHANNELS;
-       return awe_clear_voice();
-}
-
-
-/* set up voice; used by sequencer2 */
-static void
-awe_setup_voice(int dev, int voice, int chn)
-{
-       struct channel_info *info;
-       if (synth_devs[dev] == NULL ||
-           (info = &synth_devs[dev]->chn_info[chn]) == NULL)
-               return;
-
-       if (voice < 0 || voice >= awe_max_voices)
-               return;
-
-       DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
-       channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
-       channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
-       channels[chn].panning =
-               info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
-       channels[chn].bender = info->bender_value; /* zero center */
-       channels[chn].bank = info->controllers[CTL_BANK_SELECT];
-       channels[chn].sustained = info->controllers[CTL_SUSTAIN];
-       if (info->controllers[CTL_EXT_EFF_DEPTH]) {
-               FX_SET(&channels[chn].fx, AWE_FX_REVERB,
-                      info->controllers[CTL_EXT_EFF_DEPTH] * 2);
-       }
-       if (info->controllers[CTL_CHORUS_DEPTH]) {
-               FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
-                      info->controllers[CTL_CHORUS_DEPTH] * 2);
-       }
-       awe_set_instr(dev, chn, info->pgm_num);
-}
-
-
-#ifdef CONFIG_AWE32_MIXER
-/*
- * AWE32 mixer device control
- */
-
-static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
-
-static int my_mixerdev = -1;
-
-static struct mixer_operations awe_mixer_operations = {
-       .owner  = THIS_MODULE,
-       .id     = "AWE",
-       .name   = "AWE32 Equalizer",
-       .ioctl  = awe_mixer_ioctl,
-};
-
-static void __init attach_mixer(void)
-{
-       if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
-               mixer_devs[my_mixerdev] = &awe_mixer_operations;
-       }
-}
-
-static void unload_mixer(void)
-{
-       if (my_mixerdev >= 0)
-               sound_unload_mixerdev(my_mixerdev);
-}
-
-static int
-awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
-{
-       int i, level, value;
-
-       if (((cmd >> 8) & 0xff) != 'M')
-               return -EINVAL;
-
-       if (get_user(level, (int __user *)arg))
-               return -EFAULT;
-       level = ((level & 0xff) + (level >> 8)) / 2;
-       DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
-
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-               switch (cmd & 0xff) {
-               case SOUND_MIXER_BASS:
-                       value = level * 12 / 100;
-                       if (value >= 12)
-                               value = 11;
-                       ctrls[AWE_MD_BASS_LEVEL] = value;
-                       awe_update_equalizer();
-                       break;
-               case SOUND_MIXER_TREBLE:
-                       value = level * 12 / 100;
-                       if (value >= 12)
-                               value = 11;
-                       ctrls[AWE_MD_TREBLE_LEVEL] = value;
-                       awe_update_equalizer();
-                       break;
-               case SOUND_MIXER_VOLUME:
-                       level = level * 127 / 100;
-                       if (level >= 128) level = 127;
-                       atten_relative = FALSE;
-                       atten_offset = vol_table[level];
-                       awe_update_volume();
-                       break;
-               }
-       }
-       switch (cmd & 0xff) {
-       case SOUND_MIXER_BASS:
-               level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_TREBLE:
-               level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_VOLUME:
-               value = atten_offset;
-               if (atten_relative)
-                       value += ctrls[AWE_MD_ZERO_ATTEN];
-               for (i = 127; i > 0; i--) {
-                       if (value <= vol_table[i])
-                               break;
-               }
-               level = i * 100 / 127;
-               level = (level << 8) | level;
-               break;
-       case SOUND_MIXER_DEVMASK:
-               level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
-               break;
-       default:
-               level = 0;
-               break;
-       }
-       if (put_user(level, (int __user *)arg))
-               return -EFAULT;
-       return level;
-}
-#endif /* CONFIG_AWE32_MIXER */
-
-
-/*
- * initialization of Emu8000
- */
-
-/* intiailize audio channels */
-static void
-awe_init_audio(void)
-{
-       int ch;
-
-       /* turn off envelope engines */
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke(AWE_DCYSUSV(ch), 0x80);
-       }
-  
-       /* reset all other parameters to zero */
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke(AWE_ENVVOL(ch), 0);
-               awe_poke(AWE_ENVVAL(ch), 0);
-               awe_poke(AWE_DCYSUS(ch), 0);
-               awe_poke(AWE_ATKHLDV(ch), 0);
-               awe_poke(AWE_LFO1VAL(ch), 0);
-               awe_poke(AWE_ATKHLD(ch), 0);
-               awe_poke(AWE_LFO2VAL(ch), 0);
-               awe_poke(AWE_IP(ch), 0);
-               awe_poke(AWE_IFATN(ch), 0);
-               awe_poke(AWE_PEFE(ch), 0);
-               awe_poke(AWE_FMMOD(ch), 0);
-               awe_poke(AWE_TREMFRQ(ch), 0);
-               awe_poke(AWE_FM2FRQ2(ch), 0);
-               awe_poke_dw(AWE_PTRX(ch), 0);
-               awe_poke_dw(AWE_VTFT(ch), 0);
-               awe_poke_dw(AWE_PSST(ch), 0);
-               awe_poke_dw(AWE_CSL(ch), 0);
-               awe_poke_dw(AWE_CCCA(ch), 0);
-       }
-
-       for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
-               awe_poke_dw(AWE_CPF(ch), 0);
-               awe_poke_dw(AWE_CVCF(ch), 0);
-       }
-}
-
-
-/* initialize DMA address */
-static void
-awe_init_dma(void)
-{
-       awe_poke_dw(AWE_SMALR, 0);
-       awe_poke_dw(AWE_SMARR, 0);
-       awe_poke_dw(AWE_SMALW, 0);
-       awe_poke_dw(AWE_SMARW, 0);
-}
-
-
-/* initialization arrays; from ADIP */
-
-static unsigned short init1[128] = {
-       0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
-       0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
-       0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
-       0x33ff, 0x0c30,  0x37ff, 0x0d30, 0x3bff, 0x0e30,  0x3fff, 0x0f30,
-
-       0x43ff, 0x0030,  0x47ff, 0x0130, 0x4bff, 0x0230,  0x4fff, 0x0330,
-       0x53ff, 0x0430,  0x57ff, 0x0530, 0x5bff, 0x0630,  0x5fff, 0x0730,
-       0x63ff, 0x0830,  0x67ff, 0x0930, 0x6bff, 0x0a30,  0x6fff, 0x0b30,
-       0x73ff, 0x0c30,  0x77ff, 0x0d30, 0x7bff, 0x0e30,  0x7fff, 0x0f30,
-
-       0x83ff, 0x0030,  0x87ff, 0x0130, 0x8bff, 0x0230,  0x8fff, 0x0330,
-       0x93ff, 0x0430,  0x97ff, 0x0530, 0x9bff, 0x0630,  0x9fff, 0x0730,
-       0xa3ff, 0x0830,  0xa7ff, 0x0930, 0xabff, 0x0a30,  0xafff, 0x0b30,
-       0xb3ff, 0x0c30,  0xb7ff, 0x0d30, 0xbbff, 0x0e30,  0xbfff, 0x0f30,
-
-       0xc3ff, 0x0030,  0xc7ff, 0x0130, 0xcbff, 0x0230,  0xcfff, 0x0330,
-       0xd3ff, 0x0430,  0xd7ff, 0x0530, 0xdbff, 0x0630,  0xdfff, 0x0730,
-       0xe3ff, 0x0830,  0xe7ff, 0x0930, 0xebff, 0x0a30,  0xefff, 0x0b30,
-       0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
-};
-
-static unsigned short init2[128] = {
-       0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
-       0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
-       0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
-       0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
-
-       0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
-       0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
-       0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
-       0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
-
-       0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
-       0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
-       0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
-       0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
-
-       0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
-       0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
-       0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
-       0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
-};
-
-static unsigned short init3[128] = {
-       0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-       0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
-       0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
-       0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
-
-       0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
-       0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
-       0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
-       0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
-
-       0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
-       0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
-       0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
-       0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
-
-       0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
-       0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
-       0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
-       0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-static unsigned short init4[128] = {
-       0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
-       0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
-       0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
-       0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
-
-       0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
-       0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
-       0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
-       0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
-
-       0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
-       0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
-       0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
-       0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
-
-       0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
-       0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
-       0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
-       0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
-};
-
-
-/* send initialization arrays to start up */
-static void
-awe_init_array(void)
-{
-       awe_send_array(init1);
-       awe_wait(1024);
-       awe_send_array(init2);
-       awe_send_array(init3);
-       awe_poke_dw(AWE_HWCF4, 0);
-       awe_poke_dw(AWE_HWCF5, 0x83);
-       awe_poke_dw(AWE_HWCF6, 0x8000);
-       awe_send_array(init4);
-}
-
-/* send an initialization array */
-static void
-awe_send_array(unsigned short *data)
-{
-       int i;
-       unsigned short *p;
-
-       p = data;
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT1(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT2(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT3(i), *p);
-       for (i = 0; i < AWE_MAX_VOICES; i++, p++)
-               awe_poke(AWE_INIT4(i), *p);
-}
-
-
-/*
- * set up awe32 channels to some known state.
- */
-
-/* set the envelope & LFO parameters to the default values; see ADIP */
-static void
-awe_tweak_voice(int i)
-{
-       /* set all mod/vol envelope shape to minimum */
-       awe_poke(AWE_ENVVOL(i), 0x8000);
-       awe_poke(AWE_ENVVAL(i), 0x8000);
-       awe_poke(AWE_DCYSUS(i), 0x7F7F);
-       awe_poke(AWE_ATKHLDV(i), 0x7F7F);
-       awe_poke(AWE_ATKHLD(i), 0x7F7F);
-       awe_poke(AWE_PEFE(i), 0);  /* mod envelope height to zero */
-       awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
-       awe_poke(AWE_LFO2VAL(i), 0x8000);
-       awe_poke(AWE_IP(i), 0xE000);    /* no pitch shift */
-       awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
-       awe_poke(AWE_FMMOD(i), 0);
-       awe_poke(AWE_TREMFRQ(i), 0);
-       awe_poke(AWE_FM2FRQ2(i), 0);
-}
-
-static void
-awe_tweak(void)
-{
-       int i;
-       /* reset all channels */
-       for (i = 0; i < awe_max_voices; i++)
-               awe_tweak_voice(i);
-}
-
-
-/*
- *  initializes the FM section of AWE32;
- *   see Vince Vu's unofficial AWE32 programming guide
- */
-
-static void
-awe_init_fm(void)
-{
-#ifndef AWE_ALWAYS_INIT_FM
-       /* if no extended memory is on board.. */
-       if (memsize <= 0)
-               return;
-#endif
-       DEBUG(3,printk("AWE32: initializing FM\n"));
-
-       /* Initialize the last two channels for DRAM refresh and producing
-          the reverb and chorus effects for Yamaha OPL-3 synthesizer */
-
-       /* 31: FM left channel, 0xffffe0-0xffffe8 */
-       awe_poke(AWE_DCYSUSV(30), 0x80);
-       awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
-       awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
-                   (DEF_FM_CHORUS_DEPTH << 24));
-       awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
-       awe_poke_dw(AWE_CPF(30), 0);
-       awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
-
-       /* 32: FM right channel, 0xfffff0-0xfffff8 */
-       awe_poke(AWE_DCYSUSV(31), 0x80);
-       awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
-       awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
-                   (DEF_FM_CHORUS_DEPTH << 24));
-       awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
-       awe_poke_dw(AWE_CPF(31), 0x8000);
-       awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
-
-       /* skew volume & cutoff */
-       awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
-       awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
-
-       voices[30].state = AWE_ST_FM;
-       voices[31].state = AWE_ST_FM;
-
-       /* change maximum channels to 30 */
-       awe_max_voices = AWE_NORMAL_VOICES;
-       if (playing_mode == AWE_PLAY_DIRECT)
-               awe_info.nr_voices = awe_max_voices;
-       else
-               awe_info.nr_voices = AWE_MAX_CHANNELS;
-       voice_alloc->max_voice = awe_max_voices;
-}
-
-/*
- *  AWE32 DRAM access routines
- */
-
-/* open DRAM write accessing mode */
-static int
-awe_open_dram_for_write(int offset, int channels)
-{
-       int vidx[AWE_NORMAL_VOICES];
-       int i;
-
-       if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
-               channels = AWE_NORMAL_VOICES;
-               for (i = 0; i < AWE_NORMAL_VOICES; i++)
-                       vidx[i] = i;
-       } else {
-               for (i = 0; i < channels; i++) {
-                       vidx[i] = awe_clear_voice();
-                       voices[vidx[i]].state = AWE_ST_MARK;
-               }
-       }
-
-       /* use all channels for DMA transfer */
-       for (i = 0; i < channels; i++) {
-               if (vidx[i] < 0) continue;
-               awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
-               awe_poke_dw(AWE_VTFT(vidx[i]), 0);
-               awe_poke_dw(AWE_CVCF(vidx[i]), 0);
-               awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
-               awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
-               awe_poke_dw(AWE_PSST(vidx[i]), 0);
-               awe_poke_dw(AWE_CSL(vidx[i]), 0);
-               awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
-               voices[vidx[i]].state = AWE_ST_DRAM;
-       }
-       /* point channels 31 & 32 to ROM samples for DRAM refresh */
-       awe_poke_dw(AWE_VTFT(30), 0);
-       awe_poke_dw(AWE_PSST(30), 0x1d8);
-       awe_poke_dw(AWE_CSL(30), 0x1e0);
-       awe_poke_dw(AWE_CCCA(30), 0x1d8);
-       awe_poke_dw(AWE_VTFT(31), 0);
-       awe_poke_dw(AWE_PSST(31), 0x1d8);
-       awe_poke_dw(AWE_CSL(31), 0x1e0);
-       awe_poke_dw(AWE_CCCA(31), 0x1d8);
-       voices[30].state = AWE_ST_FM;
-       voices[31].state = AWE_ST_FM;
-
-       /* if full bit is on, not ready to write on */
-       if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
-               for (i = 0; i < channels; i++) {
-                       awe_poke_dw(AWE_CCCA(vidx[i]), 0);
-                       voices[vidx[i]].state = AWE_ST_OFF;
-               }
-               printk("awe: not ready to write..\n");
-               return -EPERM;
-       }
-
-       /* set address to write */
-       awe_poke_dw(AWE_SMALW, offset);
-
-       return 0;
-}
-
-/* open DRAM for RAM size detection */
-static void
-awe_open_dram_for_check(void)
-{
-       int i;
-       for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-               awe_poke(AWE_DCYSUSV(i), 0x80);
-               awe_poke_dw(AWE_VTFT(i), 0);
-               awe_poke_dw(AWE_CVCF(i), 0);
-               awe_poke_dw(AWE_PTRX(i), 0x40000000);
-               awe_poke_dw(AWE_CPF(i), 0x40000000);
-               awe_poke_dw(AWE_PSST(i), 0);
-               awe_poke_dw(AWE_CSL(i), 0);
-               if (i & 1) /* DMA write */
-                       awe_poke_dw(AWE_CCCA(i), 0x06000000);
-               else       /* DMA read */
-                       awe_poke_dw(AWE_CCCA(i), 0x04000000);
-               voices[i].state = AWE_ST_DRAM;
-       }
-}
-
-
-/* close dram access */
-static void
-awe_close_dram(void)
-{
-       int i;
-       /* wait until FULL bit in SMAxW register be false */
-       for (i = 0; i < 10000; i++) {
-               if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
-                       break;
-               awe_wait(10);
-       }
-
-       for (i = 0; i < AWE_NORMAL_VOICES; i++) {
-               if (voices[i].state == AWE_ST_DRAM) {
-                       awe_poke_dw(AWE_CCCA(i), 0);
-                       awe_poke(AWE_DCYSUSV(i), 0x807F);
-                       voices[i].state = AWE_ST_OFF;
-               }
-       }
-}
-
-
-/*
- * check dram size on AWE board
- */
-
-/* any three numbers you like */
-#define UNIQUE_ID1     0x1234
-#define UNIQUE_ID2     0x4321
-#define UNIQUE_ID3     0xABCD
-
-static void __init
-awe_check_dram(void)
-{
-       if (awe_present) /* already initialized */
-               return;
-
-       if (memsize >= 0) { /* given by config file or module option */
-               memsize *= 1024; /* convert to Kbytes */
-               return;
-       }
-
-       awe_open_dram_for_check();
-
-       memsize = 0;
-
-       /* set up unique two id numbers */
-       awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
-       awe_poke(AWE_SMLD, UNIQUE_ID1);
-       awe_poke(AWE_SMLD, UNIQUE_ID2);
-
-       while (memsize < AWE_MAX_DRAM_SIZE) {
-               awe_wait(5);
-               /* read a data on the DRAM start address */
-               awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
-               awe_peek(AWE_SMLD); /* discard stale data  */
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
-                       break;
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
-                       break;
-               memsize += 512;  /* increment 512kbytes */
-               /* Write a unique data on the test address;
-                * if the address is out of range, the data is written on
-                * 0x200000(=AWE_DRAM_OFFSET).  Then the two id words are
-                * broken by this data.
-                */
-               awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
-               awe_poke(AWE_SMLD, UNIQUE_ID3);
-               awe_wait(5);
-               /* read a data on the just written DRAM address */
-               awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
-               awe_peek(AWE_SMLD); /* discard stale data  */
-               if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
-                       break;
-       }
-       awe_close_dram();
-
-       DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
-
-       /* convert to Kbytes */
-       memsize *= 1024;
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * chorus and reverb controls; from VV's guide
- */
-
-/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
-static char chorus_defined[AWE_CHORUS_NUMBERS];
-static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
-       {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
-       {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
-       {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
-       {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
-       {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
-       {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
-       {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
-       {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
-};
-
-static int
-awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
-               printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
-               return -EINVAL;
-       }
-       if (count < sizeof(awe_chorus_fx_rec)) {
-               printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-                          sizeof(awe_chorus_fx_rec)))
-               return -EFAULT;
-       chorus_defined[patch->optarg] = TRUE;
-       return 0;
-}
-
-static void
-awe_set_chorus_mode(int effect)
-{
-       if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
-           (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
-               return;
-       awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
-       awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
-       awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
-       awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
-       awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
-       awe_poke_dw(AWE_HWCF6, 0x8000);
-       awe_poke_dw(AWE_HWCF7, 0x0000);
-}
-
-static void
-awe_update_chorus_mode(void)
-{
-       awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
-}
-
-/*----------------------------------------------------------------*/
-
-/* reverb mode settings; write the following 28 data of 16 bit length
- *   on the corresponding ports in the reverb_cmds array
- */
-static char reverb_defined[AWE_CHORUS_NUMBERS];
-static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
-{{  /* room 1 */
-       0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
-       0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
-       0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 2 */
-       0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* room 3 */
-       0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
-       0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
-       0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
-}},
-{{  /* hall 1 */
-       0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
-       0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
-       0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
-}},
-{{  /* hall 2 */
-       0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
-       0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
-       0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* plate */
-       0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
-       0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
-       0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
-       0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
-}},
-{{  /* delay */
-       0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
-       0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-       0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-       0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-{{  /* panning delay */
-       0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
-       0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
-       0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
-       0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
-}},
-};
-
-static struct ReverbCmdPair {
-       unsigned short cmd, port;
-} reverb_cmds[28] = {
-  {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
-  {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
-  {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
-  {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
-  {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
-  {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
-  {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
-};
-
-static int
-awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
-{
-       if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
-               printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
-               return -EINVAL;
-       }
-       if (count < sizeof(awe_reverb_fx_rec)) {
-               printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
-               return -EINVAL;
-       }
-       if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
-                          sizeof(awe_reverb_fx_rec)))
-               return -EFAULT;
-       reverb_defined[patch->optarg] = TRUE;
-       return 0;
-}
-
-static void
-awe_set_reverb_mode(int effect)
-{
-       int i;
-       if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
-           (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
-               return;
-       for (i = 0; i < 28; i++)
-               awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
-                        reverb_parm[effect].parms[i]);
-}
-
-static void
-awe_update_reverb_mode(void)
-{
-       awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
-}
-
-/*
- * treble/bass equalizer control
- */
-
-static unsigned short bass_parm[12][3] = {
-       {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
-       {0xD25B, 0xD35B, 0x0000}, /*  -8 */
-       {0xD24C, 0xD34C, 0x0000}, /*  -6 */
-       {0xD23D, 0xD33D, 0x0000}, /*  -4 */
-       {0xD21F, 0xD31F, 0x0000}, /*  -2 */
-       {0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
-       {0xC219, 0xC319, 0x0001}, /*  +2 */
-       {0xC22A, 0xC32A, 0x0001}, /*  +4 */
-       {0xC24C, 0xC34C, 0x0001}, /*  +6 */
-       {0xC26E, 0xC36E, 0x0001}, /*  +8 */
-       {0xC248, 0xC348, 0x0002}, /* +10 */
-       {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
-};
-
-static unsigned short treble_parm[12][9] = {
-       {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
-       {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
-       {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
-       {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
-       {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
-};
-
-
-/*
- * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
- */
-static void
-awe_equalizer(int bass, int treble)
-{
-       unsigned short w;
-
-       if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
-               return;
-       awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
-       awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
-       awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
-       awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
-       awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
-       awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
-       awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
-       awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
-       awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
-       awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
-       w = bass_parm[bass][2] + treble_parm[treble][8];
-       awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
-       awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
-}
-
-static void awe_update_equalizer(void)
-{
-       awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
-}
-
-
-/*----------------------------------------------------------------*/
-
-#ifdef CONFIG_AWE32_MIDIEMU
-
-/*
- * Emu8000 MIDI Emulation
- */
-
-/*
- * midi queue record
- */
-
-/* queue type */
-enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
-
-#define MAX_MIDIBUF    64
-
-/* midi status */
-typedef struct MidiStatus {
-       int queue;      /* queue type */
-       int qlen;       /* queue length */
-       int read;       /* chars read */
-       int status;     /* current status */
-       int chan;       /* current channel */
-       unsigned char buf[MAX_MIDIBUF];
-} MidiStatus;
-
-/* MIDI mode type */
-enum { MODE_GM, MODE_GS, MODE_XG, };
-
-/* NRPN / CC -> Emu8000 parameter converter */
-typedef struct {
-       int control;
-       int awe_effect;
-       unsigned short (*convert)(int val);
-} ConvTable;
-
-
-/*
- * prototypes
- */
-
-static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
-static void awe_midi_close(int dev);
-static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
-static int awe_midi_outputc(int dev, unsigned char midi_byte);
-
-static void init_midi_status(MidiStatus *st);
-static void clear_rpn(void);
-static void get_midi_char(MidiStatus *st, int c);
-/*static void queue_varlen(MidiStatus *st, int c);*/
-static void special_event(MidiStatus *st, int c);
-static void queue_read(MidiStatus *st, int c);
-static void midi_note_on(MidiStatus *st);
-static void midi_note_off(MidiStatus *st);
-static void midi_key_pressure(MidiStatus *st);
-static void midi_channel_pressure(MidiStatus *st);
-static void midi_pitch_wheel(MidiStatus *st);
-static void midi_program_change(MidiStatus *st);
-static void midi_control_change(MidiStatus *st);
-static void midi_select_bank(MidiStatus *st, int val);
-static void midi_nrpn_event(MidiStatus *st);
-static void midi_rpn_event(MidiStatus *st);
-static void midi_detune(int chan, int coarse, int fine);
-static void midi_system_exclusive(MidiStatus *st);
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
-static int xg_control_change(MidiStatus *st, int cmd, int val);
-
-#define numberof(ary)  (sizeof(ary)/sizeof(ary[0]))
-
-
-/*
- * OSS Midi device record
- */
-
-static struct midi_operations awe_midi_operations =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"AWE Midi Emu", 0, 0, SNDCARD_SB},
-       .in_info        = {0},
-       .open           = awe_midi_open, /*open*/
-       .close          = awe_midi_close, /*close*/
-       .ioctl          = awe_midi_ioctl, /*ioctl*/
-       .outputc        = awe_midi_outputc, /*outputc*/
-};
-
-static int my_mididev = -1;
-
-static void __init attach_midiemu(void)
-{
-       if ((my_mididev = sound_alloc_mididev()) < 0)
-               printk ("Sound: Too many midi devices detected\n");
-       else
-               midi_devs[my_mididev] = &awe_midi_operations;
-}
-
-static void unload_midiemu(void)
-{
-       if (my_mididev >= 0)
-               sound_unload_mididev(my_mididev);
-}
-
-
-/*
- * open/close midi device
- */
-
-static int midi_opened = FALSE;
-
-static int midi_mode;
-static int coarsetune, finetune;
-
-static int xg_mapping = TRUE;
-static int xg_bankmode;
-
-/* effect sensitivity */
-
-#define FX_CUTOFF      0
-#define FX_RESONANCE   1
-#define FX_ATTACK      2
-#define FX_RELEASE     3
-#define FX_VIBRATE     4
-#define FX_VIBDEPTH    5
-#define FX_VIBDELAY    6
-#define FX_NUMS                7
-
-#define DEF_FX_CUTOFF          170
-#define DEF_FX_RESONANCE       6
-#define DEF_FX_ATTACK          50
-#define DEF_FX_RELEASE         50
-#define DEF_FX_VIBRATE         30
-#define DEF_FX_VIBDEPTH                4
-#define DEF_FX_VIBDELAY                1500
-
-/* effect sense: */
-static int gs_sense[] = 
-{
-       DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-       DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-static int xg_sense[] = 
-{
-       DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
-       DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
-};
-
-
-/* current status */
-static MidiStatus curst;
-
-
-static int
-awe_midi_open (int dev, int mode,
-              void (*input)(int,unsigned char),
-              void (*output)(int))
-{
-       if (midi_opened)
-               return -EBUSY;
-
-       midi_opened = TRUE;
-
-       midi_mode = MODE_GM;
-
-       curst.queue = Q_NONE;
-       curst.qlen = 0;
-       curst.read = 0;
-       curst.status = 0;
-       curst.chan = 0;
-       memset(curst.buf, 0, sizeof(curst.buf));
-
-       init_midi_status(&curst);
-
-       return 0;
-}
-
-static void
-awe_midi_close (int dev)
-{
-       midi_opened = FALSE;
-}
-
-
-static int
-awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-       return -EPERM;
-}
-
-static int
-awe_midi_outputc (int dev, unsigned char midi_byte)
-{
-       if (! midi_opened)
-               return 1;
-
-       /* force to change playing mode */
-       playing_mode = AWE_PLAY_MULTI;
-
-       get_midi_char(&curst, midi_byte);
-       return 1;
-}
-
-
-/*
- * initialize
- */
-
-static void init_midi_status(MidiStatus *st)
-{
-       clear_rpn();
-       coarsetune = 0;
-       finetune = 0;
-}
-
-
-/*
- * RPN & NRPN
- */
-
-#define MAX_MIDI_CHANNELS      16
-
-/* RPN & NRPN */
-static unsigned char nrpn[MAX_MIDI_CHANNELS];  /* current event is NRPN? */
-static int msb_bit;  /* current event is msb for RPN/NRPN */
-/* RPN & NRPN indeces */
-static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
-/* RPN & NRPN values */
-static int rpn_val[MAX_MIDI_CHANNELS];
-
-static void clear_rpn(void)
-{
-       int i;
-       for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
-               nrpn[i] = 0;
-               rpn_msb[i] = 127;
-               rpn_lsb[i] = 127;
-               rpn_val[i] = 0;
-       }
-       msb_bit = 0;
-}
-
-
-/*
- * process midi queue
- */
-
-/* status event types */
-typedef void (*StatusEvent)(MidiStatus *st);
-static struct StatusEventList {
-       StatusEvent process;
-       int qlen;
-} status_event[8] = {
-       {midi_note_off, 2},
-       {midi_note_on, 2},
-       {midi_key_pressure, 2},
-       {midi_control_change, 2},
-       {midi_program_change, 1},
-       {midi_channel_pressure, 1},
-       {midi_pitch_wheel, 2},
-       {NULL, 0},
-};
-
-
-/* read a char from fifo and process it */
-static void get_midi_char(MidiStatus *st, int c)
-{
-       if (c == 0xfe) {
-               /* ignore active sense */
-               st->queue = Q_NONE;
-               return;
-       }
-
-       switch (st->queue) {
-       /* case Q_VARLEN: queue_varlen(st, c); break;*/
-       case Q_READ:
-       case Q_SYSEX:
-               queue_read(st, c);
-               break;
-       case Q_NONE:
-               st->read = 0;
-               if ((c & 0xf0) == 0xf0) {
-                       special_event(st, c);
-               } else if (c & 0x80) { /* status change */
-                       st->status = (c >> 4) & 0x07;
-                       st->chan = c & 0x0f;
-                       st->queue = Q_READ;
-                       st->qlen = status_event[st->status].qlen;
-                       if (st->qlen == 0)
-                               st->queue = Q_NONE;
-               }
-               break;
-       }
-}
-
-/* 0xfx events */
-static void special_event(MidiStatus *st, int c)
-{
-       switch (c) {
-       case 0xf0: /* system exclusive */
-               st->queue = Q_SYSEX;
-               st->qlen = 0;
-               break;
-       case 0xf1: /* MTC quarter frame */
-       case 0xf3: /* song select */
-               st->queue = Q_READ;
-               st->qlen = 1;
-               break;
-       case 0xf2: /* song position */
-               st->queue = Q_READ;
-               st->qlen = 2;
-               break;
-       }
-}
-
-#if 0
-/* read variable length value */
-static void queue_varlen(MidiStatus *st, int c)
-{
-       st->qlen += (c & 0x7f);
-       if (c & 0x80) {
-               st->qlen <<= 7;
-               return;
-       }
-       if (st->qlen <= 0) {
-               st->qlen = 0;
-               st->queue = Q_NONE;
-       }
-       st->queue = Q_READ;
-       st->read = 0;
-}
-#endif
-
-
-/* read a char */
-static void queue_read(MidiStatus *st, int c)
-{
-       if (st->read < MAX_MIDIBUF) {
-               if (st->queue != Q_SYSEX)
-                       c &= 0x7f;
-               st->buf[st->read] = (unsigned char)c;
-       }
-       st->read++;
-       if (st->queue == Q_SYSEX && c == 0xf7) {
-               midi_system_exclusive(st);
-               st->queue = Q_NONE;
-       } else if (st->queue == Q_READ && st->read >= st->qlen) {
-               if (status_event[st->status].process)
-                       status_event[st->status].process(st);
-               st->queue = Q_NONE;
-       }
-}
-
-
-/*
- * status events
- */
-
-/* note on */
-static void midi_note_on(MidiStatus *st)
-{
-       DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-       if (st->buf[1] == 0)
-               midi_note_off(st);
-       else
-               awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* note off */
-static void midi_note_off(MidiStatus *st)
-{
-       DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
-       awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* key pressure change */
-static void midi_key_pressure(MidiStatus *st)
-{
-       awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
-}
-
-/* channel pressure change */
-static void midi_channel_pressure(MidiStatus *st)
-{
-       channels[st->chan].chan_press = st->buf[0];
-       awe_modwheel_change(st->chan, st->buf[0]);
-}
-
-/* pitch wheel change */
-static void midi_pitch_wheel(MidiStatus *st)
-{
-       int val = (int)st->buf[1] * 128 + st->buf[0];
-       awe_bender(0, st->chan, val);
-}
-
-/* program change */
-static void midi_program_change(MidiStatus *st)
-{
-       int preset;
-       preset = st->buf[0];
-       if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
-               preset = 0;
-       else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
-               preset += 64;
-
-       awe_set_instr(0, st->chan, preset);
-}
-
-#define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
-#define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
-#define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
-
-/* midi control change */
-static void midi_control_change(MidiStatus *st)
-{
-       int cmd = st->buf[0];
-       int val = st->buf[1];
-
-       DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
-       if (midi_mode == MODE_XG) {
-               if (xg_control_change(st, cmd, val))
-                       return;
-       }
-
-       /* controls #31 - #64 are LSB of #0 - #31 */
-       msb_bit = 1;
-       if (cmd >= 0x20 && cmd < 0x40) {
-               msb_bit = 0;
-               cmd -= 0x20;
-       }
-
-       switch (cmd) {
-       case CTL_SOFT_PEDAL:
-               if (val == 127)
-                       add_effect(st->chan, AWE_FX_CUTOFF, -160);
-               else
-                       unset_effect(st->chan, AWE_FX_CUTOFF);
-               break;
-
-       case CTL_BANK_SELECT:
-               midi_select_bank(st, val);
-               break;
-               
-       /* set RPN/NRPN parameter */
-       case CTL_REGIST_PARM_NUM_MSB:
-               nrpn[st->chan]=0; rpn_msb[st->chan]=val;
-               break;
-       case CTL_REGIST_PARM_NUM_LSB:
-               nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
-               break;
-       case CTL_NONREG_PARM_NUM_MSB:
-               nrpn[st->chan]=1; rpn_msb[st->chan]=val;
-               break;
-       case CTL_NONREG_PARM_NUM_LSB:
-               nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
-               break;
-
-       /* send RPN/NRPN entry */
-       case CTL_DATA_ENTRY:
-               if (msb_bit)
-                       rpn_val[st->chan] = val * 128;
-               else
-                       rpn_val[st->chan] |= val;
-               if (nrpn[st->chan])
-                       midi_nrpn_event(st);
-               else
-                       midi_rpn_event(st);
-               break;
-
-       /* increase/decrease data entry */
-       case CTL_DATA_INCREMENT:
-               rpn_val[st->chan]++;
-               midi_rpn_event(st);
-               break;
-       case CTL_DATA_DECREMENT:
-               rpn_val[st->chan]--;
-               midi_rpn_event(st);
-               break;
-
-       /* default */
-       default:
-               awe_controller(0, st->chan, cmd, val);
-               break;
-       }
-}
-
-/* tone bank change */
-static void midi_select_bank(MidiStatus *st, int val)
-{
-       if (midi_mode == MODE_XG && msb_bit) {
-               xg_bankmode = val;
-               /* XG MSB value; not normal bank selection */
-               switch (val) {
-               case 127: /* remap to drum channel */
-                       awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
-                       break;
-               default: /* remap to normal channel */
-                       awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-                       break;
-               }
-               return;
-       } else if (midi_mode == MODE_GS && !msb_bit)
-               /* ignore LSB bank in GS mode (used for mapping) */
-               return;
-
-       /* normal bank controls; accept both MSB and LSB */
-       if (! IS_DRUM_CHANNEL(st->chan)) {
-               if (midi_mode == MODE_XG) {
-                       if (xg_bankmode) return;
-                       if (val == 64 || val == 126)
-                               val = 0;
-               } else if (midi_mode == MODE_GS && val == 127)
-                       val = 0;
-               awe_controller(0, st->chan, CTL_BANK_SELECT, val);
-       }
-}
-
-
-/*
- * RPN events
- */
-
-static void midi_rpn_event(MidiStatus *st)
-{
-       int type;
-       type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
-       switch (type) {
-       case 0x0000: /* Pitch bend sensitivity */
-               /* MSB only / 1 semitone per 128 */
-               if (msb_bit) {
-                       channels[st->chan].bender_range = 
-                               rpn_val[st->chan] * 100 / 128;
-               }
-               break;
-                                       
-       case 0x0001: /* fine tuning: */
-               /* MSB/LSB, 8192=center, 100/8192 cent step */
-               finetune = rpn_val[st->chan] - 8192;
-               midi_detune(st->chan, coarsetune, finetune);
-               break;
-
-       case 0x0002: /* coarse tuning */
-               /* MSB only / 8192=center, 1 semitone per 128 */
-               if (msb_bit) {
-                       coarsetune = rpn_val[st->chan] - 8192;
-                       midi_detune(st->chan, coarsetune, finetune);
-               }
-               break;
-
-       case 0x7F7F: /* "lock-in" RPN */
-               break;
-       }
-}
-
-
-/* tuning:
- *   coarse = -8192 to 8192 (100 cent per 128)
- *   fine = -8192 to 8192 (max=100cent)
- */
-static void midi_detune(int chan, int coarse, int fine)
-{
-       /* 4096 = 1200 cents in AWE parameter */
-       int val;
-       val = coarse * 4096 / (12 * 128);
-       val += fine / 24;
-       if (val)
-               send_effect(chan, AWE_FX_INIT_PITCH, val);
-       else
-               unset_effect(chan, AWE_FX_INIT_PITCH);
-}
-
-
-/*
- * system exclusive message
- * GM/GS/XG macros are accepted
- */
-
-static void midi_system_exclusive(MidiStatus *st)
-{
-       /* GM on */
-       static unsigned char gm_on_macro[] = {
-               0x7e,0x7f,0x09,0x01,
-       };
-       /* XG on */
-       static unsigned char xg_on_macro[] = {
-               0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
-       };
-       /* GS prefix
-        * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
-        * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
-        * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
-        */
-       static unsigned char gs_pfx_macro[] = {
-               0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
-       };
-
-#if 0
-       /* SC88 system mode set
-        * single module mode: XX=1
-        * double module mode: XX=0
-        */
-       static unsigned char gs_mode_macro[] = {
-               0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
-       };
-       /* SC88 display macro: XX=01:bitmap, 00:text
-        */
-       static unsigned char gs_disp_macro[] = {
-               0x41,0x10,0x45,0x12,0x10,/*XX,00*/
-       };
-#endif
-
-       /* GM on */
-       if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
-               if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-                       midi_mode = MODE_GM;
-               init_midi_status(st);
-       }
-
-       /* GS macros */
-       else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
-               if (midi_mode != MODE_GS && midi_mode != MODE_XG)
-                       midi_mode = MODE_GS;
-
-               if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
-                       /* GS reset */
-                       init_midi_status(st);
-               }
-
-               else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
-                       /* drum pattern */
-                       int p = st->buf[5] & 0x0f;
-                       if (p == 0) p = 9;
-                       else if (p < 10) p--;
-                       if (st->buf[7] == 0)
-                               DRUM_CHANNEL_OFF(p);
-                       else
-                               DRUM_CHANNEL_ON(p);
-
-               } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
-                       /* program */
-                       int p = st->buf[5] & 0x0f;
-                       if (p == 0) p = 9;
-                       else if (p < 10) p--;
-                       if (! IS_DRUM_CHANNEL(p))
-                               awe_set_instr(0, p, st->buf[7]);
-
-               } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
-                       /* reverb mode */
-                       awe_set_reverb_mode(st->buf[7]);
-
-               } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
-                       /* chorus mode */
-                       awe_set_chorus_mode(st->buf[7]);
-
-               } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
-                       /* master volume */
-                       awe_change_master_volume(st->buf[7]);
-
-               }
-       }
-
-       /* XG on */
-       else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
-               midi_mode = MODE_XG;
-               xg_mapping = TRUE;
-               xg_bankmode = 0;
-       }
-}
-
-
-/*----------------------------------------------------------------*/
-
-/*
- * convert NRPN/control values
- */
-
-static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-       int i, cval;
-       for (i = 0; i < num_tables; i++) {
-               if (table[i].control == type) {
-                       cval = table[i].convert(val);
-                       send_effect(st->chan, table[i].awe_effect, cval);
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
-{
-       int i, cval;
-       for (i = 0; i < num_tables; i++) {
-               if (table[i].control == type) {
-                       cval = table[i].convert(val);
-                       add_effect(st->chan, table[i].awe_effect|0x80, cval);
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-
-/*
- * AWE32 NRPN effects
- */
-
-static unsigned short fx_delay(int val);
-static unsigned short fx_attack(int val);
-static unsigned short fx_hold(int val);
-static unsigned short fx_decay(int val);
-static unsigned short fx_the_value(int val);
-static unsigned short fx_twice_value(int val);
-static unsigned short fx_conv_pitch(int val);
-static unsigned short fx_conv_Q(int val);
-
-/* function for each NRPN */           /* [range]  units */
-#define fx_env1_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_env1_attack fx_attack       /* [0,5940] 1msec */
-#define fx_env1_hold   fx_hold         /* [0,8191] 1msec */
-#define fx_env1_decay  fx_decay        /* [0,5940] 4msec */
-#define fx_env1_release        fx_decay        /* [0,5940] 4msec */
-#define fx_env1_sustain        fx_the_value    /* [0,127] 0.75dB */
-#define fx_env1_pitch  fx_the_value    /* [-127,127] 9.375cents */
-#define fx_env1_cutoff fx_the_value    /* [-127,127] 56.25cents */
-
-#define fx_env2_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_env2_attack fx_attack       /* [0,5940] 1msec */
-#define fx_env2_hold   fx_hold         /* [0,8191] 1msec */
-#define fx_env2_decay  fx_decay        /* [0,5940] 4msec */
-#define fx_env2_release        fx_decay        /* [0,5940] 4msec */
-#define fx_env2_sustain        fx_the_value    /* [0,127] 0.75dB */
-
-#define fx_lfo1_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_lfo1_freq   fx_twice_value  /* [0,127] 84mHz */
-#define fx_lfo1_volume fx_twice_value  /* [0,127] 0.1875dB */
-#define fx_lfo1_pitch  fx_the_value    /* [-127,127] 9.375cents */
-#define fx_lfo1_cutoff fx_twice_value  /* [-64,63] 56.25cents */
-
-#define fx_lfo2_delay  fx_delay        /* [0,5900] 4msec */
-#define fx_lfo2_freq   fx_twice_value  /* [0,127] 84mHz */
-#define fx_lfo2_pitch  fx_the_value    /* [-127,127] 9.375cents */
-
-#define fx_init_pitch  fx_conv_pitch   /* [-8192,8192] cents */
-#define fx_chorus      fx_the_value    /* [0,255] -- */
-#define fx_reverb      fx_the_value    /* [0,255] -- */
-#define fx_cutoff      fx_twice_value  /* [0,127] 62Hz */
-#define fx_filterQ     fx_conv_Q       /* [0,127] -- */
-
-static unsigned short fx_delay(int val)
-{
-       return (unsigned short)calc_parm_delay(val);
-}
-
-static unsigned short fx_attack(int val)
-{
-       return (unsigned short)calc_parm_attack(val);
-}
-
-static unsigned short fx_hold(int val)
-{
-       return (unsigned short)calc_parm_hold(val);
-}
-
-static unsigned short fx_decay(int val)
-{
-       return (unsigned short)calc_parm_decay(val);
-}
-
-static unsigned short fx_the_value(int val)
-{
-       return (unsigned short)(val & 0xff);
-}
-
-static unsigned short fx_twice_value(int val)
-{
-       return (unsigned short)((val * 2) & 0xff);
-}
-
-static unsigned short fx_conv_pitch(int val)
-{
-       return (short)(val * 4096 / 1200);
-}
-
-static unsigned short fx_conv_Q(int val)
-{
-       return (unsigned short)((val / 8) & 0xff);
-}
-
-
-static ConvTable awe_effects[] =
-{
-       { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
-       { 1, AWE_FX_LFO1_FREQ,  fx_lfo1_freq},
-       { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
-       { 3, AWE_FX_LFO2_FREQ,  fx_lfo2_freq},
-
-       { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
-       { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
-       { 6, AWE_FX_ENV1_HOLD,  fx_env1_hold},
-       { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
-       { 8, AWE_FX_ENV1_SUSTAIN,       fx_env1_sustain},
-       { 9, AWE_FX_ENV1_RELEASE,       fx_env1_release},
-
-       {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
-       {11, AWE_FX_ENV2_ATTACK,        fx_env2_attack},
-       {12, AWE_FX_ENV2_HOLD,  fx_env2_hold},
-       {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
-       {14, AWE_FX_ENV2_SUSTAIN,       fx_env2_sustain},
-       {15, AWE_FX_ENV2_RELEASE,       fx_env2_release},
-
-       {16, AWE_FX_INIT_PITCH, fx_init_pitch},
-       {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
-       {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
-       {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
-       {20, AWE_FX_LFO1_VOLUME,        fx_lfo1_volume},
-       {21, AWE_FX_CUTOFF,             fx_cutoff},
-       {22, AWE_FX_FILTERQ,    fx_filterQ},
-       {23, AWE_FX_LFO1_CUTOFF,        fx_lfo1_cutoff},
-       {24, AWE_FX_ENV1_CUTOFF,        fx_env1_cutoff},
-       {25, AWE_FX_CHORUS,             fx_chorus},
-       {26, AWE_FX_REVERB,             fx_reverb},
-};
-
-static int num_awe_effects = numberof(awe_effects);
-
-
-/*
- * GS(SC88) NRPN effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short gs_cutoff(int val)
-{
-       return (val - 64) * gs_sense[FX_CUTOFF] / 50;
-}
-
-/* resonance: 0 to 15(max) */
-static unsigned short gs_filterQ(int val)
-{
-       return (val - 64) * gs_sense[FX_RESONANCE] / 50;
-}
-
-/* attack: */
-static unsigned short gs_attack(int val)
-{
-       return -(val - 64) * gs_sense[FX_ATTACK] / 50;
-}
-
-/* decay: */
-static unsigned short gs_decay(int val)
-{
-       return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* release: */
-static unsigned short gs_release(int val)
-{
-       return -(val - 64) * gs_sense[FX_RELEASE] / 50;
-}
-
-/* vibrato freq: 0.042Hz step, max=255 */
-static unsigned short gs_vib_rate(int val)
-{
-       return (val - 64) * gs_sense[FX_VIBRATE] / 50;
-}
-
-/* vibrato depth: max=127, 1 octave */
-static unsigned short gs_vib_depth(int val)
-{
-       return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
-}
-
-/* vibrato delay: -0.725msec step */
-static unsigned short gs_vib_delay(int val)
-{
-       return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
-}
-
-static ConvTable gs_effects[] =
-{
-       {32, AWE_FX_CUTOFF,     gs_cutoff},
-       {33, AWE_FX_FILTERQ,    gs_filterQ},
-       {99, AWE_FX_ENV2_ATTACK, gs_attack},
-       {100, AWE_FX_ENV2_DECAY, gs_decay},
-       {102, AWE_FX_ENV2_RELEASE, gs_release},
-       {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
-       {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
-       {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
-};
-
-static int num_gs_effects = numberof(gs_effects);
-
-
-/*
- * NRPN events: accept as AWE32/SC88 specific controls
- */
-
-static void midi_nrpn_event(MidiStatus *st)
-{
-       if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
-               if (! msb_bit) /* both MSB/LSB necessary */
-                       send_converted_effect(awe_effects, num_awe_effects,
-                                             st, rpn_lsb[st->chan],
-                                             rpn_val[st->chan] - 8192);
-       } else if (rpn_msb[st->chan] == 1) {
-               if (msb_bit) /* only MSB is valid */
-                       add_converted_effect(gs_effects, num_gs_effects,
-                                            st, rpn_lsb[st->chan],
-                                            rpn_val[st->chan] / 128);
-       }
-}
-
-
-/*
- * XG control effects; still experimental
- */
-
-/* cutoff: quarter semitone step, max=255 */
-static unsigned short xg_cutoff(int val)
-{
-       return (val - 64) * xg_sense[FX_CUTOFF] / 64;
-}
-
-/* resonance: 0(open) to 15(most nasal) */
-static unsigned short xg_filterQ(int val)
-{
-       return (val - 64) * xg_sense[FX_RESONANCE] / 64;
-}
-
-/* attack: */
-static unsigned short xg_attack(int val)
-{
-       return -(val - 64) * xg_sense[FX_ATTACK] / 64;
-}
-
-/* release: */
-static unsigned short xg_release(int val)
-{
-       return -(val - 64) * xg_sense[FX_RELEASE] / 64;
-}
-
-static ConvTable xg_effects[] =
-{
-       {71, AWE_FX_CUTOFF,     xg_cutoff},
-       {74, AWE_FX_FILTERQ,    xg_filterQ},
-       {72, AWE_FX_ENV2_RELEASE, xg_release},
-       {73, AWE_FX_ENV2_ATTACK, xg_attack},
-};
-
-static int num_xg_effects = numberof(xg_effects);
-
-static int xg_control_change(MidiStatus *st, int cmd, int val)
-{
-       return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
-}
-
-#endif /* CONFIG_AWE32_MIDIEMU */
-
-
-/*----------------------------------------------------------------*/
-
-
-/*
- * initialization of AWE driver
- */
-
-static void
-awe_initialize(void)
-{
-       DEBUG(0,printk("AWE32: initializing..\n"));
-
-       /* initialize hardware configuration */
-       awe_poke(AWE_HWCF1, 0x0059);
-       awe_poke(AWE_HWCF2, 0x0020);
-
-       /* disable audio; this seems to reduce a clicking noise a bit.. */
-       awe_poke(AWE_HWCF3, 0);
-
-       /* initialize audio channels */
-       awe_init_audio();
-
-       /* initialize DMA */
-       awe_init_dma();
-
-       /* initialize init array */
-       awe_init_array();
-
-       /* check DRAM memory size */
-       awe_check_dram();
-
-       /* initialize the FM section of the AWE32 */
-       awe_init_fm();
-
-       /* set up voice envelopes */
-       awe_tweak();
-
-       /* enable audio */
-       awe_poke(AWE_HWCF3, 0x0004);
-
-       /* set default values */
-       awe_init_ctrl_parms(TRUE);
-
-       /* set equalizer */
-       awe_update_equalizer();
-
-       /* set reverb & chorus modes */
-       awe_update_reverb_mode();
-       awe_update_chorus_mode();
-}
-
-
-/*
- * Core Device Management Functions
- */
-
-/* store values to i/o port array */
-static void setup_ports(int port1, int port2, int port3)
-{
-       awe_ports[0] = port1;
-       if (port2 == 0)
-               port2 = port1 + 0x400;
-       awe_ports[1] = port2;
-       awe_ports[2] = port2 + 2;
-       if (port3 == 0)
-               port3 = port1 + 0x800;
-       awe_ports[3] = port3;
-       awe_ports[4] = port3 + 2;
-
-       port_setuped = TRUE;
-}
-
-/*
- * port request
- *  0x620-623, 0xA20-A23, 0xE20-E23
- */
-
-static int
-awe_request_region(void)
-{
-       if (! port_setuped)
-               return 0;
-       if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
-               return 0;
-       if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
-               goto err_out;
-       if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
-               goto err_out1;
-       return 1;
-err_out1:
-       release_region(awe_ports[1], 4);
-err_out:
-       release_region(awe_ports[0], 4);
-       return 0;
-}
-
-static void
-awe_release_region(void)
-{
-       if (! port_setuped) return;
-       release_region(awe_ports[0], 4);
-       release_region(awe_ports[1], 4);
-       release_region(awe_ports[3], 4);
-}
-
-static int awe_attach_device(void)
-{
-       if (awe_present) return 0; /* for OSS38.. called twice? */
-
-       /* reserve I/O ports for awedrv */
-       if (! awe_request_region()) {
-               printk(KERN_ERR "AWE32: I/O area already used.\n");
-               return 0;
-       }
-
-       /* set buffers to NULL */
-       sfhead = sftail = NULL;
-
-       my_dev = sound_alloc_synthdev();
-       if (my_dev == -1) {
-               printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
-               awe_release_region();
-               return 0;
-       }
-
-       voice_alloc = &awe_operations.alloc;
-       voice_alloc->max_voice = awe_max_voices;
-       synth_devs[my_dev] = &awe_operations;
-
-#ifdef CONFIG_AWE32_MIXER
-       attach_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-       attach_midiemu();
-#endif
-
-       /* clear all samples */
-       awe_reset_samples();
-
-       /* initialize AWE32 hardware */
-       awe_initialize();
-
-       sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
-               AWEDRV_VERSION, memsize/1024);
-       printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
-
-       awe_present = TRUE;
-
-       return 1;
-}
-
-static void awe_dettach_device(void)
-{
-       if (awe_present) {
-               awe_reset_samples();
-               awe_release_region();
-               free_tables();
-#ifdef CONFIG_AWE32_MIXER
-               unload_mixer();
-#endif
-#ifdef CONFIG_AWE32_MIDIEMU
-               unload_midiemu();
-#endif
-               sound_unload_synthdev(my_dev);
-               awe_present = FALSE;
-       }
-}
-
-
-/*
- * Legacy device Probing
- */
-
-/* detect emu8000 chip on the specified address; from VV's guide */
-
-static int __init
-awe_detect_base(int addr)
-{
-       setup_ports(addr, 0, 0);
-       if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
-               return 0;
-       if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
-               return 0;
-       if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
-               return 0;
-        DEBUG(0,printk("AWE32 found at %x\n", addr));
-       return 1;
-}
-
-static int __init awe_detect_legacy_devices(void)
-{
-       int base;
-       for (base = 0x620; base <= 0x680; base += 0x20)
-               if (awe_detect_base(base)) {
-                       awe_attach_device();
-                       return 1;
-                       }
-       DEBUG(0,printk("AWE32 Legacy detection failed\n"));
-       return 0;
-}
-
-
-/*
- * PnP device Probing
- */
-
-static struct pnp_device_id awe_pnp_ids[] = {
-       {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
-       {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
-       {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
-       { } /* terminator */
-};
-
-MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
-
-static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
-{
-       int io1, io2, io3;
-
-       if (awe_present) {
-               printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
-       }
-
-       if (!pnp_port_valid(dev,0) ||
-           !pnp_port_valid(dev,1) ||
-           !pnp_port_valid(dev,2)) {
-               printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
-               return -EINVAL;
-       }
-       io1 = pnp_port_start(dev,0);
-       io2 = pnp_port_start(dev,1);
-       io3 = pnp_port_start(dev,2);
-       printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
-              io1, io2, io3);
-       setup_ports(io1, io2, io3);
-
-       awe_attach_device();
-       return 0;
-}
-
-static void awe_pnp_remove(struct pnp_dev *dev)
-{
-       awe_dettach_device();
-}
-
-static struct pnp_driver awe_pnp_driver = {
-       .name           = "AWE32",
-       .id_table       = awe_pnp_ids,
-       .probe          = awe_pnp_probe,
-       .remove         = awe_pnp_remove,
-};
-
-static int __init awe_detect_pnp_devices(void)
-{
-       int ret;
-
-       ret = pnp_register_driver(&awe_pnp_driver);
-       if (ret<0)
-               printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
-       return ret;
-}
-
-
-/*
- * device / lowlevel (module) interface
- */
-
-static int __init
-awe_detect(void)
-{
-       printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
-       if (isapnp) {
-               if (awe_detect_pnp_devices()>=0)
-                       return 1;
-       } else
-               printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
-
-       if (awe_detect_legacy_devices())
-               return 1;
-
-       return 0;
-}
-
-static int __init attach_awe(void)
-{
-       return awe_detect() ? 0 : -ENODEV;
-}
-
-static void __exit unload_awe(void)
-{
-       pnp_unregister_driver(&awe_pnp_driver);
-       awe_dettach_device();
-}
-
-
-module_init(attach_awe);
-module_exit(unload_awe);
-
-#ifndef MODULE
-static int __init setup_awe(char *str)
-{
-       /* io, memsize, isapnp */
-       int ints[4];
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       io = ints[1];
-       memsize = ints[2];
-       isapnp = ints[3];
-
-       return 1;
-}
-
-__setup("awe=", setup_awe);
-#endif
diff --git a/sound/oss/awe_wave.h b/sound/oss/awe_wave.h
deleted file mode 100644 (file)
index fe58481..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * sound/oss/awe_wave.h
- *
- * Configuration of AWE32/SB32/AWE64 wave table synth driver.
- *   version 0.4.4; Jan. 4, 2000
- *
- * Copyright (C) 1996-1998 Takashi Iwai
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * chorus & reverb effects send for FM chip: from 0 to 0xff
- * larger numbers often cause weird sounds.
- */
-
-#define DEF_FM_CHORUS_DEPTH    0x10
-#define DEF_FM_REVERB_DEPTH    0x10
-
-
-/*
- * other compile conditions
- */
-
-/* initialize FM passthrough even without extended RAM */
-#undef AWE_ALWAYS_INIT_FM
-
-/* debug on */
-#define AWE_DEBUG_ON
-
-/* GUS compatible mode */
-#define AWE_HAS_GUS_COMPATIBILITY
-
-/* add MIDI emulation by wavetable */
-#define CONFIG_AWE32_MIDIEMU
-
-/* add mixer control of emu8000 equalizer */
-#undef CONFIG_AWE32_MIXER
-
-/* use new volume calculation method as default */
-#define AWE_USE_NEW_VOLUME_CALC
-
-/* check current volume target for searching empty voices */
-#define AWE_CHECK_VTARGET
-
-/* allow sample sharing */
-#define AWE_ALLOW_SAMPLE_SHARING
-
-/*
- * AWE32 card configuration:
- * uncomment the following lines *ONLY* when auto detection doesn't
- * work properly on your machine.
- */
-
-/*#define AWE_DEFAULT_BASE_ADDR        0x620*/ /* base port address */
-/*#define AWE_DEFAULT_MEM_SIZE 512*/   /* kbytes */
-
-/*
- * AWE driver version number
- */
-#define AWE_MAJOR_VERSION      0
-#define AWE_MINOR_VERSION      4
-#define AWE_TINY_VERSION       4
-#define AWE_VERSION_NUMBER     ((AWE_MAJOR_VERSION<<16)|(AWE_MINOR_VERSION<<8)|AWE_TINY_VERSION)
-#define AWEDRV_VERSION         "0.4.4"
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
deleted file mode 100644 (file)
index ea51aaf..0000000
+++ /dev/null
@@ -1,3381 +0,0 @@
-/*
- *      cmpci.c  --  C-Media PCI audio driver.
- *
- *      Copyright (C) 1999  C-media support (support@cmedia.com.tw)
- *
- *      Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *     For update, visit:
- *             http://www.cmedia.com.tw
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi, Jan Pfeifer
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.98   0.1   Initial release
- *    10.05.98   0.2   Fixed many bugs, esp. ADC rate calculation
- *                     First stab at a simple midi interface (no bells&whistles)
- *    13.05.98   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                     set_dac_rate in the FMODE_WRITE case in cm_open
- *                     Fix hwptr out of bounds (now mpg123 works)
- *    14.05.98   0.4   Don't allow excessive interrupt rates
- *    08.06.98   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.98   0.6   Do not include modversions.h
- *                     Now mixer behaviour can basically be selected between
- *                     "OSS documented" and "OSS actual" behaviour
- *    31.08.98   0.7   Fix realplayer problems - dac.count issues
- *    10.12.98   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.98   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.99   0.10  remove the silly SA_INTERRUPT flag.
- *                     hopefully killed the egcs section type conflict
- *    12.03.99   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                     reported by Johan Maes <joma@telindus.be>
- *    22.03.99   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                     read/write cannot be executed
- *    18.08.99   1.5   Only deallocate DMA buffer when unloading.
- *    02.09.99   1.6   Enable SPDIF LOOP
- *                     Change the mixer read back
- *    21.09.99   2.33  Use RCS version as driver version.
- *                     Add support for modem, S/PDIF loop and 4 channels.
- *                     (8738 only)
- *                     Fix bug cause x11amp cannot play.
- *
- *    Fixes:
- *    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *    18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it
- *                was calling prog_dmabuf with s->lock held, call missing
- *                unlock_kernel in cm_midi_release
- *    08/10/2001 - use set_current_state in some more places
- *
- *     Carlos Eduardo Gorges <carlos@techlinux.com.br>
- *     Fri May 25 2001
- *     - SMP support ( spin[un]lock* revision )
- *     - speaker mixer support
- *     Mon Aug 13 2001
- *     - optimizations and cleanups
- *
- *    03/01/2003 - open_mode fixes from Georg Acher <acher@in.tum.de>
- *     Simon Braunschmidt <brasimon@web.de>
- *     Sat Jan 31 2004
- *     - provide support for opl3 FM by releasing IO range after initialization
- *
- *    ChenLi Tien <cltien@cmedia.com.tw>
- *    Mar 9 2004
- *     - Fix S/PDIF out if spdif_loop enabled
- *     - Load opl3 driver if enabled (fmio in proper range)
- *     - Load mpu401 if enabled (mpuio in proper range)
- *    Apr 5 2004
- *     - Fix DUAL_DAC dma synchronization bug
- *     - Check exist FM/MPU401 I/O before activate.
- *     - Add AFTM_S16_BE format support, so MPlayer/Xine can play AC3/mutlichannel
- *       on Mac
- *     - Change to support kernel 2.6 so only small patch needed
- *     - All parameters default to 0
- *     - Add spdif_out to send PCM through S/PDIF out jack
- *     - Add hw_copy to get 4-spaker output for general PCM/analog output
- *
- *    Stefan Thater <stefan.thaeter@gmx.de>
- *    Apr 5 2004
- *     - Fix mute single channel for CD/Line-in/AUX-in
- */
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-#include "sound_config.h"
-#include "mpu401.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-#include "opl3.h"
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-#include <linux/gameport.h>
-#include <linux/mutex.h>
-
-#endif
-
-/* --------------------------------------------------------------------- */
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#undef DMABYTEIO
-#define        DBG(x) {}
-/* --------------------------------------------------------------------- */
-
-#define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
-
-/* CM8338 registers definition ****************/
-
-#define CODEC_CMI_FUNCTRL0             (0x00)
-#define CODEC_CMI_FUNCTRL1             (0x04)
-#define CODEC_CMI_CHFORMAT             (0x08)
-#define CODEC_CMI_INT_HLDCLR           (0x0C)
-#define CODEC_CMI_INT_STATUS           (0x10)
-#define CODEC_CMI_LEGACY_CTRL          (0x14)
-#define CODEC_CMI_MISC_CTRL            (0x18)
-#define CODEC_CMI_TDMA_POS             (0x1C)
-#define CODEC_CMI_MIXER                        (0x20)
-#define CODEC_SB16_DATA                        (0x22)
-#define CODEC_SB16_ADDR                        (0x23)
-#define CODEC_CMI_MIXER1               (0x24)
-#define CODEC_CMI_MIXER2               (0x25)
-#define CODEC_CMI_AUX_VOL              (0x26)
-#define CODEC_CMI_MISC                 (0x27)
-#define CODEC_CMI_AC97                 (0x28)
-
-#define CODEC_CMI_CH0_FRAME1           (0x80)
-#define CODEC_CMI_CH0_FRAME2           (0x84)
-#define CODEC_CMI_CH1_FRAME1           (0x88)
-#define CODEC_CMI_CH1_FRAME2           (0x8C)
-
-#define CODEC_CMI_SPDIF_CTRL           (0x90)
-#define CODEC_CMI_MISC_CTRL2           (0x92)
-
-#define CODEC_CMI_EXT_REG              (0xF0)
-
-/*  Mixer registers for SB16 ******************/
-
-#define DSP_MIX_DATARESETIDX           ((unsigned char)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L         ((unsigned char)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R         ((unsigned char)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L          ((unsigned char)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R          ((unsigned char)(0x33))
-#define DSP_MIX_FMVOLIDX_L             ((unsigned char)(0x34))
-#define DSP_MIX_FMVOLIDX_R             ((unsigned char)(0x35))
-#define DSP_MIX_CDVOLIDX_L             ((unsigned char)(0x36))
-#define DSP_MIX_CDVOLIDX_R             ((unsigned char)(0x37))
-#define DSP_MIX_LINEVOLIDX_L           ((unsigned char)(0x38))
-#define DSP_MIX_LINEVOLIDX_R           ((unsigned char)(0x39))
-
-#define DSP_MIX_MICVOLIDX              ((unsigned char)(0x3A))
-#define DSP_MIX_SPKRVOLIDX             ((unsigned char)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX              ((unsigned char)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L            ((unsigned char)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R            ((unsigned char)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L            ((unsigned char)(0x3F))
-#define DSP_MIX_INGAINIDX_R            ((unsigned char)(0x40))
-#define DSP_MIX_OUTGAINIDX_L           ((unsigned char)(0x41))
-#define DSP_MIX_OUTGAINIDX_R           ((unsigned char)(0x42))
-
-#define DSP_MIX_AGCIDX                 ((unsigned char)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L            ((unsigned char)(0x44))
-#define DSP_MIX_TREBLEIDX_R            ((unsigned char)(0x45))
-#define DSP_MIX_BASSIDX_L              ((unsigned char)(0x46))
-#define DSP_MIX_BASSIDX_R              ((unsigned char)(0x47))
-#define DSP_MIX_EXTENSION              ((unsigned char)(0xf0))
-// pseudo register for AUX
-#define        DSP_MIX_AUXVOL_L                ((unsigned char)(0x50))
-#define        DSP_MIX_AUXVOL_R                ((unsigned char)(0x51))
-
-// I/O length
-#define CM_EXTENT_CODEC          0x100
-#define CM_EXTENT_MIDI   0x2
-#define CM_EXTENT_SYNTH          0x4
-#define CM_EXTENT_GAME   0x8
-
-// Function Control Register 0 (00h)
-#define CHADC0         0x01
-#define CHADC1         0x02
-#define PAUSE0         0x04
-#define PAUSE1         0x08
-
-// Function Control Register 0+2 (02h)
-#define CHEN0          0x01
-#define CHEN1          0x02
-#define RST_CH0                0x04
-#define RST_CH1                0x08
-
-// Function Control Register 1 (04h)
-#define JYSTK_EN       0x02
-#define UART_EN                0x04
-#define        SPDO2DAC        0x40
-#define        SPDFLOOP        0x80
-
-// Function Control Register 1+1 (05h)
-#define        SPDF_0          0x01
-#define        SPDF_1          0x02
-#define        ASFC            0x1c
-#define        DSFC            0xe0
-#define        SPDIF2DAC       (SPDF_1 << 8 | SPDO2DAC)
-
-// Channel Format Register (08h)
-#define CM_CFMT_STEREO 0x01
-#define CM_CFMT_16BIT  0x02
-#define CM_CFMT_MASK   0x03
-#define        POLVALID        0x20
-#define        INVSPDIFI       0x80
-
-// Channel Format Register+2 (0ah)
-#define SPD24SEL       0x20
-
-// Channel Format Register+3 (0bh)
-#define CHB3D          0x20
-#define CHB3D5C                0x80
-
-// Interrupt Hold/Clear Register+2 (0eh)
-#define        CH0_INT_EN      0x01
-#define        CH1_INT_EN      0x02
-
-// Interrupt Register (10h)
-#define CHINT0         0x01
-#define CHINT1         0x02
-#define        CH0BUSY         0x04
-#define        CH1BUSY         0x08
-
-// Legacy Control/Status Register+1 (15h)
-#define        EXBASEN         0x10
-#define        BASE2LIN        0x20
-#define        CENTR2LIN       0x40
-#define        CB2LIN          (BASE2LIN | CENTR2LIN)
-#define        CHB3D6C         0x80
-
-// Legacy Control/Status Register+2 (16h)
-#define        DAC2SPDO        0x20
-#define        SPDCOPYRHT      0x40
-#define        ENSPDOUT        0x80
-
-// Legacy Control/Status Register+3 (17h)
-#define        FMSEL           0x03
-#define        VSBSEL          0x0c
-#define        VMPU            0x60
-#define        NXCHG           0x80
-
-// Miscellaneous Control Register (18h)
-#define        REAR2LIN        0x20
-#define        MUTECH1         0x40
-#define        ENCENTER        0x80
-
-// Miscellaneous Control Register+1 (19h)
-#define        SELSPDIFI2      0x01
-#define        SPDF_AC97       0x80
-
-// Miscellaneous Control Register+2 (1ah)
-#define        AC3_EN          0x04
-#define        FM_EN           0x08
-#define        SPD32SEL        0x20
-#define        XCHGDAC         0x40
-#define        ENDBDAC         0x80
-
-// Miscellaneous Control Register+3 (1bh)
-#define        SPDIFI48K       0x01
-#define        SPDO5V          0x02
-#define        N4SPK3D         0x04
-#define        RESET           0x40
-#define        PWD             0x80
-#define        SPDIF48K        (SPDIFI48K << 24 | SPDF_AC97 << 8)
-
-// Mixer1 (24h)
-#define        CDPLAY          0x01
-#define        X3DEN           0x02
-#define        REAR2FRONT      0x10
-#define        SPK4            0x20
-#define        WSMUTE          0x40
-#define        FMMUTE          0x80
-
-// Miscellaneous Register (27h)
-#define        SPDVALID        0x02
-#define        CENTR2MIC       0x04
-
-// Miscellaneous Register2 (92h)
-#define        SPD32KFMT       0x10
-
-#define CM_CFMT_DACSHIFT   2
-#define CM_CFMT_ADCSHIFT   0
-#define CM_FREQ_DACSHIFT   5
-#define CM_FREQ_ADCSHIFT   2
-#define        RSTDAC  RST_CH1
-#define        RSTADC  RST_CH0
-#define        ENDAC   CHEN1
-#define        ENADC   CHEN0
-#define        PAUSEDAC        PAUSE1
-#define        PAUSEADC        PAUSE0
-#define CODEC_CMI_ADC_FRAME1   CODEC_CMI_CH0_FRAME1
-#define CODEC_CMI_ADC_FRAME2   CODEC_CMI_CH0_FRAME2
-#define CODEC_CMI_DAC_FRAME1   CODEC_CMI_CH1_FRAME1
-#define CODEC_CMI_DAC_FRAME2   CODEC_CMI_CH1_FRAME2
-#define        DACINT  CHINT1
-#define        ADCINT  CHINT0
-#define        DACBUSY CH1BUSY
-#define        ADCBUSY CH0BUSY
-#define        ENDACINT        CH1_INT_EN
-#define        ENADCINT        CH0_INT_EN
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[]   = { 0, 1, 1, 2 };
-
-#define SND_DEV_DSP16   5
-
-#define NR_DEVICE 3            /* maximum number of devices */
-
-#define        set_dac1_rate   set_adc_rate
-#define        set_dac1_rate_unlocked  set_adc_rate_unlocked
-#define        stop_dac1       stop_adc
-#define        stop_dac1_unlocked      stop_adc_unlocked
-#define        get_dmadac1     get_dmaadc
-
-static unsigned int devindex = 0;
-
-//*********************************************/
-
-struct cm_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of cmedia devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       int dev_audio;                  /* soundcore stuff */
-       int dev_mixer;
-
-       unsigned int iosb, iobase, iosynth,
-                        iomidi, iogame, irq;   /* hardware resources */
-       unsigned short deviceid;                /* pci_id */
-
-        struct {                               /* mixer stuff */
-                unsigned int modcnt;
-               unsigned short vol[13];
-        } mix;
-
-       unsigned int rateadc, ratedac;          /* wave stuff */
-       unsigned char fmt, enable;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error;         /* over/underrun */
-               wait_queue_head_t wait;
-
-               unsigned fragsize;      /* redundant, but makes calculations easier */
-               unsigned dmasize;
-               unsigned fragsamples;
-               unsigned dmasamples;
-
-               unsigned mapped:1;      /* OSS stuff */
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       int midi_devc;
-       struct address_info mpu_data;
-#endif
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-       struct gameport *gameport;
-#endif
-
-       int     chip_version;
-       int     max_channels;
-       int     curr_channels;
-       int     capability;             /* HW capability, various for chip versions */
-
-       int     status;                 /* HW or SW state */
-
-       int     spdif_counter;          /* spdif frame counter */
-};
-
-/* flags used for capability */
-#define        CAN_AC3_HW              0x00000001              /* 037 or later */
-#define        CAN_AC3_SW              0x00000002              /* 033 or later */
-#define        CAN_AC3                 (CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC           0x00000004              /* 033 or later */
-#define        CAN_MULTI_CH_HW         0x00000008              /* 039 or later */
-#define        CAN_MULTI_CH            (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define        CAN_LINE_AS_REAR        0x00000010              /* 033 or later */
-#define        CAN_LINE_AS_BASS        0x00000020              /* 039 or later */
-#define        CAN_MIC_AS_BASS         0x00000040              /* 039 or later */
-
-/* flags used for status */
-#define        DO_AC3_HW               0x00000001
-#define        DO_AC3_SW               0x00000002
-#define        DO_AC3                  (DO_AC3_HW | DO_AC3_SW)
-#define        DO_DUAL_DAC             0x00000004
-#define        DO_MULTI_CH_HW          0x00000008
-#define        DO_MULTI_CH             (DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define        DO_LINE_AS_REAR         0x00000010              /* 033 or later */
-#define        DO_LINE_AS_BASS         0x00000020              /* 039 or later */
-#define        DO_MIC_AS_BASS          0x00000040              /* 039 or later */
-#define        DO_SPDIF_OUT            0x00000100
-#define        DO_SPDIF_IN             0x00000200
-#define        DO_SPDIF_LOOP           0x00000400
-#define        DO_BIGENDIAN_W          0x00001000              /* used in PowerPC */
-#define        DO_BIGENDIAN_R          0x00002000              /* used in PowerPC */
-
-static LIST_HEAD(devs);
-
-static int     mpuio;
-static int     fmio;
-static int     joystick;
-static int     spdif_inverse;
-static int     spdif_loop;
-static int     spdif_out;
-static int     use_line_as_rear;
-static int     use_line_as_bass;
-static int     use_mic_as_bass;
-static int     mic_boost;
-static int     hw_copy;
-module_param(mpuio, int, 0);
-module_param(fmio, int, 0);
-module_param(joystick, bool, 0);
-module_param(spdif_inverse, bool, 0);
-module_param(spdif_loop, bool, 0);
-module_param(spdif_out, bool, 0);
-module_param(use_line_as_rear, bool, 0);
-module_param(use_line_as_bass, bool, 0);
-module_param(use_mic_as_bass, bool, 0);
-module_param(mic_boost, bool, 0);
-module_param(hw_copy, bool, 0);
-MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
-MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver");
-MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
-MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
-MODULE_PARM_DESC(spdif_out, "(1/0) Send PCM to S/PDIF-out (PCM volume will not function)");
-MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out");
-MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center");
-MODULE_PARM_DESC(use_mic_as_bass, "(1/0) Use mic-in jack as bass/center");
-MODULE_PARM_DESC(mic_boost, "(1/0) Enable microphone boost");
-MODULE_PARM_DESC(hw_copy, "Copy front channel to surround channel");
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned exp=16,l=5,r=0;
-       static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
-
-       /* num: 2, 4, 16, 256, 65536 */
-       /* exp: 1, 2,  4,   8,    16 */
-
-       while(l--) {
-               if( x >= num[l] ) {
-                       if(num[l]>2) x >>= exp;
-                       r+=exp;
-               }
-               exp>>=1;
-       }
-
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outb((inb(addr) & mask) | value, addr);
-}
-
-static void maskw(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outw((inw(addr) & mask) | value, addr);
-}
-
-static void maskl(unsigned int addr, unsigned int mask, unsigned int value)
-{
-       outl((inl(addr) & mask) | value, addr);
-}
-
-static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       if (addr)
-           outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC0, 0);
-}
-
-static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CHADC0);
-}
-
-static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count)
-{
-       outl(addr, s->iobase + CODEC_CMI_DAC_FRAME1);
-       outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, 0);
-       if (s->status & DO_DUAL_DAC)
-               set_dmadac1(s, 0, count);
-}
-
-static void set_countadc(struct cm_state *s, unsigned count)
-{
-       outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2 + 2);
-}
-
-static void set_countdac(struct cm_state *s, unsigned count)
-{
-       outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2 + 2);
-       if (s->status & DO_DUAL_DAC)
-           set_countadc(s, count);
-}
-
-static unsigned get_dmadac(struct cm_state *s)
-{
-       unsigned int curr_addr;
-
-       curr_addr = inw(s->iobase + CODEC_CMI_DAC_FRAME2) + 1;
-       curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-       curr_addr = s->dma_dac.dmasize - curr_addr;
-
-       return curr_addr;
-}
-
-static unsigned get_dmaadc(struct cm_state *s)
-{
-       unsigned int curr_addr;
-
-       curr_addr = inw(s->iobase + CODEC_CMI_ADC_FRAME2) + 1;
-       curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
-       curr_addr = s->dma_adc.dmasize - curr_addr;
-
-       return curr_addr;
-}
-
-static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
-{
-       unsigned char regval, pseudo;
-
-       // pseudo register
-       if (idx == DSP_MIX_AUXVOL_L) {
-               data >>= 4;
-               data &= 0x0f;
-               regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0x0f;
-               outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-               return;
-       }
-       if (idx == DSP_MIX_AUXVOL_R) {
-               data &= 0xf0;
-               regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0xf0;
-               outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL);
-               return;
-       }
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       // pseudo bits
-       if (idx == DSP_MIX_OUTMIXIDX) {
-               pseudo = data & ~0x1f;
-               pseudo >>= 1;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x30;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_L) {
-               pseudo = data & 0x80;
-               pseudo >>= 1;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x40;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_R) {
-               pseudo = data & 0x80;
-               regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x80;
-               outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2);
-       }
-       outb(data, s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-}
-
-static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
-{
-       unsigned char v, pseudo;
-
-       // pseudo register
-       if (idx == DSP_MIX_AUXVOL_L) {
-               v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0x0f;
-               v <<= 4;
-               return v;
-       }
-       if (idx == DSP_MIX_AUXVOL_L) {
-               v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0xf0;
-               return v;
-       }
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       v = inb(s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-       // pseudo bits
-       if (idx == DSP_MIX_OUTMIXIDX) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x30;
-               pseudo <<= 1;
-               v |= pseudo;
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_L) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x40;
-               pseudo <<= 1;
-               v |= pseudo;
-       }
-       if (idx == DSP_MIX_ADCMIXIDX_R) {
-               pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x80;
-               v |= pseudo;
-       }
-       return v;
-}
-
-static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-       if (mask && s->chip_version > 0) {      /* 8338 cannot keep this */
-               s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
-               udelay(10);
-       }
-       s->fmt = (s->fmt & mask) | data;
-       outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
-       udelay(10);
-}
-
-static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_fmt_unlocked(s,mask,data);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-       outb(idx, s->iobase + CODEC_SB16_ADDR);
-       udelay(10);
-       outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
-       udelay(10);
-}
-
-static struct {
-       unsigned        rate;
-       unsigned        lower;
-       unsigned        upper;
-       unsigned char   freq;
-} rate_lookup[] =
-{
-       { 5512,         (0 + 5512) / 2,         (5512 + 8000) / 2,      0 },
-       { 8000,         (5512 + 8000) / 2,      (8000 + 11025) / 2,     4 },
-       { 11025,        (8000 + 11025) / 2,     (11025 + 16000) / 2,    1 },
-       { 16000,        (11025 + 16000) / 2,    (16000 + 22050) / 2,    5 },
-       { 22050,        (16000 + 22050) / 2,    (22050 + 32000) / 2,    2 },
-       { 32000,        (22050 + 32000) / 2,    (32000 + 44100) / 2,    6 },
-       { 44100,        (32000 + 44100) / 2,    (44100 + 48000) / 2,    3 },
-       { 48000,        (44100 + 48000) / 2,    48000,                  7 }
-};
-
-static void set_spdif_copyright(struct cm_state *s, int spdif_copyright)
-{
-       /* enable SPDIF-in Copyright */
-       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~SPDCOPYRHT, spdif_copyright ? SPDCOPYRHT : 0);
-}
-
-static void set_spdif_loop(struct cm_state *s, int spdif_loop)
-{
-       /* enable SPDIF loop */
-       if (spdif_loop) {
-               s->status |= DO_SPDIF_LOOP;
-               /* turn on spdif-in to spdif-out */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, SPDFLOOP);
-       } else {
-               s->status &= ~DO_SPDIF_LOOP;
-               /* turn off spdif-in to spdif-out */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDFLOOP, 0);
-       }
-}
-
-static void set_spdif_monitor(struct cm_state *s, int channel)
-{
-       // SPDO2DAC
-       maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDO2DAC, channel == 2 ? SPDO2DAC : 0);
-       // CDPLAY
-       if (s->chip_version >= 39)
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, channel ? CDPLAY : 0);
-}
-
-static void set_spdifout_level(struct cm_state *s, int level5v)
-{
-       /* SPDO5V */
-       if (s->chip_version > 0)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~SPDO5V, level5v ? SPDO5V : 0);
-}
-
-static void set_spdifin_inverse(struct cm_state *s, int spdif_inverse)
-{
-       if (s->chip_version == 0)       /* 8338 has not this feature */
-               return;
-       if (spdif_inverse) {
-               /* turn on spdif-in inverse */
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT, ~0, INVSPDIFI);
-               else
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
-       } else {
-               /* turn off spdif-ininverse */
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT, ~INVSPDIFI, 0);
-               else
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
-       }
-}
-
-static void set_spdifin_channel2(struct cm_state *s, int channel2)
-{
-       /* SELSPDIFI2 */
-       if (s->chip_version >= 39)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 1, ~SELSPDIFI2, channel2 ? SELSPDIFI2 : 0);
-}
-
-static void set_spdifin_valid(struct cm_state *s, int valid)
-{
-       /* SPDVALID */
-       maskb(s->iobase + CODEC_CMI_MISC, ~SPDVALID, valid ? SPDVALID : 0);
-}
-
-static void set_spdifout_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (rate != 48000 && rate != 44100)
-               rate = 0;
-       if (rate == 48000 || rate == 44100) {
-               set_spdif_loop(s, 0);
-               // SPDF_1
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-               // SPDIFI48K SPDF_AC97
-               maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-               if (s->chip_version >= 55)
-               // SPD32KFMT
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL2, ~SPD32KFMT, rate == 48000 ? SPD32KFMT : 0);
-               if (s->chip_version > 0)
-               // ENSPDOUT
-                       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, ENSPDOUT);
-               // monitor SPDIF out
-               set_spdif_monitor(s, 2);
-               s->status |= DO_SPDIF_OUT;
-       } else {
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~ENSPDOUT, 0);
-               // monitor none
-               set_spdif_monitor(s, 0);
-               s->status &= ~DO_SPDIF_OUT;
-       }
-}
-
-static void set_spdifout(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifout_unlocked(s,rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_spdifin_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (rate == 48000 || rate == 44100) {
-               // SPDF_1
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1);
-               // SPDIFI48K SPDF_AC97
-               maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0);
-               s->status |= DO_SPDIF_IN;
-       } else {
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0);
-               s->status &= ~DO_SPDIF_IN;
-       }
-}
-
-static void set_spdifin(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifin_unlocked(s,rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* find parity for bit 4~30 */
-static unsigned parity(unsigned data)
-{
-       unsigned parity = 0;
-       int counter = 4;
-
-       data >>= 4;     // start from bit 4
-       while (counter <= 30) {
-               if (data & 1)
-                       parity++;
-               data >>= 1;
-               counter++;
-       }
-       return parity & 1;
-}
-
-static void set_ac3_unlocked(struct cm_state *s, unsigned rate)
-{
-       if (!(s->capability & CAN_AC3))
-               return;
-       /* enable AC3 */
-       if (rate && rate != 44100)
-               rate = 48000;
-       if (rate == 48000 || rate == 44100) {
-               // mute DAC
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, WSMUTE);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0, MUTECH1);
-               // AC3EN for 039, 0x04
-               if (s->chip_version >= 39) {
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, AC3_EN);
-                       if (s->chip_version == 55)
-                               maskb(s->iobase + CODEC_CMI_SPDIF_CTRL, ~2, 0);
-               // AC3EN for 037, 0x10
-               } else if (s->chip_version == 37)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10);
-               if (s->capability & CAN_AC3_HW) {
-                       // SPD24SEL for 039, 0x20, but cannot be set
-                       if (s->chip_version == 39)
-                               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, SPD24SEL);
-                       // SPD24SEL for 037, 0x02
-                       else if (s->chip_version == 37)
-                               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02);
-                       if (s->chip_version >= 39)
-                               maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, 0);
-
-                       s->status |= DO_AC3_HW;
-                } else {
-                       // SPD32SEL for 037 & 039
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, SPD32SEL);
-                       // set 176K sample rate to fix 033 HW bug
-                       if (s->chip_version == 33) {
-                               if (rate == 48000)
-                                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08);
-                               else
-                                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-                       }
-                       s->status |= DO_AC3_SW;
-               }
-       } else {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~WSMUTE, 0);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~MUTECH1, 0);
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~(SPD24SEL|0x12), 0);
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~(SPD32SEL|AC3_EN), 0);
-               if (s->chip_version == 33)
-                       maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0);
-               if (s->chip_version >= 39)
-                       maskb(s->iobase + CODEC_CMI_MIXER1, ~0, CDPLAY);
-               s->status &= ~DO_AC3;
-       }
-       s->spdif_counter = 0;
-}
-
-static void set_line_as_rear(struct cm_state *s, int use_line_as_rear)
-{
-       if (!(s->capability & CAN_LINE_AS_REAR))
-               return;
-       if (use_line_as_rear) {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, SPK4);
-               s->status |= DO_LINE_AS_REAR;
-       } else {
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~SPK4, 0);
-               s->status &= ~DO_LINE_AS_REAR;
-       }
-}
-
-static void set_line_as_bass(struct cm_state *s, int use_line_as_bass)
-{
-       if (!(s->capability & CAN_LINE_AS_BASS))
-               return;
-       if (use_line_as_bass) {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, CB2LIN);
-               s->status |= DO_LINE_AS_BASS;
-       } else {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CB2LIN, 0);
-               s->status &= ~DO_LINE_AS_BASS;
-       }
-}
-
-static void set_mic_as_bass(struct cm_state *s, int use_mic_as_bass)
-{
-       if (!(s->capability & CAN_MIC_AS_BASS))
-               return;
-       if (use_mic_as_bass) {
-               maskb(s->iobase + CODEC_CMI_MISC, ~0, 0x04);
-               s->status |= DO_MIC_AS_BASS;
-       } else {
-               maskb(s->iobase + CODEC_CMI_MISC, ~0x04, 0);
-               s->status &= ~DO_MIC_AS_BASS;
-       }
-}
-
-static void set_hw_copy(struct cm_state *s, int hw_copy)
-{
-       if (s->max_channels > 2 && hw_copy)
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, N4SPK3D);
-       else
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~N4SPK3D, 0);
-}
-
-static void set_ac3(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       set_spdifout_unlocked(s, rate);
-       set_ac3_unlocked(s, rate);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int trans_ac3(struct cm_state *s, void *dest, const char __user *source, int size)
-{
-       int   i = size / 2;
-       unsigned long data;
-       unsigned short data16;
-       unsigned long *dst = (unsigned long *) dest;
-       unsigned short __user *src = (unsigned short __user *)source;
-       int err;
-
-       do {
-               if ((err = __get_user(data16, src++)))
-                       return err;
-               data = (unsigned long)le16_to_cpu(data16);
-               data <<= 12;                    // ok for 16-bit data
-               if (s->spdif_counter == 2 || s->spdif_counter == 3)
-                       data |= 0x40000000;     // indicate AC-3 raw data
-               if (parity(data))
-                       data |= 0x80000000;     // parity
-               if (s->spdif_counter == 0)
-                       data |= 3;              // preamble 'M'
-               else if (s->spdif_counter & 1)
-                       data |= 5;              // odd, 'W'
-               else
-                       data |= 9;              // even, 'M'
-               *dst++ = cpu_to_le32(data);
-               s->spdif_counter++;
-               if (s->spdif_counter == 384)
-                       s->spdif_counter = 0;
-       } while (--i);
-
-       return 0;
-}
-
-static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate)
-{
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->rateadc = rate;
-       freq <<= CM_FREQ_ADCSHIFT;
-
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-}
-
-static void set_adc_rate(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->rateadc = rate;
-       freq <<= CM_FREQ_ADCSHIFT;
-
-       spin_lock_irqsave(&s->lock, flags);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void set_dac_rate(struct cm_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char freq = 4;
-       int     i;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 8000)
-               rate = 8000;
-       for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) {
-               if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) {
-                       rate = rate_lookup[i].rate;
-                       freq = rate_lookup[i].freq;
-                       break;
-               }
-       }
-       s->ratedac = rate;
-       freq <<= CM_FREQ_DACSHIFT;
-
-       spin_lock_irqsave(&s->lock, flags);
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~DSFC, freq);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-       if (s->curr_channels <= 2 && spdif_out)
-               set_spdifout(s, rate);
-       if (s->status & DO_DUAL_DAC)
-               set_dac1_rate(s, rate);
-}
-
-/* --------------------------------------------------------------------- */
-static inline void reset_adc(struct cm_state *s)
-{
-       /* reset bus master */
-       outb(s->enable | RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       udelay(10);
-       outb(s->enable & ~RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-}
-
-static inline void reset_dac(struct cm_state *s)
-{
-       /* reset bus master */
-       outb(s->enable | RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       udelay(10);
-       outb(s->enable & ~RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       if (s->status & DO_DUAL_DAC)
-               reset_adc(s);
-}
-
-static inline void pause_adc(struct cm_state *s)
-{
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEADC);
-}
-
-static inline void pause_dac(struct cm_state *s)
-{
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEDAC);
-       if (s->status & DO_DUAL_DAC)
-               pause_adc(s);
-}
-
-static inline void disable_adc(struct cm_state *s)
-{
-       /* disable channel */
-       s->enable &= ~ENADC;
-       outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       reset_adc(s);
-}
-
-static inline void disable_dac(struct cm_state *s)
-{
-       /* disable channel */
-       s->enable &= ~ENDAC;
-       outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       reset_dac(s);
-       if (s->status & DO_DUAL_DAC)
-               disable_adc(s);
-}
-
-static inline void enable_adc(struct cm_state *s)
-{
-       if (!(s->enable & ENADC)) {
-               /* enable channel */
-               s->enable |= ENADC;
-               outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       }
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEADC, 0);
-}
-
-static inline void enable_dac_unlocked(struct cm_state *s)
-{
-       if (!(s->enable & ENDAC)) {
-               /* enable channel */
-               s->enable |= ENDAC;
-               outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
-       }
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEDAC, 0);
-
-       if (s->status & DO_DUAL_DAC)
-               enable_adc(s);
-}
-
-static inline void stop_adc_unlocked(struct cm_state *s)
-{
-       if (s->enable & ENADC) {
-               /* disable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENADCINT, 0);
-               disable_adc(s);
-       }
-}
-
-static inline void stop_adc(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       stop_adc_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-
-}
-
-static inline void stop_dac_unlocked(struct cm_state *s)
-{
-       if (s->enable & ENDAC) {
-               /* disable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENDACINT, 0);
-               disable_dac(s);
-       }
-       if (s->status & DO_DUAL_DAC)
-               stop_dac1_unlocked(s);
-}
-
-static inline void stop_dac(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       stop_dac_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static inline void start_adc_unlocked(struct cm_state *s)
-{
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
-               enable_adc(s);
-       }
-}
-
-static void start_adc(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       start_adc_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac1_unlocked(struct cm_state *s)
-{
-       if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT);
-               enable_dac_unlocked(s);
-       }
-}
-
-static void start_dac_unlocked(struct cm_state *s)
-{
-       if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               /* enable interrupt */
-               maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENDACINT);
-               enable_dac_unlocked(s);
-       }
-       if (s->status & DO_DUAL_DAC)
-               start_dac1_unlocked(s);
-}
-
-static void start_dac(struct cm_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       start_dac_unlocked(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec);
-
-static int set_dac_channels(struct cm_state *s, int channels)
-{
-       unsigned long flags;
-       static unsigned int fmmute = 0;
-
-       spin_lock_irqsave(&s->lock, flags);
-
-       if ((channels > 2) && (channels <= s->max_channels)
-        && (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) {
-           set_spdifout_unlocked(s, 0);
-           if (s->capability & CAN_MULTI_CH_HW) {
-               // NXCHG
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, NXCHG);
-               // CHB3D or CHB3D5C
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), channels > 4 ? CHB3D5C : CHB3D);
-               // CHB3D6C
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, channels == 6 ? CHB3D6C : 0);
-               // ENCENTER
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~ENCENTER, channels == 6 ? ENCENTER : 0);
-               s->status |= DO_MULTI_CH_HW;
-           } else if (s->capability & CAN_DUAL_DAC) {
-               unsigned char fmtm = ~0, fmts = 0;
-               ssize_t ret;
-
-               // ENDBDAC, turn on double DAC mode
-               // XCHGDAC, CH0 -> back, CH1->front
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, ENDBDAC|XCHGDAC);
-               // mute FM
-               fmmute = inb(s->iobase + CODEC_CMI_MIXER1) & FMMUTE;
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~0, FMMUTE);
-               s->status |= DO_DUAL_DAC;
-               // prepare secondary buffer
-               spin_unlock_irqrestore(&s->lock, flags);
-               ret = prog_dmabuf(s, 1);
-               if (ret) return ret;
-               spin_lock_irqsave(&s->lock, flags);
-
-               // copy the hw state
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-               // the HW only support 16-bit stereo
-               fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-               fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-               fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-               fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-
-               set_fmt_unlocked(s, fmtm, fmts);
-               set_adc_rate_unlocked(s, s->ratedac);
-           }
-           // disable 4 speaker mode (analog duplicate)
-           set_hw_copy(s, 0);
-           s->curr_channels = channels;
-
-           // enable jack redirect
-           set_line_as_rear(s, use_line_as_rear);
-           if (channels > 4) {
-                   set_line_as_bass(s, use_line_as_bass);
-                   set_mic_as_bass(s, use_mic_as_bass);
-           }
-       } else {
-           if (s->status & DO_MULTI_CH_HW) {
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~NXCHG, 0);
-               maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), 0);
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, 0);
-           } else if (s->status & DO_DUAL_DAC) {
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~ENDBDAC, 0);
-               maskb(s->iobase + CODEC_CMI_MIXER1, ~FMMUTE, fmmute);
-           }
-           // enable 4 speaker mode (analog duplicate)
-           set_hw_copy(s, hw_copy);
-           s->status &= ~DO_MULTI_CH;
-           s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-           // disable jack redirect
-           set_line_as_rear(s, hw_copy ? use_line_as_rear : 0);
-           set_line_as_bass(s, 0);
-           set_mic_as_bass(s, 0);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return s->curr_channels;
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct cm_state *s, struct dmabuf *db)
-{
-       struct page *pstart, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-                       ClearPageReserved(pstart);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-/* Ch1 is used for playback, Ch0 is used for recording */
-
-static int prog_dmabuf(struct cm_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *pstart, *pend;
-       unsigned char fmt;
-       unsigned long flags;
-
-       fmt = s->fmt;
-       if (rec) {
-               stop_adc(s);
-               fmt >>= CM_CFMT_ADCSHIFT;
-       } else {
-               stop_dac(s);
-               fmt >>= CM_CFMT_DACSHIFT;
-       }
-
-       fmt &= CM_CFMT_MASK;
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf || !db->dmaaddr)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++)
-                       SetPageReserved(pstart);
-       }
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       /* to make fragsize >= 4096 */
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       db->dmasamples = db->dmasize >> sample_shift[fmt];
-       memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) {
-               if (s->status & DO_DUAL_DAC)
-                   set_dmadac1(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               else
-                   set_dmaadc(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               /* program sample counts */
-               set_countdac(s, db->fragsamples);
-       } else {
-               set_dmadac(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]);
-               /* program sample counts */
-               set_countdac(s, db->fragsamples);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(struct cm_state *s)
-{
-       unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80;
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned char *buf1 = s->dma_adc.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               if (s->status & DO_DUAL_DAC)
-                       memset(buf1 + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-       if (s->status & DO_DUAL_DAC)
-               memset(buf1 + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void cm_update_ptr(struct cm_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-           if (s->status & DO_DUAL_DAC) {
-                   /* the dac part will finish for this */
-           } else {
-               hwptr = get_dmaadc(s) % s->dma_adc.dmasize;
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               pause_adc(s);
-                               s->dma_adc.error++;
-                       }
-               }
-           }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = get_dmadac(s) % s->dma_dac.dmasize;
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->status & DO_DUAL_DAC) {
-                       s->dma_adc.hwptr = hwptr;
-                       s->dma_adc.total_bytes += diff;
-               }
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               pause_dac(s);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                               if (s->status & DO_DUAL_DAC)
-                                       s->dma_adc.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-static irqreturn_t cm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct cm_state *s = (struct cm_state *)dev_id;
-       unsigned int intsrc, intstat;
-       unsigned char mask = 0;
-
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
-       if (!(intsrc & 0x80000000))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       /* acknowledge interrupt */
-       if (intsrc & ADCINT)
-               mask |= ENADCINT;
-       if (intsrc & DACINT)
-               mask |= ENDACINT;
-       outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-       cm_update_ptr(s);
-       spin_unlock(&s->lock);
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       if (intsrc & 0x00010000) {      // UART interrupt
-               if (s->midi_devc && intchk_mpu401((void *)s->midi_devc))
-                       mpuintr(irq, (void *)s->midi_devc, regs);
-               else
-                       inb(s->iomidi);// dummy read
-       }
-#endif
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != CM_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-#define MT_5MUTEMONO  5
-
-static const struct {
-       unsigned left;
-       unsigned right;
-       unsigned type;
-       unsigned rec;
-       unsigned play;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_CD]     = { DSP_MIX_CDVOLIDX_L,     DSP_MIX_CDVOLIDX_R,     MT_5MUTE,     0x04, 0x06 },
-       [SOUND_MIXER_LINE]   = { DSP_MIX_LINEVOLIDX_L,   DSP_MIX_LINEVOLIDX_R,   MT_5MUTE,     0x10, 0x18 },
-       [SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      DSP_MIX_MICVOLIDX,      MT_5MUTEMONO, 0x01, 0x01 },
-       [SOUND_MIXER_SYNTH]  = { DSP_MIX_FMVOLIDX_L,     DSP_MIX_FMVOLIDX_R,     MT_5MUTE,     0x40, 0x00 },
-       [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,     0x00, 0x00 },
-       [SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 },
-       [SOUND_MIXER_LINE1]  = { DSP_MIX_AUXVOL_L,       DSP_MIX_AUXVOL_R,       MT_5MUTE,     0x80, 0x60 },
-       [SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,     DSP_MIX_SPKRVOLIDX,     MT_5MUTEMONO, 0x00, 0x01 }
-};
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
-{
-       [SOUND_MIXER_CD]     = 1,
-       [SOUND_MIXER_LINE]   = 2,
-       [SOUND_MIXER_MIC]    = 3,
-       [SOUND_MIXER_SYNTH]  = 4,
-       [SOUND_MIXER_VOLUME] = 5,
-       [SOUND_MIXER_PCM]    = 6,
-       [SOUND_MIXER_LINE1]  = 7,
-       [SOUND_MIXER_SPEAKER]= 8
-};
-
-static unsigned mixer_outmask(struct cm_state *s)
-{
-       unsigned long flags;
-       int i, j, k;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdmixer(s, DSP_MIX_OUTMIXIDX);
-       spin_unlock_irqrestore(&s->lock, flags);
-       for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-               if (j & mixtable[i].play)
-                       k |= 1 << i;
-       return k;
-}
-
-static unsigned mixer_recmask(struct cm_state *s)
-{
-       unsigned long flags;
-       int i, j, k;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
-       spin_unlock_irqrestore(&s->lock, flags);
-       for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-               if (j & mixtable[i].rec)
-                       k |= 1 << i;
-       return k;
-}
-
-static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val, j;
-       unsigned char l, r, rl, rr;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "cmpci", sizeof(info.id));
-               strlcpy(info.name, "C-Media PCI", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "cmpci", sizeof(info.id));
-               strlcpy(info.name, "C-Media cmpci", sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       val = mixer_recmask(s);
-                       return put_user(val, p);
-
-                case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-                       val = mixer_outmask(s);
-                       return put_user(val, p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].rec)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].play)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                 case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_CAPS:
-                       return put_user(0, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-                       if (!volidx[i])
-                               return -EINVAL;
-                       return put_user(s->mix.vol[volidx[i]-1], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE))
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               i = hweight32(val);
-               for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (!mixtable[i].rec) {
-                               val &= ~(1 << i);
-                               continue;
-                       }
-                       j |= mixtable[i].rec;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
-               wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1) | (j & 0x80));
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (!mixtable[i].play) {
-                               val &= ~(1 << i);
-                               continue;
-                       }
-                       j |= mixtable[i].play;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               wrmixer(s, DSP_MIX_OUTMIXIDX, j);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               r = (val >> 8) & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (r > 100)
-                       r = 100;
-               spin_lock_irqsave(&s->lock, flags);
-               switch (mixtable[i].type) {
-               case MT_4:
-                       if (l >= 10)
-                               l -= 10;
-                       if (r >= 10)
-                               r -= 10;
-                       frobindir(s, mixtable[i].left, 0xf0, l / 6);
-                       frobindir(s, mixtable[i].right, 0xf0, l / 6);
-                       break;
-
-               case MT_4MUTEMONO:
-                       rl = (l < 4 ? 0 : (l - 5) / 3) & 31;
-                       rr = (rl >> 2) & 7;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       if (i == SOUND_MIXER_MIC)
-                               maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-                       break;
-
-               case MT_5MUTEMONO:
-                       rl = l < 4 ? 0 : (l - 5) / 3;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       l = rdmixer(s, DSP_MIX_OUTMIXIDX) & ~mixtable[i].play;
-                       r = rl ? mixtable[i].play : 0;
-                       wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-                       /* for recording */
-                       if (i == SOUND_MIXER_MIC) {
-                               if (s->chip_version >= 37) {
-                                       rr = rl >> 1;
-                                       maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, (rr&0x07)<<1);
-                                       frobindir(s, DSP_MIX_EXTENSION, ~0x01, rr>>3);
-                               } else {
-                                       rr = rl >> 2;
-                                       maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1);
-                               }
-                       }
-                       break;
-
-               case MT_5MUTE:
-                       rl = l < 4 ? 0 : (l - 5) / 3;
-                       rr = r < 4 ? 0 : (r - 5) / 3;
-                       wrmixer(s, mixtable[i].left, rl<<3);
-                       wrmixer(s, mixtable[i].right, rr<<3);
-                       l = rdmixer(s, DSP_MIX_OUTMIXIDX);
-                       l &= ~mixtable[i].play;
-                       r = (rl|rr) ? mixtable[i].play : 0;
-                       wrmixer(s, DSP_MIX_OUTMIXIDX, l | r);
-                       break;
-
-               case MT_6MUTE:
-                       if (l < 6)
-                               rl = 0x00;
-                       else
-                               rl = l * 2 / 3;
-                       if (r < 6)
-                               rr = 0x00;
-                       else
-                               rr = r * 2 / 3;
-                       wrmixer(s, mixtable[i].left, rl);
-                       wrmixer(s, mixtable[i].right, rr);
-                       break;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (!volidx[i])
-                       return -EINVAL;
-               s->mix.vol[volidx[i]-1] = val;
-               return put_user(s->mix.vol[volidx[i]-1], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int cm_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct cm_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct cm_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int cm_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations cm_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = cm_ioctl_mixdev,
-       .open    = cm_open_mixdev,
-       .release = cm_release_mixdev,
-};
-
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct cm_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "cmpci: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t cm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-        add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_adc_unlocked(s);
-                               set_dmaadc(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-                               /* program sample counts */
-                               set_countadc(s, s->dma_adc.fragsamples);
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (s->status & DO_BIGENDIAN_R) {
-                       int     i, err;
-                       unsigned char *src;
-                       char __user *dst = buffer;
-                       unsigned char data[2];
-
-                       src = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 2; i++) {
-                               data[0] = src[1];
-                               data[1] = src[0];
-                               if ((err = __put_user(data[0], dst++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __put_user(data[1], dst++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               src += 2;
-                       }
-               } else if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc_unlocked(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-out:
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t cm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (s->status & DO_DUAL_DAC) {
-               if (s->dma_adc.mapped)
-                       return -ENXIO;
-               if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                       return ret;
-       }
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-        add_wait_queue(&s->dma_dac.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               if (s->status & DO_DUAL_DAC) {
-                       s->dma_adc.swptr = s->dma_dac.swptr;
-                       s->dma_adc.count = s->dma_dac.count;
-                       s->dma_adc.endcleared = s->dma_dac.endcleared;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->status & DO_AC3_SW) {
-                       if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize)
-                               cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2;
-               } else {
-                       if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                               cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               }
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if ((s->status & DO_DUAL_DAC) && (cnt > count / 2))
-                   cnt = count / 2;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_dac_unlocked(s);
-                               set_dmadac(s, s->dma_dac.dmaaddr, s->dma_dac.dmasamples);
-                               /* program sample counts */
-                               set_countdac(s, s->dma_dac.fragsamples);
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               if (s->status & DO_DUAL_DAC)  {
-                                       set_dmadac1(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples);
-                                       s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               }
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (s->status & DO_AC3_SW) {
-                       int err;
-
-                       // clip exceeded data, caught by 033 and 037
-                       if (swptr + 2 * cnt > s->dma_dac.dmasize)
-                               cnt = (s->dma_dac.dmasize - swptr) / 2;
-                       if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt))) {
-                               ret = err;
-                               goto out;
-                       }
-                       swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize;
-               } else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) {
-                       int     i, err;
-                       const char __user *src = buffer;
-                       unsigned char *dst0, *dst1;
-                       unsigned char data[8];
-
-                       dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-                       dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 4; i++) {
-                               if ((err = __get_user(data[0], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[1], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[2], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[3], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[4], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[5], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[6], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[7], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               dst0[0] = data[1];
-                               dst0[1] = data[0];
-                               dst0[2] = data[3];
-                               dst0[3] = data[2];
-                               dst1[0] = data[5];
-                               dst1[1] = data[4];
-                               dst1[2] = data[7];
-                               dst1[3] = data[6];
-                               dst0 += 4;
-                               dst1 += 4;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else if (s->status & DO_DUAL_DAC) {
-                       int     i, err;
-                       unsigned long __user *src = (unsigned long __user *) buffer;
-                       unsigned long *dst0, *dst1;
-
-                       dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr);
-                       dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr);
-                       // copy left/right sample at one time
-                       for (i = 0; i < cnt / 4; i++) {
-                               if ((err = __get_user(*dst0++, src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(*dst1++, src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else if (s->status & DO_BIGENDIAN_W) {
-                       int     i, err;
-                       const char __user *src = buffer;
-                       unsigned char *dst;
-                       unsigned char data[2];
-
-                       dst = (unsigned char *) (s->dma_dac.rawbuf + swptr);
-                       // swap hi/lo bytes for each sample
-                       for (i = 0; i < cnt / 2; i++) {
-                               if ((err = __get_user(data[0], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               if ((err = __get_user(data[1], src++))) {
-                                       ret = err;
-                                       goto out;
-                               }
-                               dst[0] = data[1];
-                               dst[1] = data[0];
-                               dst += 2;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               } else {
-                       if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                               if (!ret)
-                                       ret = -EFAULT;
-                               goto out;
-                       }
-                       swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               if (s->status & DO_AC3_SW)
-                       s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->status & DO_DUAL_DAC) {
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-               }
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-out:
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 0))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       cm_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int cm_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-#define SNDCTL_SPDIF_COPYRIGHT _SIOW('S',  0, int)       // set/reset S/PDIF copy protection
-#define SNDCTL_SPDIF_LOOP      _SIOW('S',  1, int)       // set/reset S/PDIF loop
-#define SNDCTL_SPDIF_MONITOR   _SIOW('S',  2, int)       // set S/PDIF monitor
-#define SNDCTL_SPDIF_LEVEL     _SIOW('S',  3, int)       // set/reset S/PDIF out level
-#define SNDCTL_SPDIF_INV       _SIOW('S',  4, int)       // set/reset S/PDIF in inverse
-#define SNDCTL_SPDIF_SEL2      _SIOW('S',  5, int)       // set S/PDIF in #2
-#define SNDCTL_SPDIF_VALID     _SIOW('S',  6, int)       // set S/PDIF valid
-#define SNDCTL_SPDIFOUT                _SIOW('S',  7, int)       // set S/PDIF out
-#define SNDCTL_SPDIFIN         _SIOW('S',  8, int)       // set S/PDIF out
-
-static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, p);
-
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               spin_lock_irqsave(&s->lock, flags);
-                               stop_adc_unlocked(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate_unlocked(s, val);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (s->status & DO_DUAL_DAC)
-                                       s->dma_adc.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                       else
-                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                       else
-                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-                       if (s->status & DO_DUAL_DAC) {
-                               s->dma_adc.ready = 0;
-                               if (val)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                       }
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT);
-                               if (s->status & DO_DUAL_DAC) {
-                                       s->dma_adc.ready = 0;
-                                       if (val >= 2)
-                                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                                       else
-                                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                               }
-                       }
-                       set_fmt(s, fmtm, fmtd);
-                       if ((s->capability & CAN_MULTI_CH)
-                            && (file->f_mode & FMODE_WRITE)) {
-                               val = set_dac_channels(s, val);
-                               return put_user(val, p);
-                       }
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT)
-                                          : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_BE|AFMT_S16_LE|AFMT_U8|
-                       ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-                                       fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT);
-                               if (val == AFMT_S16_BE)
-                                       s->status |= DO_BIGENDIAN_R;
-                               else
-                                       s->status &= ~DO_BIGENDIAN_R;
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_BE || val == AFMT_S16_LE || val == AFMT_AC3)
-                                       fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-                               else
-                                       fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT);
-                               if (val == AFMT_AC3) {
-                                       fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT;
-                                       set_ac3(s, 48000);
-                               } else
-                                       set_ac3(s, 0);
-                               if (s->status & DO_DUAL_DAC) {
-                                       s->dma_adc.ready = 0;
-                                       if (val == AFMT_S16_BE || val == AFMT_S16_LE)
-                                               fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT;
-                                       else
-                                               fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT);
-                               }
-                               if (val == AFMT_S16_BE)
-                                       s->status |= DO_BIGENDIAN_W;
-                               else
-                                       s->status &= ~DO_BIGENDIAN_W;
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               if (s->status & DO_AC3) return put_user(AFMT_AC3, p);
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT)
-                                          : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p);
-
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (s->status & DO_DUAL_DAC) {
-                       if (file->f_mode & FMODE_WRITE &&
-                        (s->enable & ENDAC) &&
-                        (s->enable & ENADC))
-                               val |= PCM_ENABLE_OUTPUT;
-                       return put_user(val, p);
-               }
-               if (file->f_mode & FMODE_READ && s->enable & ENADC)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->enable & ENDAC)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               if (s->status & DO_DUAL_DAC) {
-                                       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-                                               return ret;
-                               }
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!(s->enable & ENDAC) && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!(s->enable & ENADC) && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo))  ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               spin_lock_irqsave(&s->lock, flags);
-               cm_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               if (s->status & DO_DUAL_DAC) {
-                       if (s->dma_adc.mapped)
-                               s->dma_adc.count &= s->dma_adc.fragsize-1;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       if (s->status & DO_DUAL_DAC) {
-                               if ((val = prog_dmabuf(s, 1)))
-                                       return val;
-                               return put_user(2 * s->dma_dac.fragsize, p);
-                       }
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-                       if (s->status & DO_DUAL_DAC) {
-                               s->dma_adc.ossfragshift = s->dma_dac.ossfragshift;
-                               s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags;
-                       }
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.subdivision = val;
-                       if (s->status & DO_DUAL_DAC)
-                               s->dma_adc.subdivision = val;
-               }
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_READ_FILTER:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-       case SNDCTL_DSP_GETCHANNELMASK:
-               return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, p);
-
-       case SNDCTL_DSP_BIND_CHANNEL:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val == DSP_BIND_QUERY) {
-                       val = DSP_BIND_FRONT;
-                       if (s->status & DO_SPDIF_OUT)
-                               val |= DSP_BIND_SPDIF;
-                       else {
-                               if (s->curr_channels == 4)
-                                       val |= DSP_BIND_SURR;
-                               if (s->curr_channels > 4)
-                                       val |= DSP_BIND_CENTER_LFE;
-                       }
-               } else {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val & DSP_BIND_SPDIF) {
-                                       set_spdifin(s, s->rateadc);
-                                       if (!(s->status & DO_SPDIF_OUT))
-                                               val &= ~DSP_BIND_SPDIF;
-                               }
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val & DSP_BIND_SPDIF) {
-                                       set_spdifout(s, s->ratedac);
-                                       set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1);
-                                       if (!(s->status & DO_SPDIF_OUT))
-                                               val &= ~DSP_BIND_SPDIF;
-                               } else {
-                                       int channels;
-                                       int mask;
-
-                                       mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE);
-                                       switch (mask) {
-                                           case DSP_BIND_FRONT:
-                                               channels = 2;
-                                               break;
-                                           case DSP_BIND_FRONT|DSP_BIND_SURR:
-                                               channels = 4;
-                                               break;
-                                           case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE:
-                                               channels = 6;
-                                               break;
-                                           default:
-                                               channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1;
-                                               break;
-                                       }
-                                       set_dac_channels(s, channels);
-                               }
-                       }
-               }
-               return put_user(val, p);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-        case SNDCTL_DSP_SETSYNCRO:
-                return -EINVAL;
-       case SNDCTL_SPDIF_COPYRIGHT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_copyright(s, val);
-                return 0;
-       case SNDCTL_SPDIF_LOOP:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_loop(s, val);
-                return 0;
-       case SNDCTL_SPDIF_MONITOR:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdif_monitor(s, val);
-                return 0;
-       case SNDCTL_SPDIF_LEVEL:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifout_level(s, val);
-                return 0;
-       case SNDCTL_SPDIF_INV:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_inverse(s, val);
-                return 0;
-       case SNDCTL_SPDIF_SEL2:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_channel2(s, val);
-                return 0;
-       case SNDCTL_SPDIF_VALID:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin_valid(s, val);
-                return 0;
-       case SNDCTL_SPDIFOUT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifout(s, val ? s->ratedac : 0);
-                return 0;
-       case SNDCTL_SPDIFIN:
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_spdifin(s, val ? s->rateadc : 0);
-                return 0;
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int cm_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned char fmtm = ~0, fmts = 0;
-       struct list_head *list;
-       struct cm_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct cm_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->status &= ~DO_BIGENDIAN_R;
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               set_adc_rate(s, 8000);
-               // spdif-in is turnned off by default
-               set_spdifin(s, 0);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->status &= ~DO_BIGENDIAN_W;
-               fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               s->dma_dac.enabled = 1;
-               set_dac_rate(s, 8000);
-               // clear previous multichannel, spdif, ac3 state
-               set_spdifout(s, 0);
-               set_ac3(s, 0);
-               set_dac_channels(s, 1);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int cm_release(struct inode *inode, struct file *file)
-{
-       struct cm_state *s = (struct cm_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-
-               dealloc_dmabuf(s, &s->dma_dac);
-               if (s->status & DO_DUAL_DAC)
-                       dealloc_dmabuf(s, &s->dma_adc);
-
-               if (s->status & DO_MULTI_CH)
-                       set_dac_channels(s, 1);
-               if (s->status & DO_AC3)
-                       set_ac3(s, 0);
-               if (s->status & DO_SPDIF_OUT)
-                       set_spdifout(s, 0);
-               /* enable SPDIF loop */
-               set_spdif_loop(s, spdif_loop);
-               s->status &= ~DO_BIGENDIAN_W;
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-               s->status &= ~DO_BIGENDIAN_R;
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations cm_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cm_read,
-       .write   = cm_write,
-       .poll    = cm_poll,
-       .ioctl   = cm_ioctl,
-       .mmap    = cm_mmap,
-       .open    = cm_open,
-       .release = cm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_CD, 0x4f4f },
-       { SOUND_MIXER_WRITE_LINE, 0x4f4f },
-       { SOUND_MIXER_WRITE_MIC, 0x4f4f },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4f4f },
-       { SOUND_MIXER_WRITE_VOLUME, 0x4f4f },
-       { SOUND_MIXER_WRITE_PCM, 0x4f4f }
-};
-
-/* check chip version and capability */
-static int query_chip(struct cm_state *s)
-{
-       int ChipVersion = -1;
-       unsigned char RegValue;
-
-       // check reg 0Ch, bit 24-31
-       RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3);
-       if (RegValue == 0) {
-           // check reg 08h, bit 24-28
-           RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3);
-           RegValue &= 0x1f;
-           if (RegValue == 0) {
-               ChipVersion = 33;
-               s->max_channels = 4;
-               s->capability |= CAN_AC3_SW;
-               s->capability |= CAN_DUAL_DAC;
-           } else {
-               ChipVersion = 37;
-               s->max_channels = 4;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-           }
-       } else {
-           // check reg 0Ch, bit 26
-           if (RegValue & (1 << (26-24))) {
-               ChipVersion = 39;
-               if (RegValue & (1 << (24-24)))
-                   s->max_channels = 6;
-               else
-                   s->max_channels = 4;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_MULTI_CH_HW;
-               s->capability |= CAN_LINE_AS_BASS;
-               s->capability |= CAN_MIC_AS_BASS;
-           } else {
-               ChipVersion = 55; // 4 or 6 channels
-               s->max_channels = 6;
-               s->capability |= CAN_AC3_HW;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_MULTI_CH_HW;
-               s->capability |= CAN_LINE_AS_BASS;
-               s->capability |= CAN_MIC_AS_BASS;
-           }
-       }
-       s->capability |= CAN_LINE_AS_REAR;
-       return ChipVersion;
-}
-
-#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
-static int __devinit cm_create_gameport(struct cm_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, CM_EXTENT_GAME, "cmpci GAME")) {
-               printk(KERN_ERR "cmpci: gameport io ports 0x%#x in use\n", io_port);
-               return -EBUSY;
-       }
-
-       if (!(s->gameport = gp = gameport_allocate_port())) {
-               printk(KERN_ERR "cmpci: can not allocate memory for gameport\n");
-               release_region(io_port, CM_EXTENT_GAME);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "C-Media GP");
-       gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       /* enable joystick */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02);
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static void __devexit cm_free_gameport(struct cm_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-
-               gameport_unregister_port(s->gameport);
-               s->gameport = NULL;
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-               release_region(gpio, CM_EXTENT_GAME);
-       }
-}
-#else
-static inline int cm_create_gameport(struct cm_state *s, int io_port) { return -ENOSYS; }
-static inline void cm_free_gameport(struct cm_state *s) { }
-#endif
-
-#define        echo_option(x)\
-if (x) strcat(options, "" #x " ")
-
-static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct cm_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-       unsigned char reg_mask;
-       int timeout;
-       struct resource *ports;
-       struct {
-               unsigned short  deviceid;
-               char            *devicename;
-       } devicetable[] = {
-               { PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" },
-               { PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" },
-               { PCI_DEVICE_ID_CMEDIA_CM8738,  "CM8738" },
-               { PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" },
-       };
-       char    *devicename = "unknown";
-       char    options[256];
-
-       if ((ret = pci_enable_device(pcidev)))
-               return ret;
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-       if (i) {
-               printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n");
-               return i;
-       }
-       s = kmalloc(sizeof(*s), GFP_KERNEL);
-       if (!s) {
-               printk(KERN_WARNING "cmpci: out of memory\n");
-               return -ENOMEM;
-       }
-       /* search device name */
-       for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) {
-               if (devicetable[i].deviceid == pcidev->device) {
-                       devicename = devicetable[i].devicename;
-                       break;
-               }
-       }
-       memset(s, 0, sizeof(struct cm_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = CM_MAGIC;
-       s->dev = pcidev;
-       s->iobase = pci_resource_start(pcidev, 0);
-       s->iosynth = fmio;
-       s->iomidi = mpuio;
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       s->midi_devc = 0;
-#endif
-       s->status = 0;
-       if (s->iobase == 0)
-               return -ENODEV;
-       s->irq = pcidev->irq;
-
-       if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-               printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
-               ret = -EBUSY;
-               goto err_region5;
-       }
-       /* dump parameters */
-       strcpy(options, "cmpci: ");
-       echo_option(joystick);
-       echo_option(spdif_inverse);
-       echo_option(spdif_loop);
-       echo_option(spdif_out);
-       echo_option(use_line_as_rear);
-       echo_option(use_line_as_bass);
-       echo_option(use_mic_as_bass);
-       echo_option(mic_boost);
-       echo_option(hw_copy);
-       printk(KERN_INFO "%s\n", options);
-
-       /* initialize codec registers */
-       outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-       outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-       /* reset mixer */
-       wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-       /* request irq */
-       if ((ret = request_irq(s->irq, cm_interrupt, IRQF_SHARED, "cmpci", s))) {
-               printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       printk(KERN_INFO "cmpci: found %s adapter at io %#x irq %u\n",
-              devicename, s->iobase, s->irq);
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       pci_set_master(pcidev); /* enable bus mastering */
-       /* initialize the chips */
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       /* set mixer output */
-       frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f);
-       /* set mixer input */
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-       /* use channel 1 for playback, channel 0 for record */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, CHADC0);
-       /* turn off VMIC3 - mic boost */
-       if (mic_boost)
-               maskb(s->iobase + CODEC_CMI_MIXER2, ~1, 0);
-       else
-               maskb(s->iobase + CODEC_CMI_MIXER2, ~0, 1);
-       s->deviceid = pcidev->device;
-
-       if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738
-        || pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738B) {
-
-               /* chip version and hw capability check */
-               s->chip_version = query_chip(s);
-               printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
-
-               /* set SPDIF-in inverse before enable SPDIF loop */
-               set_spdifin_inverse(s, spdif_inverse);
-
-               /* use SPDIF in #1 */
-               set_spdifin_channel2(s, 0);
-       } else {
-               s->chip_version = 0;
-               /* 8338 will fall here */
-               s->max_channels = 4;
-               s->capability |= CAN_DUAL_DAC;
-               s->capability |= CAN_LINE_AS_REAR;
-       }
-       /* enable SPDIF loop */
-       set_spdif_loop(s, spdif_loop);
-
-       // enable 4 speaker mode (analog duplicate)
-       set_hw_copy(s, hw_copy);
-
-       reg_mask = 0;
-#ifdef CONFIG_SOUND_CMPCI_FM
-       /* disable FM */
-       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-       if (s->iosynth) {
-           /* don't enable OPL3 if there is one */
-           if (opl3_detect(s->iosynth, NULL)) {
-               s->iosynth = 0;
-           } else {
-               /* set IO based at 0x388 */
-               switch (s->iosynth) {
-                   case 0x388:
-                       reg_mask = 0;
-                       break;
-                   case 0x3C8:
-                       reg_mask = 0x01;
-                       break;
-                   case 0x3E0:
-                       reg_mask = 0x02;
-                       break;
-                   case 0x3E8:
-                       reg_mask = 0x03;
-                       break;
-                   default:
-                       s->iosynth = 0;
-                       break;
-               }
-               maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask);
-               /* enable FM */
-               if (s->iosynth) {
-                       maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8);
-                       if (opl3_detect(s->iosynth, NULL))
-                               ret = opl3_init(s->iosynth, NULL, THIS_MODULE);
-                       else {
-                               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-                               s->iosynth = 0;
-                       }
-               }
-           }
-       }
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       switch (s->iomidi) {
-           case 0x330:
-               reg_mask = 0;
-               break;
-           case 0x320:
-               reg_mask = 0x20;
-               break;
-           case 0x310:
-               reg_mask = 0x40;
-               break;
-           case 0x300:
-               reg_mask = 0x60;
-               break;
-           default:
-               s->iomidi = 0;
-               goto skip_mpu;
-       }
-       ports = request_region(s->iomidi, 2, "mpu401");
-       if (!ports)
-               goto skip_mpu;
-       /* disable MPU-401 */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-       s->mpu_data.name = "cmpci mpu";
-       s->mpu_data.io_base = s->iomidi;
-       s->mpu_data.irq = -s->irq;      // tell mpu401 to share irq
-       if (probe_mpu401(&s->mpu_data, ports)) {
-               release_region(s->iomidi, 2);
-               s->iomidi = 0;
-               goto skip_mpu;
-       }
-       maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x60, reg_mask);
-       /* enable MPU-401 */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-       /* clear all previously received interrupt */
-       for (timeout = 900000; timeout > 0; timeout--) {
-               if ((inb(s->iomidi + 1) && 0x80) == 0)
-                       inb(s->iomidi);
-               else
-                       break;
-       }
-       if (!probe_mpu401(&s->mpu_data, ports)) {
-               release_region(s->iomidi, 2);
-               s->iomidi = 0;
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04);
-       } else {
-               attach_mpu401(&s->mpu_data, THIS_MODULE);
-               s->midi_devc = s->mpu_data.slots[1];
-       }
-skip_mpu:
-#endif
-       /* disable joystick port */
-       maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0);
-       if (joystick)
-               cm_create_gameport(s, 0x200);
-
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
-err_dev2:
-       unregister_sound_dsp(s->dev_audio);
-err_dev1:
-       printk(KERN_ERR "cmpci: cannot register misc device\n");
-       free_irq(s->irq, s);
-err_irq:
-       release_region(s->iobase, CM_EXTENT_CODEC);
-err_region5:
-       kfree(s);
-       return ret;
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw");
-MODULE_DESCRIPTION("CM8x38 Audio Driver");
-MODULE_LICENSE("GPL");
-
-static void __devexit cm_remove(struct pci_dev *dev)
-{
-       struct cm_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-
-       cm_free_gameport(s);
-
-#ifdef CONFIG_SOUND_CMPCI_FM
-       if (s->iosynth) {
-               /* disable FM */
-               maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
-       }
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-       if (s->iomidi) {
-               unload_mpu401(&s->mpu_data);
-               /* disable MPU-401 */
-               maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
-       }
-#endif
-       set_spdif_loop(s, 0);
-       list_del(&s->devs);
-       outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-       synchronize_irq(s->irq);
-       outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
-       free_irq(s->irq, s);
-
-       /* reset mixer */
-       wrmixer(s, DSP_MIX_DATARESETIDX, 0);
-
-       release_region(s->iobase, CM_EXTENT_CODEC);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] __devinitdata = {
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver cm_driver = {
-       .name    = "cmpci",
-       .id_table = id_table,
-       .probe   = cm_probe,
-       .remove  = __devexit_p(cm_remove)
-};
-
-static int __init init_cmpci(void)
-{
-       printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&cm_driver);
-}
-
-static void __exit cleanup_cmpci(void)
-{
-       printk(KERN_INFO "cmpci: unloading\n");
-       pci_unregister_driver(&cm_driver);
-}
-
-module_init(init_cmpci);
-module_exit(cleanup_cmpci);
diff --git a/sound/oss/cs4281/Makefile b/sound/oss/cs4281/Makefile
deleted file mode 100644 (file)
index 6d527e8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for Cirrus Logic-Crystal CS4281 
-#
-
-obj-$(CONFIG_SOUND_CS4281) += cs4281.o
-
-cs4281-objs += cs4281m.o
diff --git a/sound/oss/cs4281/cs4281_hwdefs.h b/sound/oss/cs4281/cs4281_hwdefs.h
deleted file mode 100644 (file)
index 701d595..0000000
+++ /dev/null
@@ -1,1234 +0,0 @@
-//****************************************************************************
-//
-// HWDEFS.H - Definitions of the registers and data structures used by the
-//            CS4281
-//
-// Copyright (c) 1999,2000,2001 Crystal Semiconductor Corp.
-//
-//****************************************************************************
-
-#ifndef _H_HWDEFS
-#define _H_HWDEFS
-
-//****************************************************************************
-//
-// The following define the offsets of the registers located in the PCI
-// configuration space of the CS4281 part.
-//
-//****************************************************************************
-#define PCICONFIG_DEVID_VENID                   0x00000000L
-#define PCICONFIG_STATUS_COMMAND                0x00000004L
-#define PCICONFIG_CLASS_REVISION                0x00000008L
-#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
-#define PCICONFIG_BA0                           0x00000010L
-#define PCICONFIG_BA1                           0x00000014L
-#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
-#define PCICONFIG_INTERRUPT                     0x0000003CL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers accessed via base address
-// register zero on the CS4281 part.
-//
-//****************************************************************************
-#define BA0_HISR                                0x00000000L
-#define BA0_HICR                                0x00000008L
-#define BA0_HIMR                                0x0000000CL
-#define BA0_IIER                                0x00000010L
-#define BA0_HDSR0                               0x000000F0L
-#define BA0_HDSR1                               0x000000F4L
-#define BA0_HDSR2                               0x000000F8L
-#define BA0_HDSR3                               0x000000FCL
-#define BA0_DCA0                                0x00000110L
-#define BA0_DCC0                                0x00000114L
-#define BA0_DBA0                                0x00000118L
-#define BA0_DBC0                                0x0000011CL
-#define BA0_DCA1                                0x00000120L
-#define BA0_DCC1                                0x00000124L
-#define BA0_DBA1                                0x00000128L
-#define BA0_DBC1                                0x0000012CL
-#define BA0_DCA2                                0x00000130L
-#define BA0_DCC2                                0x00000134L
-#define BA0_DBA2                                0x00000138L
-#define BA0_DBC2                                0x0000013CL
-#define BA0_DCA3                                0x00000140L
-#define BA0_DCC3                                0x00000144L
-#define BA0_DBA3                                0x00000148L
-#define BA0_DBC3                                0x0000014CL
-#define BA0_DMR0                                0x00000150L
-#define BA0_DCR0                                0x00000154L
-#define BA0_DMR1                                0x00000158L
-#define BA0_DCR1                                0x0000015CL
-#define BA0_DMR2                                0x00000160L
-#define BA0_DCR2                                0x00000164L
-#define BA0_DMR3                                0x00000168L
-#define BA0_DCR3                                0x0000016CL
-#define BA0_DLMR                                0x00000170L
-#define BA0_DLSR                                0x00000174L
-#define BA0_FCR0                                0x00000180L
-#define BA0_FCR1                                0x00000184L
-#define BA0_FCR2                                0x00000188L
-#define BA0_FCR3                                0x0000018CL
-#define BA0_FPDR0                               0x00000190L
-#define BA0_FPDR1                               0x00000194L
-#define BA0_FPDR2                               0x00000198L
-#define BA0_FPDR3                               0x0000019CL
-#define BA0_FCHS                                0x0000020CL
-#define BA0_FSIC0                               0x00000210L
-#define BA0_FSIC1                               0x00000214L
-#define BA0_FSIC2                               0x00000218L
-#define BA0_FSIC3                               0x0000021CL
-#define BA0_PCICFG00                            0x00000300L
-#define BA0_PCICFG04                            0x00000304L
-#define BA0_PCICFG08                            0x00000308L
-#define BA0_PCICFG0C                            0x0000030CL
-#define BA0_PCICFG10                            0x00000310L
-#define BA0_PCICFG14                            0x00000314L
-#define BA0_PCICFG18                            0x00000318L
-#define BA0_PCICFG1C                            0x0000031CL
-#define BA0_PCICFG20                            0x00000320L
-#define BA0_PCICFG24                            0x00000324L
-#define BA0_PCICFG28                            0x00000328L
-#define BA0_PCICFG2C                            0x0000032CL
-#define BA0_PCICFG30                            0x00000330L
-#define BA0_PCICFG34                            0x00000334L
-#define BA0_PCICFG38                            0x00000338L
-#define BA0_PCICFG3C                            0x0000033CL
-#define BA0_PCICFG40                            0x00000340L
-#define BA0_PMCS                                0x00000344L
-#define BA0_CWPR                                0x000003E0L
-#define BA0_EPPMC                               0x000003E4L
-#define BA0_GPIOR                               0x000003E8L
-#define BA0_SPMC                                0x000003ECL
-#define BA0_CFLR                                0x000003F0L
-#define BA0_IISR                                0x000003F4L
-#define BA0_TMS                                 0x000003F8L
-#define BA0_SSVID                               0x000003FCL
-#define BA0_CLKCR1                              0x00000400L
-#define BA0_FRR                                 0x00000410L
-#define BA0_SLT12O                              0x0000041CL
-#define BA0_SERMC                               0x00000420L
-#define BA0_SERC1                               0x00000428L
-#define BA0_SERC2                               0x0000042CL
-#define BA0_SLT12M                              0x0000045CL
-#define BA0_ACCTL                               0x00000460L
-#define BA0_ACSTS                               0x00000464L
-#define BA0_ACOSV                               0x00000468L
-#define BA0_ACCAD                               0x0000046CL
-#define BA0_ACCDA                               0x00000470L
-#define BA0_ACISV                               0x00000474L
-#define BA0_ACSAD                               0x00000478L
-#define BA0_ACSDA                               0x0000047CL
-#define BA0_JSPT                                0x00000480L
-#define BA0_JSCTL                               0x00000484L
-#define BA0_MIDCR                               0x00000490L
-#define BA0_MIDCMD                              0x00000494L
-#define BA0_MIDSR                               0x00000494L
-#define BA0_MIDWP                               0x00000498L
-#define BA0_MIDRP                               0x0000049CL
-#define BA0_AODSD1                              0x000004A8L
-#define BA0_AODSD2                              0x000004ACL
-#define BA0_CFGI                                0x000004B0L
-#define BA0_SLT12M2                             0x000004DCL
-#define BA0_ACSTS2                              0x000004E4L
-#define BA0_ACISV2                              0x000004F4L
-#define BA0_ACSAD2                              0x000004F8L
-#define BA0_ACSDA2                              0x000004FCL
-#define BA0_IOTGP                               0x00000500L
-#define BA0_IOTSB                               0x00000504L
-#define BA0_IOTFM                               0x00000508L
-#define BA0_IOTDMA                              0x0000050CL
-#define BA0_IOTAC0                              0x00000500L
-#define BA0_IOTAC1                              0x00000504L
-#define BA0_IOTAC2                              0x00000508L
-#define BA0_IOTAC3                              0x0000050CL
-#define BA0_IOTPCP                              0x0000052CL
-#define BA0_IOTCC                               0x00000530L
-#define BA0_IOTCR                               0x0000058CL
-#define BA0_PCPRR                               0x00000600L
-#define BA0_PCPGR                               0x00000604L
-#define BA0_PCPCR                               0x00000608L
-#define BA0_PCPCIEN                             0x00000608L
-#define BA0_SBMAR                               0x00000700L
-#define BA0_SBMDR                               0x00000704L
-#define BA0_SBRR                                0x00000708L
-#define BA0_SBRDP                               0x0000070CL
-#define BA0_SBWDP                               0x00000710L
-#define BA0_SBWBS                               0x00000710L
-#define BA0_SBRBS                               0x00000714L
-#define BA0_FMSR                                0x00000730L
-#define BA0_B0AP                                0x00000730L
-#define BA0_FMDP                                0x00000734L
-#define BA0_B1AP                                0x00000738L
-#define BA0_B1DP                                0x0000073CL
-#define BA0_SSPM                                0x00000740L
-#define BA0_DACSR                               0x00000744L
-#define BA0_ADCSR                               0x00000748L
-#define BA0_SSCR                                0x0000074CL
-#define BA0_FMLVC                               0x00000754L
-#define BA0_FMRVC                               0x00000758L
-#define BA0_SRCSA                               0x0000075CL
-#define BA0_PPLVC                               0x00000760L
-#define BA0_PPRVC                               0x00000764L
-#define BA0_PASR                                0x00000768L
-#define BA0_CASR                                0x0000076CL
-
-//****************************************************************************
-//
-// The following define the offsets of the AC97 shadow registers, which appear
-// as a virtual extension to the base address register zero memory range.
-//
-//****************************************************************************
-#define AC97_REG_OFFSET_MASK                    0x0000007EL
-#define AC97_CODEC_NUMBER_MASK                  0x00003000L
-
-#define BA0_AC97_RESET                          0x00001000L
-#define BA0_AC97_MASTER_VOLUME                  0x00001002L
-#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
-#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
-#define BA0_AC97_MASTER_TONE                    0x00001008L
-#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
-#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
-#define BA0_AC97_MIC_VOLUME                     0x0000100EL
-#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
-#define BA0_AC97_CD_VOLUME                      0x00001012L
-#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
-#define BA0_AC97_AUX_VOLUME                     0x00001016L
-#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
-#define BA0_AC97_RECORD_SELECT                  0x0000101AL
-#define BA0_AC97_RECORD_GAIN                    0x0000101CL
-#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
-#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
-#define BA0_AC97_3D_CONTROL                     0x00001022L
-#define BA0_AC97_MODEM_RATE                     0x00001024L
-#define BA0_AC97_POWERDOWN                      0x00001026L
-#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
-#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
-#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
-#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
-#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
-#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
-#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
-#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
-#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
-#define BA0_AC97_RESERVED_3A                    0x0000103AL
-#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
-#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
-#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
-#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
-#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
-#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
-#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
-#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
-#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
-#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
-#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
-#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
-#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
-#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
-#define BA0_AC97_RESERVED_58                    0x00001058L
-#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
-#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
-#define BA0_AC97_AC_MODE                        0x0000105EL
-#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
-#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
-#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
-#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
-#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
-#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
-#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
-#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
-#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
-#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
-#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
-#define BA0_AC97_CAL_ADDRESS                    0x00001076L
-#define BA0_AC97_CAL_DATA                       0x00001078L
-#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
-#define BA0_AC97_VENDOR_ID1                     0x0000107CL
-#define BA0_AC97_VENDOR_ID2                     0x0000107EL
-
-//****************************************************************************
-//
-// The following define the offsets of the registers and memories accessed via
-// base address register one on the CS4281 part.
-//
-//****************************************************************************
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI device ID/vendor ID
-// register.
-//
-//****************************************************************************
-#define PDV_VENID_MASK                          0x0000FFFFL
-#define PDV_DEVID_MASK                          0xFFFF0000L
-#define PDV_VENID_SHIFT                         0L
-#define PDV_DEVID_SHIFT                         16L
-#define VENID_CIRRUS_LOGIC                      0x1013L
-#define DEVID_CS4281                            0x6005L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI status and command
-// register.
-//
-//****************************************************************************
-#define PSC_IO_SPACE_ENABLE                     0x00000001L
-#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
-#define PSC_BUS_MASTER_ENABLE                   0x00000004L
-#define PSC_SPECIAL_CYCLES                      0x00000008L
-#define PSC_MWI_ENABLE                          0x00000010L
-#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
-#define PSC_PARITY_RESPONSE                     0x00000040L
-#define PSC_WAIT_CONTROL                        0x00000080L
-#define PSC_SERR_ENABLE                         0x00000100L
-#define PSC_FAST_B2B_ENABLE                     0x00000200L
-#define PSC_UDF_MASK                            0x007F0000L
-#define PSC_FAST_B2B_CAPABLE                    0x00800000L
-#define PSC_PARITY_ERROR_DETECTED               0x01000000L
-#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
-#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
-#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
-#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
-#define PSC_SIGNALLED_SERR                      0x40000000L
-#define PSC_DETECTED_PARITY_ERROR               0x80000000L
-#define PSC_UDF_SHIFT                           16L
-#define PSC_DEVSEL_TIMING_SHIFT                 25L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI class/revision ID
-// register.
-//
-//****************************************************************************
-#define PCR_REVID_MASK                          0x000000FFL
-#define PCR_INTERFACE_MASK                      0x0000FF00L
-#define PCR_SUBCLASS_MASK                       0x00FF0000L
-#define PCR_CLASS_MASK                          0xFF000000L
-#define PCR_REVID_SHIFT                         0L
-#define PCR_INTERFACE_SHIFT                     8L
-#define PCR_SUBCLASS_SHIFT                      16L
-#define PCR_CLASS_SHIFT                         24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI latency timer register.
-//
-//****************************************************************************
-#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
-#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
-#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
-#define PLT_BIST_MASK                           0xFF000000L
-#define PLT_CACHE_LINE_SIZE_SHIFT               0L
-#define PLT_LATENCY_TIMER_SHIFT                 8L
-#define PLT_HEADER_TYPE_SHIFT                   16L
-#define PLT_BIST_SHIFT                          24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI base address registers.
-//
-//****************************************************************************
-#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
-#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
-#define PBAR_NOT_PREFETCHABLE                   0x00000008L
-#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
-#define PBAR_LOCATION_TYPE_SHIFT                1L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI subsystem ID/subsystem
-// vendor ID register.
-//
-//****************************************************************************
-#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
-#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
-#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
-#define PSS_SUBSYSTEM_ID_SHIFT                  16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PCI interrupt register.
-//
-//****************************************************************************
-#define PI_LINE_MASK                            0x000000FFL
-#define PI_PIN_MASK                             0x0000FF00L
-#define PI_MIN_GRANT_MASK                       0x00FF0000L
-#define PI_MAX_LATENCY_MASK                     0xFF000000L
-#define PI_LINE_SHIFT                           0L
-#define PI_PIN_SHIFT                            8L
-#define PI_MIN_GRANT_SHIFT                      16L
-#define PI_MAX_LATENCY_SHIFT                    24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt status
-// register.
-//
-//****************************************************************************
-#define HISR_HVOLMASK                            0x00000003L
-#define HISR_VDNI                                0x00000001L
-#define HISR_VUPI                                0x00000002L
-#define HISR_GP1I                                0x00000004L
-#define HISR_GP3I                                0x00000008L
-#define HISR_GPSI                                0x00000010L
-#define HISR_GPPI                                0x00000020L
-#define HISR_DMAI                                0x00040000L
-#define HISR_FIFOI                               0x00100000L
-#define HISR_HVOL                                0x00200000L
-#define HISR_MIDI                                0x00400000L
-#define HISR_SBINT                               0x00800000L
-#define HISR_INTENA                              0x80000000L
-#define HISR_DMA_MASK                            0x00000F00L
-#define HISR_FIFO_MASK                           0x0000F000L
-#define HISR_DMA_SHIFT                           8L
-#define HISR_FIFO_SHIFT                          12L
-#define HISR_FIFO0                               0x00001000L
-#define HISR_FIFO1                               0x00002000L
-#define HISR_FIFO2                               0x00004000L
-#define HISR_FIFO3                               0x00008000L
-#define HISR_DMA0                                0x00000100L
-#define HISR_DMA1                                0x00000200L
-#define HISR_DMA2                                0x00000400L
-#define HISR_DMA3                                0x00000800L
-#define HISR_RESERVED                            0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the host interrupt control
-// register.
-//
-//****************************************************************************
-#define HICR_IEV                                 0x00000001L
-#define HICR_CHGM                                0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Mode Register n
-// (DMRn)
-//
-//****************************************************************************
-#define DMRn_TR_MASK                             0x0000000CL
-#define DMRn_TR_SHIFT                            2L
-#define DMRn_AUTO                                0x00000010L
-#define DMRn_TR_READ                             0x00000008L
-#define DMRn_TR_WRITE                            0x00000004L
-#define DMRn_TYPE_MASK                           0x000000C0L
-#define DMRn_TYPE_SHIFT                          6L
-#define DMRn_SIZE8                               0x00010000L
-#define DMRn_MONO                                0x00020000L
-#define DMRn_BEND                                0x00040000L
-#define DMRn_USIGN                               0x00080000L
-#define DMRn_SIZE20                              0x00100000L
-#define DMRn_SWAPC                               0x00400000L
-#define DMRn_CBC                                 0x01000000L
-#define DMRn_TBC                                 0x02000000L
-#define DMRn_POLL                                0x10000000L
-#define DMRn_DMA                                 0x20000000L
-#define DMRn_FSEL_MASK                           0xC0000000L
-#define DMRn_FSEL_SHIFT                          30L
-#define DMRn_FSEL0                               0x00000000L
-#define DMRn_FSEL1                               0x40000000L
-#define DMRn_FSEL2                               0x80000000L
-#define DMRn_FSEL3                               0xC0000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the DMA Command Register n
-// (DCRn)
-//
-//****************************************************************************
-#define DCRn_HTCIE                               0x00020000L
-#define DCRn_TCIE                                0x00010000L
-#define DCRn_MSK                                 0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the FIFO Control 
-// register n.(FCRn)
-//
-//****************************************************************************
-#define FCRn_OF_MASK                            0x0000007FL
-#define FCRn_OF_SHIFT                           0L
-#define FCRn_SZ_MASK                            0x00007F00L
-#define FCRn_SZ_SHIFT                           8L
-#define FCRn_LS_MASK                            0x001F0000L
-#define FCRn_LS_SHIFT                           16L
-#define FCRn_RS_MASK                            0x1F000000L
-#define FCRn_RS_SHIFT                           24L
-#define FCRn_FEN                                0x80000000L
-#define FCRn_PSH                                0x20000000L
-#define FCRn_DACZ                               0x40000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port Power Management
-// control register.(SPMC)
-//
-//****************************************************************************
-#define SPMC_RSTN                               0x00000001L
-#define SPMC_ASYN                               0x00000002L
-#define SPMC_WUP1                               0x00000004L
-#define SPMC_WUP2                               0x00000008L
-#define SPMC_ASDI2E                             0x00000100L
-#define SPMC_ESSPD                              0x00000200L
-#define SPMC_GISPEN                             0x00004000L
-#define SPMC_GIPPEN                             0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Configuration Load register.
-// (CFLR)
-//
-//****************************************************************************
-#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
-#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
-
-#define CFLR_CB0_MASK                            0x000000FFL
-#define CFLR_CB1_MASK                            0x0000FF00L
-#define CFLR_CB2_MASK                            0x00FF0000L
-#define CFLR_CB3_MASK                            0xFF000000L
-#define CFLR_CB0_SHIFT                           0L
-#define CFLR_CB1_SHIFT                           8L
-#define CFLR_CB2_SHIFT                           16L
-#define CFLR_CB3_SHIFT                           24L
-
-#define IOTCR_DMA0                              0x00000000L
-#define IOTCR_DMA1                              0x00000400L
-#define IOTCR_DMA2                              0x00000800L
-#define IOTCR_DMA3                              0x00000C00L
-#define IOTCR_CCLS                              0x00000100L
-#define IOTCR_PCPCI                             0x00000200L
-#define IOTCR_DDMA                              0x00000300L
-
-#define SBWBS_WBB                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the SRC Slot Assignment Register
-// (SRCSA)
-//
-//****************************************************************************
-#define SRCSA_PLSS_MASK                         0x0000001FL
-#define SRCSA_PLSS_SHIFT                        0L
-#define SRCSA_PRSS_MASK                         0x00001F00L
-#define SRCSA_PRSS_SHIFT                        8L
-#define SRCSA_CLSS_MASK                         0x001F0000L
-#define SRCSA_CLSS_SHIFT                        16L
-#define SRCSA_CRSS_MASK                         0x1F000000L
-#define SRCSA_CRSS_SHIFT                        24L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Power Management
-// register.(SSPM)
-//
-//****************************************************************************
-#define SSPM_FPDN                               0x00000080L
-#define SSPM_MIXEN                              0x00000040L
-#define SSPM_CSRCEN                             0x00000020L
-#define SSPM_PSRCEN                             0x00000010L
-#define SSPM_JSEN                               0x00000008L
-#define SSPM_ACLEN                              0x00000004L
-#define SSPM_FMEN                               0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound System Control
-// Register. (SSCR)
-//
-//****************************************************************************
-#define SSCR_SB                                 0x00000004L
-#define SSCR_HVC                                0x00000008L
-#define SSCR_LPFIFO                             0x00000040L
-#define SSCR_LPSRC                              0x00000080L
-#define SSCR_XLPSRC                             0x00000100L
-#define SSCR_MVMD                               0x00010000L
-#define SSCR_MVAD                               0x00020000L
-#define SSCR_MVLD                               0x00040000L
-#define SSCR_MVCS                               0x00080000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Clock Control Register 1. 
-// (CLKCR1)
-//
-//****************************************************************************
-#define CLKCR1_DLLSS_MASK                       0x0000000CL
-#define CLKCR1_DLLSS_SHIFT                      2L
-#define CLKCR1_DLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_DLLOS                            0x00000040L
-#define CLKCR1_CKRA                             0x00010000L
-#define CLKCR1_CKRN                             0x00020000L
-#define CLKCR1_DLLRDY                           0x01000000L
-#define CLKCR1_CLKON                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the Sound Blaster Read Buffer
-// Status.(SBRBS)
-//
-//****************************************************************************
-#define SBRBS_RD_MASK                           0x0000007FL
-#define SBRBS_RD_SHIFT                          0L
-#define SBRBS_RBF                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port master control
-// register.(SERMC)
-//
-//****************************************************************************
-#define SERMC_MSPE                              0x00000001L
-#define SERMC_PTC_MASK                          0x0000000EL
-#define SERMC_PTC_SHIFT                         1L
-#define SERMC_PTC_AC97                          0x00000002L
-#define SERMC_PLB                               0x00000010L
-#define SERMC_PXLB                              0x00000020L
-#define SERMC_LOFV                              0x00080000L
-#define SERMC_SLB                               0x00100000L
-#define SERMC_SXLB                              0x00200000L
-#define SERMC_ODSEN1                            0x01000000L
-#define SERMC_ODSEN2                            0x02000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the General Purpose I/O Register. 
-// (GPIOR)
-//
-//****************************************************************************
-#define GPIOR_VDNS                              0x00000001L
-#define GPIOR_VUPS                              0x00000002L
-#define GPIOR_GP1S                              0x00000004L
-#define GPIOR_GP3S                              0x00000008L
-#define GPIOR_GPSS                              0x00000010L
-#define GPIOR_GPPS                              0x00000020L
-#define GPIOR_GP1D                              0x00000400L
-#define GPIOR_GP3D                              0x00000800L
-#define GPIOR_VDNLT                             0x00010000L
-#define GPIOR_VDNPO                             0x00020000L
-#define GPIOR_VDNST                             0x00040000L
-#define GPIOR_VDNW                              0x00080000L
-#define GPIOR_VUPLT                             0x00100000L
-#define GPIOR_VUPPO                             0x00200000L
-#define GPIOR_VUPST                             0x00400000L
-#define GPIOR_VUPW                              0x00800000L
-#define GPIOR_GP1OE                             0x01000000L
-#define GPIOR_GP1PT                             0x02000000L
-#define GPIOR_GP1ST                             0x04000000L
-#define GPIOR_GP1W                              0x08000000L
-#define GPIOR_GP3OE                             0x10000000L
-#define GPIOR_GP3PT                             0x20000000L
-#define GPIOR_GP3ST                             0x40000000L
-#define GPIOR_GP3W                              0x80000000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the clock control register 1.
-//
-//****************************************************************************
-#define CLKCR1_PLLSS_MASK                       0x0000000CL
-#define CLKCR1_PLLSS_SERIAL                     0x00000000L
-#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
-#define CLKCR1_PLLSS_PCI                        0x00000008L
-#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
-#define CLKCR1_PLLP                             0x00000010L
-#define CLKCR1_SWCE                             0x00000020L
-#define CLKCR1_PLLOS                            0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the feature reporting register.
-//
-//****************************************************************************
-#define FRR_FAB_MASK                            0x00000003L
-#define FRR_MASK_MASK                           0x0000001CL
-#define FRR_ID_MASK                             0x00003000L
-#define FRR_FAB_SHIFT                           0L
-#define FRR_MASK_SHIFT                          2L
-#define FRR_ID_SHIFT                            12L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 1 configuration
-// register.
-//
-//****************************************************************************
-#define SERC1_VALUE                             0x00000003L
-#define SERC1_SO1EN                             0x00000001L
-#define SERC1_SO1F_MASK                         0x0000000EL
-#define SERC1_SO1F_CS423X                       0x00000000L
-#define SERC1_SO1F_AC97                         0x00000002L
-#define SERC1_SO1F_DAC                          0x00000004L
-#define SERC1_SO1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the serial port 2 configuration
-// register.
-//
-//****************************************************************************
-#define SERC2_VALUE                             0x00000003L
-#define SERC2_SI1EN                             0x00000001L
-#define SERC2_SI1F_MASK                         0x0000000EL
-#define SERC2_SI1F_CS423X                       0x00000000L
-#define SERC2_SI1F_AC97                         0x00000002L
-#define SERC2_SI1F_ADC                          0x00000004L
-#define SERC2_SI1F_SPDIF                        0x00000006L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 control register.
-//
-//****************************************************************************
-#define ACCTL_ESYN                              0x00000002L
-#define ACCTL_VFRM                              0x00000004L
-#define ACCTL_DCV                               0x00000008L
-#define ACCTL_CRW                               0x00000010L
-#define ACCTL_TC                                0x00000040L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register.
-//
-//****************************************************************************
-#define ACSTS_CRDY                              0x00000001L
-#define ACSTS_VSTS                              0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 output slot valid
-// register.
-//
-//****************************************************************************
-#define ACOSV_SLV3                              0x00000001L
-#define ACOSV_SLV4                              0x00000002L
-#define ACOSV_SLV5                              0x00000004L
-#define ACOSV_SLV6                              0x00000008L
-#define ACOSV_SLV7                              0x00000010L
-#define ACOSV_SLV8                              0x00000020L
-#define ACOSV_SLV9                              0x00000040L
-#define ACOSV_SLV10                             0x00000080L
-#define ACOSV_SLV11                             0x00000100L
-#define ACOSV_SLV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command address
-// register.
-//
-//****************************************************************************
-#define ACCAD_CI_MASK                           0x0000007FL
-#define ACCAD_CI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 command data register.
-//
-//****************************************************************************
-#define ACCDA_CD_MASK                           0x0000FFFFL
-#define ACCDA_CD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register.
-//
-//****************************************************************************
-#define ACISV_ISV3                              0x00000001L
-#define ACISV_ISV4                              0x00000002L
-#define ACISV_ISV5                              0x00000004L
-#define ACISV_ISV6                              0x00000008L
-#define ACISV_ISV7                              0x00000010L
-#define ACISV_ISV8                              0x00000020L
-#define ACISV_ISV9                              0x00000040L
-#define ACISV_ISV10                             0x00000080L
-#define ACISV_ISV11                             0x00000100L
-#define ACISV_ISV12                             0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register.
-//
-//****************************************************************************
-#define ACSAD_SI_MASK                           0x0000007FL
-#define ACSAD_SI_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register.
-//
-//****************************************************************************
-#define ACSDA_SD_MASK                           0x0000FFFFL
-#define ACSDA_SD_SHIFT                          0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers (all 12).
-//
-//****************************************************************************
-#define IOTAC_SA_MASK                           0x0000FFFFL
-#define IOTAC_MSK_MASK                          0x000F0000L
-#define IOTAC_IODC_MASK                         0x06000000L
-#define IOTAC_IODC_16_BIT                       0x00000000L
-#define IOTAC_IODC_10_BIT                       0x02000000L
-#define IOTAC_IODC_12_BIT                       0x04000000L
-#define IOTAC_WSPI                              0x08000000L
-#define IOTAC_RSPI                              0x10000000L
-#define IOTAC_WSE                               0x20000000L
-#define IOTAC_WE                                0x40000000L
-#define IOTAC_RE                                0x80000000L
-#define IOTAC_SA_SHIFT                          0L
-#define IOTAC_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI master enable
-// register.
-//
-//****************************************************************************
-#define PCPCIEN_EN                              0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick poll/trigger
-// register.
-//
-//****************************************************************************
-#define JSPT_CAX                                0x00000001L
-#define JSPT_CAY                                0x00000002L
-#define JSPT_CBX                                0x00000004L
-#define JSPT_CBY                                0x00000008L
-#define JSPT_BA1                                0x00000010L
-#define JSPT_BA2                                0x00000020L
-#define JSPT_BB1                                0x00000040L
-#define JSPT_BB2                                0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the joystick control register.
-// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
-//
-//****************************************************************************
-#define JSCTL_SP_MASK                           0x00000003L
-#define JSCTL_SP_SLOW                           0x00000000L
-#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
-#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
-#define JSCTL_SP_FAST                           0x00000003L
-#define JSCTL_ARE                               0x00000004L
-#define JSCTL_TBF                               0x00000100L
-
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI control register.
-//
-//****************************************************************************
-#define MIDCR_TXE                               0x00000001L
-#define MIDCR_RXE                               0x00000002L
-#define MIDCR_RIE                               0x00000004L
-#define MIDCR_TIE                               0x00000008L
-#define MIDCR_MLB                               0x00000010L
-#define MIDCR_MRST                              0x00000020L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI status register.
-//
-//****************************************************************************
-#define MIDSR_RBE                               0x00000080L
-#define MIDSR_RDA                               0x00008000L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI write port register.
-//
-//****************************************************************************
-#define MIDWP_MWD_MASK                          0x000000FFL
-#define MIDWP_MWD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the MIDI read port register.
-//
-//****************************************************************************
-#define MIDRP_MRD_MASK                          0x000000FFL
-#define MIDRP_MRD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the configuration interface
-// register.
-//
-//****************************************************************************
-#define CFGI_CLK                                0x00000001L
-#define CFGI_DOUT                               0x00000002L
-#define CFGI_DIN_EEN                            0x00000004L
-#define CFGI_EELD                               0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the subsystem ID and vendor ID
-// register.
-//
-//****************************************************************************
-#define SSVID_VID_MASK                          0x0000FFFFL
-#define SSVID_SID_MASK                          0xFFFF0000L
-#define SSVID_VID_SHIFT                         0L
-#define SSVID_SID_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the GPIO pin interface register.
-//
-//****************************************************************************
-#define GPIOR_VOLDN                             0x00000001L
-#define GPIOR_VOLUP                             0x00000002L
-#define GPIOR_SI2D                              0x00000004L
-#define GPIOR_SI2OE                             0x00000008L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status register 2.
-//
-//****************************************************************************
-#define ACSTS2_CRDY                             0x00000001L
-#define ACSTS2_VSTS                             0x00000002L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 input slot valid
-// register 2.
-//
-//****************************************************************************
-#define ACISV2_ISV3                             0x00000001L
-#define ACISV2_ISV4                             0x00000002L
-#define ACISV2_ISV5                             0x00000004L
-#define ACISV2_ISV6                             0x00000008L
-#define ACISV2_ISV7                             0x00000010L
-#define ACISV2_ISV8                             0x00000020L
-#define ACISV2_ISV9                             0x00000040L
-#define ACISV2_ISV10                            0x00000080L
-#define ACISV2_ISV11                            0x00000100L
-#define ACISV2_ISV12                            0x00000200L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status address
-// register 2.
-//
-//****************************************************************************
-#define ACSAD2_SI_MASK                          0x0000007FL
-#define ACSAD2_SI_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 status data register 2.
-//
-//****************************************************************************
-#define ACSDA2_SD_MASK                          0x0000FFFFL
-#define ACSDA2_SD_SHIFT                         0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap control register.
-//
-//****************************************************************************
-#define IOTCR_ITD                               0x00000001L
-#define IOTCR_HRV                               0x00000002L
-#define IOTCR_SRV                               0x00000004L
-#define IOTCR_DTI                               0x00000008L
-#define IOTCR_DFI                               0x00000010L
-#define IOTCR_DDP                               0x00000020L
-#define IOTCR_JTE                               0x00000040L
-#define IOTCR_PPE                               0x00000080L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Hardware Master Volume.  
-//
-//****************************************************************************
-#define IOTGP_SA_MASK                           0x0000FFFFL
-#define IOTGP_MSK_MASK                          0x000F0000L
-#define IOTGP_IODC_MASK                         0x06000000L
-#define IOTGP_IODC_16_BIT                       0x00000000L
-#define IOTGP_IODC_10_BIT                       0x02000000L
-#define IOTGP_IODC_12_BIT                       0x04000000L
-#define IOTGP_WSPI                              0x08000000L
-#define IOTGP_RSPI                              0x10000000L
-#define IOTGP_WSE                               0x20000000L
-#define IOTGP_WE                                0x40000000L
-#define IOTGP_RE                                0x80000000L
-#define IOTGP_SA_SHIFT                          0L
-#define IOTGP_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for Sound Blaster
-//
-//****************************************************************************
-#define IOTSB_SA_MASK                           0x0000FFFFL
-#define IOTSB_MSK_MASK                          0x000F0000L
-#define IOTSB_IODC_MASK                         0x06000000L
-#define IOTSB_IODC_16_BIT                       0x00000000L
-#define IOTSB_IODC_10_BIT                       0x02000000L
-#define IOTSB_IODC_12_BIT                       0x04000000L
-#define IOTSB_WSPI                              0x08000000L
-#define IOTSB_RSPI                              0x10000000L
-#define IOTSB_WSE                               0x20000000L
-#define IOTSB_WE                                0x40000000L
-#define IOTSB_RE                                0x80000000L
-#define IOTSB_SA_SHIFT                          0L
-#define IOTSB_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the I/O trap address and control
-// registers for FM.
-//
-//****************************************************************************
-#define IOTFM_SA_MASK                           0x0000FFFFL
-#define IOTFM_MSK_MASK                          0x000F0000L
-#define IOTFM_IODC_MASK                         0x06000000L
-#define IOTFM_IODC_16_BIT                       0x00000000L
-#define IOTFM_IODC_10_BIT                       0x02000000L
-#define IOTFM_IODC_12_BIT                       0x04000000L
-#define IOTFM_WSPI                              0x08000000L
-#define IOTFM_RSPI                              0x10000000L
-#define IOTFM_WSE                               0x20000000L
-#define IOTFM_WE                                0x40000000L
-#define IOTFM_RE                                0x80000000L
-#define IOTFM_SA_SHIFT                          0L
-#define IOTFM_MSK_SHIFT                         16L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI request register.
-//
-//****************************************************************************
-#define PCPRR_RDC_MASK                         0x00000007L
-#define PCPRR_REQ                              0x00008000L
-#define PCPRR_RDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI grant register.
-//
-//****************************************************************************
-#define PCPGR_GDC_MASK                         0x00000007L
-#define PCPGR_VL                               0x00008000L
-#define PCPGR_GDC_SHIFT                        0L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the PC/PCI Control Register.
-//
-//****************************************************************************
-#define PCPCR_EN                               0x00000001L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the debug index register.
-//
-//****************************************************************************
-#define DREG_REGID_MASK                         0x0000007FL
-#define DREG_DEBUG                              0x00000080L
-#define DREG_RGBK_MASK                          0x00000700L
-#define DREG_TRAP                               0x00000800L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_TRAPX                              0x00001000L
-#endif
-#endif
-#define DREG_REGID_SHIFT                        0L
-#define DREG_RGBK_SHIFT                         8L
-#define DREG_RGBK_REGID_MASK                    0x0000077FL
-#define DREG_REGID_R0                           0x00000010L
-#define DREG_REGID_R1                           0x00000011L
-#define DREG_REGID_R2                           0x00000012L
-#define DREG_REGID_R3                           0x00000013L
-#define DREG_REGID_R4                           0x00000014L
-#define DREG_REGID_R5                           0x00000015L
-#define DREG_REGID_R6                           0x00000016L
-#define DREG_REGID_R7                           0x00000017L
-#define DREG_REGID_R8                           0x00000018L
-#define DREG_REGID_R9                           0x00000019L
-#define DREG_REGID_RA                           0x0000001AL
-#define DREG_REGID_RB                           0x0000001BL
-#define DREG_REGID_RC                           0x0000001CL
-#define DREG_REGID_RD                           0x0000001DL
-#define DREG_REGID_RE                           0x0000001EL
-#define DREG_REGID_RF                           0x0000001FL
-#define DREG_REGID_RA_BUS_LOW                   0x00000020L
-#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
-#define DREG_REGID_YBUS_LOW                     0x00000050L
-#define DREG_REGID_YBUS_HIGH                    0x00000058L
-#define DREG_REGID_TRAP_0                       0x00000100L
-#define DREG_REGID_TRAP_1                       0x00000101L
-#define DREG_REGID_TRAP_2                       0x00000102L
-#define DREG_REGID_TRAP_3                       0x00000103L
-#define DREG_REGID_TRAP_4                       0x00000104L
-#define DREG_REGID_TRAP_5                       0x00000105L
-#define DREG_REGID_TRAP_6                       0x00000106L
-#define DREG_REGID_TRAP_7                       0x00000107L
-#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
-#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_8                       0x00000110L
-#define DREG_REGID_TRAP_9                       0x00000111L
-#define DREG_REGID_TRAP_10                      0x00000112L
-#define DREG_REGID_TRAP_11                      0x00000113L
-#define DREG_REGID_TRAP_12                      0x00000114L
-#define DREG_REGID_TRAP_13                      0x00000115L
-#define DREG_REGID_TRAP_14                      0x00000116L
-#define DREG_REGID_TRAP_15                      0x00000117L
-#define DREG_REGID_TRAP_16                      0x00000118L
-#define DREG_REGID_TRAP_17                      0x00000119L
-#define DREG_REGID_TRAP_18                      0x0000011AL
-#define DREG_REGID_TRAP_19                      0x0000011BL
-#define DREG_REGID_TRAP_20                      0x0000011CL
-#define DREG_REGID_TRAP_21                      0x0000011DL
-#define DREG_REGID_TRAP_22                      0x0000011EL
-#define DREG_REGID_TRAP_23                      0x0000011FL
-#endif
-#endif
-#define DREG_REGID_RSA0_LOW                     0x00000200L
-#define DREG_REGID_RSA0_HIGH                    0x00000201L
-#define DREG_REGID_RSA1_LOW                     0x00000202L
-#define DREG_REGID_RSA1_HIGH                    0x00000203L
-#define DREG_REGID_RSA2                         0x00000204L
-#define DREG_REGID_RSA3                         0x00000205L
-#define DREG_REGID_RSI0_LOW                     0x00000206L
-#define DREG_REGID_RSI0_HIGH                    0x00000207L
-#define DREG_REGID_RSI1                         0x00000208L
-#define DREG_REGID_RSI2                         0x00000209L
-#define DREG_REGID_SAGUSTATUS                   0x0000020AL
-#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
-#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
-#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
-#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
-#define DREG_REGID_RSDMA01E                     0x0000020FL
-#define DREG_REGID_RSDMA23E                     0x00000210L
-#define DREG_REGID_RSD0_LOW                     0x00000211L
-#define DREG_REGID_RSD0_HIGH                    0x00000212L
-#define DREG_REGID_RSD1_LOW                     0x00000213L
-#define DREG_REGID_RSD1_HIGH                    0x00000214L
-#define DREG_REGID_RSD2_LOW                     0x00000215L
-#define DREG_REGID_RSD2_HIGH                    0x00000216L
-#define DREG_REGID_RSD3_LOW                     0x00000217L
-#define DREG_REGID_RSD3_HIGH                    0x00000218L
-#define DREG_REGID_SRAR_HIGH                    0x0000021AL
-#define DREG_REGID_SRAR_LOW                     0x0000021BL
-#define DREG_REGID_DMA_STATE                    0x0000021CL
-#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
-#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
-#define DREG_REGID_CPU_STATUS                   0x00000300L
-#define DREG_REGID_MAC_MODE                     0x00000301L
-#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
-#define DREG_REGID_INDEX0                       0x00000304L
-#define DREG_REGID_INDEX1                       0x00000305L
-#define DREG_REGID_DMA_STATE_0_3                0x00000400L
-#define DREG_REGID_DMA_STATE_4_7                0x00000404L
-#define DREG_REGID_DMA_STATE_8_11               0x00000408L
-#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
-#define DREG_REGID_DMA_STATE_16_19              0x00000410L
-#define DREG_REGID_DMA_STATE_20_23              0x00000414L
-#define DREG_REGID_DMA_STATE_24_27              0x00000418L
-#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
-#define DREG_REGID_DMA_STATE_32_35              0x00000420L
-#define DREG_REGID_DMA_STATE_36_39              0x00000424L
-#define DREG_REGID_DMA_STATE_40_43              0x00000428L
-#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
-#define DREG_REGID_DMA_STATE_48_51              0x00000430L
-#define DREG_REGID_DMA_STATE_52_55              0x00000434L
-#define DREG_REGID_DMA_STATE_56_59              0x00000438L
-#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
-#define DREG_REGID_DMA_STATE_64_67              0x00000440L
-#define DREG_REGID_DMA_STATE_68_71              0x00000444L
-#define DREG_REGID_DMA_STATE_72_75              0x00000448L
-#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
-#define DREG_REGID_DMA_STATE_80_83              0x00000450L
-#define DREG_REGID_DMA_STATE_84_87              0x00000454L
-#define DREG_REGID_DMA_STATE_88_91              0x00000458L
-#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
-#define DREG_REGID_TRAP_SELECT                  0x00000500L
-#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
-#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
-#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
-#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
-#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
-#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
-#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
-#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
-#if !defined(NO_CS4612)
-#if !defined(NO_CS4615)
-#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
-#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
-#define DREG_REGID_TRAP_WRITE_10                0x00000512L
-#define DREG_REGID_TRAP_WRITE_11                0x00000513L
-#define DREG_REGID_TRAP_WRITE_12                0x00000514L
-#define DREG_REGID_TRAP_WRITE_13                0x00000515L
-#define DREG_REGID_TRAP_WRITE_14                0x00000516L
-#define DREG_REGID_TRAP_WRITE_15                0x00000517L
-#define DREG_REGID_TRAP_WRITE_16                0x00000518L
-#define DREG_REGID_TRAP_WRITE_17                0x00000519L
-#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
-#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
-#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
-#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
-#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
-#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
-#endif
-#endif
-#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
-#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
-#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
-#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
-#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
-#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
-#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
-#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
-#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
-#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
-#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
-#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
-#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
-#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
-#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
-#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
-#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
-#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
-#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
-#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
-#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
-#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
-#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
-#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
-#define DREG_REGID_RSHOUT_LOW                   0x00000620L
-#define DREG_REGID_RSHOUT_MID                   0x00000628L
-#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
-
-//****************************************************************************
-//
-// The following defines are for the flags in the AC97 S/PDIF Control register.
-//
-//****************************************************************************
-#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
-#define SPDIF_CONTROL_VAL                      0x00004000L
-#define SPDIF_CONTROL_COPY                     0x00000004L
-#define SPDIF_CONTROL_CC0                      0x00000010L
-#define SPDIF_CONTROL_CC1                      0x00000020L
-#define SPDIF_CONTROL_CC2                      0x00000040L
-#define SPDIF_CONTROL_CC3                      0x00000080L
-#define SPDIF_CONTROL_CC4                      0x00000100L
-#define SPDIF_CONTROL_CC5                      0x00000200L
-#define SPDIF_CONTROL_CC6                      0x00000400L
-#define SPDIF_CONTROL_L                        0x00000800L
-
-#endif // _H_HWDEFS
diff --git a/sound/oss/cs4281/cs4281_wrapper-24.c b/sound/oss/cs4281/cs4281_wrapper-24.c
deleted file mode 100644 (file)
index 4559f02..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281_wrapper.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/20/00 trw - new file. 
-*
-*******************************************************************************/
-
-#include <linux/spinlock.h>
-
-static int cs4281_resume_null(struct pci_dev *pcidev) { return 0; }
-static int cs4281_suspend_null(struct pci_dev *pcidev, pm_message_t state) { return 0; }
-
-#define free_dmabuf(state, dmabuf) \
-       pci_free_consistent(state->pcidev, \
-                           PAGE_SIZE << (dmabuf)->buforder, \
-                           (dmabuf)->rawbuf, (dmabuf)->dmaaddr);
-#define free_dmabuf2(state, dmabuf) \
-       pci_free_consistent((state)->pcidev, \
-                                   PAGE_SIZE << (state)->buforder_tmpbuff, \
-                                   (state)->tmpbuff, (state)->dmaaddr_tmpbuff);
-#define cs4x_pgoff(vma) ((vma)->vm_pgoff)
-
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
deleted file mode 100644 (file)
index 0400a41..0000000
+++ /dev/null
@@ -1,4487 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- adapted from drivers by Thomas Sailer, 
-*            -- but don't bug him; Problems should go to:
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Module command line parameters:
-*   none
-*
-*  Supported devices:
-*  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
-*  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
-*  /dev/midi   simple MIDI UART interface, no ioctl
-*
-* Modification History
-* 08/20/00 trw - silence and no stopping DAC until release
-* 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop.
-* 09/18/00 trw - added 16bit only record with conversion 
-* 09/24/00 trw - added Enhanced Full duplex (separate simultaneous 
-*                capture/playback rates)
-* 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin  
-*                libOSSm.so)
-* 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal)
-* 11/03/00 trw - fixed interrupt loss/stutter, added debug.
-* 11/10/00 bkz - added __devinit to cs4281_hw_init()
-* 11/10/00 trw - fixed SMP and capture spinlock hang.
-* 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm.
-* 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix.
-* 12/08/00 trw - added PM support. 
-* 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 
-*               (RH/Dell base), 2.2.18, 2.2.12.  cleaned up code mods by ident.
-* 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup.
-* 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use 
-*               defaultorder-100 as power of 2 for the buffer size. example:
-*               106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*
-*******************************************************************************/
-
-/* uncomment the following line to disable building PM support into the driver */
-//#define NOT_CS4281_PM 1 
-
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/fs.h>
-#include <linux/wait.h>
-
-#include <asm/current.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-//#include "cs_dm.h"
-#include "cs4281_hwdefs.h"
-#include "cs4281pm.h"
-
-struct cs4281_state;
-
-static void stop_dac(struct cs4281_state *s);
-static void stop_adc(struct cs4281_state *s);
-static void start_dac(struct cs4281_state *s);
-static void start_adc(struct cs4281_state *s);
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-// --------------------------------------------------------------------- 
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS          0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
-#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
-#endif
-
-#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
-#define        CS4281_CFLR_DEFAULT     0x00000001  /* CFLR must be in AC97 link mode */
-
-// buffer order determines the size of the dma buffer for the driver.
-// under Linux, a smaller buffer allows more responsiveness from many of the 
-// applications (e.g. games).  A larger buffer allows some of the apps (esound) 
-// to not underrun the dma buffer as easily.  As default, use 32k (order=3)
-// rather than 64k as some of the games work more responsively.
-// log base 2( buff sz = 32k).
-static unsigned long defaultorder = 3;
-module_param(defaultorder, ulong, 0);
-
-//
-// Turn on/off debugging compilation by commenting out "#define CSDEBUG"
-//
-#define CSDEBUG 1
-#if CSDEBUG
-#define CSDEBUG_INTERFACE 1
-#else
-#undef CSDEBUG_INTERFACE
-#endif
-//
-// cs_debugmask areas
-//
-#define CS_INIT                0x00000001      // initialization and probe functions
-#define CS_ERROR       0x00000002      // tmp debugging bit placeholder
-#define CS_INTERRUPT   0x00000004      // interrupt handler (separate from all other)
-#define CS_FUNCTION    0x00000008      // enter/leave functions
-#define CS_WAVE_WRITE  0x00000010      // write information for wave
-#define CS_WAVE_READ   0x00000020      // read information for wave
-#define CS_MIDI_WRITE  0x00000040      // write information for midi
-#define CS_MIDI_READ   0x00000080      // read information for midi
-#define CS_MPU401_WRITE 0x00000100     // write information for mpu401
-#define CS_MPU401_READ         0x00000200      // read information for mpu401
-#define CS_OPEN                0x00000400      // all open functions in the driver
-#define CS_RELEASE     0x00000800      // all release functions in the driver
-#define CS_PARMS       0x00001000      // functional and operational parameters
-#define CS_IOCTL       0x00002000      // ioctl (non-mixer)
-#define CS_PM          0x00004000      // power management 
-#define CS_TMP         0x10000000      // tmp debug mask bit
-
-#define CS_IOCTL_CMD_SUSPEND   0x1     // suspend
-#define CS_IOCTL_CMD_RESUME    0x2     // resume
-//
-// CSDEBUG is usual mode is set to 1, then use the
-// cs_debuglevel and cs_debugmask to turn on or off debugging.
-// Debug level of 1 has been defined to be kernel errors and info
-// that should be printed on any released driver.
-//
-#if CSDEBUG
-#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;}
-#else
-#define CS_DBGOUT(mask,level,x)
-#endif
-
-#if CSDEBUG
-static unsigned long cs_debuglevel = 1;        // levels range from 1-9
-static unsigned long cs_debugmask = CS_INIT | CS_ERROR;        // use CS_DBGOUT with various mask values
-module_param(cs_debuglevel, ulong, 0);
-module_param(cs_debugmask, ulong, 0);
-#endif
-#define CS_TRUE        1
-#define CS_FALSE       0
-
-// MIDI buffer sizes 
-#define MIDIINBUF  500
-#define MIDIOUTBUF 500
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define CS4281_MAJOR_VERSION   1
-#define CS4281_MINOR_VERSION   13
-#ifdef __ia64__
-#define CS4281_ARCH            64      //architecture key
-#else
-#define CS4281_ARCH            32      //architecture key
-#endif
-
-#define CS_TYPE_ADC 0
-#define CS_TYPE_DAC 1
-
-
-static const char invalid_magic[] =
-    KERN_CRIT "cs4281: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-        if (!(s) || (s)->magic != CS4281_MAGIC) { \
-                printk(invalid_magic);            \
-                return -ENXIO;                    \
-        }                                         \
-})
-
-//LIST_HEAD(cs4281_devs);
-static struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs };
-
-struct cs4281_state; 
-
-#include "cs4281_wrapper-24.c"
-
-struct cs4281_state {
-       // magic 
-       unsigned int magic;
-
-       // we keep the cards in a linked list 
-       struct cs4281_state *next;
-
-       // pcidev is needed to turn off the DDMA controller at driver shutdown 
-       struct pci_dev *pcidev;
-       struct list_head list;
-
-       // soundcore stuff 
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-
-       // hardware resources 
-       unsigned int pBA0phys, pBA1phys;
-       char __iomem *pBA0;
-       char __iomem *pBA1;
-       unsigned int irq;
-
-       // mixer registers 
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-       } mix;
-
-       // wave stuff   
-       struct properties {
-               unsigned fmt;
-               unsigned fmt_original;  // original requested format
-               unsigned channels;
-               unsigned rate;
-               unsigned char clkdiv;
-       } prop_dac, prop_adc;
-       unsigned conversion:1;  // conversion from 16 to 8 bit in progress
-       void *tmpbuff;          // tmp buffer for sample conversions
-       unsigned ena;
-       spinlock_t lock;
-       struct mutex open_sem;
-       struct mutex open_sem_adc;
-       struct mutex open_sem_dac;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-       wait_queue_head_t open_wait_adc;
-       wait_queue_head_t open_wait_dac;
-
-       dma_addr_t dmaaddr_tmpbuff;
-       unsigned buforder_tmpbuff;      // Log base 2 of 'rawbuf' size in bytes..
-       struct dmabuf {
-               void *rawbuf;   // Physical address of  
-               dma_addr_t dmaaddr;
-               unsigned buforder;      // Log base 2 of 'rawbuf' size in bytes..
-               unsigned numfrag;       // # of 'fragments' in the buffer.
-               unsigned fragshift;     // Log base 2 of fragment size.
-               unsigned hwptr, swptr;
-               unsigned total_bytes;   // # bytes process since open.
-               unsigned blocks;        // last returned blocks value GETOPTR
-               unsigned wakeup;        // interrupt occurred on block 
-               int count;
-               unsigned underrun;      // underrun flag
-               unsigned error; // over/underrun 
-               wait_queue_head_t wait;
-               // redundant, but makes calculations easier 
-               unsigned fragsize;      // 2**fragshift..
-               unsigned dmasize;       // 2**buforder.
-               unsigned fragsamples;
-               // OSS stuff 
-               unsigned mapped:1;      // Buffer mapped in cs4281_mmap()?
-               unsigned ready:1;       // prog_dmabuf_dac()/adc() successful?
-               unsigned endcleared:1;
-               unsigned type:1;        // adc or dac buffer (CS_TYPE_XXX)
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       // midi stuff 
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-       struct cs4281_pm pm;
-       struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
-};
-
-#include "cs4281pm-24.c"
-
-#if CSDEBUG
-
-// DEBUG ROUTINES
-
-#define SOUND_MIXER_CS_GETDBGLEVEL     _SIOWR('M',120, int)
-#define SOUND_MIXER_CS_SETDBGLEVEL     _SIOWR('M',121, int)
-#define SOUND_MIXER_CS_GETDBGMASK      _SIOWR('M',122, int)
-#define SOUND_MIXER_CS_SETDBGMASK      _SIOWR('M',123, int)
-
-#define SOUND_MIXER_CS_APM             _SIOWR('M',124, int)
-
-
-static void cs_printioctl(unsigned int x)
-{
-       unsigned int i;
-       unsigned char vidx;
-       // Index of mixtable1[] member is Device ID 
-       // and must be <= SOUND_MIXER_NRDEVICES.
-       // Value of array member is index into s->mix.vol[]
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM] = 1,  // voice 
-               [SOUND_MIXER_LINE1] = 2,        // AUX
-               [SOUND_MIXER_CD] = 3,   // CD 
-               [SOUND_MIXER_LINE] = 4, // Line 
-               [SOUND_MIXER_SYNTH] = 5,        // FM
-               [SOUND_MIXER_MIC] = 6,  // Mic 
-               [SOUND_MIXER_SPEAKER] = 7,      // Speaker 
-               [SOUND_MIXER_RECLEV] = 8,       // Recording level 
-               [SOUND_MIXER_VOLUME] = 9        // Master Volume 
-       };
-
-       switch (x) {
-       case SOUND_MIXER_CS_GETDBGMASK:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_GETDBGMASK:\n"));
-               break;
-       case SOUND_MIXER_CS_GETDBGLEVEL:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_GETDBGLEVEL:\n"));
-               break;
-       case SOUND_MIXER_CS_SETDBGMASK:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_SETDBGMASK:\n"));
-               break;
-       case SOUND_MIXER_CS_SETDBGLEVEL:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_MIXER_CS_SETDBGLEVEL:\n"));
-               break;
-       case OSS_GETVERSION:
-               CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n"));
-               break;
-       case SNDCTL_DSP_SYNC:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n"));
-               break;
-       case SNDCTL_DSP_SETDUPLEX:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n"));
-               break;
-       case SNDCTL_DSP_GETCAPS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n"));
-               break;
-       case SNDCTL_DSP_RESET:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n"));
-               break;
-       case SNDCTL_DSP_SPEED:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n"));
-               break;
-       case SNDCTL_DSP_STEREO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n"));
-               break;
-       case SNDCTL_DSP_CHANNELS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n"));
-               break;
-       case SNDCTL_DSP_GETFMTS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n"));
-               break;
-       case SNDCTL_DSP_SETFMT:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n"));
-               break;
-       case SNDCTL_DSP_POST:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n"));
-               break;
-       case SNDCTL_DSP_GETTRIGGER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n"));
-               break;
-       case SNDCTL_DSP_SETTRIGGER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n"));
-               break;
-       case SNDCTL_DSP_GETOSPACE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n"));
-               break;
-       case SNDCTL_DSP_GETISPACE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n"));
-               break;
-       case SNDCTL_DSP_NONBLOCK:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n"));
-               break;
-       case SNDCTL_DSP_GETODELAY:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n"));
-               break;
-       case SNDCTL_DSP_GETIPTR:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n"));
-               break;
-       case SNDCTL_DSP_GETOPTR:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n"));
-               break;
-       case SNDCTL_DSP_GETBLKSIZE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n"));
-               break;
-       case SNDCTL_DSP_SETFRAGMENT:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SNDCTL_DSP_SETFRAGMENT:\n"));
-               break;
-       case SNDCTL_DSP_SUBDIVIDE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n"));
-               break;
-       case SOUND_PCM_READ_RATE:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n"));
-               break;
-       case SOUND_PCM_READ_CHANNELS:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_PCM_READ_CHANNELS:\n"));
-               break;
-       case SOUND_PCM_READ_BITS:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n"));
-               break;
-       case SOUND_PCM_WRITE_FILTER:
-               CS_DBGOUT(CS_IOCTL, 4,
-                         printk("SOUND_PCM_WRITE_FILTER:\n"));
-               break;
-       case SNDCTL_DSP_SETSYNCRO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n"));
-               break;
-       case SOUND_PCM_READ_FILTER:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE1:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE2:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE3:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE4:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n"));
-               break;
-       case SOUND_MIXER_PRIVATE5:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n"));
-               break;
-       case SOUND_MIXER_INFO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n"));
-               break;
-       case SOUND_OLD_MIXER_INFO:
-               CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n"));
-               break;
-
-       default:
-               switch (_IOC_NR(x)) {
-               case SOUND_MIXER_VOLUME:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_VOLUME:\n"));
-                       break;
-               case SOUND_MIXER_SPEAKER:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_SPEAKER:\n"));
-                       break;
-               case SOUND_MIXER_RECLEV:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECLEV:\n"));
-                       break;
-               case SOUND_MIXER_MIC:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_MIC:\n"));
-                       break;
-               case SOUND_MIXER_SYNTH:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_SYNTH:\n"));
-                       break;
-               case SOUND_MIXER_RECSRC:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECSRC:\n"));
-                       break;
-               case SOUND_MIXER_DEVMASK:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_DEVMASK:\n"));
-                       break;
-               case SOUND_MIXER_RECMASK:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_RECMASK:\n"));
-                       break;
-               case SOUND_MIXER_STEREODEVS:
-                       CS_DBGOUT(CS_IOCTL, 4,
-                                 printk("SOUND_MIXER_STEREODEVS:\n"));
-                       break;
-               case SOUND_MIXER_CAPS:
-                       CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n"));
-                       break;
-               default:
-                       i = _IOC_NR(x);
-                       if (i >= SOUND_MIXER_NRDEVICES
-                           || !(vidx = mixtable1[i])) {
-                               CS_DBGOUT(CS_IOCTL, 4, printk
-                                       ("UNKNOWN IOCTL: 0x%.8x NR=%d\n",
-                                               x, i));
-                       } else {
-                               CS_DBGOUT(CS_IOCTL, 4, printk
-                                       ("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n",
-                                               x, i));
-                       }
-                       break;
-               }
-       }
-}
-#endif
-static int prog_dmabuf_adc(struct cs4281_state *s);
-static void prog_codec(struct cs4281_state *s, unsigned type);
-
-// --------------------------------------------------------------------- 
-//
-//              Hardware Interfaces For the CS4281
-//
-
-
-//******************************************************************************
-// "delayus()-- Delay for the specified # of microseconds.
-//******************************************************************************
-static void delayus(struct cs4281_state *s, u32 delay)
-{
-       u32 j;
-       if ((delay > 9999) && (s->pm.flags & CS4281_PM_IDLE)) {
-               j = (delay * HZ) / 1000000;     /* calculate delay in jiffies  */
-               if (j < 1)
-                       j = 1;  /* minimum one jiffy. */
-               current->state = TASK_UNINTERRUPTIBLE;
-               schedule_timeout(j);
-       } else
-               udelay(delay);
-       return;
-}
-
-
-//******************************************************************************
-// "cs4281_read_ac97" -- Reads a word from the specified location in the
-//               CS4281's address space(based on the BA0 register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
-//                                            0h for reads.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
-// 5. if DCV not cleared, break and return error
-// 6. Read ACSTS = Status Register = 464h, check VSTS bit
-//****************************************************************************
-static int cs4281_read_ac97(struct cs4281_state *card, u32 offset,
-                           u32 * value)
-{
-       u32 count, status;
-
-       // Make sure that there is not data sitting
-       // around from a previous uncompleted access.
-       // ACSDA = Status Data Register = 47Ch
-       status = readl(card->pBA0 + BA0_ACSDA);
-
-       // Setup the AC97 control registers on the CS4281 to send the
-       // appropriate command to the AC97 to perform the read.
-       // ACCAD = Command Address Register = 46Ch
-       // ACCDA = Command Data Register = 470h
-       // ACCTL = Control Register = 460h
-       // bit DCV - will clear when process completed
-       // bit CRW - Read command
-       // bit VFRM - valid frame enabled
-       // bit ESYN - ASYNC generation enabled
-
-       // Get the actual AC97 register from the offset
-       writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-       writel(0, card->pBA0 + BA0_ACCDA);
-       writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN,
-              card->pBA0 + BA0_ACCTL);
-
-       // Wait for the read to occur.
-       for (count = 0; count < 10; count++) {
-               // First, we want to wait for a short time.
-               udelay(25);
-
-               // Now, check to see if the read has completed.
-               // ACCTL = 460h, DCV should be reset by now and 460h = 17h
-               if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV))
-                       break;
-       }
-
-       // Make sure the read completed.
-       if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)
-               return 1;
-
-       // Wait for the valid status bit to go active.
-       for (count = 0; count < 10; count++) {
-               // Read the AC97 status register.
-               // ACSTS = Status Register = 464h
-               status = readl(card->pBA0 + BA0_ACSTS);
-
-               // See if we have valid status.
-               // VSTS - Valid Status
-               if (status & ACSTS_VSTS)
-                       break;
-               // Wait for a short while.
-               udelay(25);
-       }
-
-       // Make sure we got valid status.
-       if (!(status & ACSTS_VSTS))
-               return 1;
-
-       // Read the data returned from the AC97 register.
-       // ACSDA = Status Data Register = 474h
-       *value = readl(card->pBA0 + BA0_ACSDA);
-
-       // Success.
-       return (0);
-}
-
-
-//****************************************************************************
-//
-// "cs4281_write_ac97()"-- writes a word to the specified location in the
-// CS461x's address space (based on the part's base address zero register).
-//
-// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
-// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
-// 3. Write ACCTL = Control Register = 460h for initiating the write
-// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
-// 5. if DCV not cleared, break and return error
-//
-//****************************************************************************
-static int cs4281_write_ac97(struct cs4281_state *card, u32 offset,
-                            u32 value)
-{
-       u32 count, status=0;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n"));
-
-       // Setup the AC97 control registers on the CS4281 to send the
-       // appropriate command to the AC97 to perform the read.
-       // ACCAD = Command Address Register = 46Ch
-       // ACCDA = Command Data Register = 470h
-       // ACCTL = Control Register = 460h
-       // set DCV - will clear when process completed
-       // reset CRW - Write command
-       // set VFRM - valid frame enabled
-       // set ESYN - ASYNC generation enabled
-       // set RSTN - ARST# inactive, AC97 codec not reset
-
-       // Get the actual AC97 register from the offset
-
-       writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD);
-       writel(value, card->pBA0 + BA0_ACCDA);
-       writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN,
-              card->pBA0 + BA0_ACCTL);
-
-       // Wait for the write to occur.
-       for (count = 0; count < 100; count++) {
-               // First, we want to wait for a short time.
-               udelay(25);
-               // Now, check to see if the write has completed.
-               // ACCTL = 460h, DCV should be reset by now and 460h = 07h
-               status = readl(card->pBA0 + BA0_ACCTL);
-               if (!(status & ACCTL_DCV))
-                       break;
-       }
-
-       // Make sure the write completed.
-       if (status & ACCTL_DCV) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                       "cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n"));
-               return 1;
-       }
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n"));
-       // Success.
-       return 0;
-}
-
-
-//******************************************************************************
-// "Init4281()" -- Bring up the part.
-//******************************************************************************
-static __devinit int cs4281_hw_init(struct cs4281_state *card)
-{
-       u32 ac97_slotid;
-       u32 temp1, temp2;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n"));
-#ifndef NOT_CS4281_PM
-       if(!card)
-               return 1;
-#endif
-       temp2 = readl(card->pBA0 + BA0_CFLR);
-       CS_DBGOUT(CS_INIT | CS_ERROR | CS_PARMS, 4, printk(KERN_INFO 
-               "cs4281: cs4281_hw_init() CFLR 0x%x\n", temp2));
-       if(temp2 != CS4281_CFLR_DEFAULT)
-       {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-                       "cs4281: cs4281_hw_init() CFLR invalid - resetting from 0x%x to 0x%x\n",
-                               temp2,CS4281_CFLR_DEFAULT));
-               writel(CS4281_CFLR_DEFAULT, card->pBA0 + BA0_CFLR);
-               temp2 = readl(card->pBA0 + BA0_CFLR);
-               if(temp2 != CS4281_CFLR_DEFAULT)
-               {
-                       CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO 
-                               "cs4281: cs4281_hw_init() Invalid hardware - unable to configure CFLR\n"));
-                       return 1;
-               }
-       }
-
-       //***************************************7
-       //  Set up the Sound System Configuration
-       //***************************************
-
-       // Set the 'Configuration Write Protect' register
-       // to 4281h.  Allows vendor-defined configuration
-       // space between 0e4h and 0ffh to be written.
-
-       writel(0x4281, card->pBA0 + BA0_CWPR);  // (3e0h)
-
-       // (0), Blast the clock control register to zero so that the
-       // PLL starts out in a known state, and blast the master serial
-       // port control register to zero so that the serial ports also
-       // start out in a known state.
-
-       writel(0, card->pBA0 + BA0_CLKCR1);     // (400h)
-       writel(0, card->pBA0 + BA0_SERMC);      // (420h)
-
-
-       // (1), Make ESYN go to zero to turn off
-       // the Sync pulse on the AC97 link.
-
-       writel(0, card->pBA0 + BA0_ACCTL);
-       udelay(50);
-
-
-       // (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
-       // the AC97 spec) and then drive it high.  This is done for non
-       // AC97 modes since there might be logic external to the CS461x
-       // that uses the ARST# line for a reset.
-
-       writel(0, card->pBA0 + BA0_SPMC);       // (3ech)
-       udelay(100);
-       writel(SPMC_RSTN, card->pBA0 + BA0_SPMC);
-       delayus(card,50000);            // Wait 50 ms for ABITCLK to become stable.
-
-       // (3) Turn on the Sound System Clocks.
-       writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1);   // (400h)
-       delayus(card,50000);            // Wait for the PLL to stabilize.
-       // Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
-       writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1);
-
-       // (4) Power on everything for now..
-       writel(0x7E, card->pBA0 + BA0_SSPM);    // (740h)
-
-       // (5) Wait for clock stabilization.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               udelay(1000);
-               if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)
-                       break;
-       }
-       if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR 
-                       "cs4281: DLLRDY failed!\n"));
-               return -EIO;
-       }
-       // (6) Enable ASYNC generation.
-       writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL);     // (460h)
-
-       // Now wait 'for a short while' to allow the  AC97
-       // part to start generating bit clock. (so we don't
-       // Try to start the PLL without an input clock.)
-       delayus(card,50000);
-
-       // Set the serial port timing configuration, so that the
-       // clock control circuit gets its clock from the right place.
-       writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2.
-
-       // (7) Wait for the codec ready signal from the AC97 codec.
-
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               // Delay a mil to let things settle out and
-               // to prevent retrying the read too quickly.
-               udelay(1000);
-               if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY) // If ready,  (464h)
-                       break;  //   exit the 'for' loop.
-       }
-       if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY))      // If never came ready,
-       {
-               CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-                        "cs4281: ACSTS never came ready!\n"));
-               return -EIO;    //   exit initialization.
-       }
-       // (8) Assert the 'valid frame' signal so we can
-       // begin sending commands to the AC97 codec.
-       writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL);        // (460h)
-
-       // (9), Wait until CODEC calibration is finished.
-       // Print an error message if it doesn't.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               delayus(card,10000);
-               // Read the AC97 Powerdown Control/Status Register.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
-               if ((temp2 & 0x0000000F) == 0x0000000F)
-                       break;
-       }
-       if ((temp2 & 0x0000000F) != 0x0000000F) {
-               CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
-                       "cs4281: Codec failed to calibrate.  Status = %.8x.\n",
-                               temp2));
-               return -EIO;
-       }
-       // (10), Set the serial port timing configuration, so that the
-       // clock control circuit gets its clock from the right place.
-       writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2.
-
-
-       // (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
-       // that the codec is pumping ADC data across the AC link.
-       for (temp1 = 0; temp1 < 1000; temp1++) {
-               // Delay a mil to let things settle out and
-               // to prevent retrying the read too quickly.
-               delayus(card,1000);     //(test)
-
-               // Read the input slot valid register;  See
-               // if input slots 3 and 4 are valid yet.
-               if (
-                   (readl(card->pBA0 + BA0_ACISV) &
-                    (ACISV_ISV3 | ACISV_ISV4)) ==
-                   (ACISV_ISV3 | ACISV_ISV4)) break;   // Exit the 'for' if slots are valid.
-       }
-       // If we never got valid data, exit initialization.
-       if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4))
-           != (ACISV_ISV3 | ACISV_ISV4)) {
-               CS_DBGOUT(CS_FUNCTION, 2,
-                         printk(KERN_ERR
-                                "cs4281: Never got valid data!\n"));
-               return -EIO;    // If no valid data, exit initialization.
-       }
-       // (12), Start digital data transfer of audio data to the codec.
-       writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV);        // (468h)
-
-
-       //**************************************
-       // Unmute the Master and Alternate
-       // (headphone) volumes.  Set to max.
-       //**************************************
-       cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0);
-       cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0);
-
-       //******************************************
-       // Power on the DAC(AddDACUser()from main())
-       //******************************************
-       cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-       cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
-
-       // Wait until we sample a DAC ready state.
-       for (temp2 = 0; temp2 < 32; temp2++) {
-               // Let's wait a mil to let things settle.
-               delayus(card,1000);
-               // Read the current state of the power control reg.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-               // If the DAC ready state bit is set, stop waiting.
-               if (temp1 & 0x2)
-                       break;
-       }
-
-       //******************************************
-       // Power on the ADC(AddADCUser()from main())
-       //******************************************
-       cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-       cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
-
-       // Wait until we sample ADC ready state.
-       for (temp2 = 0; temp2 < 32; temp2++) {
-               // Let's wait a mil to let things settle.
-               delayus(card,1000);
-               // Read the current state of the power control reg.
-               cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
-               // If the ADC ready state bit is set, stop waiting.
-               if (temp1 & 0x1)
-                       break;
-       }
-       // Set up 4281 Register contents that
-       // don't change for boot duration.
-
-       // For playback, we map AC97 slot 3 and 4(Left
-       // & Right PCM playback) to DMA Channel 0.
-       // Set the fifo to be 15 bytes at offset zero.
-
-       ac97_slotid = 0x01000f00;       // FCR0.RS[4:0]=1(=>slot4, right PCM playback).
-       // FCR0.LS[4:0]=0(=>slot3, left PCM playback).
-       // FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
-       writel(ac97_slotid, card->pBA0 + BA0_FCR0);     // (180h)
-       writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);  // Turn on FIFO Enable.
-
-       // For capture, we map AC97 slot 10 and 11(Left
-       // and Right PCM Record) to DMA Channel 1.
-       // Set the fifo to be 15 bytes at offset sixteen.
-       ac97_slotid = 0x0B0A0f10;       // FCR1.RS[4:0]=11(=>slot11, right PCM record).
-       // FCR1.LS[4:0]=10(=>slot10, left PCM record).
-       // FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
-       writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);  // (184h)
-       writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);  // Turn on FIFO Enable.
-
-       // Map the Playback SRC to the same AC97 slots(3 & 4--
-       // --Playback left & right)as DMA channel 0.
-       // Map the record SRC to the same AC97 slots(10 & 11--
-       // -- Record left & right) as DMA channel 1.
-
-       ac97_slotid = 0x0b0a0100;       // SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
-       // SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
-       // SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
-       // SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
-       writel(ac97_slotid, card->pBA0 + BA0_SRCSA);    // (75ch)
-
-       // Set 'Half Terminal Count Interrupt Enable' and 'Terminal
-       // Count Interrupt Enable' in DMA Control Registers 0 & 1.
-       // Set 'MSK' flag to 1 to keep the DMA engines paused.
-       temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);    // (00030001h)
-       writel(temp1, card->pBA0 + BA0_DCR0);   // (154h
-       writel(temp1, card->pBA0 + BA0_DCR1);   // (15ch)
-
-       // Set 'Auto-Initialize Control' to 'enabled'; For playback,
-       // set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
-       // for record, set Transfer Type Control to 'write transfer'.
-       // All other bits set to zero;  Some will be changed @ transfer start.
-       temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);  // (20000018h)
-       writel(temp1, card->pBA0 + BA0_DMR0);   // (150h)
-       temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); // (20000014h)
-       writel(temp1, card->pBA0 + BA0_DMR1);   // (158h)
-
-       // Enable DMA interrupts generally, and
-       // DMA0 & DMA1 interrupts specifically.
-       temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
-       writel(temp1, card->pBA0 + BA0_HIMR);
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n"));
-       return 0;
-}
-
-#ifndef NOT_CS4281_PM
-static void printpm(struct cs4281_state *s)
-{
-       CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-       CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n",
-               (unsigned)s->pm.flags,s->pm.u32CLKCR1_SAVE,s->pm.u32SSPMValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32PPLVCvalue: 0x%x u32PPRVCvalue: 0x%x\n",
-               s->pm.u32PPLVCvalue,s->pm.u32PPRVCvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32FMLVCvalue: 0x%x u32FMRVCvalue: 0x%x\n",
-               s->pm.u32FMLVCvalue,s->pm.u32FMRVCvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32GPIORvalue: 0x%x u32JSCTLvalue: 0x%x\n",
-               s->pm.u32GPIORvalue,s->pm.u32JSCTLvalue));
-       CS_DBGOUT(CS_PM, 9, printk("u32SSCR: 0x%x u32SRCSA: 0x%x\n",
-               s->pm.u32SSCR,s->pm.u32SRCSA));
-       CS_DBGOUT(CS_PM, 9, printk("u32DacASR: 0x%x u32AdcASR: 0x%x\n",
-               s->pm.u32DacASR,s->pm.u32AdcASR));
-       CS_DBGOUT(CS_PM, 9, printk("u32DacSR: 0x%x u32AdcSR: 0x%x\n",
-               s->pm.u32DacSR,s->pm.u32AdcSR));
-       CS_DBGOUT(CS_PM, 9, printk("u32MIDCR_Save: 0x%x\n",
-               s->pm.u32MIDCR_Save));
-
-}
-static void printpipe(struct cs4281_pipeline *pl)
-{
-
-       CS_DBGOUT(CS_PM, 9, printk("pm struct:\n"));
-       CS_DBGOUT(CS_PM, 9, printk("flags:0x%x number: 0%x\n",
-               (unsigned)pl->flags,pl->number));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBAnValue: 0%x u32DBCnValue: 0x%x\n",
-               pl->u32DBAnValue,pl->u32DBCnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32DMRnValue: 0x%x u32DCRnValue: 0x%x\n",
-               pl->u32DMRnValue,pl->u32DCRnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBAnAddress: 0x%x u32DBCnAddress: 0x%x\n",
-               pl->u32DBAnAddress,pl->u32DBCnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCAnAddress: 0x%x u32DCCnAddress: 0x%x\n",
-               pl->u32DCCnAddress,pl->u32DCCnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32DMRnAddress: 0x%x u32DCRnAddress: 0x%x\n",
-               pl->u32DMRnAddress,pl->u32DCRnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32HDSRnAddress: 0x%x u32DBAn_Save: 0x%x\n",
-               pl->u32HDSRnAddress,pl->u32DBAn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DBCn_Save: 0x%x u32DMRn_Save: 0x%x\n",
-               pl->u32DBCn_Save,pl->u32DMRn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCRn_Save: 0x%x u32DCCn_Save: 0x%x\n",
-               pl->u32DCRn_Save,pl->u32DCCn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32DCAn_Save: 0x%x\n",
-               pl->u32DCAn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRn_Save: 0x%x u32FSICn_Save: 0x%x\n",
-               pl->u32FCRn_Save,pl->u32FSICn_Save));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRnValue: 0x%x u32FSICnValue: 0x%x\n",
-               pl->u32FCRnValue,pl->u32FSICnValue));
-       CS_DBGOUT(CS_PM, 9, printk("u32FCRnAddress: 0x%x u32FSICnAddress: 0x%x\n",
-               pl->u32FCRnAddress,pl->u32FSICnAddress));
-       CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n",
-               pl->u32FPDRnValue,pl->u32FPDRnAddress));
-}
-static void printpipelines(struct cs4281_state *s)
-{
-       int i;
-       for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-       {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-                       printpipe(&s->pl[i]);
-               }
-       }
-}
-/****************************************************************************
-*
-*  Suspend - save the ac97 regs, mute the outputs and power down the part.  
-*
-****************************************************************************/
-static void cs4281_ac97_suspend(struct cs4281_state *s)
-{
-       int Count,i;
-
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()+\n"));
-/*
-* change the state, save the current hwptr, then stop the dac/adc
-*/
-       s->pm.flags &= ~CS4281_PM_IDLE;
-       s->pm.flags |= CS4281_PM_SUSPENDING;
-       s->pm.u32hwptr_playback = readl(s->pBA0 + BA0_DCA0);
-       s->pm.u32hwptr_capture = readl(s->pBA0 + BA0_DCA1);
-       stop_dac(s);
-       stop_adc(s);
-
-       for(Count = 0x2, i=0; (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-                       && (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-               Count += 2, i++)
-       {
-               cs4281_read_ac97(s, BA0_AC97_RESET + Count, &s->pm.ac97[i]);
-       }
-/*
-* Save the ac97 volume registers as well as the current powerdown state.
-* Now, mute the all the outputs (master, headphone, and mono), as well
-* as the PCM volume, in preparation for powering down the entire part.
-*/ 
-       cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME, &s->pm.u32AC97_master_volume);
-       cs4281_read_ac97(s, BA0_AC97_HEADPHONE_VOLUME, &s->pm.u32AC97_headphone_volume);
-       cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, &s->pm.u32AC97_master_volume_mono);
-       cs4281_read_ac97(s, BA0_AC97_PCM_OUT_VOLUME, &s->pm.u32AC97_pcm_out_volume);
-               
-       cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, 0x8000);
-       cs4281_write_ac97(s, BA0_AC97_PCM_OUT_VOLUME, 0x8000);
-
-       cs4281_read_ac97(s, BA0_AC97_POWERDOWN, &s->pm.u32AC97_powerdown);
-       cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &s->pm.u32AC97_general_purpose);
-
-/*
-* And power down everything on the AC97 codec.
-*/
-       cs4281_write_ac97(s, BA0_AC97_POWERDOWN, 0xff00);
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()-\n"));
-}
-
-/****************************************************************************
-*
-*  Resume - power up the part and restore its registers..  
-*
-****************************************************************************/
-static void cs4281_ac97_resume(struct cs4281_state *s)
-{
-       int Count,i;
-
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()+\n"));
-
-/* do not save the power state registers at this time
-    //
-    // If we saved away the power control registers, write them into the
-    // shadows so those saved values get restored instead of the current
-    // shadowed value.
-    //
-    if( bPowerStateSaved )
-    {
-        PokeShadow( 0x26, ulSaveReg0x26 );
-        bPowerStateSaved = FALSE;
-    }
-*/
-
-//
-// First, we restore the state of the general purpose register.  This
-// contains the mic select (mic1 or mic2) and if we restore this after
-// we restore the mic volume/boost state and mic2 was selected at
-// suspend time, we will end up with a brief period of time where mic1
-// is selected with the volume/boost settings for mic2, causing
-// acoustic feedback.  So we restore the general purpose register
-// first, thereby getting the correct mic selected before we restore
-// the mic volume/boost.
-//
-       cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, s->pm.u32AC97_general_purpose);
-
-//
-// Now, while the outputs are still muted, restore the state of power
-// on the AC97 part.
-//
-       cs4281_write_ac97(s, BA0_AC97_POWERDOWN, s->pm.u32AC97_powerdown);
-
-/*
-* Restore just the first set of registers, from register number
-* 0x02 to the register number that ulHighestRegToRestore specifies.
-*/
-       for(    Count = 0x2, i=0; 
-               (Count <= CS4281_AC97_HIGHESTREGTORESTORE)
-                       && (i < CS4281_AC97_NUMBER_RESTORE_REGS); 
-               Count += 2, i++)
-       {
-               cs4281_write_ac97(s, BA0_AC97_RESET + Count, s->pm.ac97[i]);
-       }
-       CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()-\n"));
-}
-
-/* do not save the power state registers at this time
-****************************************************************************
-*
-*  SavePowerState - Save the power registers away. 
-*
-****************************************************************************
-void 
-HWAC97codec::SavePowerState(void)
-{
-    ENTRY(TM_OBJECTCALLS, "HWAC97codec::SavePowerState()\r\n");
-
-    ulSaveReg0x26 = PeekShadow(0x26);
-
-    //
-    // Note that we have saved registers that need to be restored during a
-    // resume instead of ulAC97Regs[].
-    //
-    bPowerStateSaved = TRUE;
-
-} // SavePowerState
-*/
-
-static void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to save the contents of the BASIC FIFO Registers.
- */
-       pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress);
-       pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
- /*
- * We need to restore the contents of the BASIC FIFO Registers.
- */
-       writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress);
-       writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress);
-}
-static void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-       //
-       // We need to save the contents of the BASIC DMA Registers.
-       //
-       pl->u32DBAn_Save = readl(s->pBA0 + pl->u32DBAnAddress);
-       pl->u32DBCn_Save = readl(s->pBA0 + pl->u32DBCnAddress);
-       pl->u32DMRn_Save = readl(s->pBA0 + pl->u32DMRnAddress);
-       pl->u32DCRn_Save = readl(s->pBA0 + pl->u32DCRnAddress);
-       pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress);
-       pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress);
-}
-static void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl)
-{
-       //
-       // We need to save the contents of the BASIC DMA Registers.
-       //
-       writel( pl->u32DBAn_Save, s->pBA0 + pl->u32DBAnAddress);
-       writel( pl->u32DBCn_Save, s->pBA0 + pl->u32DBCnAddress);
-       writel( pl->u32DMRn_Save, s->pBA0 + pl->u32DMRnAddress);
-       writel( pl->u32DCRn_Save, s->pBA0 + pl->u32DCRnAddress);
-       writel( pl->u32DCCn_Save, s->pBA0 + pl->u32DCCnAddress);
-       writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress);
-}
-
-static int cs4281_suspend(struct cs4281_state *s)
-{
-       int i;
-       u32 u32CLKCR1;
-       struct cs4281_pm *pm = &s->pm;
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-               printk("cs4281: cs4281_suspend()+ flags=%d\n",
-                       (unsigned)s->pm.flags));
-/*
-* check the current state, only suspend if IDLE
-*/
-       if(!(s->pm.flags & CS4281_PM_IDLE))
-       {
-               CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-                       printk("cs4281: cs4281_suspend() unable to suspend, not IDLE\n"));
-               return 1;
-       }
-       s->pm.flags &= ~CS4281_PM_IDLE;
-       s->pm.flags |= CS4281_PM_SUSPENDING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-
-       pm->u32CLKCR1_SAVE = u32CLKCR1;
-       if(!(u32CLKCR1 & 0x00010000 ) )
-               writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-//
-// First, turn on the clocks (yikes) to the devices, so that they will
-// respond when we try to save their state.
-//
-       if(!(u32CLKCR1 & CLKCR1_SWCE))
-       {
-               writel(u32CLKCR1 | CLKCR1_SWCE , s->pBA0 + BA0_CLKCR1);
-       }
-    
-       //
-       // Save the power state
-       //
-       pm->u32SSPMValue = readl(s->pBA0 + BA0_SSPM);
-
-       //
-       // Disable interrupts.
-       //
-       writel(HICR_CHGM, s->pBA0 + BA0_HICR);
-
-       //
-       // Save the PCM Playback Left and Right Volume Control.
-       //
-       pm->u32PPLVCvalue = readl(s->pBA0 + BA0_PPLVC);
-       pm->u32PPRVCvalue = readl(s->pBA0 + BA0_PPRVC);
-
-       //
-       // Save the FM Synthesis Left and Right Volume Control.
-       //
-       pm->u32FMLVCvalue = readl(s->pBA0 + BA0_FMLVC);
-       pm->u32FMRVCvalue = readl(s->pBA0 + BA0_FMRVC);
-
-       //
-       // Save the GPIOR value.
-       //
-       pm->u32GPIORvalue = readl(s->pBA0 + BA0_GPIOR);
-
-       //
-       // Save the JSCTL value.
-       //
-       pm->u32JSCTLvalue = readl(s->pBA0 + BA0_GPIOR);
-
-       //
-       // Save Sound System Control Register
-       //
-       pm->u32SSCR = readl(s->pBA0 + BA0_SSCR);
-
-       //
-       // Save SRC Slot Assinment register
-       //
-       pm->u32SRCSA = readl(s->pBA0 + BA0_SRCSA);
-
-       //
-       // Save sample rate
-       //
-       pm->u32DacASR = readl(s->pBA0 + BA0_PASR);
-       pm->u32AdcASR = readl(s->pBA0 + BA0_CASR);
-       pm->u32DacSR = readl(s->pBA0 + BA0_DACSR);
-       pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR);
-
-       //
-       // Loop through all of the PipeLines 
-       //
-       for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-               //
-               // Ask the DMAengines and FIFOs to Suspend.
-               //
-                       cs4281_SuspendDMAengine(s,&s->pl[i]);
-                       cs4281_SuspendFIFO(s,&s->pl[i]);
-               }
-       }
-       //
-       // We need to save the contents of the Midi Control Register.
-       //
-       pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR);
-/*
-* save off the AC97 part information
-*/
-       cs4281_ac97_suspend(s);
-    
-       //
-       // Turn off the serial ports.
-       //
-       writel(0, s->pBA0 + BA0_SERMC);
-
-       //
-       // Power off FM, Joystick, AC link, 
-       //
-       writel(0, s->pBA0 + BA0_SSPM);
-
-       //
-       // DLL off.
-       //
-       writel(0, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // AC link off.
-       //
-       writel(0, s->pBA0 + BA0_SPMC);
-
-       //
-       // Put the chip into D3(hot) state.
-       //
-       // PokeBA0(BA0_PMCS, 0x00000003);
-
-       //
-       // Gershwin CLKRUN - Clear CKRA
-       //
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-       writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1);
-
-#ifdef CSDEBUG
-       printpm(s);
-       printpipelines(s);
-#endif
-
-       s->pm.flags &= ~CS4281_PM_SUSPENDING;
-       s->pm.flags |= CS4281_PM_SUSPENDED;
-
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, 
-               printk("cs4281: cs4281_suspend()- flags=%d\n",
-                       (unsigned)s->pm.flags));
-       return 0;
-}
-
-static int cs4281_resume(struct cs4281_state *s)
-{
-       int i;
-       unsigned temp1;
-       u32 u32CLKCR1;
-       struct cs4281_pm *pm = &s->pm;
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 4, 
-               printk( "cs4281: cs4281_resume()+ flags=%d\n",
-                       (unsigned)s->pm.flags));
-       if(!(s->pm.flags & CS4281_PM_SUSPENDED))
-       {
-               CS_DBGOUT(CS_PM | CS_ERROR, 2, 
-                       printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n"));
-               return 1;
-       }
-       s->pm.flags &= ~CS4281_PM_SUSPENDED;
-       s->pm.flags |= CS4281_PM_RESUMING;
-
-//
-// Gershwin CLKRUN - Set CKRA
-//
-       u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1);
-       writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // set the power state.
-       //
-       //old PokeBA0(BA0_PMCS, 0);
-
-       //
-       // Program the clock circuit and serial ports.
-       //
-       temp1 = cs4281_hw_init(s);
-       if (temp1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1,
-                   printk(KERN_ERR
-                       "cs4281: resume cs4281_hw_init() error.\n"));
-               return -1;
-       }
-
-       //
-       // restore the Power state
-       //
-       writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM);
-
-       //
-       // Set post SRC mix setting (FM or ALT48K)
-       //
-       writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM);
-
-       //
-       // Loop through all of the PipeLines 
-       //
-       for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++)
-        {
-               if(s->pl[i].flags & CS4281_PIPELINE_VALID)
-               {
-               //
-               // Ask the DMAengines and FIFOs to Resume.
-               //
-                       cs4281_ResumeDMAengine(s,&s->pl[i]);
-                       cs4281_ResumeFIFO(s,&s->pl[i]);
-               }
-       }
-       //
-       // We need to restore the contents of the Midi Control Register.
-       //
-       writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR);
-
-       cs4281_ac97_resume(s);
-       //
-       // Restore the PCM Playback Left and Right Volume Control.
-       //
-       writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC);
-       writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC);
-
-       //
-       // Restore the FM Synthesis Left and Right Volume Control.
-       //
-       writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC);
-       writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC);
-
-       //
-       // Restore the JSCTL value.
-       //
-       writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL);
-
-       //
-       // Restore the GPIOR register value.
-       //
-       writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR);
-
-       //
-       // Restore Sound System Control Register
-       //
-       writel(pm->u32SSCR, s->pBA0 + BA0_SSCR);
-
-       //
-       // Restore SRC Slot Assignment register
-       //
-       writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA);
-
-       //
-       // Restore sample rate
-       //
-       writel(pm->u32DacASR, s->pBA0 + BA0_PASR);
-       writel(pm->u32AdcASR, s->pBA0 + BA0_CASR);
-       writel(pm->u32DacSR, s->pBA0 + BA0_DACSR);
-       writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR);
-
-       // 
-       // Restore CFL1/2 registers we saved to compensate for OEM bugs.
-       //
-       //      PokeBA0(BA0_CFLR, ulConfig);
-
-       //
-       // Gershwin CLKRUN - Clear CKRA
-       //
-       writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1);
-
-       //
-       // Enable interrupts on the part.
-       //
-       writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-
-#ifdef CSDEBUG
-       printpm(s);
-       printpipelines(s);
-#endif
-/*
-* change the state, restore the current hwptrs, then stop the dac/adc
-*/
-       s->pm.flags |= CS4281_PM_IDLE;
-       s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED 
-                       | CS4281_PM_RESUMING | CS4281_PM_RESUMED);
-
-       writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0);
-       writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1);
-       start_dac(s);
-       start_adc(s);
-
-       CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n",
-               (unsigned)s->pm.flags));
-       return 0;
-}
-
-#endif
-
-//******************************************************************************
-// "cs4281_play_rate()" --
-//******************************************************************************
-static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
-{
-       u32 DACSRvalue = 1;
-
-       // Based on the sample rate, program the DACSR register.
-       if (playrate == 8000)
-               DACSRvalue = 5;
-       if (playrate == 11025)
-               DACSRvalue = 4;
-       else if (playrate == 22050)
-               DACSRvalue = 2;
-       else if (playrate == 44100)
-               DACSRvalue = 1;
-       else if ((playrate <= 48000) && (playrate >= 6023))
-               DACSRvalue = 24576000 / (playrate * 16);
-       else if (playrate < 6023)
-               // Not allowed by open.
-               return;
-       else if (playrate > 48000)
-               // Not allowed by open.
-               return;
-       CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
-               "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
-                       DACSRvalue, playrate));
-       //  Write the 'sample rate select code'
-       //  to the 'DAC Sample Rate' register.
-       writel(DACSRvalue, card->pBA0 + BA0_DACSR);     // (744h)
-}
-
-//******************************************************************************
-// "cs4281_record_rate()" -- Initialize the record sample rate converter.
-//******************************************************************************
-static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
-{
-       u32 ADCSRvalue = 1;
-
-       //
-       // Based on the sample rate, program the ADCSR register
-       //
-       if (outrate == 8000)
-               ADCSRvalue = 5;
-       if (outrate == 11025)
-               ADCSRvalue = 4;
-       else if (outrate == 22050)
-               ADCSRvalue = 2;
-       else if (outrate == 44100)
-               ADCSRvalue = 1;
-       else if ((outrate <= 48000) && (outrate >= 6023))
-               ADCSRvalue = 24576000 / (outrate * 16);
-       else if (outrate < 6023) {
-               // Not allowed by open.
-               return;
-       } else if (outrate > 48000) {
-               // Not allowed by open.
-               return;
-       }
-       CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
-               "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
-                       ADCSRvalue, outrate));
-       //  Write the 'sample rate select code
-       //  to the 'ADC Sample Rate' register.
-       writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);     // (748h)
-}
-
-
-
-static void stop_dac(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n"));
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_WRITE;
-       temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK;
-       writel(temp1, s->pBA0 + BA0_DCR0);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-
-static void start_dac(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n"));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
-                                       (s->dma_dac.count > 0
-                                       && s->dma_dac.ready))
-#ifndef NOT_CS4281_PM
-       && (s->pm.flags & CS4281_PM_IDLE))
-#else
-)
-#endif
- {
-               s->ena |= FMODE_WRITE;
-               temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK;  // Clear DMA0 channel mask.
-               writel(temp1, s->pBA0 + BA0_DCR0);      // Start DMA'ing.
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts.              
-
-               writel(7, s->pBA0 + BA0_PPRVC);
-               writel(7, s->pBA0 + BA0_PPLVC);
-               CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: start_dac(): writel 0x%x start dma\n", temp1));
-
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: start_dac()-\n"));
-}
-
-
-static void stop_adc(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: stop_adc()+\n"));
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_READ;
-
-       if (s->conversion == 1) {
-               s->conversion = 0;
-               s->prop_adc.fmt = s->prop_adc.fmt_original;
-       }
-       temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK;
-       writel(temp1, s->pBA0 + BA0_DCR1);
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 3,
-                 printk(KERN_INFO "cs4281: stop_adc()-\n"));
-}
-
-
-static void start_adc(struct cs4281_state *s)
-{
-       unsigned long flags;
-       unsigned temp1;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: start_adc()+\n"));
-
-       if (!(s->ena & FMODE_READ) &&
-           (s->dma_adc.mapped || s->dma_adc.count <=
-            (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize))
-           && s->dma_adc.ready
-#ifndef NOT_CS4281_PM
-       && (s->pm.flags & CS4281_PM_IDLE))
-#else
-) 
-#endif
-       {
-               if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) {
-                       // 
-                       // now only use 16 bit capture, due to truncation issue
-                       // in the chip, noticable distortion occurs.
-                       // allocate buffer and then convert from 16 bit to 
-                       // 8 bit for the user buffer.
-                       //
-                       s->prop_adc.fmt_original = s->prop_adc.fmt;
-                       if (s->prop_adc.fmt & AFMT_S8) {
-                               s->prop_adc.fmt &= ~AFMT_S8;
-                               s->prop_adc.fmt |= AFMT_S16_LE;
-                       }
-                       if (s->prop_adc.fmt & AFMT_U8) {
-                               s->prop_adc.fmt &= ~AFMT_U8;
-                               s->prop_adc.fmt |= AFMT_U16_LE;
-                       }
-                       //
-                       // prog_dmabuf_adc performs a stop_adc() but that is
-                       // ok since we really haven't started the DMA yet.
-                       //
-                       prog_codec(s, CS_TYPE_ADC);
-
-                       if (prog_dmabuf_adc(s) != 0) {
-                               CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-                                        "cs4281: start_adc(): error in prog_dmabuf_adc\n"));
-                       }
-                       s->conversion = 1;
-               }
-               spin_lock_irqsave(&s->lock, flags);
-               s->ena |= FMODE_READ;
-               temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK;  // Clear DMA1 channel mask bit.
-               writel(temp1, s->pBA0 + BA0_DCR1);      // Start recording
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts.
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO
-                        "cs4281: start_adc(): writel 0x%x \n", temp1));
-       }
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: start_adc()-\n"));
-
-}
-
-
-// --------------------------------------------------------------------- 
-
-#define DMABUF_MINORDER 1      // ==> min buffer size = 8K.
-
-
-static void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-       struct page *map, *mapend;
-
-       if (db->rawbuf) {
-               // Undo prog_dmabuf()'s marking the pages as reserved 
-               mapend =
-                   virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) -
-                                1);
-               for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-                       ClearPageReserved(map);
-               free_dmabuf(s, db);
-       }
-       if (s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-               // Undo prog_dmabuf()'s marking the pages as reserved 
-               mapend =
-                   virt_to_page(s->tmpbuff +
-                                (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-               for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-                       ClearPageReserved(map);
-               free_dmabuf2(s, db);
-       }
-       s->tmpbuff = NULL;
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
-{
-       int order;
-       unsigned bytespersec, temp1;
-       unsigned bufs, sample_shift = 0;
-       struct page *map, *mapend;
-       unsigned long df;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_dmabuf()+\n"));
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error =
-           db->endcleared = db->blocks = db->wakeup = db->underrun = 0;
-/*
-* check for order within limits, but do not overwrite value, check
-* later for a fractional defaultorder (i.e. 100+).
-*/
-       if((defaultorder > 0) && (defaultorder < 12))
-               df = defaultorder;
-       else
-               df = 1; 
-
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = df; order >= DMABUF_MINORDER; order--)
-                       if ( (db->rawbuf = (void *) pci_alloc_consistent(
-                               s->pcidev, PAGE_SIZE << order, &db-> dmaaddr)))
-                                   break;
-               if (!db->rawbuf) {
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                               "cs4281: prog_dmabuf(): unable to allocate rawbuf\n"));
-                       return -ENOMEM;
-               }
-               db->buforder = order;
-               // Now mark the pages as reserved; otherwise the 
-               // remap_pfn_range() in cs4281_mmap doesn't work.
-               // 1. get index to last page in mem_map array for rawbuf.
-               mapend = virt_to_page(db->rawbuf + 
-                       (PAGE_SIZE << db->buforder) - 1);
-
-               // 2. mark each physical page in range as 'reserved'.
-               for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
-                       SetPageReserved(map);
-       }
-       if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) {
-               for (order = df; order >= DMABUF_MINORDER;
-                    order--)
-                       if ( (s->tmpbuff = (void *) pci_alloc_consistent(
-                                       s->pcidev, PAGE_SIZE << order, 
-                                       &s->dmaaddr_tmpbuff)))
-                                   break;
-               if (!s->tmpbuff) {
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                               "cs4281: prog_dmabuf(): unable to allocate tmpbuff\n"));
-                       return -ENOMEM;
-               }
-               s->buforder_tmpbuff = order;
-               // Now mark the pages as reserved; otherwise the 
-               // remap_pfn_range() in cs4281_mmap doesn't work.
-               // 1. get index to last page in mem_map array for rawbuf.
-               mapend = virt_to_page(s->tmpbuff + 
-                               (PAGE_SIZE << s->buforder_tmpbuff) - 1);
-
-               // 2. mark each physical page in range as 'reserved'.
-               for (map = virt_to_page(s->tmpbuff); map <= mapend; map++)
-                       SetPageReserved(map);
-       }
-       if (db->type == CS_TYPE_DAC) {
-               if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       sample_shift++;
-               if (s->prop_dac.channels > 1)
-                       sample_shift++;
-               bytespersec = s->prop_dac.rate << sample_shift;
-       } else                  // CS_TYPE_ADC
-       {
-               if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       sample_shift++;
-               if (s->prop_adc.channels > 1)
-                       sample_shift++;
-               bytespersec = s->prop_adc.rate << sample_shift;
-       }
-       bufs = PAGE_SIZE << db->buforder;
-
-/*
-* added fractional "defaultorder" inputs. if >100 then use 
-* defaultorder-100 as power of 2 for the buffer size. example:
-* 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size.
-*/
-       if(defaultorder >= 100)
-       {
-               bufs = 1 << (defaultorder-100);
-       }
-
-#define INTERRUPT_RATE_MS       100    // Interrupt rate in milliseconds.
-       db->numfrag = 2;
-/* 
-* Nominal frag size(bytes/interrupt)
-*/
-       temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS);
-       db->fragshift = 8;      // Min 256 bytes.
-       while (1 << db->fragshift < temp1)      // Calc power of 2 frag size.
-               db->fragshift += 1;
-       db->fragsize = 1 << db->fragshift;
-       db->dmasize = db->fragsize * 2;
-       db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment.
-
-// If the calculated size is larger than the allocated
-//  buffer, divide the allocated buffer into 2 fragments.
-       if (db->dmasize > bufs) {
-
-               db->numfrag = 2;        // Two fragments.
-               db->fragsize = bufs >> 1;       // Each 1/2 the alloc'ed buffer.
-               db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment.
-               db->dmasize = bufs;     // Use all the alloc'ed buffer.
-
-               db->fragshift = 0;      // Calculate 'fragshift'.
-               temp1 = db->fragsize;   // update_ptr() uses it 
-               while ((temp1 >>= 1) > 1)       // to calc 'total-bytes'
-                       db->fragshift += 1;     // returned in DSP_GETI/OPTR. 
-       }
-       CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n",
-                       db->numfrag, db->fragsize, db->fragsamples, 
-                       db->fragshift, bufs, 
-                       (db->type == CS_TYPE_DAC) ? s->prop_dac.fmt : 
-                               s->prop_adc.fmt, 
-                       (db->type == CS_TYPE_DAC) ? s->prop_dac.channels : 
-                               s->prop_adc.channels));
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_dmabuf()-\n"));
-       return 0;
-}
-
-
-static int prog_dmabuf_adc(struct cs4281_state *s)
-{
-       unsigned long va;
-       unsigned count;
-       int c;
-       stop_adc(s);
-       s->dma_adc.type = CS_TYPE_ADC;
-       if ((c = prog_dmabuf(s, &s->dma_adc)))
-               return c;
-
-       if (s->dma_adc.rawbuf) {
-               memset(s->dma_adc.rawbuf,
-                      (s->prop_adc.
-                       fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-                      s->dma_adc.dmasize);
-       }
-       if (s->tmpbuff) {
-               memset(s->tmpbuff,
-                      (s->prop_adc.
-                       fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-                      PAGE_SIZE << s->buforder_tmpbuff);
-       }
-
-       va = virt_to_bus(s->dma_adc.rawbuf);
-
-       count = s->dma_adc.dmasize;
-
-       if (s->prop_adc.
-           fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-                   count /= 2; // 16-bit.
-
-       if (s->prop_adc.channels > 1)
-               count /= 2;     // Assume stereo.
-
-       CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n",
-                       count, (unsigned) va));
-
-       writel(va, s->pBA0 + BA0_DBA1); // Set buffer start address.
-       writel(count - 1, s->pBA0 + BA0_DBC1);  // Set count. 
-       s->dma_adc.ready = 1;
-       return 0;
-}
-
-
-static int prog_dmabuf_dac(struct cs4281_state *s)
-{
-       unsigned long va;
-       unsigned count;
-       int c;
-       stop_dac(s);
-       s->dma_dac.type = CS_TYPE_DAC;
-       if ((c = prog_dmabuf(s, &s->dma_dac)))
-               return c;
-       memset(s->dma_dac.rawbuf,
-              (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
-              s->dma_dac.dmasize);
-
-       va = virt_to_bus(s->dma_dac.rawbuf);
-
-       count = s->dma_dac.dmasize;
-       if (s->prop_dac.
-           fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
-                   count /= 2; // 16-bit.
-
-       if (s->prop_dac.channels > 1)
-               count /= 2;     // Assume stereo.
-
-       writel(va, s->pBA0 + BA0_DBA0); // Set buffer start address.
-       writel(count - 1, s->pBA0 + BA0_DBC0);  // Set count.             
-
-       CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
-               "cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n",
-                       count, (unsigned) va));
-
-       s->dma_dac.ready = 1;
-       return 0;
-}
-
-
-static void clear_advance(void *buf, unsigned bsize, unsigned bptr,
-                         unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *) buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
-               "cs4281: clear_advance(): memset %d at %p for %d size \n",
-                       (unsigned)c, ((char *) buf) + bptr, len));
-       memset(((char *) buf) + bptr, c, len);
-}
-
-
-
-// call with spinlock held! 
-static void cs4281_update_ptr(struct cs4281_state *s, int intflag)
-{
-       int diff;
-       unsigned hwptr, va;
-
-       // update ADC pointer 
-       if (s->ena & FMODE_READ) {
-               hwptr = readl(s->pBA0 + BA0_DCA1);      // Read capture DMA address.
-               va = virt_to_bus(s->dma_adc.rawbuf);
-               hwptr -= (unsigned) va;
-               diff =
-                   (s->dma_adc.dmasize + hwptr -
-                    s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count > s->dma_adc.dmasize)
-                       s->dma_adc.count = s->dma_adc.dmasize;
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >=
-                           (signed) s->dma_adc.fragsize) wake_up(&s->
-                                                                 dma_adc.
-                                                                 wait);
-               } else {
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
-               }
-               CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-                               s, s->dma_adc.hwptr, s->dma_adc.total_bytes, s->dma_adc.count));
-       }
-       // update DAC pointer 
-       //
-       // check for end of buffer, means that we are going to wait for another interrupt
-       // to allow silence to fill the fifos on the part, to keep pops down to a minimum.
-       //
-       if (s->ena & FMODE_WRITE) {
-               hwptr = readl(s->pBA0 + BA0_DCA0);      // Read play DMA address.
-               va = virt_to_bus(s->dma_dac.rawbuf);
-               hwptr -= (unsigned) va;
-               diff = (s->dma_dac.dmasize + hwptr -
-                    s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= s->dma_dac.fragsize) {
-                               s->dma_dac.wakeup = 1;
-                               wake_up(&s->dma_dac.wait);
-                               if (s->dma_dac.count > s->dma_dac.dmasize)
-                                       s->dma_dac.count &=
-                                           s->dma_dac.dmasize - 1;
-                       }
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               //
-                               // fill with silence, and do not shut down the DAC.
-                               // Continue to play silence until the _release.
-                               //
-                               CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
-                                       "cs4281: cs4281_update_ptr(): memset %d at %p for %d size \n",
-                                               (unsigned)(s->prop_dac.fmt & 
-                                               (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
-                                               s->dma_dac.rawbuf, s->dma_dac.dmasize));
-                               memset(s->dma_dac.rawbuf,
-                                      (s->prop_dac.
-                                       fmt & (AFMT_U8 | AFMT_U16_LE)) ?
-                                      0x80 : 0, s->dma_dac.dmasize);
-                               if (s->dma_dac.count < 0) {
-                                       s->dma_dac.underrun = 1;
-                                       s->dma_dac.count = 0;
-                                       CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO
-                                        "cs4281: cs4281_update_ptr(): underrun\n"));
-                               }
-                       } else if (s->dma_dac.count <=
-                                  (signed) s->dma_dac.fragsize
-                                  && !s->dma_dac.endcleared) {
-                               clear_advance(s->dma_dac.rawbuf,
-                                             s->dma_dac.dmasize,
-                                             s->dma_dac.swptr,
-                                             s->dma_dac.fragsize,
-                                             (s->prop_dac.
-                                              fmt & (AFMT_U8 |
-                                                     AFMT_U16_LE)) ? 0x80
-                                             : 0);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if ( (s->dma_dac.count <= (signed) s->dma_dac.dmasize/2) ||
-                               intflag)
-                       {
-                               wake_up(&s->dma_dac.wait);
-                       }
-               }
-               CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
-                       "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n",
-                               s, s->dma_dac.hwptr, s->dma_dac.total_bytes, s->dma_dac.count));
-       }
-}
-
-
-// --------------------------------------------------------------------- 
-
-static void prog_codec(struct cs4281_state *s, unsigned type)
-{
-       unsigned long flags;
-       unsigned temp1, format;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_codec()+ \n"));
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (type == CS_TYPE_ADC) {
-               temp1 = readl(s->pBA0 + BA0_DCR1);
-               writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1);   // Stop capture DMA, if active.
-
-               // program sampling rates  
-               // Note, for CS4281, capture & play rates can be set independently.
-               cs4281_record_rate(s, s->prop_adc.rate);
-
-               // program ADC parameters 
-               format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
-               if (s->prop_adc.
-                   fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {    // 16-bit
-                       if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE))      // Big-endian?
-                               format |= DMRn_BEND;
-                       if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-                               format |= DMRn_USIGN;   // Unsigned.      
-               } else
-                       format |= DMRn_SIZE8 | DMRn_USIGN;      // 8-bit, unsigned
-               if (s->prop_adc.channels < 2)
-                       format |= DMRn_MONO;
-
-               writel(format, s->pBA0 + BA0_DMR1);
-
-               CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-                       "cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n",
-                               (format & DMRn_SIZE8) ? "8" : "16",
-                               (format & DMRn_USIGN) ?  "Unsigned" : "Signed", 
-                               (format & DMRn_MONO) ? "Mono" : "Stereo", 
-                               s->prop_adc.rate, format));
-
-               s->ena &= ~FMODE_READ;  // not capturing data yet
-       }
-
-
-       if (type == CS_TYPE_DAC) {
-               temp1 = readl(s->pBA0 + BA0_DCR0);
-               writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0);   // Stop play DMA, if active.
-
-               // program sampling rates  
-               // Note, for CS4281, capture & play rates can be set independently.
-               cs4281_play_rate(s, s->prop_dac.rate);
-
-               // program DAC parameters 
-               format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
-               if (s->prop_dac.
-                   fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) {    // 16-bit
-                       if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE))
-                               format |= DMRn_BEND;    // Big Endian.
-                       if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE))
-                               format |= DMRn_USIGN;   // Unsigned.      
-               } else
-                       format |= DMRn_SIZE8 | DMRn_USIGN;      // 8-bit, unsigned
-
-               if (s->prop_dac.channels < 2)
-                       format |= DMRn_MONO;
-
-               writel(format, s->pBA0 + BA0_DMR0);
-
-
-               CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
-                       "cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n",
-                               (format & DMRn_SIZE8) ? "8" : "16",
-                               (format & DMRn_USIGN) ?  "Unsigned" : "Signed",
-                               (format & DMRn_MONO) ? "Mono" : "Stereo", 
-                               s->prop_dac.rate, format));
-
-               s->ena &= ~FMODE_WRITE; // not capturing data yet
-
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: prog_codec()- \n"));
-}
-
-
-static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd,
-                      unsigned long arg)
-{
-       // Index to mixer_src[] is value of AC97 Input Mux Select Reg.
-       // Value of array member is recording source Device ID Mask.
-       static const unsigned int mixer_src[8] = {
-               SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
-               SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
-       };
-       void __user *argp = (void __user *)arg;
-
-       // Index of mixtable1[] member is Device ID 
-       // and must be <= SOUND_MIXER_NRDEVICES.
-       // Value of array member is index into s->mix.vol[]
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM] = 1,  // voice 
-               [SOUND_MIXER_LINE1] = 2,        // AUX
-               [SOUND_MIXER_CD] = 3,   // CD 
-               [SOUND_MIXER_LINE] = 4, // Line 
-               [SOUND_MIXER_SYNTH] = 5,        // FM
-               [SOUND_MIXER_MIC] = 6,  // Mic 
-               [SOUND_MIXER_SPEAKER] = 7,      // Speaker 
-               [SOUND_MIXER_RECLEV] = 8,       // Recording level 
-               [SOUND_MIXER_VOLUME] = 9        // Master Volume 
-       };
-
-
-       static const unsigned mixreg[] = {
-               BA0_AC97_PCM_OUT_VOLUME,
-               BA0_AC97_AUX_VOLUME,
-               BA0_AC97_CD_VOLUME,
-               BA0_AC97_LINE_IN_VOLUME
-       };
-       unsigned char l, r, rl, rr, vidx;
-       unsigned char attentbl[11] =
-           { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 };
-       unsigned temp1;
-       int i, val;
-
-       VALIDATE_STATE(s);
-       CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-                "cs4281: mixer_ioctl(): s=%p cmd=0x%.8x\n", s, cmd));
-#if CSDEBUG
-       cs_printioctl(cmd);
-#endif
-#if CSDEBUG_INTERFACE
-
-       if ((cmd == SOUND_MIXER_CS_GETDBGMASK) ||
-           (cmd == SOUND_MIXER_CS_SETDBGMASK) ||
-           (cmd == SOUND_MIXER_CS_GETDBGLEVEL) ||
-           (cmd == SOUND_MIXER_CS_SETDBGLEVEL) ||
-           (cmd == SOUND_MIXER_CS_APM))
-       {
-               switch (cmd) {
-
-               case SOUND_MIXER_CS_GETDBGMASK:
-                       return put_user(cs_debugmask,
-                                       (unsigned long __user *) argp);
-
-               case SOUND_MIXER_CS_GETDBGLEVEL:
-                       return put_user(cs_debuglevel,
-                                       (unsigned long __user *) argp);
-
-               case SOUND_MIXER_CS_SETDBGMASK:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       cs_debugmask = val;
-                       return 0;
-
-               case SOUND_MIXER_CS_SETDBGLEVEL:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       cs_debuglevel = val;
-                       return 0;
-#ifndef NOT_CS4281_PM
-               case SOUND_MIXER_CS_APM:
-                       if (get_user(val, (unsigned long __user *) argp))
-                               return -EFAULT;
-                       if(val == CS_IOCTL_CMD_SUSPEND)
-                               cs4281_suspend(s);
-                       else if(val == CS_IOCTL_CMD_RESUME)
-                               cs4281_resume(s);
-                       else
-                       {
-                               CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                                   "cs4281: mixer_ioctl(): invalid APM cmd (%d)\n",
-                                       val));
-                       }
-                       return 0;
-#endif
-               default:
-                       CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
-                               "cs4281: mixer_ioctl(): ERROR unknown debug cmd\n"));
-                       return 0;
-               }
-       }
-#endif
-
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               // enable/disable/query mixer preamp 
-               if (get_user(val, (int __user *) argp))
-                       return -EFAULT;
-               if (val != -1) {
-                       cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-                       temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
-                       cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-               }
-               cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-               val = (temp1 & 0x40) ? 1 : 0;
-               return put_user(val, (int __user *) argp);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               // enable/disable/query spatializer 
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               if (val != -1) {
-                       temp1 = (val & 0x3f) >> 2;
-                       cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
-                       cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-                                        &temp1);
-                       cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,
-                                         temp1 | 0x2000);
-               }
-               cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
-               return put_user((temp1 << 2) | 3, (int __user *)argp);
-       }
-       if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strlcpy(info.id, "CS4281", sizeof(info.id));
-               strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strlcpy(info.id, "CS4281", sizeof(info.id));
-               strlcpy(info.name, "Crystal CS4281", sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int __user *) argp);
-
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-               return -EINVAL;
-
-       // If ioctl has only the SIOC_READ bit(bit 31)
-       // on, process the only-read commands. 
-       if (_SIOC_DIR(cmd) == _SIOC_READ) {
-               switch (_IOC_NR(cmd)) {
-               case SOUND_MIXER_RECSRC:        // Arg contains a bit for each recording source 
-                       cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
-                       return put_user(mixer_src[temp1&7], (int __user *)argp);
-
-               case SOUND_MIXER_DEVMASK:       // Arg contains a bit for each supported device 
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-                                       SOUND_MASK_CD | SOUND_MASK_LINE |
-                                       SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME |
-                                       SOUND_MASK_RECLEV |
-                                       SOUND_MASK_SPEAKER, (int __user *)argp);
-
-               case SOUND_MIXER_RECMASK:       // Arg contains a bit for each supported recording source 
-                       return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC |
-                                       SOUND_MASK_CD | SOUND_MASK_VOLUME |
-                                       SOUND_MASK_LINE1, (int __user *) argp);
-
-               case SOUND_MIXER_STEREODEVS:    // Mixer channels supporting stereo 
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH |
-                                       SOUND_MASK_CD | SOUND_MASK_LINE |
-                                       SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME |
-                                       SOUND_MASK_RECLEV, (int __user *)argp);
-
-               case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, (int __user *)argp);
-
-               default:
-                       i = _IOC_NR(cmd);
-                       if (i >= SOUND_MIXER_NRDEVICES
-                           || !(vidx = mixtable1[i]))
-                               return -EINVAL;
-                       return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-               }
-       }
-       // If ioctl doesn't have both the SIOC_READ and 
-       // the SIOC_WRITE bit set, return invalid.
-       if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE))
-               return -EINVAL;
-
-       // Increment the count of volume writes.
-       s->mix.modcnt++;
-
-       // Isolate the command; it must be a write.
-       switch (_IOC_NR(cmd)) {
-
-       case SOUND_MIXER_RECSRC:        // Arg contains a bit for each recording source 
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               i = hweight32(val);     // i = # bits on in val.
-               if (i != 1)     // One & only 1 bit must be on.
-                       return 0;
-               for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) {
-                       if (val == mixer_src[i]) {
-                               temp1 = (i << 8) | i;
-                               cs4281_write_ac97(s,
-                                                 BA0_AC97_RECORD_SELECT,
-                                                 temp1);
-                               return 0;
-                       }
-               }
-               return 0;
-
-       case SOUND_MIXER_VOLUME:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;        // Max soundcard.h vol is 100.
-               if (l < 6) {
-                       rl = 63;
-                       l = 0;
-               } else
-                       rl = attentbl[(10 * l) / 100];  // Convert 0-100 vol to 63-0 atten.
-
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;        // Max right volume is 100, too
-               if (r < 6) {
-                       rr = 63;
-                       r = 0;
-               } else
-                       rr = attentbl[(10 * r) / 100];  // Convert volume to attenuation.
-
-               if ((rl > 60) && (rr > 60))     // If both l & r are 'low',          
-                       temp1 = 0x8000; //  turn on the mute bit.
-               else
-                       temp1 = 0;
-
-               temp1 |= (rl << 8) | rr;
-
-               cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
-               cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[8] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[8] = val;
-#endif
-               return put_user(s->mix.vol[8], (int __user *)argp);
-
-       case SOUND_MIXER_SPEAKER:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 3) {
-                       rl = 0;
-                       l = 0;
-               } else {
-                       rl = (l * 2 - 5) / 13;  // Convert 0-100 range to 0-15.
-                       l = (rl * 13 + 5) / 2;
-               }
-
-               if (rl < 3) {
-                       temp1 = 0x8000;
-                       rl = 0;
-               } else
-                       temp1 = 0;
-               rl = 15 - rl;   // Convert volume to attenuation.
-               temp1 |= rl << 1;
-               cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[6] = l << 8;
-#else
-               s->mix.vol[6] = val;
-#endif
-               return put_user(s->mix.vol[6], (int __user *)argp);
-
-       case SOUND_MIXER_RECLEV:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               rl = (l * 2 - 5) / 13;  // Convert 0-100 scale to 0-15.
-               rr = (r * 2 - 5) / 13;
-               if (rl < 3 && rr < 3)
-                       temp1 = 0x8000;
-               else
-                       temp1 = 0;
-
-               temp1 = temp1 | (rl << 8) | rr;
-               cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[7] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[7] = val;
-#endif
-               return put_user(s->mix.vol[7], (int __user *)argp);
-
-       case SOUND_MIXER_MIC:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 1) {
-                       l = 0;
-                       rl = 0;
-               } else {
-                       rl = ((unsigned) l * 5 - 4) / 16;       // Convert 0-100 range to 0-31.
-                       l = (rl * 16 + 4) / 5;
-               }
-               cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
-               temp1 &= 0x40;  // Isolate 20db gain bit.
-               if (rl < 3) {
-                       temp1 |= 0x8000;
-                       rl = 0;
-               }
-               rl = 31 - rl;   // Convert volume to attenuation.
-               temp1 |= rl;
-               cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[5] = val << 8;
-#else
-               s->mix.vol[5] = val;
-#endif
-               return put_user(s->mix.vol[5], (int __user *)argp);
-
-
-       case SOUND_MIXER_SYNTH:
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               rl = (l * 2 - 11) / 3;  // Convert 0-100 range to 0-63.
-               rr = (r * 2 - 11) / 3;
-               if (rl < 3)     // If l is low, turn on
-                       temp1 = 0x0080; //  the mute bit.
-               else
-                       temp1 = 0;
-
-               rl = 63 - rl;   // Convert vol to attenuation.
-               writel(temp1 | rl, s->pBA0 + BA0_FMLVC);
-               if (rr < 3)     //  If rr is low, turn on
-                       temp1 = 0x0080; //   the mute bit.
-               else
-                       temp1 = 0;
-               rr = 63 - rr;   // Convert vol to attenuation.
-               writel(temp1 | rr, s->pBA0 + BA0_FMRVC);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[4] = (r << 8) | l;
-#else
-               s->mix.vol[4] = val;
-#endif
-               return put_user(s->mix.vol[4], (int __user *)argp);
-
-
-       default:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                       "cs4281: mixer_ioctl(): default\n"));
-
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                       return -EINVAL;
-               if (get_user(val, (int __user *)argp))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (l < 1) {
-                       l = 0;
-                       rl = 31;
-               } else
-                       rl = (attentbl[(l * 10) / 100]) >> 1;
-
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               if (r < 1) {
-                       r = 0;
-                       rr = 31;
-               } else
-                       rr = (attentbl[(r * 10) / 100]) >> 1;
-               if ((rl > 30) && (rr > 30))
-                       temp1 = 0x8000;
-               else
-                       temp1 = 0;
-               temp1 = temp1 | (rl << 8) | rr;
-               cs4281_write_ac97(s, mixreg[vidx - 1], temp1);
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l;
-#else
-               s->mix.vol[vidx - 1] = val;
-#endif
-#ifndef NOT_CS4281_PM
-               CS_DBGOUT(CS_PM, 9, printk(KERN_INFO 
-                       "write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n", 
-                               vidx-1,temp1,s->mix.vol[vidx-1]));
-#endif
-               return put_user(s->mix.vol[vidx - 1], (int __user *)argp);
-       }
-}
-
-
-// --------------------------------------------------------------------- 
-
-static int cs4281_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_open_mixdev()+\n"));
-
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-               if(s->dev_mixer == minor)
-                       break;
-       }
-       if (!s)
-       {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
-                       printk(KERN_INFO "cs4281: cs4281_open_mixdev()- -ENODEV\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_open_mixdev()- 0\n"));
-
-       return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-
-static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
-                              unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct cs4281_state *) file->private_data, cmd,
-                          arg);
-}
-
-
-// ******************************************************************************************
-//   Mixer file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = cs4281_ioctl_mixdev,
-       .open    = cs4281_open_mixdev,
-       .release = cs4281_release_mixdev,
-};
-
-// --------------------------------------------------------------------- 
-
-
-static int drain_adc(struct cs4281_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-
-       if (s->dma_adc.mapped)
-               return 0;
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_adc.count;
-               CS_DBGOUT(CS_FUNCTION, 2,
-                         printk(KERN_INFO "cs4281: drain_adc() %d\n", count));
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0) {
-                       CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-                                "cs4281: drain_adc() count<0\n"));
-                       break;
-               }
-               if (signal_pending(current))
-                       break;
-               if (nonblock) {
-                       remove_wait_queue(&s->dma_adc.wait, &wait);
-                       current->state = TASK_RUNNING;
-                       return -EBUSY;
-               }
-               tmo =
-                   3 * HZ * (count +
-                             s->dma_adc.fragsize) / 2 / s->prop_adc.rate;
-               if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->prop_adc.channels > 1)
-                       tmo >>= 1;
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "cs4281: dma timed out??\n");
-       }
-       remove_wait_queue(&s->dma_adc.wait, &wait);
-       current->state = TASK_RUNNING;
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-static int drain_dac(struct cs4281_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-
-       if (s->dma_dac.mapped)
-               return 0;
-       add_wait_queue(&s->dma_dac.wait, &wait);
-       for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                       break;
-               if (nonblock) {
-                       remove_wait_queue(&s->dma_dac.wait, &wait);
-                       current->state = TASK_RUNNING;
-                       return -EBUSY;
-               }
-               tmo =
-                   3 * HZ * (count +
-                             s->dma_dac.fragsize) / 2 / s->prop_dac.rate;
-               if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->prop_dac.channels > 1)
-                       tmo >>= 1;
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "cs4281: dma timed out??\n");
-       }
-       remove_wait_queue(&s->dma_dac.wait, &wait);
-       current->state = TASK_RUNNING;
-       if (signal_pending(current))
-               return -ERESTARTSYS;
-       return 0;
-}
-
-//****************************************************************************
-//
-// CopySamples copies 16-bit stereo samples from the source to the
-// destination, possibly converting down to either 8-bit or mono or both.
-// count specifies the number of output bytes to write.
-//
-//  Arguments:
-//
-//  dst             - Pointer to a destination buffer.
-//  src             - Pointer to a source buffer
-//  count           - The number of bytes to copy into the destination buffer.
-//  iChannels       - Stereo - 2
-//                    Mono   - 1
-//  fmt             - AFMT_xxx (soundcard.h formats)
-//
-// NOTES: only call this routine for conversion to 8bit from 16bit
-//
-//****************************************************************************
-static void CopySamples(char *dst, char *src, int count, int iChannels,
-                       unsigned fmt)
-{
-
-       unsigned short *psSrc;
-       long lAudioSample;
-
-       CS_DBGOUT(CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: CopySamples()+ "));
-       CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                " dst=%p src=%p count=%d iChannels=%d fmt=0x%x\n",
-                        dst, src, (unsigned) count, (unsigned) iChannels, (unsigned) fmt));
-
-       // Gershwin does format conversion in hardware so normally
-       // we don't do any host based coversion. The data formatter
-       // truncates 16 bit data to 8 bit and that causes some hiss.
-       // We have already forced the HW to do 16 bit sampling and 
-       // 2 channel so that we can use software to round instead 
-       // of truncate
-
-       //
-       // See if the data should be output as 8-bit unsigned stereo.
-       // or if the data should be output at 8-bit unsigned mono.
-       //
-       if ( ((iChannels == 2) && (fmt & AFMT_U8)) ||
-               ((iChannels == 1) && (fmt & AFMT_U8)) ) {
-               //
-               // Convert each 16-bit unsigned stereo sample to 8-bit unsigned 
-               // stereo using rounding.
-               //
-               psSrc = (unsigned short *) src;
-               count = count / 2;
-               while (count--) {
-                       lAudioSample = (long) psSrc[count] + (long) 0x80;
-                       if (lAudioSample > 0xffff) {
-                               lAudioSample = 0xffff;
-                       }
-                       dst[count] = (char) (lAudioSample >> 8);
-               }
-       }
-       //
-       // check for 8-bit signed stereo.
-       //
-       else if ((iChannels == 2) && (fmt & AFMT_S8)) {
-               //
-               // Convert each 16-bit stereo sample to 8-bit stereo using rounding.
-               //
-               psSrc = (short *) src;
-               while (count--) {
-                       lAudioSample =
-                           (((long) psSrc[0] + (long) psSrc[1]) / 2);
-                       psSrc += 2;
-                       *dst++ = (char) ((short) lAudioSample >> 8);
-               }
-       }
-       //
-       // Otherwise, the data should be output as 8-bit signed mono.
-       //
-       else if ((iChannels == 1) && (fmt & AFMT_S8)) {
-               //
-               // Convert each 16-bit signed mono sample to 8-bit signed mono 
-               // using rounding.
-               //
-               psSrc = (short *) src;
-               count = count / 2;
-               while (count--) {
-                       lAudioSample =
-                           (((long) psSrc[0] + (long) psSrc[1]) / 2);
-                       if (lAudioSample > 0x7fff) {
-                               lAudioSample = 0x7fff;
-                       }
-                       psSrc += 2;
-                       *dst++ = (char) ((short) lAudioSample >> 8);
-               }
-       }
-}
-
-//
-// cs_copy_to_user()
-// replacement for the standard copy_to_user, to allow for a conversion from
-// 16 bit to 8 bit if the record conversion is active.  the cs4281 has some
-// issues with 8 bit capture, so the driver always captures data in 16 bit
-// and then if the user requested 8 bit, converts from 16 to 8 bit.
-//
-static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest,
-                               unsigned *hwsrc, unsigned cnt,
-                               unsigned *copied)
-{
-       void *src = hwsrc;      //default to the standard destination buffer addr
-
-       CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO
-               "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=%p\n",
-                       s->prop_adc.fmt, s->prop_adc.fmt_original,
-                       (unsigned) cnt, dest));
-
-       if (cnt > s->dma_adc.dmasize) {
-               cnt = s->dma_adc.dmasize;
-       }
-       if (!cnt) {
-               *copied = 0;
-               return 0;
-       }
-       if (s->conversion) {
-               if (!s->tmpbuff) {
-                       *copied = cnt / 2;
-                       return 0;
-               }
-               CopySamples(s->tmpbuff, (void *) hwsrc, cnt,
-                           (unsigned) s->prop_adc.channels,
-                           s->prop_adc.fmt_original);
-               src = s->tmpbuff;
-               cnt = cnt / 2;
-       }
-
-       if (copy_to_user(dest, src, cnt)) {
-               *copied = 0;
-               return -EFAULT;
-       }
-       *copied = cnt;
-       CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO
-               "cs4281: cs_copy_to_user()- copied bytes is %d \n", cnt));
-       return 0;
-}
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count,
-                          loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       unsigned copied = 0;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-                 printk(KERN_INFO "cs4281: cs4281_read()+ %Zu \n", count));
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-//
-// "count" is the amount of bytes to read (from app), is decremented each loop
-//      by the amount of bytes that have been returned to the user buffer.
-// "cnt" is the running total of each read from the buffer (changes each loop)
-// "buffer" points to the app's buffer
-// "ret" keeps a running total of the amount of bytes that have been copied
-//      to the user buffer.
-// "copied" is the total bytes copied into the user buffer for each loop.
-//
-       while (count > 0) {
-               CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                       "_read() count>0 count=%Zu .count=%d .swptr=%d .hwptr=%d \n",
-                               count, s->dma_adc.count,
-                               s->dma_adc.swptr, s->dma_adc.hwptr));
-               spin_lock_irqsave(&s->lock, flags);
-
-               // get the current copy point of the sw buffer
-               swptr = s->dma_adc.swptr;
-
-               // cnt is the amount of unread bytes from the end of the 
-               // hw buffer to the current sw pointer
-               cnt = s->dma_adc.dmasize - swptr;
-
-               // dma_adc.count is the current total bytes that have not been read.
-               // if the amount of unread bytes from the current sw pointer to the
-               // end of the buffer is greater than the current total bytes that
-               // have not been read, then set the "cnt" (unread bytes) to the
-               // amount of unread bytes.  
-
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               //
-               // if we are converting from 8/16 then we need to copy
-               // twice the number of 16 bit bytes then 8 bit bytes.
-               // 
-               if (s->conversion) {
-                       if (cnt > (count * 2))
-                               cnt = (count * 2);
-               } else {
-                       if (cnt > count)
-                               cnt = count;
-               }
-               //
-               // "cnt" NOW is the smaller of the amount that will be read,
-               // and the amount that is requested in this read (or partial).
-               // if there are no bytes in the buffer to read, then start the
-               // ADC and wait for the interrupt handler to wake us up.
-               //
-               if (cnt <= 0) {
-
-                       // start up the dma engine and then continue back to the top of
-                       // the loop when wake up occurs.
-                       start_adc(s);
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->dma_adc.wait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               // there are bytes in the buffer to read.
-               // copy from the hw buffer over to the user buffer.
-               // user buffer is designated by "buffer"
-               // virtual address to copy from is rawbuf+swptr
-               // the "cnt" is the number of bytes to read.
-
-               CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO
-                       "_read() copy_to cnt=%d count=%Zu ", cnt, count));
-               CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO
-                        " .dmasize=%d .count=%d buffer=%p ret=%Zd\n",
-                                s->dma_adc.dmasize, s->dma_adc.count, buffer, ret));
-
-               if (cs_copy_to_user
-                   (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied))
-                       return ret ? ret : -EFAULT;
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= copied;
-               buffer += copied;
-               ret += copied;
-               start_adc(s);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
-                 printk(KERN_INFO "cs4281: cs4281_read()- %Zd\n", ret));
-       return ret;
-}
-
-
-static ssize_t cs4281_write(struct file *file, const char __user *buffer,
-                           size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr, hwptr, busaddr;
-       int cnt;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-                 printk(KERN_INFO "cs4281: cs4281_write()+ count=%Zu\n",
-                        count));
-       VALIDATE_STATE(s);
-
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               if (s->dma_dac.underrun) {
-                       s->dma_dac.underrun = 0;
-                       hwptr = readl(s->pBA0 + BA0_DCA0);
-                       busaddr = virt_to_bus(s->dma_dac.rawbuf);
-                       hwptr -= (unsigned) busaddr;
-                       s->dma_dac.swptr = s->dma_dac.hwptr = hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize - swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       start_dac(s);
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->dma_dac.wait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
-                       return ret ? ret : -EFAULT;
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_dac(s);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
-                 printk(KERN_INFO "cs4281: cs4281_write()- %Zd\n", ret));
-       return ret;
-}
-
-
-static unsigned int cs4281_poll(struct file *file,
-                               struct poll_table_struct *wait)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                 printk(KERN_INFO "cs4281: cs4281_poll()+\n"));
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                         printk(KERN_INFO
-                                "cs4281: cs4281_poll() wait on FMODE_WRITE\n"));
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                         printk(KERN_INFO
-                                "cs4281: cs4281_poll() wait on FMODE_READ\n"));
-               if(!s->dma_dac.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       cs4281_update_ptr(s,CS_FALSE);
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >=
-                           (signed) s->dma_dac.fragsize) {
-                               if (s->dma_dac.wakeup)
-                                       mask |= POLLOUT | POLLWRNORM;
-                               else
-                                       mask = 0;
-                               s->dma_dac.wakeup = 0;
-                       }
-               } else {
-                       if ((signed) (s->dma_dac.dmasize/2) >= s->dma_dac.count)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       } else if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) 
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
-                 printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",
-                        mask));
-       return mask;
-}
-
-
-static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       struct dmabuf *db;
-       int ret;
-       unsigned long size;
-
-       CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_mmap()+\n"));
-
-       VALIDATE_STATE(s);
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)) != 0)
-                       return ret;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0)
-                       return ret;
-               db = &s->dma_adc;
-       } else
-               return -EINVAL;
-//
-// only support PLAYBACK for now
-//
-       db = &s->dma_dac;
-
-       if (cs4x_pgoff(vma) != 0)
-               return -EINVAL;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               return -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               return -EAGAIN;
-       db->mapped = 1;
-
-       CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
-                 printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
-                        (unsigned) size));
-
-       return 0;
-}
-
-
-static int cs4281_ioctl(struct inode *inode, struct file *file,
-                       unsigned int cmd, unsigned long arg)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       int val, mapped, ret;
-       int __user *p = (int __user *)arg;
-
-       CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO
-                "cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd));
-#if CSDEBUG
-       cs_printioctl(cmd);
-#endif
-       VALIDATE_STATE(s);
-       mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-           ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n",
-                                SOUND_VERSION));
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SYNC\n"));
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s,
-                                        0 /*file->f_flags & O_NONBLOCK */
-                                        );
-               return 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
-                               DSP_CAP_TRIGGER | DSP_CAP_MMAP,
-                               p);
-
-       case SNDCTL_DSP_RESET:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_RESET\n"));
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr =
-                           s->dma_dac.count = s->dma_dac.total_bytes =
-                           s->dma_dac.blocks = s->dma_dac.wakeup = 0;
-                       prog_codec(s, CS_TYPE_DAC);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr =
-                           s->dma_adc.count = s->dma_adc.total_bytes =
-                           s->dma_adc.blocks = s->dma_dac.wakeup = 0;
-                       prog_codec(s, CS_TYPE_ADC);
-               }
-               return 0;
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val));
-               //
-               // support independent capture and playback channels
-               // assume that the file mode bit determines the 
-               // direction of the data flow.
-               //
-               if (file->f_mode & FMODE_READ) {
-                       if (val >= 0) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               // program sampling rates 
-                               if (val > 48000)
-                                       val = 48000;
-                               if (val < 6300)
-                                       val = 6300;
-                               s->prop_adc.rate = val;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val >= 0) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               // program sampling rates 
-                               if (val > 48000)
-                                       val = 48000;
-                               if (val < 6300)
-                                       val = 6300;
-                               s->prop_dac.rate = val;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               }
-
-               if (file->f_mode & FMODE_WRITE)
-                       val = s->prop_dac.rate;
-               else if (file->f_mode & FMODE_READ)
-                       val = s->prop_adc.rate;
-
-               return put_user(val, p);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val));
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       s->prop_adc.channels = val ? 2 : 1;
-                       prog_codec(s, CS_TYPE_ADC);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       s->prop_dac.channels = val ? 2 : 1;
-                       prog_codec(s, CS_TYPE_DAC);
-               }
-               return 0;
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n",
-                                val));
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       s->prop_adc.channels = 2;
-                               else
-                                       s->prop_adc.channels = 1;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       s->prop_dac.channels = 2;
-                               else
-                                       s->prop_dac.channels = 1;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               }
-
-               if (file->f_mode & FMODE_WRITE)
-                       val = s->prop_dac.channels;
-               else if (file->f_mode & FMODE_READ)
-                       val = s->prop_adc.channels;
-
-               return put_user(val, p);
-
-       case SNDCTL_DSP_GETFMTS:        // Returns a mask 
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n",
-                                AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-                                AFMT_U8));
-               return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 |
-                               AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n",
-                                val));
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val != AFMT_S16_LE
-                                   && val != AFMT_U16_LE && val != AFMT_S8
-                                   && val != AFMT_U8)
-                                       val = AFMT_U8;
-                               s->prop_adc.fmt = val;
-                               s->prop_adc.fmt_original = s->prop_adc.fmt;
-                               prog_codec(s, CS_TYPE_ADC);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val != AFMT_S16_LE
-                                   && val != AFMT_U16_LE && val != AFMT_S8
-                                   && val != AFMT_U8)
-                                       val = AFMT_U8;
-                               s->prop_dac.fmt = val;
-                               s->prop_dac.fmt_original = s->prop_dac.fmt;
-                               prog_codec(s, CS_TYPE_DAC);
-                       }
-               } else {
-                       if (file->f_mode & FMODE_WRITE)
-                               val = s->prop_dac.fmt_original;
-                       else if (file->f_mode & FMODE_READ)
-                               val = s->prop_adc.fmt_original;
-               }
-               CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO
-                 "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n", 
-                       val));
-               return put_user(val, p);
-
-       case SNDCTL_DSP_POST:
-               CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO
-                        "cs4281: cs4281_ioctl(): DSP_POST\n"));
-               return 0;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & s->ena & FMODE_READ)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & s->ena & FMODE_WRITE)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready
-                                   && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready
-                                   && (ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                               start_dac(s);
-                       } else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)))
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               if (s->dma_dac.mapped)
-                       abinfo.bytes = s->dma_dac.dmasize;
-               else
-                       abinfo.bytes =
-                           s->dma_dac.dmasize - s->dma_dac.count;
-               abinfo.fragstotal = s->dma_dac.numfrag;
-               abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
-               CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
-                       "cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n",
-                               abinfo.fragsize,abinfo.bytes,abinfo.fragstotal,
-                               abinfo.fragments));
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(p, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)))
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               if (s->conversion) {
-                       abinfo.fragsize = s->dma_adc.fragsize / 2;
-                       abinfo.bytes = s->dma_adc.count / 2;
-                       abinfo.fragstotal = s->dma_adc.numfrag;
-                       abinfo.fragments =
-                           abinfo.bytes >> (s->dma_adc.fragshift - 1);
-               } else {
-                       abinfo.fragsize = s->dma_adc.fragsize;
-                       abinfo.bytes = s->dma_adc.count;
-                       abinfo.fragstotal = s->dma_adc.numfrag;
-                       abinfo.fragments =
-                           abinfo.bytes >> s->dma_adc.fragshift;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(p, &abinfo,
-                                   sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-       case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if(!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               cinfo.bytes = s->dma_adc.total_bytes;
-               if (s->dma_adc.mapped) {
-                       cinfo.blocks =
-                           (cinfo.bytes >> s->dma_adc.fragshift) -
-                           s->dma_adc.blocks;
-                       s->dma_adc.blocks =
-                           cinfo.bytes >> s->dma_adc.fragshift;
-               } else {
-                       if (s->conversion) {
-                               cinfo.blocks =
-                                   s->dma_adc.count /
-                                   2 >> (s->dma_adc.fragshift - 1);
-                       } else
-                               cinfo.blocks =
-                                   s->dma_adc.count >> s->dma_adc.
-                                   fragshift;
-               }
-               if (s->conversion)
-                       cinfo.ptr = s->dma_adc.hwptr / 2;
-               else
-                       cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize - 1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if(!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_update_ptr(s,CS_FALSE);
-               cinfo.bytes = s->dma_dac.total_bytes;
-               if (s->dma_dac.mapped) {
-                       cinfo.blocks =
-                           (cinfo.bytes >> s->dma_dac.fragshift) -
-                           s->dma_dac.blocks;
-                       s->dma_dac.blocks =
-                           cinfo.bytes >> s->dma_dac.fragshift;
-               } else {
-                       cinfo.blocks =
-                           s->dma_dac.count >> s->dma_dac.fragshift;
-               }
-               cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize - 1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(p, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac(s)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               if (s->conversion)
-                       return put_user(s->dma_adc.fragsize / 2, p);
-               else
-                       return put_user(s->dma_adc.fragsize, p);
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               return 0;       // Say OK, but do nothing.
-
-       case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision)
-                   || (file->f_mode & FMODE_WRITE
-                       && s->dma_dac.subdivision)) return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               else if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-       case SOUND_PCM_READ_RATE:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->prop_adc.rate, p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               if (file->f_mode & FMODE_READ)
-                       return put_user(s->prop_adc.channels, p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return put_user(s->prop_dac.channels, p);
-
-       case SOUND_PCM_READ_BITS:
-               if (file->f_mode & FMODE_READ)
-                       return
-                           put_user(
-                                    (s->prop_adc.
-                                     fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    p);
-               else if (file->f_mode & FMODE_WRITE)
-                       return
-                           put_user(
-                                    (s->prop_dac.
-                                     fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16,
-                                    p);
-
-       case SOUND_PCM_WRITE_FILTER:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_READ_FILTER:
-               return -EINVAL;
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-
-static int cs4281_release(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-
-       CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO
-                "cs4281: cs4281_release(): inode=%p file=%p f_mode=%d\n",
-                        inode, file, file->f_mode));
-
-       VALIDATE_STATE(s);
-
-       if (file->f_mode & FMODE_WRITE) {
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-               mutex_lock(&s->open_sem_dac);
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-               s->open_mode &= ~FMODE_WRITE;
-               mutex_unlock(&s->open_sem_dac);
-               wake_up(&s->open_wait_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               drain_adc(s, file->f_flags & O_NONBLOCK);
-               mutex_lock(&s->open_sem_adc);
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-               s->open_mode &= ~FMODE_READ;
-               mutex_unlock(&s->open_sem_adc);
-               wake_up(&s->open_wait_adc);
-       }
-       return 0;
-}
-
-static int cs4281_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-               "cs4281: cs4281_open(): inode=%p file=%p f_mode=0x%x\n",
-                       inode, file, file->f_mode));
-
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-       if (entry == &cs4281_devs)
-               return -ENODEV;
-       if (!s) {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-                       "cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-
-       // wait for device to become free 
-       if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO
-                        "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n"));
-               return -ENODEV;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               mutex_lock(&s->open_sem_dac);
-               while (s->open_mode & FMODE_WRITE) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               mutex_unlock(&s->open_sem_dac);
-                               return -EBUSY;
-                       }
-                       mutex_unlock(&s->open_sem_dac);
-                       interruptible_sleep_on(&s->open_wait_dac);
-
-                       if (signal_pending(current))
-                               return -ERESTARTSYS;
-                       mutex_lock(&s->open_sem_dac);
-               }
-       }
-       if (file->f_mode & FMODE_READ) {
-               mutex_lock(&s->open_sem_adc);
-               while (s->open_mode & FMODE_READ) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               mutex_unlock(&s->open_sem_adc);
-                               return -EBUSY;
-                       }
-                       mutex_unlock(&s->open_sem_adc);
-                       interruptible_sleep_on(&s->open_wait_adc);
-
-                       if (signal_pending(current))
-                               return -ERESTARTSYS;
-                       mutex_lock(&s->open_sem_adc);
-               }
-       }
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       if (file->f_mode & FMODE_READ) {
-               s->prop_adc.fmt = AFMT_U8;
-               s->prop_adc.fmt_original = s->prop_adc.fmt;
-               s->prop_adc.channels = 1;
-               s->prop_adc.rate = 8000;
-               s->prop_adc.clkdiv = 96 | 0x80;
-               s->conversion = 0;
-               s->ena &= ~FMODE_READ;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
-                   s->dma_adc.subdivision = 0;
-               mutex_unlock(&s->open_sem_adc);
-
-               if (prog_dmabuf_adc(s)) {
-                       CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-                               "cs4281: adc Program dmabufs failed.\n"));
-                       cs4281_release(inode, file);
-                       return -ENOMEM;
-               }
-               prog_codec(s, CS_TYPE_ADC);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->prop_dac.fmt = AFMT_U8;
-               s->prop_dac.fmt_original = s->prop_dac.fmt;
-               s->prop_dac.channels = 1;
-               s->prop_dac.rate = 8000;
-               s->prop_dac.clkdiv = 96 | 0x80;
-               s->conversion = 0;
-               s->ena &= ~FMODE_WRITE;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
-                   s->dma_dac.subdivision = 0;
-               mutex_unlock(&s->open_sem_dac);
-
-               if (prog_dmabuf_dac(s)) {
-                       CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
-                               "cs4281: dac Program dmabufs failed.\n"));
-                       cs4281_release(inode, file);
-                       return -ENOMEM;
-               }
-               prog_codec(s, CS_TYPE_DAC);
-       }
-       CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
-                 printk(KERN_INFO "cs4281: cs4281_open()- 0\n"));
-       return nonseekable_open(inode, file);
-}
-
-
-// ******************************************************************************************
-//   Wave (audio) file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cs4281_read,
-       .write   = cs4281_write,
-       .poll    = cs4281_poll,
-       .ioctl   = cs4281_ioctl,
-       .mmap    = cs4281_mmap,
-       .open    = cs4281_open,
-       .release = cs4281_release,
-};
-
-// --------------------------------------------------------------------- 
-
-// hold spinlock for the following! 
-static void cs4281_handle_midi(struct cs4281_state *s)
-{
-       unsigned char ch;
-       int wake;
-       unsigned temp1;
-
-       wake = 0;
-       while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) {
-               ch = readl(s->pBA0 + BA0_MIDRP);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
-               temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff;
-               writel(temp1, s->pBA0 + BA0_MIDWP);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF - 16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-
-
-static irqreturn_t cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct cs4281_state *s = (struct cs4281_state *) dev_id;
-       unsigned int temp1;
-
-       // fastpath out, to ease interrupt sharing 
-       temp1 = readl(s->pBA0 + BA0_HISR);      // Get Int Status reg.
-
-       CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
-                 "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n", temp1));
-/*
-* If not DMA or MIDI interrupt, then just return.
-*/
-       if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);
-               CS_DBGOUT(CS_INTERRUPT, 9, printk(KERN_INFO
-                       "cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n"));
-               return IRQ_NONE;
-       }
-
-       if (temp1 & HISR_DMA0)  // If play interrupt,
-               readl(s->pBA0 + BA0_HDSR0);     //   clear the source.
-
-       if (temp1 & HISR_DMA1)  // Same for play.
-               readl(s->pBA0 + BA0_HDSR1);
-       writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Local EOI
-
-       spin_lock(&s->lock);
-       cs4281_update_ptr(s,CS_TRUE);
-       cs4281_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-// **************************************************************************
-
-static void cs4281_midi_timer(unsigned long data)
-{
-       struct cs4281_state *s = (struct cs4281_state *) data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       cs4281_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies + 1;
-       add_timer(&s->midi.timer);
-}
-
-
-// --------------------------------------------------------------------- 
-
-static ssize_t cs4281_midi_read(struct file *file, char __user *buffer,
-                               size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->midi.iwait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
-                       return ret ? ret : -EFAULT;
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-       return ret;
-}
-
-
-static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer,
-                                size_t count, loff_t * ppos)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0)
-                       cs4281_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK)
-                               return ret ? ret : -EAGAIN;
-                       interruptible_sleep_on(&s->midi.owait);
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
-                       return ret ? ret : -EFAULT;
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               cs4281_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       return ret;
-}
-
-
-static unsigned int cs4281_midi_poll(struct file *file,
-                                    struct poll_table_struct *wait)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_flags & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-
-static int cs4281_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned long flags, temp1;
-       unsigned int minor = iminor(inode);
-       struct cs4281_state *s=NULL;
-       struct list_head *entry;
-       list_for_each(entry, &cs4281_devs)
-       {
-               s = list_entry(entry, struct cs4281_state, list);
-
-               if (s->dev_midi == minor)
-                       break;
-       }
-
-       if (entry == &cs4281_devs)
-               return -ENODEV;
-       if (!s)
-       {
-               CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
-                       "cs4281: cs4281_open(): Error - unable to find audio state struct\n"));
-               return -ENODEV;
-       }
-       VALIDATE_STATE(s);
-       file->private_data = s;
-       // wait for device to become free 
-       mutex_lock(&s->open_sem);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_sem);
-                       return -EBUSY;
-               }
-               mutex_unlock(&s->open_sem);
-               interruptible_sleep_on(&s->open_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_sem);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               writel(1, s->pBA0 + BA0_MIDCR); // Reset the interface.
-               writel(0, s->pBA0 + BA0_MIDCR); // Return to normal mode.
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               writel(0x0000000f, s->pBA0 + BA0_MIDCR);        // Enable transmit, record, ints.
-               temp1 = readl(s->pBA0 + BA0_HIMR);
-               writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR); // Enable midi int. recognition.
-               writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);       // Enable interrupts
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies + 1;
-               s->midi.timer.data = (unsigned long) s;
-               s->midi.timer.function = cs4281_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |=
-           (file->
-            f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
-                                           FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_sem);
-       return nonseekable_open(inode, file);
-}
-
-
-static int cs4281_midi_release(struct inode *inode, struct file *file)
-{
-       struct cs4281_state *s =
-           (struct cs4281_state *) file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               remove_wait_queue(&s->midi.owait, &wait);
-                               current->state = TASK_RUNNING;
-                               return -EBUSY;
-                       }
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG
-                                      "cs4281: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               current->state = TASK_RUNNING;
-       }
-       mutex_lock(&s->open_sem);
-       s->open_mode &=
-           (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
-                                                    FMODE_MIDI_WRITE);
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               writel(0, s->pBA0 + BA0_MIDCR); // Disable Midi interrupts.  
-               del_timer(&s->midi.timer);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       mutex_unlock(&s->open_sem);
-       wake_up(&s->open_wait);
-       return 0;
-}
-
-// ******************************************************************************************
-//   Midi file operations struct.
-// ******************************************************************************************
-static /*const */ struct file_operations cs4281_midi_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = cs4281_midi_read,
-       .write   = cs4281_midi_write,
-       .poll    = cs4281_midi_poll,
-       .open    = cs4281_midi_open,
-       .release = cs4281_midi_release,
-};
-
-
-// --------------------------------------------------------------------- 
-
-// maximum number of devices 
-#define NR_DEVICE 8            // Only eight devices supported currently.
-
-// --------------------------------------------------------------------- 
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-
-       {
-       SOUND_MIXER_WRITE_VOLUME, 0x4040}, {
-       SOUND_MIXER_WRITE_PCM, 0x4040}, {
-       SOUND_MIXER_WRITE_SYNTH, 0x4040}, {
-       SOUND_MIXER_WRITE_CD, 0x4040}, {
-       SOUND_MIXER_WRITE_LINE, 0x4040}, {
-       SOUND_MIXER_WRITE_LINE1, 0x4040}, {
-       SOUND_MIXER_WRITE_RECLEV, 0x0000}, {
-       SOUND_MIXER_WRITE_SPEAKER, 0x4040}, {
-       SOUND_MIXER_WRITE_MIC, 0x0000}
-};
-
-
-#ifndef NOT_CS4281_PM
-static void __devinit cs4281_BuildFIFO(
-       struct cs4281_pipeline *p, 
-       struct cs4281_state *s)
-{
-       switch(p->number)
-       {
-               case 0:  /* playback */
-               {
-                       p->u32FCRnAddress  =  BA0_FCR0;
-                       p->u32FSICnAddress = BA0_FSIC0;
-                       p->u32FPDRnAddress = BA0_FPDR0;
-                       break;
-               }
-               case 1:  /* capture */
-               {
-                       p->u32FCRnAddress  =  BA0_FCR1;
-                       p->u32FSICnAddress = BA0_FSIC1;
-                       p->u32FPDRnAddress = BA0_FPDR1;
-                       break;
-               }
-
-               case 2: 
-               {
-                       p->u32FCRnAddress  =  BA0_FCR2;
-                       p->u32FSICnAddress = BA0_FSIC2;
-                       p->u32FPDRnAddress = BA0_FPDR2;
-                       break;
-               }
-               case 3: 
-               {
-                       p->u32FCRnAddress  =  BA0_FCR3;
-                       p->u32FSICnAddress = BA0_FSIC3;
-                       p->u32FPDRnAddress = BA0_FPDR3;
-                       break;
-               }
-               default:
-                       break;
-       }
-       //
-       // first read the hardware to initialize the member variables
-       //
-       p->u32FCRnValue = readl(s->pBA0 + p->u32FCRnAddress);
-       p->u32FSICnValue = readl(s->pBA0 + p->u32FSICnAddress);
-       p->u32FPDRnValue = readl(s->pBA0 + p->u32FPDRnAddress);
-
-}
-
-static void __devinit cs4281_BuildDMAengine(
-       struct cs4281_pipeline *p, 
-       struct cs4281_state *s)
-{
-/*
-* initialize all the addresses of this pipeline dma info.
-*/
-       switch(p->number)
-       {
-               case 0:  /* playback */
-               {
-                       p->u32DBAnAddress = BA0_DBA0;
-                       p->u32DCAnAddress = BA0_DCA0;
-                       p->u32DBCnAddress = BA0_DBC0;
-                       p->u32DCCnAddress = BA0_DCC0;
-                       p->u32DMRnAddress = BA0_DMR0;
-                       p->u32DCRnAddress = BA0_DCR0;
-                       p->u32HDSRnAddress = BA0_HDSR0;
-                       break;
-               }
-
-               case 1: /* capture */
-               {
-                       p->u32DBAnAddress = BA0_DBA1;
-                       p->u32DCAnAddress = BA0_DCA1;
-                       p->u32DBCnAddress = BA0_DBC1;
-                       p->u32DCCnAddress = BA0_DCC1;
-                       p->u32DMRnAddress = BA0_DMR1;
-                       p->u32DCRnAddress = BA0_DCR1;
-                       p->u32HDSRnAddress = BA0_HDSR1;
-                       break;
-               }
-
-               case 2:
-               {
-                       p->u32DBAnAddress = BA0_DBA2;
-                       p->u32DCAnAddress = BA0_DCA2;
-                       p->u32DBCnAddress = BA0_DBC2;
-                       p->u32DCCnAddress = BA0_DCC2;
-                       p->u32DMRnAddress = BA0_DMR2;
-                       p->u32DCRnAddress = BA0_DCR2;
-                       p->u32HDSRnAddress = BA0_HDSR2;
-                       break;
-               }
-
-               case 3:
-               {
-                       p->u32DBAnAddress = BA0_DBA3;
-                       p->u32DCAnAddress = BA0_DCA3;
-                       p->u32DBCnAddress = BA0_DBC3;
-                       p->u32DCCnAddress = BA0_DCC3;
-                       p->u32DMRnAddress = BA0_DMR3;
-                       p->u32DCRnAddress = BA0_DCR3;
-                       p->u32HDSRnAddress = BA0_HDSR3;
-                       break;
-               }
-               default:
-                       break;
-       }
-
-//
-// Initialize the dma values for this pipeline
-//
-       p->u32DBAnValue = readl(s->pBA0 + p->u32DBAnAddress);
-       p->u32DBCnValue = readl(s->pBA0 + p->u32DBCnAddress);
-       p->u32DMRnValue = readl(s->pBA0 + p->u32DMRnAddress);
-       p->u32DCRnValue = readl(s->pBA0 + p->u32DCRnAddress);
-
-}
-
-static void __devinit cs4281_InitPM(struct cs4281_state *s)
-{
-       int i;
-       struct cs4281_pipeline *p;
-
-       for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++)
-       {
-               p = &s->pl[i];
-               p->number = i;
-               cs4281_BuildDMAengine(p,s);
-               cs4281_BuildFIFO(p,s);
-       /*
-       * currently only  2 pipelines are used
-       * so, only set the valid bit on the playback and capture.
-       */
-               if( (i == CS4281_PLAYBACK_PIPELINE_NUMBER) || 
-                       (i == CS4281_CAPTURE_PIPELINE_NUMBER))
-                       p->flags |= CS4281_PIPELINE_VALID;
-       }
-       s->pm.u32SSPM_BITS = 0x7e;  /* rev c, use 0x7c for rev a or b */
-}
-#endif
-
-static int __devinit cs4281_probe(struct pci_dev *pcidev,
-                                 const struct pci_device_id *pciid)
-{
-       struct cs4281_state *s;
-       dma_addr_t dma_mask;
-       mm_segment_t fs;
-       int i, val;
-       unsigned int temp1, temp2;
-
-       CS_DBGOUT(CS_FUNCTION | CS_INIT, 2,
-                 printk(KERN_INFO "cs4281: probe()+\n"));
-
-       if (pci_enable_device(pcidev)) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: pci_enable_device() failed\n"));
-               return -1;
-       }
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM) ||
-           !(pci_resource_flags(pcidev, 1) & IORESOURCE_MEM)) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe()- Memory region not assigned\n"));
-               return -ENODEV;
-       }
-       if (pcidev->irq == 0) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() IRQ not assigned\n"));
-               return -ENODEV;
-       }
-       dma_mask = 0xffffffff;  /* this enables playback and recording */
-       i = pci_set_dma_mask(pcidev, dma_mask);
-       if (i) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                     "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n"));
-               return i;
-       }
-       if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
-               CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
-                     "cs4281: probe() no memory for state struct.\n"));
-               return -1;
-       }
-       memset(s, 0, sizeof(struct cs4281_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->open_wait_adc);
-       init_waitqueue_head(&s->open_wait_dac);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_sem);
-       mutex_init(&s->open_sem_adc);
-       mutex_init(&s->open_sem_dac);
-       spin_lock_init(&s->lock);
-       s->pBA0phys = pci_resource_start(pcidev, 0);
-       s->pBA1phys = pci_resource_start(pcidev, 1);
-
-       /* Convert phys to linear. */
-       s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);
-       if (!s->pBA0) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: BA0 I/O mapping failed. Skipping part.\n"));
-               goto err_free;
-       }
-       s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);
-       if (!s->pBA1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: BA1 I/O mapping failed. Skipping part.\n"));
-               goto err_unmap;
-       }
-
-       temp1 = readl(s->pBA0 + BA0_PCICFG00);
-       temp2 = readl(s->pBA0 + BA0_PCICFG04);
-
-       CS_DBGOUT(CS_INIT, 2,
-                 printk(KERN_INFO
-                        "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=%p pBA1=%p \n",
-                        (unsigned) temp1, (unsigned) temp2, s->pBA0, s->pBA1));
-       CS_DBGOUT(CS_INIT, 2,
-                 printk(KERN_INFO
-                        "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
-                        (unsigned) s->pBA0phys, (unsigned) s->pBA1phys));
-
-#ifndef NOT_CS4281_PM
-       s->pm.flags = CS4281_PM_IDLE;
-#endif
-       temp1 = cs4281_hw_init(s);
-       if (temp1) {
-               CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR
-                        "cs4281: cs4281_hw_init() failed. Skipping part.\n"));
-               goto err_irq;
-       }
-       s->magic = CS4281_MAGIC;
-       s->pcidev = pcidev;
-       s->irq = pcidev->irq;
-       if (request_irq
-           (s->irq, cs4281_interrupt, IRQF_SHARED, "Crystal CS4281", s)) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1,
-                         printk(KERN_ERR "cs4281: irq %u in use\n", s->irq));
-               goto err_irq;
-       }
-       if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) <
-           0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_dsp() failed.\n"));
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) <
-           0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_mixer() failed.\n"));
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) {
-               CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR
-                        "cs4281: probe() register_sound_midi() failed.\n"));
-               goto err_dev3;
-       }
-#ifndef NOT_CS4281_PM
-       cs4281_InitPM(s);
-       s->pm.flags |= CS4281_PM_NOT_REGISTERED;
-#endif
-
-       pci_set_master(pcidev); // enable bus mastering 
-
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val);
-       for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val);
-       }
-       val = 1;                // enable mic preamp 
-       mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val);
-       set_fs(fs);
-
-       pci_set_drvdata(pcidev, s);
-       list_add(&s->list, &cs4281_devs);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-               "cs4281: probe()- device allocated successfully\n"));
-       return 0;
-
-      err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
-      err_dev2:
-       unregister_sound_dsp(s->dev_audio);
-      err_dev1:
-       free_irq(s->irq, s);
-      err_irq:
-       iounmap(s->pBA1);
-      err_unmap:
-       iounmap(s->pBA0);
-      err_free:
-       kfree(s);
-
-       CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO
-               "cs4281: probe()- no device allocated\n"));
-       return -ENODEV;
-} // probe_cs4281
-
-
-// --------------------------------------------------------------------- 
-
-static void __devexit cs4281_remove(struct pci_dev *pci_dev)
-{
-       struct cs4281_state *s = pci_get_drvdata(pci_dev);
-       // stop DMA controller 
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       iounmap(s->pBA1);
-       iounmap(s->pBA0);
-       pci_set_drvdata(pci_dev,NULL);
-       list_del(&s->list);
-       kfree(s);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO
-                "cs4281: cs4281_remove()-: remove successful\n"));
-}
-
-static struct pci_device_id cs4281_pci_tbl[] = {
-       {
-               .vendor    = PCI_VENDOR_ID_CIRRUS,
-               .device    = PCI_DEVICE_ID_CRYSTAL_CS4281,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl);
-
-static struct pci_driver cs4281_pci_driver = {
-       .name     = "cs4281",
-       .id_table = cs4281_pci_tbl,
-       .probe    = cs4281_probe,
-       .remove   = __devexit_p(cs4281_remove),
-       .suspend  = CS4281_SUSPEND_TBL,
-       .resume   = CS4281_RESUME_TBL,
-};
-
-static int __init cs4281_init_module(void)
-{
-       int rtn = 0;
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
-               "cs4281: cs4281_init_module()+ \n"));
-       printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " "
-              __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION,
-              CS4281_ARCH);
-       rtn = pci_register_driver(&cs4281_pci_driver);
-
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn));
-       return rtn;
-}
-
-static void __exit cs4281_cleanup_module(void)
-{
-       pci_unregister_driver(&cs4281_pci_driver);
-       CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
-                 printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
-}
-// --------------------------------------------------------------------- 
-
-MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com");
-MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
-MODULE_LICENSE("GPL");
-
-// --------------------------------------------------------------------- 
-
-module_init(cs4281_init_module);
-module_exit(cs4281_cleanup_module);
-
diff --git a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c
deleted file mode 100644 (file)
index 90cbd76..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*******************************************************************************
-*
-*      "cs4281pm.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-
-#ifndef NOT_CS4281_PM
-#include <linux/pm.h>
-
-static int cs4281_suspend(struct cs4281_state *s);
-static int cs4281_resume(struct cs4281_state *s);
-/* 
-* for now (12/22/00) only enable the pm_register PM support.
-* allow these table entries to be null.
-#define CS4281_SUSPEND_TBL cs4281_suspend_tbl
-#define CS4281_RESUME_TBL cs4281_resume_tbl
-*/
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-
-#else /* CS4281_PM */
-#define CS4281_SUSPEND_TBL cs4281_suspend_null
-#define CS4281_RESUME_TBL cs4281_resume_null
-#endif /* CS4281_PM */
-
diff --git a/sound/oss/cs4281/cs4281pm.h b/sound/oss/cs4281/cs4281pm.h
deleted file mode 100644 (file)
index b44fdc9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef NOT_CS4281_PM
-/*******************************************************************************
-*
-*      "cs4281pm.h" --  Cirrus Logic-Crystal CS4281 linux audio driver.
-*
-*      Copyright (C) 2000,2001  Cirrus Logic Corp.  
-*            -- tom woller (twoller@crystal.cirrus.com) or
-*               (audio@crystal.cirrus.com).
-*
-*      This program is free software; you can redistribute it and/or modify
-*      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
-*
-*      This program is distributed in the hope that it will be useful,
-*      but WITHOUT ANY WARRANTY; without even the implied warranty of
-*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*      GNU General Public License for more details.
-*
-*      You should have received a copy of the GNU General Public License
-*      along with this program; if not, write to the Free Software
-*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* 12/22/00 trw - new file. 
-*
-*******************************************************************************/
-/* general pm definitions */
-#define CS4281_AC97_HIGHESTREGTORESTORE 0x26
-#define CS4281_AC97_NUMBER_RESTORE_REGS (CS4281_AC97_HIGHESTREGTORESTORE/2-1)
-
-/* pipeline definitions */
-#define CS4281_NUMBER_OF_PIPELINES     4
-#define CS4281_PIPELINE_VALID          0x0001
-#define CS4281_PLAYBACK_PIPELINE_NUMBER        0x0000
-#define CS4281_CAPTURE_PIPELINE_NUMBER         0x0001
-
-/* PM state defintions */
-#define CS4281_PM_NOT_REGISTERED       0x1000
-#define CS4281_PM_IDLE                 0x0001
-#define CS4281_PM_SUSPENDING           0x0002
-#define CS4281_PM_SUSPENDED            0x0004
-#define CS4281_PM_RESUMING             0x0008
-#define CS4281_PM_RESUMED              0x0010
-
-struct cs4281_pm {
-       unsigned long flags;
-       u32 u32CLKCR1_SAVE,u32SSPMValue,u32PPLVCvalue,u32PPRVCvalue;
-       u32 u32FMLVCvalue,u32FMRVCvalue,u32GPIORvalue,u32JSCTLvalue,u32SSCR;
-       u32 u32SRCSA,u32DacASR,u32AdcASR,u32DacSR,u32AdcSR,u32MIDCR_Save;
-       u32 u32SSPM_BITS;
-       u32 ac97[CS4281_AC97_NUMBER_RESTORE_REGS];
-       u32 u32AC97_master_volume, u32AC97_headphone_volume, u32AC97_master_volume_mono;
-       u32 u32AC97_pcm_out_volume, u32AC97_powerdown, u32AC97_general_purpose;
-       u32 u32hwptr_playback,u32hwptr_capture;
-};
-
-struct cs4281_pipeline {
-       unsigned flags;
-       unsigned number;
-       u32 u32DBAnValue,u32DBCnValue,u32DMRnValue,u32DCRnValue;
-       u32 u32DBAnAddress,u32DCAnAddress,u32DBCnAddress,u32DCCnAddress;
-       u32 u32DMRnAddress,u32DCRnAddress,u32HDSRnAddress;
-       u32 u32DBAn_Save,u32DBCn_Save,u32DMRn_Save,u32DCRn_Save;
-       u32 u32DCCn_Save,u32DCAn_Save;
-/* 
-* technically, these are fifo variables, but just map the 
-* first fifo with the first pipeline and then use the fifo
-* variables inside of the pipeline struct.
-*/
-       u32 u32FCRn_Save,u32FSICn_Save;
-       u32 u32FCRnValue,u32FCRnAddress,u32FSICnValue,u32FSICnAddress;
-       u32 u32FPDRnValue,u32FPDRnAddress;
-};
-#endif
diff --git a/sound/oss/dm.h b/sound/oss/dm.h
deleted file mode 100644 (file)
index 14a9059..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef _DRIVERS_SOUND_DM_H
-#define _DRIVERS_SOUND_DM_H
-
-/*
- *     Definitions of the 'direct midi sound' interface used
- *     by the newer commercial OSS package. We should export
- *     this to userland somewhere in glibc later.
- */
-
-/*
- * Data structure composing an FM "note" or sound event.
- */
-
-struct dm_fm_voice
-{
-       u8 op;
-       u8 voice;
-       u8 am;
-       u8 vibrato;
-       u8 do_sustain;
-       u8 kbd_scale;
-       u8 harmonic;
-       u8 scale_level;
-       u8 volume;
-       u8 attack;
-       u8 decay;
-       u8 sustain;
-       u8 release;
-       u8 feedback;
-       u8 connection;
-       u8 left;
-       u8 right;
-       u8 waveform;
-};
-
-/*
- *     This describes an FM note by its voice, octave, frequency number (10bit)
- *     and key on/off.
- */
-
-struct dm_fm_note
-{
-       u8 voice;
-       u8 octave;
-       u32 fnum;
-       u8 key_on;
-};
-
-/*
- * FM parameters that apply globally to all voices, and thus are not "notes"
- */
-
-struct dm_fm_params
-{
-       u8 am_depth;
-       u8 vib_depth;
-       u8 kbd_split;
-       u8 rhythm;
-
-       /* This block is the percussion instrument data */
-       u8 bass;
-       u8 snare;
-       u8 tomtom;
-       u8 cymbal;
-       u8 hihat;
-};
-
-/*
- *     FM mode ioctl settings
- */
-#define FM_IOCTL_RESET        0x20
-#define FM_IOCTL_PLAY_NOTE    0x21
-#define FM_IOCTL_SET_VOICE    0x22
-#define FM_IOCTL_SET_PARAMS   0x23
-#define FM_IOCTL_SET_MODE     0x24
-#define FM_IOCTL_SET_OPL      0x25
-
-#endif
index 6c1cf74b78c5610973c2ab1282042a2e151d0dfd..6ff67f73cbb955a83ba699e29044d146f09341a0 100644 (file)
@@ -1155,36 +1155,6 @@ void DMAbuf_inputintr(int dev)
        spin_unlock_irqrestore(&dmap->lock,flags);
 }
 
-int DMAbuf_open_dma(int dev)
-{
-       /*
-        *    NOTE!  This routine opens only the primary DMA channel (output).
-        */
-       struct audio_operations *adev = audio_devs[dev];
-       int err;
-
-       if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)
-               return -EBUSY;
-       dma_init_buffers(adev->dmap_out);
-       adev->dmap_out->flags |= DMA_ALLOC_DONE;
-       adev->dmap_out->fragment_size = adev->dmap_out->buffsize;
-
-       if (adev->dmap_out->dma >= 0) {
-               unsigned long flags;
-
-               flags=claim_dma_lock();
-               clear_dma_ff(adev->dmap_out->dma);
-               disable_dma(adev->dmap_out->dma);
-               release_dma_lock(flags);
-       }
-       return 0;
-}
-
-void DMAbuf_close_dma(int dev)
-{
-       close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);
-}
-
 void DMAbuf_init(int dev, int dma1, int dma2)
 {
        struct audio_operations *adev = audio_devs[dev];
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
deleted file mode 100644 (file)
index 13f4831..0000000
+++ /dev/null
@@ -1,2819 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      es1370.c  --  Ensoniq ES1370/Asahi Kasei AK4531 audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   lineout  if 1 the LINE jack is used as an output instead of an input.
- *            LINE then contains the unmixed dsp output. This can be used
- *            to make the card a four channel one: use dsp to output two
- *            channels to LINE and dac to output the other two channels to
- *            SPKR. Set the mixer to only output synth to SPKR.
- *   micbias  sets the +5V bias to the mic if using an electretmic.
- *            
- *
- *  Note: sync mode is not yet supported (i.e. running dsp and dac from the same
- *  clock source)
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/dsp1   additional DAC, like /dev/dsp, but output only,
- *              only 5512, 11025, 22050 and 44100 samples/s,
- *              outputs to mixer "SYNTH" setting
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed
- *  to be done in software. That is what /dev/dac is for. By now (Q2 1998)
- *  there are several MIDI to PCM (WAV) packages, one of them is timidity.
- *
- *  Revision history
- *    26.03.1998   0.1   Initial release
- *    31.03.1998   0.2   Fix bug in GETOSPACE
- *    04.04.1998   0.3   Make it work (again) under 2.0.33
- *                       Fix mixer write operation not returning the actual
- *                       settings
- *    05.04.1998   0.4   First attempt at using the new PCI stuff
- *    29.04.1998   0.5   Fix hang when ^C is pressed on amp
- *    07.05.1998   0.6   Don't double lock around stop_*() in *_release()
- *    10.05.1998   0.7   First stab at a simple midi interface (no bells&whistles)
- *    14.05.1998   0.8   Don't allow excessive interrupt rates
- *    08.06.1998   0.9   First release using Alan Cox' soundcore instead of
- *                       miscdevice
- *    05.07.1998   0.10  Fixed the driver to correctly maintin OSS style volume
- *                       settings (not sure if this should be standard)
- *                       Fixed many references: f_flags should be f_mode
- *                       -- Gerald Britton <gbritton@mit.edu>
- *    03.08.1998   0.11  Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *                       Fixed mixer table thanks to Hakan.Lennestal@lu.erisoft.se
- *                       On module startup, set DAC2 to 11kSPS instead of 5.5kSPS,
- *                       as it produces an annoying ssssh in the lower sampling rate
- *                       Do not include modversions.h
- *    22.08.1998   0.12  Mixer registers actually have 5 instead of 4 bits
- *                       pointed out by Itai Nahshon
- *    31.08.1998   0.13  Fix realplayer problems - dac.count issues
- *    08.10.1998   0.14  Joystick support fixed
- *                      -- Oliver Neukum <c188@org.chemie.uni-muenchen.de>
- *    10.12.1998   0.15  Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.16  Don't wake up app until there are fragsize bytes to read/write
- *    06.01.1999   0.17  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.18  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.19  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.20  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: joystick address handling might still be wrong on archs
- *                       other than i386
- *    10.05.1999   0.21  Added support for an electret mic for SB PCI64
- *                       to the Linux kernel sound driver. This mod also straighten
- *                       out the question marks around the mic impedance setting
- *                       (micz). From Kim.Berts@fisub.mail.abb.com
- *    11.05.1999   0.22  Implemented the IMIX call to mute recording monitor.
- *                       Guenter Geiger <geiger@epy.co.at>
- *    15.06.1999   0.23  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.24  Add pci_set_master
- *    02.08.1999   0.25  Added workaround for the "phantom write" bug first
- *                       documented by Dave Sharpless from Anchor Games
- *    03.08.1999   0.26  adapt to Linus' new __setup/__initcall
- *                       added kernel command line option "es1370=joystick[,lineout[,micbias]]"
- *                       removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge
- *    12.08.1999   0.27  module_init/__setup fixes
- *    19.08.1999   0.28  SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it>
- *    31.08.1999   0.29  add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.30  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.31  More waitqueue races fixed
- *    08.01.2000   0.32  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *    07.02.2000   0.33  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.34  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.35  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    07.01.2001   0.36  Timeout change in wrcodec as requested by Frank Klemm <pfk@fuchs.offl.uni-jena.de>
- *    31.01.2001   0.37  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    03.01.2003   0.38  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- * some important things missing in Ensoniq documentation:
- *
- * Experimental PCLKDIV results:  play the same waveforms on both DAC1 and DAC2
- * and vary PCLKDIV to obtain zero beat.
- *  5512sps:  254
- * 44100sps:   30
- * seems to be fs = 1411200/(PCLKDIV+2)
- *
- * should find out when curr_sample_ct is cleared and
- * where exactly the CCB fetches data
- *
- * The card uses a 22.5792 MHz crystal.
- * The LINEIN jack may be converted to an AOUT jack by
- * setting pin 47 (XCTL0) of the ES1370 to high.
- * Pin 48 (XCTL1) of the ES1370 sets the +5V bias for an electretmic
- * 
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-#define DBG(x) {}
-/*#define DBG(x) {x}*/
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ENSONIQ
-#define PCI_VENDOR_ID_ENSONIQ        0x1274    
-#endif
-
-#ifndef PCI_DEVICE_ID_ENSONIQ_ES1370
-#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
-#endif
-
-#define ES1370_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1370)
-
-#define ES1370_EXTENT             0x40
-#define JOY_EXTENT                8
-
-#define ES1370_REG_CONTROL        0x00
-#define ES1370_REG_STATUS         0x04
-#define ES1370_REG_UART_DATA      0x08
-#define ES1370_REG_UART_STATUS    0x09
-#define ES1370_REG_UART_CONTROL   0x09
-#define ES1370_REG_UART_TEST      0x0a
-#define ES1370_REG_MEMPAGE        0x0c
-#define ES1370_REG_CODEC          0x10
-#define ES1370_REG_SERIAL_CONTROL 0x20
-#define ES1370_REG_DAC1_SCOUNT    0x24
-#define ES1370_REG_DAC2_SCOUNT    0x28
-#define ES1370_REG_ADC_SCOUNT     0x2c
-
-#define ES1370_REG_DAC1_FRAMEADR    0xc30
-#define ES1370_REG_DAC1_FRAMECNT    0xc34
-#define ES1370_REG_DAC2_FRAMEADR    0xc38
-#define ES1370_REG_DAC2_FRAMECNT    0xc3c
-#define ES1370_REG_ADC_FRAMEADR     0xd30
-#define ES1370_REG_ADC_FRAMECNT     0xd34
-#define ES1370_REG_PHANTOM_FRAMEADR 0xd38
-#define ES1370_REG_PHANTOM_FRAMECNT 0xd3c
-
-#define ES1370_FMT_U8_MONO     0
-#define ES1370_FMT_U8_STEREO   1
-#define ES1370_FMT_S16_MONO    2
-#define ES1370_FMT_S16_STEREO  3
-#define ES1370_FMT_STEREO      1
-#define ES1370_FMT_S16         2
-#define ES1370_FMT_MASK        3
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-static const unsigned dac1_samplerate[] = { 5512, 11025, 22050, 44100 };
-
-#define DAC2_SRTODIV(x) (((1411200+(x)/2)/(x))-2)
-#define DAC2_DIVTOSR(x) (1411200/((x)+2))
-
-#define CTRL_ADC_STOP   0x80000000  /* 1 = ADC stopped */
-#define CTRL_XCTL1      0x40000000  /* electret mic bias */
-#define CTRL_OPEN       0x20000000  /* no function, can be read and written */
-#define CTRL_PCLKDIV    0x1fff0000  /* ADC/DAC2 clock divider */
-#define CTRL_SH_PCLKDIV 16
-#define CTRL_MSFMTSEL   0x00008000  /* MPEG serial data fmt: 0 = Sony, 1 = I2S */
-#define CTRL_M_SBB      0x00004000  /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */
-#define CTRL_WTSRSEL    0x00003000  /* DAC1 clock freq: 0=5512, 1=11025, 2=22050, 3=44100 */
-#define CTRL_SH_WTSRSEL 12
-#define CTRL_DAC_SYNC   0x00000800  /* 1 = DAC2 runs off DAC1 clock */
-#define CTRL_CCB_INTRM  0x00000400  /* 1 = CCB "voice" ints enabled */
-#define CTRL_M_CB       0x00000200  /* recording source: 0 = ADC, 1 = MPEG */
-#define CTRL_XCTL0      0x00000100  /* 0 = Line in, 1 = Line out */
-#define CTRL_BREQ       0x00000080  /* 1 = test mode (internal mem test) */
-#define CTRL_DAC1_EN    0x00000040  /* enable DAC1 */
-#define CTRL_DAC2_EN    0x00000020  /* enable DAC2 */
-#define CTRL_ADC_EN     0x00000010  /* enable ADC */
-#define CTRL_UART_EN    0x00000008  /* enable MIDI uart */
-#define CTRL_JYSTK_EN   0x00000004  /* enable Joystick port (presumably at address 0x200) */
-#define CTRL_CDC_EN     0x00000002  /* enable serial (CODEC) interface */
-#define CTRL_SERR_DIS   0x00000001  /* 1 = disable PCI SERR signal */
-
-#define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
-#define STAT_CSTAT      0x00000400  /* 1 = codec busy or codec write in progress */
-#define STAT_CBUSY      0x00000200  /* 1 = codec busy */
-#define STAT_CWRIP      0x00000100  /* 1 = codec write in progress */
-#define STAT_VC         0x00000060  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
-#define STAT_SH_VC      5
-#define STAT_MCCB       0x00000010  /* CCB int pending */
-#define STAT_UART       0x00000008  /* UART int pending */
-#define STAT_DAC1       0x00000004  /* DAC1 int pending */
-#define STAT_DAC2       0x00000002  /* DAC2 int pending */
-#define STAT_ADC        0x00000001  /* ADC int pending */
-
-#define USTAT_RXINT     0x80        /* UART rx int pending */
-#define USTAT_TXINT     0x04        /* UART tx int pending */
-#define USTAT_TXRDY     0x02        /* UART tx ready */
-#define USTAT_RXRDY     0x01        /* UART rx ready */
-
-#define UCTRL_RXINTEN   0x80        /* 1 = enable RX ints */
-#define UCTRL_TXINTEN   0x60        /* TX int enable field mask */
-#define UCTRL_ENA_TXINT 0x20        /* enable TX int */
-#define UCTRL_CNTRL     0x03        /* control field */
-#define UCTRL_CNTRL_SWR 0x03        /* software reset command */
-
-#define SCTRL_P2ENDINC    0x00380000  /*  */
-#define SCTRL_SH_P2ENDINC 19
-#define SCTRL_P2STINC     0x00070000  /*  */
-#define SCTRL_SH_P2STINC  16
-#define SCTRL_R1LOOPSEL   0x00008000  /* 0 = loop mode */
-#define SCTRL_P2LOOPSEL   0x00004000  /* 0 = loop mode */
-#define SCTRL_P1LOOPSEL   0x00002000  /* 0 = loop mode */
-#define SCTRL_P2PAUSE     0x00001000  /* 1 = pause mode */
-#define SCTRL_P1PAUSE     0x00000800  /* 1 = pause mode */
-#define SCTRL_R1INTEN     0x00000400  /* enable interrupt */
-#define SCTRL_P2INTEN     0x00000200  /* enable interrupt */
-#define SCTRL_P1INTEN     0x00000100  /* enable interrupt */
-#define SCTRL_P1SCTRLD    0x00000080  /* reload sample count register for DAC1 */
-#define SCTRL_P2DACSEN    0x00000040  /* 1 = DAC2 play back last sample when disabled */
-#define SCTRL_R1SEB       0x00000020  /* 1 = 16bit */
-#define SCTRL_R1SMB       0x00000010  /* 1 = stereo */
-#define SCTRL_R1FMT       0x00000030  /* format mask */
-#define SCTRL_SH_R1FMT    4
-#define SCTRL_P2SEB       0x00000008  /* 1 = 16bit */
-#define SCTRL_P2SMB       0x00000004  /* 1 = stereo */
-#define SCTRL_P2FMT       0x0000000c  /* format mask */
-#define SCTRL_SH_P2FMT    2
-#define SCTRL_P1SEB       0x00000002  /* 1 = 16bit */
-#define SCTRL_P1SMB       0x00000001  /* 1 = stereo */
-#define SCTRL_P1FMT       0x00000003  /* format mask */
-#define SCTRL_SH_P1FMT    0
-
-/* misc stuff */
-
-#define FMODE_DAC         4           /* slight misuse of mode_t */
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-/* --------------------------------------------------------------------- */
-
-struct es1370_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of es1370 devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_dac;
-       int dev_midi;
-       
-       /* hardware resources */
-       unsigned long io; /* long for SPARC */
-       unsigned int irq;
-
-       /* mixer registers; there is no HW readback */
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-               unsigned int imix;
-       } mix;
-
-       /* wave stuff */
-       unsigned ctrl;
-       unsigned sctrl;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac1, dma_dac2, dma_adc;
-
-       /* The following buffer is used to point the phantom write channel to. */
-       unsigned char *bugbuf_cpu;
-       dma_addr_t bugbuf_dma;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#ifdef SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-
-       struct mutex mutex;
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static void wrcodec(struct es1370_state *s, unsigned char idx, unsigned char data)
-{
-       unsigned long tmo = jiffies + HZ/10, j;
-       
-       do {
-               j = jiffies;
-               if (!(inl(s->io+ES1370_REG_STATUS) & STAT_CSTAT)) {
-                       outw((((unsigned short)idx)<<8)|data, s->io+ES1370_REG_CODEC);
-                       return;
-               }
-               schedule();
-       } while ((signed)(tmo-j) > 0);
-       printk(KERN_ERR "es1370: write to codec register timeout\n");
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_ADC_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac1(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC1_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac2(struct es1370_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl &= ~CTRL_DAC2_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac1(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0)
-           && s->dma_dac1.ready) {
-               s->ctrl |= CTRL_DAC1_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac1.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac2(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0)
-           && s->dma_dac2.ready) {
-               s->ctrl |= CTRL_DAC2_EN;
-               s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | 
-                                        SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN |
-                       (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | 
-                       (0 << SCTRL_SH_P2STINC);
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_dac2.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct es1370_state *s)
-{
-       unsigned long flags;
-       unsigned fragremain, fshift;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               s->ctrl |= CTRL_ADC_EN;
-               s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1));
-               fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT];
-               if (fragremain < 2*fshift)
-                       fragremain = s->dma_adc.fragsize;
-               outl((fragremain >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-               outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct es1370_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct es1370_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg)
-{
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       fmt &= ES1370_FMT_MASK;
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       memset(db->rawbuf, (fmt & ES1370_FMT_S16) ? 0 : 0x80, db->dmasize);
-       outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       outl(db->dmaaddr, s->io+(reg & 0xff));
-       outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff));
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct es1370_state *s)
-{
-       stop_adc(s);
-       return prog_dmabuf(s, &s->dma_adc, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-                          (s->sctrl >> SCTRL_SH_R1FMT) & ES1370_FMT_MASK, ES1370_REG_ADC_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac2(struct es1370_state *s)
-{
-       stop_dac2(s);
-       return prog_dmabuf(s, &s->dma_dac2, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV),
-                          (s->sctrl >> SCTRL_SH_P2FMT) & ES1370_FMT_MASK, ES1370_REG_DAC2_FRAMEADR);
-}
-
-static inline int prog_dmabuf_dac1(struct es1370_state *s)
-{
-       stop_dac1(s);
-       return prog_dmabuf(s, &s->dma_dac1, dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL],
-                          (s->sctrl >> SCTRL_SH_P1FMT) & ES1370_FMT_MASK, ES1370_REG_DAC1_FRAMEADR);
-}
-
-static inline unsigned get_hwptr(struct es1370_state *s, struct dmabuf *db, unsigned reg)
-{
-       unsigned hwptr, diff;
-
-       outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc;
-       diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize;
-       db->hwptr = hwptr;
-       return diff;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *)buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void es1370_update_ptr(struct es1370_state *s)
-{
-       int diff;
-
-       /* update ADC pointer */
-       if (s->ctrl & CTRL_ADC_EN) {
-               diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT);
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->ctrl &= ~CTRL_ADC_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC1 pointer */
-       if (s->ctrl & CTRL_DAC1_EN) {
-               diff = get_hwptr(s, &s->dma_dac1, ES1370_REG_DAC1_FRAMECNT);
-               s->dma_dac1.total_bytes += diff;
-               if (s->dma_dac1.mapped) {
-                       s->dma_dac1.count += diff;
-                       if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                               wake_up(&s->dma_dac1.wait);
-               } else {
-                       s->dma_dac1.count -= diff;
-                       if (s->dma_dac1.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC1_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_dac1.error++;
-                       } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) {
-                               clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, 
-                                             s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80);
-                               s->dma_dac1.endcleared = 1;
-                       }
-                       if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize)
-                               wake_up(&s->dma_dac1.wait);
-               }
-       }
-       /* update DAC2 pointer */
-       if (s->ctrl & CTRL_DAC2_EN) {
-               diff = get_hwptr(s, &s->dma_dac2, ES1370_REG_DAC2_FRAMECNT);
-               s->dma_dac2.total_bytes += diff;
-               if (s->dma_dac2.mapped) {
-                       s->dma_dac2.count += diff;
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize)
-                               wake_up(&s->dma_dac2.wait);
-               } else {
-                       s->dma_dac2.count -= diff;
-                       if (s->dma_dac2.count <= 0) {
-                               s->ctrl &= ~CTRL_DAC2_EN;
-                               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                               s->dma_dac2.error++;
-                       } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) {
-                               clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, 
-                                             s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80);
-                               s->dma_dac2.endcleared = 1;
-                       }
-                       if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize)
-                               wake_up(&s->dma_dac2.wait);
-               }
-       }
-}
-
-/* hold spinlock for the following! */
-static void es1370_handle_midi(struct es1370_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       if (!(s->ctrl & CTRL_UART_EN))
-               return;
-       wake = 0;
-       while (inb(s->io+ES1370_REG_UART_STATUS) & USTAT_RXRDY) {
-               ch = inb(s->io+ES1370_REG_UART_DATA);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while ((inb(s->io+ES1370_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->io+ES1370_REG_UART_DATA);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-       outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1370_REG_UART_CONTROL);
-}
-
-static irqreturn_t es1370_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct es1370_state *s = (struct es1370_state *)dev_id;
-       unsigned int intsrc, sctl;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inl(s->io+ES1370_REG_STATUS);
-       if (!(intsrc & 0x80000000))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       /* clear audio interrupts first */
-       sctl = s->sctrl;
-       if (intsrc & STAT_ADC)
-               sctl &= ~SCTRL_R1INTEN;
-       if (intsrc & STAT_DAC1)
-               sctl &= ~SCTRL_P1INTEN;
-       if (intsrc & STAT_DAC2)
-               sctl &= ~SCTRL_P2INTEN;
-       outl(sctl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       es1370_update_ptr(s);
-       es1370_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "es1370: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != ES1370_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static const struct {
-       unsigned volidx:4;
-       unsigned left:4;
-       unsigned right:4;
-       unsigned stereo:1;
-       unsigned recmask:13;
-       unsigned avail:1;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 },   /* master */
-       [SOUND_MIXER_PCM]    = { 1, 0x2, 0x3, 1, 0x0400, 1 },   /* voice */
-       [SOUND_MIXER_SYNTH]  = { 2, 0x4, 0x5, 1, 0x0060, 1 },   /* FM */
-       [SOUND_MIXER_CD]     = { 3, 0x6, 0x7, 1, 0x0006, 1 },   /* CD */
-       [SOUND_MIXER_LINE]   = { 4, 0x8, 0x9, 1, 0x0018, 1 },   /* Line */
-       [SOUND_MIXER_LINE1]  = { 5, 0xa, 0xb, 1, 0x1800, 1 },   /* AUX */
-       [SOUND_MIXER_LINE2]  = { 6, 0xc, 0x0, 0, 0x0100, 1 },   /* Mono1 */
-       [SOUND_MIXER_LINE3]  = { 7, 0xd, 0x0, 0, 0x0200, 1 },   /* Mono2 */
-       [SOUND_MIXER_MIC]    = { 8, 0xe, 0x0, 0, 0x0001, 1 },   /* Mic */
-       [SOUND_MIXER_OGAIN]  = { 9, 0xf, 0x0, 0, 0x0000, 1 }    /* mono out */
-};
-
-static void set_recsrc(struct es1370_state *s, unsigned int val)
-{
-       unsigned int i, j;
-
-       for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-               if (!(val & (1 << i)))
-                       continue;
-               if (!mixtable[i].recmask) {
-                       val &= ~(1 << i);
-                       continue;
-               }
-               j |= mixtable[i].recmask;
-       }
-       s->mix.recsrc = val;
-       wrcodec(s, 0x12, j & 0xd5);
-       wrcodec(s, 0x13, j & 0xaa);
-       wrcodec(s, 0x14, (j >> 8) & 0x17);
-       wrcodec(s, 0x15, (j >> 8) & 0x0f);
-       i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60;
-       if (!s->mix.imix) {
-               i &= 0xff60;  /* mute record and line monitor */
-       }
-       wrcodec(s, 0x10, i);
-       wrcodec(s, 0x11, i >> 8);
-}
-
-static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val;
-       unsigned char l, r, rl, rr;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               /* enable/disable/query mixer preamp */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       s->mix.micpreamp = !!val;
-                       wrcodec(s, 0x19, s->mix.micpreamp);
-               }
-               return put_user(s->mix.micpreamp, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               /* enable/disable/query use of linein as second lineout */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->ctrl |= CTRL_XCTL0;
-                       else
-                               s->ctrl &= ~CTRL_XCTL0;
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE3) {
-               /* enable/disable/query microphone impedance setting */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->ctrl |= CTRL_XCTL1;
-                       else
-                               s->ctrl &= ~CTRL_XCTL1;
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, p);
-       }
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strncpy(info.id, "ES1370", sizeof(info.id));
-               strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strncpy(info.id, "ES1370", sizeof(info.id));
-               strncpy(info.name, "Ensoniq ES1370", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(s->mix.recsrc, p);
-                       
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       val = SOUND_MASK_IMIX;
-                       for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].avail)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].recmask)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].stereo)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(0, p);
-               
-               case SOUND_MIXER_IMIX:
-                       return put_user(s->mix.imix, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-                                return -EINVAL;
-                       return put_user(s->mix.vol[mixtable[i].volidx], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-
-       case SOUND_MIXER_IMIX:
-               if (get_user(s->mix.imix, p))
-                       return -EFAULT;
-               set_recsrc(s, s->mix.recsrc);
-               return 0;
-
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               set_recsrc(s, val);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               if (mixtable[i].stereo) {
-                       r = (val >> 8) & 0xff;
-                       if (r > 100)
-                               r = 100;
-                       if (l < 7) {
-                               rl = 0x80;
-                               l = 0;
-                       } else {
-                               rl = 31 - ((l - 7) / 3);
-                               l = (31 - rl) * 3 + 7;
-                       }
-                       if (r < 7) {
-                               rr = 0x80;
-                               r = 0;
-                       } else {
-                               rr =  31 - ((r - 7) / 3);
-                               r = (31 - rr) * 3 + 7;
-                       }
-                       wrcodec(s, mixtable[i].right, rr);
-               } else { 
-                       if (mixtable[i].left == 15) {
-                               if (l < 2) {
-                                       rr = rl = 0x80;
-                                       r = l = 0;
-                               } else {
-                                       rl = 7 - ((l - 2) / 14);
-                                       r = l = (7 - rl) * 14 + 2;
-                               }
-                       } else {
-                               if (l < 7) {
-                                       rl = 0x80;
-                                       r = l = 0;
-                               } else {
-                                       rl = 31 - ((l - 7) / 3);
-                                       r = l = (31 - rl) * 3 + 7;
-                               }
-                       }
-               }
-               wrcodec(s, mixtable[i].left, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-               s->mix.vol[mixtable[i].volidx] = ((unsigned int)r << 8) | l;
-#else
-               s->mix.vol[mixtable[i].volidx] = val;
-#endif
-                return put_user(s->mix.vol[mixtable[i].volidx], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int es1370_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct es1370_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations es1370_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = es1370_ioctl_mixdev,
-       .open           = es1370_open_mixdev,
-       .release        = es1370_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac1(struct es1370_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-       
-       if (s->dma_dac1.mapped || !s->dma_dac1.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac1.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac1.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2
-                       / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL];
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-static int drain_dac2(struct es1370_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac2.mapped || !s->dma_dac2.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac2.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac2.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2
-                       / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV);
-               tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT];
-               if (!schedule_timeout(tmo + 1))
-                       DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");)
-        }
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->mutex);
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               goto out;
-        
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       mutex_unlock(&s->mutex);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;
-                       }
-                       mutex_lock(&s->mutex);
-                       if (s->dma_adc.mapped)
-                       {
-                               ret = -ENXIO;
-                               goto out;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-       }
-out:
-       mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac2.mapped)
-               return -ENXIO;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       mutex_lock(&s->mutex);
-       if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-               goto out;
-       ret = 0;
-        add_wait_queue(&s->dma_dac2.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac2.count < 0) {
-                       s->dma_dac2.count = 0;
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr;
-               }
-               swptr = s->dma_dac2.swptr;
-               cnt = s->dma_dac2.dmasize-swptr;
-               if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize)
-                       cnt = s->dma_dac2.dmasize - s->dma_dac2.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac2.enabled)
-                               start_dac2(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               goto out;
-                       }
-                       mutex_unlock(&s->mutex);
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               goto out;       
-                       }
-                       mutex_lock(&s->mutex);
-                       if (s->dma_dac2.mapped)
-                       {
-                       ret = -ENXIO;
-                       goto out;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       goto out;
-               }
-               swptr = (swptr + cnt) % s->dma_dac2.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac2.swptr = swptr;
-               s->dma_dac2.count += cnt;
-               s->dma_dac2.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac2.enabled)
-                       start_dac2(s);
-       }
-out:
-       mutex_unlock(&s->mutex);
-        remove_wait_queue(&s->dma_dac2.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac2.ready && prog_dmabuf_dac2(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac2.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       es1370_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac2.mapped) {
-                       if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = 0;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->mutex);
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac2(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_dac2;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0) {
-                       goto out;
-               }
-               db = &s->dma_adc;
-       } else  {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder)) {
-               ret = -EINVAL;
-               goto out;
-       }
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot)) {
-               ret = -EAGAIN;
-               goto out;
-       }
-       db->mapped = 1;
-out:
-       mutex_unlock(&s->mutex);
-       unlock_kernel();
-       return ret;
-}
-
-static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, mapped, ret;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-                               return -EINVAL;
-                       if (val < 4000)
-                               val = 4000;
-                       if (val > 50000)
-                               val = 50000;
-                       stop_adc(s);
-                       stop_dac2(s);
-                       s->dma_adc.ready = s->dma_dac2.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV);
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_R1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_R1SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac2(s);
-                       s->dma_dac2.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val)
-                               s->sctrl |= SCTRL_P2SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P2SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-                }
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_R1SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SMB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val >= 2)
-                                       s->sctrl |= SCTRL_P2SMB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SMB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_R1SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_R1SEB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac2(s);
-                               s->dma_dac2.ready = 0;
-                               spin_lock_irqsave(&s->lock, flags);
-                               if (val == AFMT_S16_LE)
-                                       s->sctrl |= SCTRL_P2SEB;
-                               else
-                                       s->sctrl &= ~SCTRL_P2SEB;
-                               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-               }
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               AFMT_S16_LE : AFMT_U8, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-                                       return ret;
-                               s->dma_dac2.enabled = 1;
-                               start_dac2(s);
-                       } else {
-                               s->dma_dac2.enabled = 0;
-                               stop_dac2(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_dac2.fragsize;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac2.dmasize - count;
-                abinfo.fragstotal = s->dma_dac2.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                count = s->dma_dac2.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac2.total_bytes;
-               count = s->dma_dac2.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac2.fragshift;
-                cinfo.ptr = s->dma_dac2.hwptr;
-               if (s->dma_dac2.mapped)
-                       s->dma_dac2.count &= s->dma_dac2.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac2(s)))
-                               return val;
-                       return put_user(s->dma_dac2.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac2.ossfragshift = val & 0xffff;
-                       s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac2.ossfragshift < 4)
-                               s->dma_dac2.ossfragshift = 4;
-                       if (s->dma_dac2.ossfragshift > 15)
-                               s->dma_dac2.ossfragshift = 15;
-                       if (s->dma_dac2.ossmaxfrags < 4)
-                               s->dma_dac2.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac2.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?
-                               2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 
-                               16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_READ|FMODE_WRITE)))
-               s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV);
-       if (file->f_mode & FMODE_READ) {
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               s->sctrl &= ~SCTRL_R1FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_R1FMT;
-               else
-                       s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_R1FMT;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0;
-               s->dma_dac2.enabled = 1;
-               s->sctrl &= ~SCTRL_P2FMT;
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P2FMT;
-               else
-                       s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P2FMT;
-       }
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       mutex_init(&s->mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac2(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac2(s);
-               synchronize_irq(s->irq);
-               dealloc_dmabuf(s, &s->dma_dac2);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1370_read,
-       .write          = es1370_write,
-       .poll           = es1370_poll,
-       .ioctl          = es1370_ioctl,
-       .mmap           = es1370_mmap,
-       .open           = es1370_open,
-       .release        = es1370_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret = 0;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac1.mapped)
-               return -ENXIO;
-       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-        add_wait_queue(&s->dma_dac1.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac1.count < 0) {
-                       s->dma_dac1.count = 0;
-                       s->dma_dac1.swptr = s->dma_dac1.hwptr;
-               }
-               swptr = s->dma_dac1.swptr;
-               cnt = s->dma_dac1.dmasize-swptr;
-               if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize)
-                       cnt = s->dma_dac1.dmasize - s->dma_dac1.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac1.enabled)
-                               start_dac1(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac1.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac1.swptr = swptr;
-               s->dma_dac1.count += cnt;
-               s->dma_dac1.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac1.enabled)
-                       start_dac1(s);
-       }
-        remove_wait_queue(&s->dma_dac1.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_poll_dac(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (!s->dma_dac1.ready && prog_dmabuf_dac1(s))
-               return 0;
-       poll_wait(file, &s->dma_dac1.wait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       es1370_update_ptr(s);
-       if (s->dma_dac1.mapped) {
-               if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       } else {
-               if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       int ret;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       if (!(vma->vm_flags & VM_WRITE))
-               return -EINVAL;
-       lock_kernel();
-       if ((ret = prog_dmabuf_dac1(s)) != 0)
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << s->dma_dac1.buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-               goto out;
-       s->dma_dac1.mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       unsigned ctrl;
-       int val, ret;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/);
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               stop_dac1(s);
-               synchronize_irq(s->irq);
-               s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0;
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       for (ctrl = 0; ctrl <= 2; ctrl++)
-                               if (val < (dac1_samplerate[ctrl] + dac1_samplerate[ctrl+1]) / 2)
-                                       break;
-                       spin_lock_irqsave(&s->lock, flags);
-                       s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (ctrl << CTRL_SH_WTSRSEL);
-                       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               stop_dac1(s);
-               s->dma_dac1.ready = 0;
-               spin_lock_irqsave(&s->lock, flags);
-               if (val)
-                       s->sctrl |= SCTRL_P1SMB;
-               else
-                       s->sctrl &= ~SCTRL_P1SMB;
-               outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       if (s->dma_dac1.mapped)
-                               return -EINVAL;
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val >= 2)
-                               s->sctrl |= SCTRL_P1SMB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SMB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-               
-        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       stop_dac1(s);
-                       s->dma_dac1.ready = 0;
-                       spin_lock_irqsave(&s->lock, flags);
-                       if (val == AFMT_S16_LE)
-                               s->sctrl |= SCTRL_P1SEB;
-                       else
-                               s->sctrl &= ~SCTRL_P1SEB;
-                       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p);
-
-        case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p);
-                                               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val & PCM_ENABLE_OUTPUT) {
-                       if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s)))
-                               return ret;
-                       s->dma_dac1.enabled = 1;
-                       start_dac1(s);
-               } else {
-                       s->dma_dac1.enabled = 0;
-                       stop_dac1(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-               abinfo.fragsize = s->dma_dac1.fragsize;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac1.dmasize - count;
-                abinfo.fragstotal = s->dma_dac1.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                count = s->dma_dac1.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_update_ptr(s);
-                cinfo.bytes = s->dma_dac1.total_bytes;
-               count = s->dma_dac1.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac1.fragshift;
-                cinfo.ptr = s->dma_dac1.hwptr;
-               if (s->dma_dac1.mapped)
-                       s->dma_dac1.count &= s->dma_dac1.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if ((val = prog_dmabuf_dac1(s)))
-                       return val;
-                return put_user(s->dma_dac1.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               s->dma_dac1.ossfragshift = val & 0xffff;
-               s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff;
-               if (s->dma_dac1.ossfragshift < 4)
-                       s->dma_dac1.ossfragshift = 4;
-               if (s->dma_dac1.ossfragshift > 15)
-                       s->dma_dac1.ossfragshift = 15;
-               if (s->dma_dac1.ossmaxfrags < 4)
-                       s->dma_dac1.ossmaxfrags = 4;
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if (s->dma_dac1.subdivision)
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               s->dma_dac1.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int es1370_open_dac(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (!((s->dev_dac ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-               /* we allow opening with O_RDWR, most programs do it although they will only write */
-#if 0
-       if (file->f_mode & FMODE_READ)
-               return -EPERM;
-#endif
-       if (!(file->f_mode & FMODE_WRITE))
-               return -EINVAL;
-               file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DAC) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
-       s->dma_dac1.enabled = 1;
-       spin_lock_irqsave(&s->lock, flags);
-       s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (1 << CTRL_SH_WTSRSEL);
-       s->sctrl &= ~SCTRL_P1FMT;
-       if ((minor & 0xf) == SND_DEV_DSP16)
-               s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P1FMT;
-       else
-               s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P1FMT;
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= FMODE_DAC;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_release_dac(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       drain_dac1(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       stop_dac1(s);
-       dealloc_dmabuf(s, &s->dma_dac1);
-       s->open_mode &= ~FMODE_DAC;
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_dac_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = es1370_write_dac,
-       .poll           = es1370_poll_dac,
-       .ioctl          = es1370_ioctl_dac,
-       .mmap           = es1370_mmap_dac,
-       .open           = es1370_open_dac,
-       .release        = es1370_release_dac,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t es1370_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t es1370_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       es1370_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               es1370_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-        remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int es1370_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int es1370_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct es1370_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct es1370_state, devs);
-               if (s->dev_midi == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               outb(UCTRL_CNTRL_SWR, s->io+ES1370_REG_UART_CONTROL);
-               outb(0, s->io+ES1370_REG_UART_CONTROL);
-               outb(0, s->io+ES1370_REG_UART_TEST);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       s->ctrl |= CTRL_UART_EN;
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       es1370_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int es1370_midi_release(struct inode *inode, struct file *file)
-{
-       struct es1370_state *s = (struct es1370_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) 
-                               break;
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");)
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->ctrl &= ~CTRL_UART_EN;
-               outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations es1370_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = es1370_midi_read,
-       .write          = es1370_midi_write,
-       .poll           = es1370_midi_poll,
-       .open           = es1370_midi_open,
-       .release        = es1370_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int lineout[NR_DEVICE];
-static int micbias[NR_DEVICE];
-
-static unsigned int devindex;
-
-module_param_array(lineout, bool, NULL, 0);
-MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out");
-module_param_array(micbias, bool, NULL, 0);
-MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone");
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ES1370 AudioPCI Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE3, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 },
-       { SOUND_MIXER_WRITE_OGAIN, 0x4040 }
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static int __devinit es1370_register_gameport(struct es1370_state *s)
-{
-       struct gameport *gp;
-
-       if (!request_region(0x200, JOY_EXTENT, "es1370")) {
-               printk(KERN_ERR "es1370: joystick io port 0x200 in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "es1370: can not allocate memory for gameport\n");
-               release_region(0x200, JOY_EXTENT);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "ESS1370");
-       gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-       gp->dev.parent = &s->dev->dev;
-       gp->io = 0x200;
-
-       s->ctrl |= CTRL_JYSTK_EN;
-       outl(s->ctrl, s->io + ES1370_REG_CONTROL);
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void es1370_unregister_gameport(struct es1370_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, JOY_EXTENT);
-
-       }
-}
-
-#else
-static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; }
-static inline void es1370_unregister_gameport(struct es1370_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct es1370_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-
-       if ( !(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-            !pci_resource_start(pcidev, 0)
-       )
-               return -ENODEV;
-       if (pcidev->irq == 0) 
-               return -ENODEV;
-       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-       if (i) {
-               printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
-               return i;
-       }
-       if (!(s = kmalloc(sizeof(struct es1370_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "es1370: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct es1370_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac1.wait);
-       init_waitqueue_head(&s->dma_dac2.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = ES1370_MAGIC;
-       s->dev = pcidev;
-       s->io = pci_resource_start(pcidev, 0);
-       s->irq = pcidev->irq;
-       if (!request_region(s->io, ES1370_EXTENT, "es1370")) {
-               printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
-               ret = -EBUSY;
-               goto err_region;
-       }
-       if ((ret=request_irq(s->irq, es1370_interrupt, IRQF_SHARED, "es1370",s))) {
-               printk(KERN_ERR "es1370: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-
-       /* initialize codec registers */
-       /* note: setting CTRL_SERR_DIS is reported to break
-        * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */
-       s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
-       if (lineout[devindex])
-               s->ctrl |= CTRL_XCTL0;
-       if (micbias[devindex])
-               s->ctrl |= CTRL_XCTL1;
-       s->sctrl = 0;
-       printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n",
-              s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in",
-              (s->ctrl & CTRL_XCTL1) ? "1" : "0");
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops, -1)) < 0) {
-               ret = s->dev_dac;
-               goto err_dev3;
-       }
-       if ((s->dev_midi = register_sound_midi(&es1370_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev4;
-       }
-       /* initialize the chips */
-       outl(s->ctrl, s->io+ES1370_REG_CONTROL);
-       outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL);
-       /* point phantom write channel to "bugbuf" */
-       s->bugbuf_cpu = pci_alloc_consistent(pcidev,16,&s->bugbuf_dma);
-       if (!s->bugbuf_cpu) {
-               ret = -ENOMEM;
-               goto err_dev5;
-       }
-       outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE);
-       outl(s->bugbuf_dma, s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff));
-       outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff));
-       pci_set_master(pcidev);  /* enable bus mastering */
-       wrcodec(s, 0x16, 3); /* no RST, PD */
-       wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!!  */
-       wrcodec(s, 0x18, 0); /* recording source is mixer */
-       wrcodec(s, 0x19, s->mix.micpreamp = 1); /* turn on MIC preamp */
-       s->mix.imix = 1;
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-
-       es1370_register_gameport(s);
-
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_dev5:
-       unregister_sound_midi(s->dev_midi);
- err_dev4:
-       unregister_sound_dsp(s->dev_dac);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "es1370: cannot register misc device\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->io, ES1370_EXTENT);
- err_region:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit es1370_remove(struct pci_dev *dev)
-{
-       struct es1370_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-       outl(CTRL_SERR_DIS | (1 << CTRL_SH_WTSRSEL), s->io+ES1370_REG_CONTROL); /* switch everything off */
-       outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */
-       synchronize_irq(s->irq);
-       free_irq(s->irq, s);
-       es1370_unregister_gameport(s);
-       release_region(s->io, ES1370_EXTENT);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_dsp(s->dev_dac);
-       unregister_sound_midi(s->dev_midi);
-       pci_free_consistent(dev, 16, s->bugbuf_cpu, s->bugbuf_dma);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver es1370_driver = {
-       .name           = "es1370",
-       .id_table       = id_table,
-       .probe          = es1370_probe,
-       .remove         = __devexit_p(es1370_remove),
-};
-
-static int __init init_es1370(void)
-{
-       printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&es1370_driver);
-}
-
-static void __exit cleanup_es1370(void)
-{
-       printk(KERN_INFO "es1370: unloading\n");
-       pci_unregister_driver(&es1370_driver);
-}
-
-module_init(init_es1370);
-module_exit(cleanup_es1370);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: es1370=lineout[,micbias]] */
-
-static int __init es1370_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-
-       (void)
-       ((get_option(&str,&lineout [nr_dev]) == 2)
-        && get_option(&str,&micbias [nr_dev])
-       );
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("es1370=", es1370_setup);
-
-#endif /* MODULE */
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
deleted file mode 100644 (file)
index 82f40a0..0000000
+++ /dev/null
@@ -1,2516 +0,0 @@
-/****************************************************************************/
-
-/*
- *      esssolo1.c  --  ESS Technology Solo1 (ES1946) audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Module command line parameters:
- *   none so far
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  Revision history
- *    10.11.1998   0.1   Initial release (without any hardware)
- *    22.03.1999   0.2   cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *                       return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    07.04.1999   0.3   implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *    15.06.1999   0.4   Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.5   Add pci_set_master
- *    12.08.1999   0.6   Fix MIDI UART crashing the driver
- *                       Changed mixer semantics from OSS documented
- *                       behaviour to OSS "code behaviour".
- *                       Recording might actually work now.
- *                       The real DDMA controller address register is at PCI config
- *                       0x60, while the register at 0x18 is used as a placeholder
- *                       register for BIOS address allocation. This register
- *                       is supposed to be copied into 0x60, according
- *                       to the Solo1 datasheet. When I do that, I can access
- *                       the DDMA registers except the mask bit, which
- *                       is stuck at 1. When I copy the contents of 0x18 +0x10
- *                       to the DDMA base register, everything seems to work.
- *                       The fun part is that the Windows Solo1 driver doesn't
- *                       seem to do these tricks.
- *                       Bugs remaining: plops and clicks when starting/stopping playback
- *    31.08.1999   0.7   add spin_lock_init
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.8   change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    07.10.1999   0.9   Fix initialization; complain if sequencer writes time out
- *                       Revised resource grabbing for the FM synthesizer
- *    28.10.1999   0.10  More waitqueue races fixed
- *    09.12.1999   0.11  Work around stupid Alpha port issue (virt_to_bus(kmalloc(GFP_DMA)) > 16M)
- *                       Disabling recording on Alpha
- *    12.01.2000   0.12  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       Integrated (aka redid 8-)) APM support patch by Zach Brown
- *    07.02.2000   0.13  Use pci_alloc_consistent and pci_register_driver
- *    19.02.2000   0.14  Use pci_dma_supported to determine if recording should be disabled
- *    13.03.2000   0.15  Reintroduce initialization of a couple of PCI config space registers
- *    21.11.2000   0.16  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.17  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.18  Register/Unregister gameport, original patch from
- *                       Nathaniel Daw <daw@cs.cmu.edu>
- *                       Fix SETTRIGGER non OSS API conformity
- *    10.03.2001         provide abs function, prevent picking up a bogus kernel macro
- *                       for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
- *    15.05.2001         pci_enable_device moved, return values in probe cleaned
- *                       up. Marcus Meissner <mm@caldera.de>
- *    22.05.2001   0.19  more cleanups, changed PM to PCI 2.4 style, got rid
- *                       of global list of devices, using pci device data.
- *                       Marcus Meissner <mm@caldera.de>
- *    03.01.2003   0.20  open_mode fixes from Georg Acher <acher@in.tum.de>
- */
-
-/*****************************************************************************/
-      
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/wait.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_ESS
-#define PCI_VENDOR_ID_ESS         0x125d
-#endif
-#ifndef PCI_DEVICE_ID_ESS_SOLO1
-#define PCI_DEVICE_ID_ESS_SOLO1   0x1969
-#endif
-
-#define SOLO1_MAGIC  ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1)
-
-#define DDMABASE_OFFSET           0    /* chip bug workaround kludge */
-#define DDMABASE_EXTENT           16
-
-#define IOBASE_EXTENT             16
-#define SBBASE_EXTENT             16
-#define VCBASE_EXTENT             (DDMABASE_EXTENT+DDMABASE_OFFSET)
-#define MPUBASE_EXTENT            4
-#define GPBASE_EXTENT             4
-#define GAMEPORT_EXTENT                  4
-
-#define FMSYNTH_EXTENT            4
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 3
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static struct pci_driver solo1_driver;
-
-/* --------------------------------------------------------------------- */
-
-struct solo1_state {
-       /* magic */
-       unsigned int magic;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-       int dev_dmfm;
-
-       /* hardware resources */
-       unsigned long iobase, sbbase, vcbase, ddmabase, mpubase; /* long for SPARC */
-       unsigned int irq;
-
-       /* mixer registers */
-       struct {
-               unsigned short vol[10];
-               unsigned int recsrc;
-               unsigned int modcnt;
-               unsigned short micpreamp;
-       } mix;
-
-       /* wave stuff */
-       unsigned fmt;
-       unsigned channels;
-       unsigned rate;
-       unsigned char clkdiv;
-       unsigned ena;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#if SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static inline void write_seq(struct solo1_state *s, unsigned char data)
-{
-        int i;
-       unsigned long flags;
-
-       /* the local_irq_save stunt is to send the data within the command window */
-        for (i = 0; i < 0xffff; i++) {
-               local_irq_save(flags);
-                if (!(inb(s->sbbase+0xc) & 0x80)) {
-                        outb(data, s->sbbase+0xc);
-                       local_irq_restore(flags);
-                        return;
-                }
-               local_irq_restore(flags);
-       }
-       printk(KERN_ERR "esssolo1: write_seq timeout\n");
-       outb(data, s->sbbase+0xc);
-}
-
-static inline int read_seq(struct solo1_state *s, unsigned char *data)
-{
-        int i;
-
-        if (!data)
-                return 0;
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80) {
-                        *data = inb(s->sbbase+0xa);
-                        return 1;
-                }
-       printk(KERN_ERR "esssolo1: read_seq timeout\n");
-        return 0;
-}
-
-static inline int reset_ctrl(struct solo1_state *s)
-{
-        int i;
-
-        outb(3, s->sbbase+6); /* clear sequencer and FIFO */
-        udelay(10);
-        outb(0, s->sbbase+6);
-        for (i = 0; i < 0xffff; i++)
-                if (inb(s->sbbase+0xe) & 0x80)
-                        if (inb(s->sbbase+0xa) == 0xaa) {
-                               write_seq(s, 0xc6); /* enter enhanced mode */
-                                return 1;
-                       }
-        return 0;
-}
-
-static void write_ctrl(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-       write_seq(s, reg);
-       write_seq(s, data);
-}
-
-#if 0 /* unused */
-static unsigned char read_ctrl(struct solo1_state *s, unsigned char reg)
-{
-        unsigned char r;
-
-       write_seq(s, 0xc0);
-       write_seq(s, reg);
-       read_seq(s, &r);
-       return r;
-}
-#endif /* unused */
-
-static void write_mixer(struct solo1_state *s, unsigned char reg, unsigned char data)
-{
-       outb(reg, s->sbbase+4);
-       outb(data, s->sbbase+5);
-}
-
-static unsigned char read_mixer(struct solo1_state *s, unsigned char reg)
-{
-       outb(reg, s->sbbase+4);
-       return inb(s->sbbase+5);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_dac(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_WRITE;
-       write_mixer(s, 0x78, 0x10);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_dac(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               s->ena |= FMODE_WRITE;
-               write_mixer(s, 0x78, 0x12);
-               udelay(10);
-               write_mixer(s, 0x78, 0x13);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_adc(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->ena &= ~FMODE_READ;
-       write_ctrl(s, 0xb8, 0xe);
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-static void start_adc(struct solo1_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
-           && s->dma_adc.ready) {
-               s->ena |= FMODE_READ;
-               write_ctrl(s, 0xb8, 0xf);
-#if 0
-               printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf);
-               printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x  stat: 0x%02x\n", 
-                      inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8));
-#endif
-                outb(0, s->ddmabase+0xd); /* master reset */
-               outb(1, s->ddmabase+0xf);  /* mask */
-               outb(0x54/*0x14*/, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-               outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase);
-               outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-               outb(0, s->ddmabase+0xf);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-       printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x  SBstat: 0x%02x\n"
-              KERN_DEBUG "solo1: DMA: stat: 0x%02x  cnt: 0x%04x  mask: 0x%02x\n", 
-              read_ctrl(s, 0xb8), inb(s->sbbase+0xc), 
-              inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf));
-       printk(KERN_DEBUG "solo1: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"  
-              KERN_DEBUG "solo1: B1: 0x%02x  B2: 0x%02x  B4: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n",
-              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb4), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), 
-              read_ctrl(s, 0xb9));
-#endif
-}
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static inline void dealloc_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-static int prog_dmabuf(struct solo1_state *s, struct dmabuf *db)
-{
-       int order;
-       unsigned bytespersec;
-       unsigned bufs, sample_shift = 0;
-       struct page *page, *pend;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-                for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               sample_shift++;
-       if (s->channels > 1)
-               sample_shift++;
-       bytespersec = s->rate << sample_shift;
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytespersec)
-                       db->fragshift = ld2(bytespersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytespersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift;
-       db->dmasize = db->numfrag << db->fragshift;
-       db->enabled = 1;
-       return 0;
-}
-
-static inline int prog_dmabuf_adc(struct solo1_state *s)
-{
-       unsigned long va;
-       int c;
-
-       stop_adc(s);
-       /* check if PCI implementation supports 24bit busmaster DMA */
-       if (s->dev->dma_mask > 0xffffff)
-               return -EIO;
-       if ((c = prog_dmabuf(s, &s->dma_adc)))
-               return c;
-       va = s->dma_adc.dmaaddr;
-       if ((va & ~((1<<24)-1)))
-               panic("solo1: buffer above 16M boundary");
-       outb(0, s->ddmabase+0xd);  /* clear */
-       outb(1, s->ddmabase+0xf); /* mask */
-       /*outb(0, s->ddmabase+8);*/  /* enable (enable is active low!) */
-       outb(0x54, s->ddmabase+0xb);  /* DMA_MODE_READ | DMA_MODE_AUTOINIT */
-       outl(va, s->ddmabase);
-       outw(s->dma_adc.dmasize-1, s->ddmabase+4);
-       c = - s->dma_adc.fragsamples;
-       write_ctrl(s, 0xa4, c);
-       write_ctrl(s, 0xa5, c >> 8);
-       outb(0, s->ddmabase+0xf);
-       s->dma_adc.ready = 1;
-       return 0;
-}
-
-static int prog_dmabuf_dac(struct solo1_state *s)
-{
-       unsigned long va;
-       int c;
-
-       stop_dac(s);
-       if ((c = prog_dmabuf(s, &s->dma_dac)))
-               return c;
-       memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80, s->dma_dac.dmasize); /* almost correct for U16 */
-       va = s->dma_dac.dmaaddr;
-       if ((va ^ (va + s->dma_dac.dmasize - 1)) & ~((1<<20)-1))
-               panic("solo1: buffer crosses 1M boundary");
-       outl(va, s->iobase);
-       /* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */
-       outw(s->dma_dac.dmasize, s->iobase+4);
-       c = - s->dma_dac.fragsamples;
-       write_mixer(s, 0x74, c);
-       write_mixer(s, 0x76, c >> 8);
-       outb(0xa, s->iobase+6);
-       s->dma_dac.ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
-{
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(((char *)buf) + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(((char *)buf) + bptr, c, len);
-}
-
-/* call with spinlock held! */
-
-static void solo1_update_ptr(struct solo1_state *s)
-{
-       int diff;
-       unsigned hwptr;
-
-       /* update ADC pointer */
-       if (s->ena & FMODE_READ) {
-               hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize;
-                diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-                s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-#if 0
-               printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n",
-                      s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count);
-#endif
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               wake_up(&s->dma_adc.wait);
-               } else {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->ena &= ~FMODE_READ;
-                               write_ctrl(s, 0xb8, 0xe);
-                               s->dma_adc.error++;
-                       }
-                       if (s->dma_adc.count > 0)
-                               wake_up(&s->dma_adc.wait);
-               }
-       }
-       /* update DAC pointer */
-       if (s->ena & FMODE_WRITE) {
-                hwptr = (s->dma_dac.dmasize - inw(s->iobase+4)) % s->dma_dac.dmasize;
-                diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-                s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-#if 0
-               printk(KERN_DEBUG "solo1: wr: hwptr %u swptr %u dmasize %u count %u\n",
-                      s->dma_dac.hwptr, s->dma_dac.swptr, s->dma_dac.dmasize, s->dma_dac.count);
-#endif
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               s->ena &= ~FMODE_WRITE;
-                               write_mixer(s, 0x78, 0x12);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s->dma_dac.rawbuf, s->dma_dac.dmasize, s->dma_dac.swptr,
-                                             s->dma_dac.fragsize, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static void prog_codec(struct solo1_state *s)
-{
-       unsigned long flags;
-       int fdiv, filter;
-       unsigned char c;
-
-       reset_ctrl(s);
-       write_seq(s, 0xd3);
-       /* program sampling rates */
-       filter = s->rate * 9 / 20; /* Set filter roll-off to 90% of rate/2 */
-       fdiv = 256 - 7160000 / (filter * 82);
-       spin_lock_irqsave(&s->lock, flags);
-       write_ctrl(s, 0xa1, s->clkdiv);
-       write_ctrl(s, 0xa2, fdiv);
-       write_mixer(s, 0x70, s->clkdiv);
-       write_mixer(s, 0x72, fdiv);
-       /* program ADC parameters */
-       write_ctrl(s, 0xb8, 0xe);
-       write_ctrl(s, 0xb9, /*0x1*/0);
-       write_ctrl(s, 0xa8, (s->channels > 1) ? 0x11 : 0x12);
-       c = 0xd0;
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               c |= 0x04;
-       if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-               c |= 0x20;
-       if (s->channels > 1)
-               c ^= 0x48;
-       write_ctrl(s, 0xb7, (c & 0x70) | 1);
-       write_ctrl(s, 0xb7, c);
-       write_ctrl(s, 0xb1, 0x50);
-       write_ctrl(s, 0xb2, 0x50);
-       /* program DAC parameters */
-       c = 0x40;
-       if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-               c |= 1;
-       if (s->fmt & (AFMT_S16_LE | AFMT_S8))
-               c |= 4;
-       if (s->channels > 1)
-               c |= 2;
-       write_mixer(s, 0x7a, c);
-       write_mixer(s, 0x78, 0x10);
-       s->ena = 0;
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "solo1: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != SOLO1_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned int mixer_src[8] = {
-               SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME,
-               SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0
-       };
-       static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
-               [SOUND_MIXER_PCM]     = 1,   /* voice */
-               [SOUND_MIXER_SYNTH]   = 2,   /* FM */
-               [SOUND_MIXER_CD]      = 3,   /* CD */
-               [SOUND_MIXER_LINE]    = 4,   /* Line */
-               [SOUND_MIXER_LINE1]   = 5,   /* AUX */
-               [SOUND_MIXER_MIC]     = 6,   /* Mic */
-               [SOUND_MIXER_LINE2]   = 7,   /* Mono in */
-               [SOUND_MIXER_SPEAKER] = 8,   /* Speaker */
-               [SOUND_MIXER_RECLEV]  = 9,   /* Recording level */
-               [SOUND_MIXER_VOLUME]  = 10   /* Master Volume */
-       };
-       static const unsigned char mixreg[] = {
-               0x7c,   /* voice */
-               0x36,   /* FM */
-               0x38,   /* CD */
-               0x3e,   /* Line */
-               0x3a,   /* AUX */
-               0x1a,   /* Mic */
-               0x6d    /* Mono in */
-       };
-       unsigned char l, r, rl, rr, vidx;
-       int i, val;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               /* enable/disable/query mixer preamp */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       val = val ? 0xff : 0xf7;
-                       write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val);
-               }
-               val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0;
-               return put_user(val, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               /* enable/disable/query spatializer */
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != -1) {
-                       val &= 0x3f;
-                       write_mixer(s, 0x52, val);
-                       write_mixer(s, 0x50, val ? 0x08 : 0);
-               }
-               return put_user(read_mixer(s, 0x52), p);
-       }
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               strncpy(info.id, "Solo1", sizeof(info.id));
-               strncpy(info.name, "ESS Solo1", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               strncpy(info.id, "Solo1", sizeof(info.id));
-               strncpy(info.name, "ESS Solo1", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(mixer_src[read_mixer(s, 0x1c) & 7], p);
-
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-                                       SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV |
-                                       SOUND_MASK_SPEAKER, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, p);
-
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
-                                       SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
-                                       SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                                return -EINVAL;
-                       return put_user(s->mix.vol[vidx-1], p);
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-#if 0
-               {
-                       static const unsigned char regs[] = {
-                               0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c
-                       };
-                       int i;
-                       
-                       for (i = 0; i < sizeof(regs); i++)
-                               printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n",
-                                      regs[i], read_mixer(s, regs[i]));
-                       printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n",
-                              0xb4, read_ctrl(s, 0xb4));
-               }
-#endif
-               if (get_user(val, p))
-                       return -EFAULT;
-                i = hweight32(val);
-                if (i == 0)
-                        return 0;
-                else if (i > 1) 
-                        val &= ~mixer_src[read_mixer(s, 0x1c) & 7];
-               for (i = 0; i < 8; i++) {
-                       if (mixer_src[i] & val)
-                               break;
-               }
-               if (i > 7)
-                       return 0;
-               write_mixer(s, 0x1c, i);
-               return 0;
-
-       case SOUND_MIXER_VOLUME:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               r = (val >> 8) & 0xff;
-               if (r > 100)
-                       r = 100;
-               if (l < 6) {
-                       rl = 0x40;
-                       l = 0;
-               } else {
-                       rl = (l * 2 - 11) / 3;
-                       l = (rl * 3 + 11) / 2;
-               }
-               if (r < 6) {
-                       rr = 0x40;
-                       r = 0;
-               } else {
-                       rr = (r * 2 - 11) / 3;
-                       r = (rr * 3 + 11) / 2;
-               }
-               write_mixer(s, 0x60, rl);
-               write_mixer(s, 0x62, rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[9] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[9] = val;
-#endif
-               return put_user(s->mix.vol[9], p);
-
-       case SOUND_MIXER_SPEAKER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               if (l > 100)
-                       l = 100;
-               else if (l < 2)
-                       l = 2;
-               rl = (l - 2) / 14;
-               l = rl * 14 + 2;
-               write_mixer(s, 0x3c, rl);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[7] = l * 0x101;
-#else
-                s->mix.vol[7] = val;
-#endif
-               return put_user(s->mix.vol[7], p);
-
-       case SOUND_MIXER_RECLEV:
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = (val << 1) & 0x1fe;
-               if (l > 200)
-                       l = 200;
-               else if (l < 5)
-                       l = 5;
-               r = (val >> 7) & 0x1fe;
-               if (r > 200)
-                       r = 200;
-               else if (r < 5)
-                       r = 5;
-               rl = (l - 5) / 13;
-               rr = (r - 5) / 13;
-               r = (rl * 13 + 5) / 2;
-               l = (rr * 13 + 5) / 2;
-               write_ctrl(s, 0xb4, (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[8] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[8] = val;
-#endif
-               return put_user(s->mix.vol[8], p);
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = (val << 1) & 0x1fe;
-               if (l > 200)
-                       l = 200;
-               else if (l < 5)
-                       l = 5;
-               r = (val >> 7) & 0x1fe;
-               if (r > 200)
-                       r = 200;
-               else if (r < 5)
-                       r = 5;
-               rl = (l - 5) / 13;
-               rr = (r - 5) / 13;
-               r = (rl * 13 + 5) / 2;
-               l = (rr * 13 + 5) / 2;
-               write_mixer(s, mixreg[vidx-1], (rl << 4) | rr);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
-#else
-                s->mix.vol[vidx-1] = val;
-#endif
-               return put_user(s->mix.vol[vidx-1], p);
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-               drvr = pci_dev_driver (pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_mixer == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct solo1_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations solo1_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = solo1_ioctl_mixdev,
-       .open           = solo1_open_mixdev,
-       .release        = solo1_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct solo1_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count;
-       unsigned tmo;
-       
-       if (s->dma_dac.mapped)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
-               if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
-                       tmo >>= 1;
-               if (s->channels > 1)
-                       tmo >>= 1;
-                if (!schedule_timeout(tmo + 1))
-                        printk(KERN_DEBUG "solo1: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-       add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-#ifdef DEBUGREC
-               printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x  cnt: %u\n", 
-                      read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt);
-#endif
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-#ifdef DEBUGREC
-                       printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-                              KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-                              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-                              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-                              inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-                       if (inb(s->ddmabase+15) & 1)
-                               printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-#ifdef DEBUGREC
-                       printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x  A2: 0x%02x  A4: 0x%02x  A5: 0x%02x  A8: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: regs: B1: 0x%02x  B2: 0x%02x  B7: 0x%02x  B8: 0x%02x  B9: 0x%02x\n"
-                              KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n"  
-                              KERN_DEBUG "solo1_read: SBstat: 0x%02x  cnt: %u\n",
-                              read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), 
-                              read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), 
-                              inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt);
-#endif
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-#ifdef DEBUGREC
-               printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x  DMAstat: 0x%02x  DMAcnt: 0x%04x  SBstat: 0x%02x\n", 
-                      read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc));
-#endif
-       }
-       remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t solo1_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-#if 0
-       printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x  71: 0x%02x  72: 0x%02x  74: 0x%02x  76: 0x%02x  78: 0x%02x  7A: 0x%02x\n"
-              KERN_DEBUG "solo1_write: DMA: addr: 0x%08x  cnt: 0x%04x  stat: 0x%02x  SBstat: 0x%02x\n", 
-              read_mixer(s, 0x70), read_mixer(s, 0x71), read_mixer(s, 0x72), read_mixer(s, 0x74), read_mixer(s, 0x76),
-              read_mixer(s, 0x78), read_mixer(s, 0x7a), inl(s->iobase), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-       printk(KERN_DEBUG "solo1_write: reg 78: 0x%02x  reg 7A: 0x%02x  DMAcnt: 0x%04x  DMAstat: 0x%02x  SBstat: 0x%02x\n", 
-              read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc));
-#endif
-       ret = 0;
-       add_wait_queue(&s->dma_dac.wait, &wait);        
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-       remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf_dac(s))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf_adc(s))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       solo1_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.mapped) {
-                       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                               mask |= POLLIN | POLLRDNORM;
-               } else {
-                       if (s->dma_adc.count > 0)
-                               mask |= POLLIN | POLLRDNORM;
-               }
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize > s->dma_dac.count)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-
-static int solo1_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf_dac(s)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf_adc(s)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else 
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret, count;
-        int div1, div2;
-        unsigned rate1, rate2;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               prog_codec(s);
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program sampling rates */
-                       if (val > 48000)
-                               val = 48000;
-                       if (val < 6300)
-                               val = 6300;
-                       div1 = (768000 + val / 2) / val;
-                       rate1 = (768000 + div1 / 2) / div1;
-                       div1 = -div1;
-                       div2 = (793800 + val / 2) / val;
-                       rate2 = (793800 + div2 / 2) / div2;
-                       div2 = (-div2) & 0x7f;
-                       if (abs(val - rate2) < abs(val - rate1)) {
-                               rate1 = rate2;
-                               div1 = div2;
-                       }
-                       s->rate = rate1;
-                       s->clkdiv = div1;
-                       prog_codec(s);
-               }
-               return put_user(s->rate, p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               stop_adc(s);
-               stop_dac(s);
-               s->dma_adc.ready = s->dma_dac.ready = 0;
-               /* program channels */
-               s->channels = val ? 2 : 1;
-               prog_codec(s);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program channels */
-                       s->channels = (val >= 2) ? 2 : 1;
-                       prog_codec(s);
-               }
-               return put_user(s->channels, p);
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       stop_adc(s);
-                       stop_dac(s);
-                       s->dma_adc.ready = s->dma_dac.ready = 0;
-                       /* program format */
-                       if (val != AFMT_S16_LE && val != AFMT_U16_LE && 
-                           val != AFMT_S8 && val != AFMT_U8)
-                               val = AFMT_U8;
-                       s->fmt = val;
-                       prog_codec(s);
-               }
-               return put_user(s->fmt, p);
-
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & s->ena & FMODE_READ)
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & s->ena & FMODE_WRITE)
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_adc(s);
-                               if (inb(s->ddmabase+15) & 1)
-                                       printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n");
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-#if 0
-               printk(KERN_DEBUG "esssolo1: GETOPTR: bytes %u blocks %u ptr %u, buforder %u numfrag %u fragshift %u\n"
-                      KERN_DEBUG "esssolo1: swptr %u count %u fragsize %u dmasize %u fragsamples %u\n",
-                      cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
-                      s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
-#endif
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf_dac(s)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf_adc(s)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user(s->channels, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int solo1_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               outb(0, s->iobase+6);  /* disable DMA */
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               outb(1, s->ddmabase+0xf); /* mask DMA channel */
-               outb(0, s->ddmabase+0xd); /* DMA master clear */
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static int solo1_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-       
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       s->fmt = AFMT_U8;
-       s->channels = 1;
-       s->rate = 8000;
-       s->clkdiv = 96 | 0x80;
-       s->ena = 0;
-       s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-       s->dma_adc.enabled = 1;
-       s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-       s->dma_dac.enabled = 1;
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       prog_codec(s);
-       return nonseekable_open(inode, file);
-}
-
-static /*const*/ struct file_operations solo1_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = solo1_read,
-       .write          = solo1_write,
-       .poll           = solo1_poll,
-       .ioctl          = solo1_ioctl,
-       .mmap           = solo1_mmap,
-       .open           = solo1_open,
-       .release        = solo1_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* hold spinlock for the following! */
-static void solo1_handle_midi(struct solo1_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       if (!(s->mpubase))
-               return;
-       wake = 0;
-       while (!(inb(s->mpubase+1) & 0x80)) {
-               ch = inb(s->mpubase);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->mpubase);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-static irqreturn_t solo1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct solo1_state *s = (struct solo1_state *)dev_id;
-       unsigned int intsrc;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inb(s->iobase+7); /* get interrupt source(s) */
-       if (!intsrc)
-               return IRQ_NONE;
-       (void)inb(s->sbbase+0xe);  /* clear interrupt */
-       spin_lock(&s->lock);
-       /* clear audio interrupts first */
-       if (intsrc & 0x20)
-               write_mixer(s, 0x7a, read_mixer(s, 0x7a) & 0x7f);
-       solo1_update_ptr(s);
-       solo1_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-static void solo1_midi_timer(unsigned long data)
-{
-       struct solo1_state *s = (struct solo1_state *)data;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&s->lock, flags);
-       solo1_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies+1;
-       add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t solo1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-       add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t solo1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       solo1_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               solo1_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int solo1_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_flags & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_flags & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_flags & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_flags & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int solo1_midi_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_midi == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               outb(0xff, s->mpubase+1); /* reset command */
-               outb(0x3f, s->mpubase+1); /* uart command */
-               if (!(inb(s->mpubase+1) & 0x80))
-                       inb(s->mpubase);
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               outb(0xb0, s->iobase + 7); /* enable A1, A2, MPU irq's */
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies+1;
-               s->midi.timer.data = (unsigned long)s;
-               s->midi.timer.function = solo1_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_midi_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK)
-                               break;
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG "solo1: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               outb(0x30, s->iobase + 7); /* enable A1, A2 irq's */
-               del_timer(&s->midi.timer);              
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations solo1_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = solo1_midi_read,
-       .write          = solo1_midi_write,
-       .poll           = solo1_midi_poll,
-       .open           = solo1_midi_open,
-       .release        = solo1_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned char op_offset[18] = {
-               0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-               0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-               0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-       };
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       struct dm_fm_voice v;
-       struct dm_fm_note n;
-       struct dm_fm_params p;
-       unsigned int io;
-       unsigned int regb;
-
-       switch (cmd) {          
-       case FM_IOCTL_RESET:
-               for (regb = 0xb0; regb < 0xb9; regb++) {
-                       outb(regb, s->sbbase);
-                       outb(0, s->sbbase+1);
-                       outb(regb, s->sbbase+2);
-                       outb(0, s->sbbase+3);
-               }
-               return 0;
-
-       case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-                       return -EFAULT;
-               if (n.voice >= 18)
-                       return -EINVAL;
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->sbbase+2;
-               } else {
-                       regb = n.voice;
-                       io = s->sbbase;
-               }
-               outb(0xa0 + regb, io);
-               outb(n.fnum & 0xff, io+1);
-               outb(0xb0 + regb, io);
-               outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-               return 0;
-
-       case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-                       return -EFAULT;
-               if (v.voice >= 18)
-                       return -EINVAL;
-               regb = op_offset[v.voice];
-               io = s->sbbase + ((v.op & 1) << 1);
-               outb(0x20 + regb, io);
-               outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-                    ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-               outb(0x40 + regb, io);
-               outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-               outb(0x60 + regb, io);
-               outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-               outb(0x80 + regb, io);
-               outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-               outb(0xe0 + regb, io);
-               outb(v.waveform & 0x7, io+1);
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->sbbase+2;
-               } else {
-                       regb = n.voice;
-                       io = s->sbbase;
-               }
-               outb(0xc0 + regb, io);
-               outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-                    (v.connection & 1), io+1);
-               return 0;
-               
-       case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void __user *)arg, sizeof(p)))
-                       return -EFAULT;
-               outb(0x08, s->sbbase);
-               outb((p.kbd_split & 1) << 6, s->sbbase+1);
-               outb(0xbd, s->sbbase);
-               outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-                    ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->sbbase+1);
-               return 0;
-
-       case FM_IOCTL_SET_OPL:
-               outb(4, s->sbbase+2);
-               outb(arg, s->sbbase+3);
-               return 0;
-
-       case FM_IOCTL_SET_MODE:
-               outb(5, s->sbbase+2);
-               outb(arg & 1, s->sbbase+3);
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int solo1_dmfm_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct solo1_state *s = NULL;
-       struct pci_dev *pci_dev = NULL;
-
-       while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver(pci_dev);
-               if (drvr != &solo1_driver)
-                       continue;
-               s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-               if (!s)
-                       continue;
-               if (s->dev_dmfm == minor)
-                       break;
-       }
-       if (!s)
-               return -ENODEV;
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DMFM) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
-               mutex_unlock(&s->open_mutex);
-               printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
-               return -EBUSY;
-       }
-       /* init the stuff */
-       outb(1, s->sbbase);
-       outb(0x20, s->sbbase+1); /* enable waveforms */
-       outb(4, s->sbbase+2);
-       outb(0, s->sbbase+3);  /* no 4op enabled */
-       outb(5, s->sbbase+2);
-       outb(1, s->sbbase+3);  /* enable OPL3 */
-       s->open_mode |= FMODE_DMFM;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int solo1_dmfm_release(struct inode *inode, struct file *file)
-{
-       struct solo1_state *s = (struct solo1_state *)file->private_data;
-       unsigned int regb;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~FMODE_DMFM;
-       for (regb = 0xb0; regb < 0xb9; regb++) {
-               outb(regb, s->sbbase);
-               outb(0, s->sbbase+1);
-               outb(regb, s->sbbase+2);
-               outb(0, s->sbbase+3);
-       }
-       release_region(s->sbbase, FMSYNTH_EXTENT);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations solo1_dmfm_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = solo1_dmfm_ioctl,
-       .open           = solo1_dmfm_open,
-       .release        = solo1_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-       { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 }
-};
-
-static int setup_solo1(struct solo1_state *s)
-{
-       struct pci_dev *pcidev = s->dev;
-       mm_segment_t fs;
-       int i, val;
-
-       /* initialize DDMA base address */
-       printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
-       pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
-       /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */
-       pci_write_config_dword(pcidev, 0x50, 0);
-       /* disable legacy audio address decode */
-       pci_write_config_word(pcidev, 0x40, 0x907f);
-
-       /* initialize the chips */
-       if (!reset_ctrl(s)) {
-               printk(KERN_ERR "esssolo1: cannot reset controller\n");
-               return -1;
-       }
-       outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */
-       
-       /* initialize mixer regs */
-       write_mixer(s, 0x7f, 0); /* disable music digital recording */
-       write_mixer(s, 0x7d, 0x0c); /* enable mic preamp, MONO_OUT is 2nd DAC right channel */
-       write_mixer(s, 0x64, 0x45); /* volume control */
-       write_mixer(s, 0x48, 0x10); /* enable music DAC/ES6xx interface */
-       write_mixer(s, 0x50, 0);  /* disable spatializer */
-       write_mixer(s, 0x52, 0);
-       write_mixer(s, 0x14, 0);  /* DAC1 minimum volume */
-       write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */
-       outb(0, s->ddmabase+0xd); /* DMA master clear */
-       outb(1, s->ddmabase+0xf); /* mask channel */
-       /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */
-
-       pci_set_master(pcidev);  /* enable bus mastering */
-       
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       val = 1; /* enable mic preamp */
-       mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
-       set_fs(fs);
-       return 0;
-}
-
-static int
-solo1_suspend(struct pci_dev *pci_dev, pm_message_t state) {
-       struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-       if (!s)
-               return 1;
-       outb(0, s->iobase+6);
-       /* DMA master clear */
-       outb(0, s->ddmabase+0xd); 
-       /* reset sequencer and FIFO */
-       outb(3, s->sbbase+6); 
-       /* turn off DDMA controller address space */
-       pci_write_config_word(s->dev, 0x60, 0); 
-       return 0;
-}
-
-static int
-solo1_resume(struct pci_dev *pci_dev) {
-       struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
-       if (!s)
-               return 1;
-       setup_solo1(s);
-       return 0;
-}
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, GAMEPORT_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: gameport io ports are in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "solo1: can not allocate memory for gameport\n");
-               release_region(io_port, GAMEPORT_EXTENT);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "ESS Solo1 Gameport");
-       gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void solo1_unregister_gameport(struct solo1_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, GAMEPORT_EXTENT);
-       }
-}
-#else
-static inline int solo1_register_gameport(struct solo1_state *s, int io_port) { return -ENOSYS; }
-static inline void solo1_unregister_gameport(struct solo1_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       struct solo1_state *s;
-       int gpio;
-       int ret;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-       if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 1) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 2) & IORESOURCE_IO) ||
-           !(pci_resource_flags(pcidev, 3) & IORESOURCE_IO))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-
-       /* Recording requires 24-bit DMA, so attempt to set dma mask
-        * to 24 bits first, then 32 bits (playback only) if that fails.
-        */
-       if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK) &&
-           pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
-               printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-
-       if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "solo1: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct solo1_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = SOLO1_MAGIC;
-       s->dev = pcidev;
-       s->iobase = pci_resource_start(pcidev, 0);
-       s->sbbase = pci_resource_start(pcidev, 1);
-       s->vcbase = pci_resource_start(pcidev, 2);
-       s->ddmabase = s->vcbase + DDMABASE_OFFSET;
-       s->mpubase = pci_resource_start(pcidev, 3);
-       gpio = pci_resource_start(pcidev, 4);
-       s->irq = pcidev->irq;
-       ret = -EBUSY;
-       if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region1;
-       }
-       if (!request_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region2;
-       }
-       if (!request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region3;
-       }
-       if (!request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1")) {
-               printk(KERN_ERR "solo1: io ports in use\n");
-               goto err_region4;
-       }
-       if ((ret=request_irq(s->irq,solo1_interrupt,IRQF_SHARED,"ESS Solo1",s))) {
-               printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&solo1_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&solo1_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev3;
-       }
-       if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0) {
-               ret = s->dev_dmfm;
-               goto err_dev4;
-       }
-       if (setup_solo1(s)) {
-               ret = -EIO;
-               goto err;
-       }
-       /* register gameport */
-       solo1_register_gameport(s, gpio);
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       return 0;
-
- err:
-       unregister_sound_special(s->dev_dmfm);
- err_dev4:
-       unregister_sound_midi(s->dev_midi);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "solo1: initialisation error\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->mpubase, MPUBASE_EXTENT);
- err_region4:
-       release_region(s->ddmabase, DDMABASE_EXTENT);
- err_region3:
-       release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
- err_region2:
-       release_region(s->iobase, IOBASE_EXTENT);
- err_region1:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit solo1_remove(struct pci_dev *dev)
-{
-       struct solo1_state *s = pci_get_drvdata(dev);
-       
-       if (!s)
-               return;
-       /* stop DMA controller */
-       outb(0, s->iobase+6);
-       outb(0, s->ddmabase+0xd); /* DMA master clear */
-       outb(3, s->sbbase+6); /* reset sequencer and FIFO */
-       synchronize_irq(s->irq);
-       pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */
-       free_irq(s->irq, s);
-       solo1_unregister_gameport(s);
-       release_region(s->iobase, IOBASE_EXTENT);
-       release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
-       release_region(s->ddmabase, DDMABASE_EXTENT);
-       release_region(s->mpubase, MPUBASE_EXTENT);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       unregister_sound_special(s->dev_dmfm);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver solo1_driver = {
-       .name           = "ESS Solo1",
-       .id_table       = id_table,
-       .probe          = solo1_probe,
-       .remove         = __devexit_p(solo1_remove),
-       .suspend        = solo1_suspend,
-       .resume         = solo1_resume,
-};
-
-
-static int __init init_solo1(void)
-{
-       printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n");
-       return pci_register_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("ESS Solo1 Driver");
-MODULE_LICENSE("GPL");
-
-
-static void __exit cleanup_solo1(void)
-{
-       printk(KERN_INFO "solo1: unloading\n");
-       pci_unregister_driver(&solo1_driver);
-}
-
-/* --------------------------------------------------------------------- */
-
-module_init(init_solo1);
-module_exit(cleanup_solo1);
-
diff --git a/sound/oss/forte.c b/sound/oss/forte.c
deleted file mode 100644 (file)
index ea1c020..0000000
+++ /dev/null
@@ -1,2139 +0,0 @@
-/*
- * forte.c - ForteMedia FM801 OSS Driver
- *
- * Written by Martin K. Petersen <mkp@mkp.net>
- * Copyright (C) 2002 Hewlett-Packard Company
- * Portions Copyright (C) 2003 Martin K. Petersen
- *
- * Latest version: http://mkp.net/forte/
- *
- * Based upon the ALSA FM801 driver by Jaroslav Kysela and OSS drivers
- * by Thomas Sailer, Alan Cox, Zach Brown, and Jeff Garzik.  Thanks
- * guys!
- *
- * 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.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-
-#include <linux/delay.h>
-#include <linux/poll.h>
-
-#include <linux/sound.h>
-#include <linux/ac97_codec.h>
-#include <linux/interrupt.h>
-
-#include <linux/proc_fs.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#define DRIVER_NAME    "forte"
-#define DRIVER_VERSION         "$Id: forte.c,v 1.63 2003/03/01 05:32:42 mkp Exp $"
-#define PFX            DRIVER_NAME ": "
-
-#undef M_DEBUG
-
-#ifdef M_DEBUG
-#define DPRINTK(args...) printk(KERN_WARNING args)
-#else
-#define DPRINTK(args...)
-#endif
-
-/* Card capabilities */
-#define FORTE_CAPS              (DSP_CAP_MMAP | DSP_CAP_TRIGGER)
-
-/* Supported audio formats */
-#define FORTE_FMTS             (AFMT_U8 | AFMT_S16_LE)
-
-/* Buffers */
-#define FORTE_MIN_FRAG_SIZE     256
-#define FORTE_MAX_FRAG_SIZE     PAGE_SIZE
-#define FORTE_DEF_FRAG_SIZE     256
-#define FORTE_MIN_FRAGMENTS     2
-#define FORTE_MAX_FRAGMENTS     256
-#define FORTE_DEF_FRAGMENTS     2
-#define FORTE_MIN_BUF_MSECS     500
-#define FORTE_MAX_BUF_MSECS     1000
-
-/* PCI BARs */
-#define FORTE_PCM_VOL           0x00    /* PCM Output Volume */
-#define FORTE_FM_VOL            0x02    /* FM Output Volume */
-#define FORTE_I2S_VOL           0x04    /* I2S Volume */
-#define FORTE_REC_SRC           0x06    /* Record Source */
-#define FORTE_PLY_CTRL          0x08    /* Playback Control */
-#define FORTE_PLY_COUNT         0x0a    /* Playback Count */
-#define FORTE_PLY_BUF1          0x0c    /* Playback Buffer I */
-#define FORTE_PLY_BUF2          0x10    /* Playback Buffer II */
-#define FORTE_CAP_CTRL          0x14    /* Capture Control */
-#define FORTE_CAP_COUNT         0x16    /* Capture Count */
-#define FORTE_CAP_BUF1          0x18    /* Capture Buffer I */
-#define FORTE_CAP_BUF2          0x1c    /* Capture Buffer II */
-#define FORTE_CODEC_CTRL        0x22    /* Codec Control */
-#define FORTE_I2S_MODE          0x24    /* I2S Mode Control */
-#define FORTE_VOLUME            0x26    /* Volume Up/Down/Mute Status */
-#define FORTE_I2C_CTRL          0x29    /* I2C Control */
-#define FORTE_AC97_CMD          0x2a    /* AC'97 Command */
-#define FORTE_AC97_DATA         0x2c    /* AC'97 Data */
-#define FORTE_MPU401_DATA       0x30    /* MPU401 Data */
-#define FORTE_MPU401_CMD        0x31    /* MPU401 Command */
-#define FORTE_GPIO_CTRL         0x52    /* General Purpose I/O Control */
-#define FORTE_GEN_CTRL          0x54    /* General Control */
-#define FORTE_IRQ_MASK          0x56    /* Interrupt Mask */
-#define FORTE_IRQ_STATUS        0x5a    /* Interrupt Status */
-#define FORTE_OPL3_BANK0        0x68    /* OPL3 Status Read / Bank 0 Write */
-#define FORTE_OPL3_DATA0        0x69    /* OPL3 Data 0 Write */
-#define FORTE_OPL3_BANK1        0x6a    /* OPL3 Bank 1 Write */
-#define FORTE_OPL3_DATA1        0x6b    /* OPL3 Bank 1 Write */
-#define FORTE_POWERDOWN         0x70    /* Blocks Power Down Control */
-
-#define FORTE_CAP_OFFSET        FORTE_CAP_CTRL - FORTE_PLY_CTRL
-
-#define FORTE_AC97_ADDR_SHIFT   10
-
-/* Playback and record control register bits */
-#define FORTE_BUF1_LAST         (1<<1)
-#define FORTE_BUF2_LAST         (1<<2)
-#define FORTE_START             (1<<5)
-#define FORTE_PAUSE             (1<<6)
-#define FORTE_IMMED_STOP        (1<<7)
-#define FORTE_RATE_SHIFT        8
-#define FORTE_RATE_MASK         (15 << FORTE_RATE_SHIFT)
-#define FORTE_CHANNELS_4        (1<<12) /* Playback only */
-#define FORTE_CHANNELS_6        (2<<12) /* Playback only */
-#define FORTE_CHANNELS_6MS      (3<<12) /* Playback only */
-#define FORTE_CHANNELS_MASK     (3<<12)
-#define FORTE_16BIT             (1<<14)
-#define FORTE_STEREO            (1<<15)
-
-/* IRQ status bits */
-#define FORTE_IRQ_PLAYBACK      (1<<8)
-#define FORTE_IRQ_CAPTURE       (1<<9)
-#define FORTE_IRQ_VOLUME        (1<<14)
-#define FORTE_IRQ_MPU           (1<<15)
-
-/* CODEC control */
-#define FORTE_CC_CODEC_RESET    (1<<5)
-#define FORTE_CC_AC97_RESET     (1<<6)
-
-/* AC97 cmd */
-#define FORTE_AC97_WRITE        (0<<7)
-#define FORTE_AC97_READ         (1<<7)
-#define FORTE_AC97_DP_INVALID   (0<<8)
-#define FORTE_AC97_DP_VALID     (1<<8)
-#define FORTE_AC97_PORT_RDY     (0<<9)
-#define FORTE_AC97_PORT_BSY     (1<<9)
-
-
-struct forte_channel {
-        const char             *name;
-
-       unsigned short          ctrl;           /* Ctrl BAR contents */
-       unsigned long           iobase;         /* Ctrl BAR address */
-
-       wait_queue_head_t       wait;
-
-       void                    *buf;           /* Buffer */
-       dma_addr_t              buf_handle;     /* Buffer handle */
-
-        unsigned int           record;
-       unsigned int            format;
-        unsigned int           rate;
-       unsigned int            stereo;
-
-       unsigned int            frag_sz;        /* Current fragment size */
-       unsigned int            frag_num;       /* Current # of fragments */
-       unsigned int            frag_msecs;     /* Milliseconds per frag */
-       unsigned int            buf_sz;         /* Current buffer size */
-
-       unsigned int            hwptr;          /* Tail */
-       unsigned int            swptr;          /* Head */
-       unsigned int            filled_frags;   /* Fragments currently full */
-       unsigned int            next_buf;       /* Index of next buffer */
-
-       unsigned int            active;         /* Channel currently in use */
-       unsigned int            mapped;         /* mmap */
-
-       unsigned int            buf_pages;      /* Real size of buffer */
-       unsigned int            nr_irqs;        /* Number of interrupts */
-       unsigned int            bytes;          /* Total bytes */
-       unsigned int            residue;        /* Partial fragment */
-};
-
-
-struct forte_chip {
-       struct pci_dev          *pci_dev;
-       unsigned long           iobase;
-       int                     irq;
-
-       struct mutex            open_mutex;     /* Device access */
-       spinlock_t              lock;           /* State */
-
-       spinlock_t              ac97_lock;
-       struct ac97_codec       *ac97;
-
-       int                     multichannel;
-       int                     dsp;            /* OSS handle */
-       int                     trigger;        /* mmap I/O trigger */
-
-       struct forte_channel    play;
-       struct forte_channel    rec;
-};
-
-
-static int channels[] = { 2, 4, 6, };
-static int rates[]    = { 5500, 8000, 9600, 11025, 16000, 19200, 
-                         22050, 32000, 38400, 44100, 48000, };
-
-static struct forte_chip *forte;
-static int found;
-
-
-/* AC97 Codec -------------------------------------------------------------- */
-
-
-/** 
- * forte_ac97_wait:
- * @chip:      fm801 instance whose AC97 codec to wait on
- *
- * FIXME:
- *             Stop busy-waiting
- */
-
-static inline int
-forte_ac97_wait (struct forte_chip *chip)
-{
-       int i = 10000;
-
-       while ( (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_PORT_BSY) 
-               && i-- )
-               cpu_relax();
-
-       return i == 0;
-}
-
-
-/**
- * forte_ac97_read:
- * @codec:     AC97 codec to read from
- * @reg:       register to read
- */
-
-static u16
-forte_ac97_read (struct ac97_codec *codec, u8 reg)
-{
-       u16 ret = 0;
-       struct forte_chip *chip = codec->private_data;
-
-       spin_lock (&chip->ac97_lock);
-
-       /* Knock, knock */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_read: Serial bus busy\n");
-               goto out;
-       }
-
-       /* Send read command */
-       outw (reg | (1<<7), chip->iobase + FORTE_AC97_CMD);
-
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_read: Bus busy reading reg 0x%x\n",
-                       reg);
-               goto out;
-       }
-       
-       /* Sanity checking */
-       if (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_DP_INVALID) {
-               printk (KERN_ERR PFX "ac97_read: Invalid data port");
-               goto out;
-       }
-
-       /* Fetch result */
-       ret = inw (chip->iobase + FORTE_AC97_DATA);
-
- out:
-       spin_unlock (&chip->ac97_lock);
-       return ret;
-}
-
-
-/**
- * forte_ac97_write:
- * @codec:     AC97 codec to send command to
- * @reg:       register to write
- * @val:       value to write
- */
-
-static void
-forte_ac97_write (struct ac97_codec *codec, u8 reg, u16 val)
-{
-       struct forte_chip *chip = codec->private_data;
-
-       spin_lock (&chip->ac97_lock);
-
-       /* Knock, knock */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_write: Serial bus busy\n");
-               goto out;
-       }
-
-       outw (val, chip->iobase + FORTE_AC97_DATA);
-       outb (reg | FORTE_AC97_WRITE, chip->iobase + FORTE_AC97_CMD);
-
-       /* Wait for completion */
-       if (forte_ac97_wait (chip)) {
-               printk (KERN_ERR PFX "ac97_write: Bus busy after write\n");
-               goto out;
-       }
-
- out:
-       spin_unlock (&chip->ac97_lock);
-}
-
-
-/* Mixer ------------------------------------------------------------------- */
-
-
-/**
- * forte_mixer_open:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_open (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = forte;
-       file->private_data = chip->ac97;
-       return 0;
-}
-
-
-/**
- * forte_mixer_release:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_release (struct inode *inode, struct file *file)
-{
-       /* We will welease Wodewick */
-       return 0;
-}
-
-
-/**
- * forte_mixer_ioctl:
- * @inode:             
- * @file:              
- */
-
-static int
-forte_mixer_ioctl (struct inode *inode, struct file *file, 
-                  unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *) file->private_data;
-
-       return codec->mixer_ioctl (codec, cmd, arg);
-}
-
-
-static struct file_operations forte_mixer_fops = {
-       .owner                  = THIS_MODULE,
-       .llseek                 = no_llseek,
-       .ioctl                  = forte_mixer_ioctl,
-       .open                   = forte_mixer_open,
-       .release                = forte_mixer_release,
-};
-
-
-/* Channel ----------------------------------------------------------------- */
-
-/** 
- * forte_channel_reset:
- * @channel:   Channel to reset
- * 
- * Locking:    Must be called with lock held.
- */
-
-static void
-forte_channel_reset (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase)
-               return;
-
-       DPRINTK ("%s: channel = %s\n", __FUNCTION__, channel->name);
-
-       channel->ctrl &= ~FORTE_START;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-       
-       /* We always play at least two fragments, hence these defaults */
-       channel->hwptr = channel->frag_sz;
-       channel->next_buf = 1;
-       channel->swptr = 0;
-       channel->filled_frags = 0;
-       channel->active = 0;
-       channel->bytes = 0;
-       channel->nr_irqs = 0;
-       channel->mapped = 0;
-       channel->residue = 0;
-}
-
-
-/** 
- * forte_channel_start:
- * @channel:   Channel to start (record/playback)
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_start (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase || channel->active) 
-               return;
-
-       channel->ctrl &= ~(FORTE_PAUSE | FORTE_BUF1_LAST | FORTE_BUF2_LAST
-                          | FORTE_IMMED_STOP);
-       channel->ctrl |= FORTE_START;
-       channel->active = 1;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_stop:
- * @channel:   Channel to stop
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_stop (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase) 
-               return;
-
-       channel->ctrl &= ~(FORTE_START | FORTE_PAUSE);  
-       channel->ctrl |= FORTE_IMMED_STOP;
-
-       channel->active = 0;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_pause:
- * @channel:   Channel to pause
- *
- * Locking:    Must be called with lock held.
- */
-
-static void inline
-forte_channel_pause (struct forte_channel *channel)
-{
-       if (!channel || !channel->iobase) 
-               return;
-
-       channel->ctrl |= FORTE_PAUSE;
-
-       channel->active = 0;
-       outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL);
-}
-
-
-/** 
- * forte_channel_rate:
- * @channel:   Channel whose rate to set.  Playback and record are
- *             independent.
- * @rate:      Channel rate in Hz
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_rate (struct forte_channel *channel, unsigned int rate)
-{
-       int new_rate;
-
-       if (!channel || !channel->iobase) 
-               return -EINVAL;
-
-       /* The FM801 only supports a handful of fixed frequencies.
-        * We find the value closest to what userland requested.
-        */
-       if      (rate <= 6250)  { rate = 5500;  new_rate =  0; }
-       else if (rate <= 8800)  { rate = 8000;  new_rate =  1; }
-       else if (rate <= 10312) { rate = 9600;  new_rate =  2; }
-       else if (rate <= 13512) { rate = 11025; new_rate =  3; }
-       else if (rate <= 17600) { rate = 16000; new_rate =  4; }
-       else if (rate <= 20625) { rate = 19200; new_rate =  5; }
-       else if (rate <= 27025) { rate = 22050; new_rate =  6; }
-       else if (rate <= 35200) { rate = 32000; new_rate =  7; }
-       else if (rate <= 41250) { rate = 38400; new_rate =  8; }
-       else if (rate <= 46050) { rate = 44100; new_rate =  9; }
-       else                    { rate = 48000; new_rate = 10; }
-
-       channel->ctrl &= ~FORTE_RATE_MASK;
-       channel->ctrl |= new_rate << FORTE_RATE_SHIFT;
-       channel->rate = rate;
-
-       DPRINTK ("%s: %s rate = %d\n", __FUNCTION__, channel->name, rate);
-
-       return rate;
-}
-
-
-/** 
- * forte_channel_format:
- * @channel:   Channel whose audio format to set
- * @format:    OSS format ID
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_format (struct forte_channel *channel, int format)
-{
-       if (!channel || !channel->iobase) 
-               return -EINVAL;
-
-       switch (format) {
-
-       case AFMT_QUERY:
-               break;
-       
-       case AFMT_U8:
-               channel->ctrl &= ~FORTE_16BIT;
-               channel->format = AFMT_U8;
-               break;
-
-       case AFMT_S16_LE:
-       default:
-               channel->ctrl |= FORTE_16BIT;
-               channel->format = AFMT_S16_LE;
-               break;
-       }
-
-       DPRINTK ("%s: %s want %d format, got %d\n", __FUNCTION__, channel->name, 
-                format, channel->format);
-
-       return channel->format;
-}
-
-
-/** 
- * forte_channel_stereo:
- * @channel:   Channel to toggle
- * @stereo:    0 for Mono, 1 for Stereo
- *
- * Locking:    Must be called with lock held.
- */
-
-static int
-forte_channel_stereo (struct forte_channel *channel, unsigned int stereo)
-{
-       int ret;
-
-       if (!channel || !channel->iobase)
-               return -EINVAL;
-
-       DPRINTK ("%s: %s stereo = %d\n", __FUNCTION__, channel->name, stereo);
-
-       switch (stereo) {
-
-       case 0:
-               channel->ctrl &= ~(FORTE_STEREO | FORTE_CHANNELS_MASK);
-               channel-> stereo = stereo;
-               ret = stereo;
-               break;
-
-       case 1:
-               channel->ctrl &= ~FORTE_CHANNELS_MASK;
-               channel->ctrl |= FORTE_STEREO;
-               channel-> stereo = stereo;
-               ret = stereo;
-               break;
-
-       default:
-               DPRINTK ("Unsupported channel format");
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
-}
-
-
-/** 
- * forte_channel_buffer:
- * @channel:   Channel whose buffer to set up
- *
- * Locking:    Must be called with lock held.
- */
-
-static void
-forte_channel_buffer (struct forte_channel *channel, int sz, int num)
-{
-       unsigned int msecs, shift;
-
-       /* Go away, I'm busy */
-       if (channel->filled_frags || channel->bytes)
-               return;
-
-       /* Fragment size must be a power of 2 */
-       shift = 0; sz++;
-       while (sz >>= 1)
-               shift++;
-       channel->frag_sz = 1 << shift;
-
-       /* Round fragment size to something reasonable */
-       if (channel->frag_sz < FORTE_MIN_FRAG_SIZE)
-               channel->frag_sz = FORTE_MIN_FRAG_SIZE;
-
-       if (channel->frag_sz > FORTE_MAX_FRAG_SIZE)
-               channel->frag_sz = FORTE_MAX_FRAG_SIZE;
-
-       /* Find fragment length in milliseconds */
-       msecs = channel->frag_sz /
-               (channel->format == AFMT_S16_LE ? 2 : 1) /
-               (channel->stereo ? 2 : 1) /
-               (channel->rate / 1000);
-
-       channel->frag_msecs = msecs;
-
-       /* Pick a suitable number of fragments */
-       if (msecs * num < FORTE_MIN_BUF_MSECS)
-            num = FORTE_MIN_BUF_MSECS / msecs;
-
-       if (msecs * num > FORTE_MAX_BUF_MSECS)
-            num = FORTE_MAX_BUF_MSECS / msecs;
-
-       /* Fragment number must be a power of 2 */
-       shift = 0;      
-       while (num >>= 1)
-               shift++;
-       channel->frag_num = 1 << (shift + 1);
-
-       /* Round fragment number to something reasonable */
-       if (channel->frag_num < FORTE_MIN_FRAGMENTS)
-               channel->frag_num = FORTE_MIN_FRAGMENTS;
-
-       if (channel->frag_num > FORTE_MAX_FRAGMENTS)
-               channel->frag_num = FORTE_MAX_FRAGMENTS;
-
-       channel->buf_sz = channel->frag_sz * channel->frag_num;
-
-       DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d\n",
-                __FUNCTION__, channel->name, channel->frag_sz, 
-                channel->frag_num, channel->buf_sz);
-}
-
-
-/** 
- * forte_channel_prep:
- * @channel:   Channel whose buffer to prepare
- *
- * Locking:    Lock held.
- */
-
-static void
-forte_channel_prep (struct forte_channel *channel)
-{
-       struct page *page;
-       int i;
-       
-       if (channel->buf)
-               return;
-
-       forte_channel_buffer (channel, channel->frag_sz, channel->frag_num);
-       channel->buf_pages = channel->buf_sz >> PAGE_SHIFT;
-
-       if (channel->buf_sz % PAGE_SIZE)
-               channel->buf_pages++;
-
-       DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d, pg = %d\n", 
-                __FUNCTION__, channel->name, channel->frag_sz, 
-                channel->frag_num, channel->buf_sz, channel->buf_pages);
-
-       /* DMA buffer */
-       channel->buf = pci_alloc_consistent (forte->pci_dev, 
-                                            channel->buf_pages * PAGE_SIZE,
-                                            &channel->buf_handle);
-
-       if (!channel->buf || !channel->buf_handle)
-               BUG();
-
-       page = virt_to_page (channel->buf);
-       
-       /* FIXME: can this go away ? */
-       for (i = 0 ; i < channel->buf_pages ; i++)
-               SetPageReserved(page++);
-
-       /* Prep buffer registers */
-       outw (channel->frag_sz - 1, channel->iobase + FORTE_PLY_COUNT);
-       outl (channel->buf_handle, channel->iobase + FORTE_PLY_BUF1);
-       outl (channel->buf_handle + channel->frag_sz, 
-             channel->iobase + FORTE_PLY_BUF2);
-
-       /* Reset hwptr */
-       channel->hwptr = channel->frag_sz;
-       channel->next_buf = 1;
-
-       DPRINTK ("%s: %s buffer @ %p (%p)\n", __FUNCTION__, channel->name, 
-                channel->buf, channel->buf_handle);
-}
-
-
-/** 
- * forte_channel_drain:
- * @chip:      
- * @channel:   
- *
- * Locking:    Don't hold the lock.
- */
-
-static inline int
-forte_channel_drain (struct forte_channel *channel)
-{
-       DECLARE_WAITQUEUE (wait, current);
-       unsigned long flags;
-
-       DPRINTK ("%s\n", __FUNCTION__);
-
-       if (channel->mapped) {
-               spin_lock_irqsave (&forte->lock, flags);
-               forte_channel_stop (channel);
-               spin_unlock_irqrestore (&forte->lock, flags);
-               return 0;
-       }
-
-       spin_lock_irqsave (&forte->lock, flags);
-       add_wait_queue (&channel->wait, &wait);
-
-       for (;;) {
-               if (channel->active == 0 || channel->filled_frags == 1)
-                       break;
-
-               spin_unlock_irqrestore (&forte->lock, flags);
-
-               __set_current_state (TASK_INTERRUPTIBLE);
-               schedule();
-
-               spin_lock_irqsave (&forte->lock, flags);
-       }
-
-       forte_channel_stop (channel);
-       forte_channel_reset (channel);
-       set_current_state (TASK_RUNNING);
-       remove_wait_queue (&channel->wait, &wait);
-       spin_unlock_irqrestore (&forte->lock, flags);
-
-       return 0;
-}
-
-
-/** 
- * forte_channel_init:
- * @chip:      Forte chip instance the channel hangs off
- * @channel:   Channel to initialize
- *
- * Description:
- *             Initializes a channel, sets defaults, and allocates
- *             buffers.
- *
- * Locking:    No lock held.
- */
-
-static int
-forte_channel_init (struct forte_chip *chip, struct forte_channel *channel)
-{
-       DPRINTK ("%s: chip iobase @ %p\n", __FUNCTION__, (void *)chip->iobase);
-
-       spin_lock_irq (&chip->lock);
-       memset (channel, 0x0, sizeof (*channel));
-
-       if (channel == &chip->play) {
-               channel->name = "PCM_OUT";
-               channel->iobase = chip->iobase;
-               DPRINTK ("%s: PCM-OUT iobase @ %p\n", __FUNCTION__,
-                        (void *) channel->iobase);
-       }
-       else if (channel == &chip->rec) {
-               channel->name = "PCM_IN";
-               channel->iobase = chip->iobase + FORTE_CAP_OFFSET;
-               channel->record = 1;
-               DPRINTK ("%s: PCM-IN iobase @ %p\n", __FUNCTION__, 
-                        (void *) channel->iobase);
-       }
-       else
-               BUG();
-
-       init_waitqueue_head (&channel->wait);
-
-       /* Defaults: 48kHz, 16-bit, stereo */
-       channel->ctrl = inw (channel->iobase + FORTE_PLY_CTRL);
-       forte_channel_reset (channel);
-       forte_channel_stereo (channel, 1);
-       forte_channel_format (channel, AFMT_S16_LE);
-       forte_channel_rate (channel, 48000);
-       channel->frag_sz = FORTE_DEF_FRAG_SIZE;
-       channel->frag_num = FORTE_DEF_FRAGMENTS;
-
-       chip->trigger = 0;
-       spin_unlock_irq (&chip->lock);
-
-       return 0;
-}
-
-
-/** 
- * forte_channel_free:
- * @chip:      Chip this channel hangs off
- * @channel:   Channel to nuke 
- *
- * Description:
- *             Resets channel and frees buffers.
- *
- * Locking:    Hold your horses.
- */
-
-static void
-forte_channel_free (struct forte_chip *chip, struct forte_channel *channel)
-{
-       DPRINTK ("%s: %s\n", __FUNCTION__, channel->name);
-
-       if (!channel->buf_handle)
-               return;
-
-       pci_free_consistent (chip->pci_dev, channel->buf_pages * PAGE_SIZE, 
-                            channel->buf, channel->buf_handle);
-       
-       memset (channel, 0x0, sizeof (*channel));
-}
-
-
-/* DSP --------------------------------------------------------------------- */
-
-
-/**
- * forte_dsp_ioctl:
- */
-
-static int
-forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-                unsigned long arg)
-{
-       int ival=0, ret, rval=0, rd, wr, count;
-       struct forte_chip *chip;
-       struct audio_buf_info abi;
-       struct count_info cinfo;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       chip = file->private_data;
-       
-       if (file->f_mode & FMODE_WRITE)
-               wr = 1;
-       else 
-               wr = 0;
-
-       if (file->f_mode & FMODE_READ)
-               rd = 1;
-       else
-               rd = 0;
-
-       switch (cmd) {
-
-       case OSS_GETVERSION:
-               return put_user (SOUND_VERSION, p);
-
-       case SNDCTL_DSP_GETCAPS:
-               DPRINTK ("%s: GETCAPS\n", __FUNCTION__);
-
-               ival = FORTE_CAPS; /* DUPLEX */
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_GETFMTS:
-               DPRINTK ("%s: GETFMTS\n", __FUNCTION__);
-
-               ival = FORTE_FMTS; /* U8, 16LE */
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_SETFMT: /* U8, 16LE */
-               DPRINTK ("%s: SETFMT\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_format (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_format (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-       
-               return put_user (rval, p);
-
-       case SNDCTL_DSP_STEREO: /* 0 - mono, 1 - stereo */
-               DPRINTK ("%s: STEREO\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-       case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */
-               DPRINTK ("%s: CHANNELS\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_stereo (&chip->rec, ival-1) + 1;
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->play);
-                       rval = forte_channel_stereo (&chip->play, ival-1) + 1;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (rval, p);
-
-       case SNDCTL_DSP_SPEED:
-               DPRINTK ("%s: SPEED\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                        return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_stop (&chip->rec);
-                       rval = forte_channel_rate (&chip->rec, ival);
-               }
-
-               if (wr) {
-                       forte_channel_stop (&chip->play);
-                       rval = forte_channel_rate (&chip->play, ival);
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user(rval, p);
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__);
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd)
-                       ival = chip->rec.frag_sz;
-
-               if (wr)
-                       ival = chip->play.frag_sz;
-
-               spin_unlock_irq (&chip->lock);
-
-                return put_user (ival, p);
-
-       case SNDCTL_DSP_RESET:
-               DPRINTK ("%s: RESET\n", __FUNCTION__);
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd)
-                       forte_channel_reset (&chip->rec);
-
-               if (wr)
-                       forte_channel_reset (&chip->play);
-
-               spin_unlock_irq (&chip->lock);
-
-                return 0;
-
-       case SNDCTL_DSP_SYNC:
-               DPRINTK ("%s: SYNC\n", __FUNCTION__);
-
-               if (wr)
-                       ret = forte_channel_drain (&chip->play);
-
-               return 0;
-
-       case SNDCTL_DSP_POST:
-               DPRINTK ("%s: POST\n", __FUNCTION__);
-
-               if (wr) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (chip->play.filled_frags)
-                               forte_channel_start (&chip->play);
-
-                       spin_unlock_irq (&chip->lock);
-               }
-
-                return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__);
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               spin_lock_irq (&chip->lock);
-
-               if (rd) {
-                       forte_channel_buffer (&chip->rec, ival & 0xffff, 
-                                             (ival >> 16) & 0xffff);
-                       ival = (chip->rec.frag_num << 16) + chip->rec.frag_sz;
-               }
-
-               if (wr) {
-                       forte_channel_buffer (&chip->play, ival & 0xffff, 
-                                             (ival >> 16) & 0xffff);
-                       ival = (chip->play.frag_num << 16) +chip->play.frag_sz;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return put_user (ival, p);
-                
-        case SNDCTL_DSP_GETISPACE:
-               DPRINTK ("%s: GETISPACE\n", __FUNCTION__);
-
-               if (!rd)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               abi.fragstotal = chip->rec.frag_num;
-               abi.fragsize = chip->rec.frag_sz;
-                       
-               if (chip->rec.mapped) {
-                       abi.fragments = chip->rec.frag_num - 2;
-                       abi.bytes = abi.fragments * abi.fragsize;
-               }
-               else {
-                       abi.fragments = chip->rec.filled_frags;
-                       abi.bytes = abi.fragments * abi.fragsize;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETIPTR:
-               DPRINTK ("%s: GETIPTR\n", __FUNCTION__);
-
-               if (!rd)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (chip->rec.active) 
-                       cinfo.ptr = chip->rec.hwptr;
-               else
-                       cinfo.ptr = 0;
-
-               cinfo.bytes = chip->rec.bytes;
-               cinfo.blocks = chip->rec.nr_irqs;
-               chip->rec.nr_irqs = 0;
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-        case SNDCTL_DSP_GETOSPACE:
-               if (!wr)
-                       return -EINVAL;
-               
-               spin_lock_irq (&chip->lock);
-
-               abi.fragstotal = chip->play.frag_num;
-               abi.fragsize = chip->play.frag_sz;
-
-               if (chip->play.mapped) {
-                       abi.fragments = chip->play.frag_num - 2;
-                       abi.bytes = chip->play.buf_sz;
-               }
-               else {
-                       abi.fragments = chip->play.frag_num - 
-                               chip->play.filled_frags;
-
-                       if (chip->play.residue)
-                               abi.fragments--;
-
-                       abi.bytes = abi.fragments * abi.fragsize +
-                               chip->play.residue;
-               }
-
-               spin_unlock_irq (&chip->lock);
-               
-               return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               if (!wr)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (chip->play.active) 
-                       cinfo.ptr = chip->play.hwptr;
-               else
-                       cinfo.ptr = 0;
-
-               cinfo.bytes = chip->play.bytes;
-               cinfo.blocks = chip->play.nr_irqs;
-               chip->play.nr_irqs = 0;
-
-               spin_unlock_irq (&chip->lock);
-
-               return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETODELAY:
-               if (!wr)
-                       return -EINVAL;
-
-               spin_lock_irq (&chip->lock);
-
-               if (!chip->play.active) {
-                       ival = 0;
-               }
-               else if (chip->play.mapped) {
-                       count = inw (chip->play.iobase + FORTE_PLY_COUNT) + 1;
-                       ival = chip->play.frag_sz - count;
-               }
-               else {
-                       ival = chip->play.filled_frags * chip->play.frag_sz;
-
-                       if (chip->play.residue)
-                               ival += chip->play.frag_sz - chip->play.residue;
-               }
-
-               spin_unlock_irq (&chip->lock);
-
-               return put_user (ival, p);
-
-       case SNDCTL_DSP_SETDUPLEX:
-               DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__);
-
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETTRIGGER:
-               DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__);
-               
-               return put_user (chip->trigger, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-
-               if (get_user (ival, p))
-                       return -EFAULT;
-
-               DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival);
-
-               if (wr) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (ival & PCM_ENABLE_OUTPUT)
-                               forte_channel_start (&chip->play);
-                       else {          
-                               chip->trigger = 1;
-                               forte_channel_prep (&chip->play);
-                               forte_channel_stop (&chip->play);
-                       }
-
-                       spin_unlock_irq (&chip->lock);
-               }
-               else if (rd) {
-                       spin_lock_irq (&chip->lock);
-
-                       if (ival & PCM_ENABLE_INPUT)
-                               forte_channel_start (&chip->rec);
-                       else {          
-                               chip->trigger = 1;
-                               forte_channel_prep (&chip->rec);
-                               forte_channel_stop (&chip->rec);
-                       }
-
-                       spin_unlock_irq (&chip->lock);
-               }
-
-               return 0;
-               
-       case SOUND_PCM_READ_RATE:
-               DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__);          
-               return put_user (chip->play.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__);
-               return put_user (chip->play.stereo, p);
-
-       case SOUND_PCM_READ_BITS:
-               DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__);          
-               return put_user (chip->play.format, p);
-
-       case SNDCTL_DSP_NONBLOCK:
-               DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__);           
-                file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       default:
-               DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp);
-               break;
-       }
-
-       return -EINVAL;
-}
-
-
-/**
- * forte_dsp_open:
- */
-
-static int 
-forte_dsp_open (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */
-
-       if (file->f_flags & O_NONBLOCK) {
-               if (!mutex_trylock(&chip->open_mutex)) {
-                       DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__);
-                       return -EAGAIN;
-               }
-       }
-       else {
-               if (mutex_lock_interruptible(&chip->open_mutex)) {
-                       DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__);
-                       return -ERESTARTSYS;
-               }
-       }
-
-       file->private_data = forte;
-
-       DPRINTK ("%s: dsp opened by %d\n", __FUNCTION__, current->pid);
-
-       if (file->f_mode & FMODE_WRITE)
-               forte_channel_init (forte, &forte->play);
-
-       if (file->f_mode & FMODE_READ)
-               forte_channel_init (forte, &forte->rec);
-
-       return nonseekable_open(inode, file);
-}
-
-
-/**
- * forte_dsp_release:
- */
-
-static int 
-forte_dsp_release (struct inode *inode, struct file *file)
-{
-       struct forte_chip *chip = file->private_data;
-       int ret = 0;
-
-       DPRINTK ("%s: chip @ %p\n", __FUNCTION__, chip);
-
-       if (file->f_mode & FMODE_WRITE) {
-               forte_channel_drain (&chip->play);
-
-               spin_lock_irq (&chip->lock);
-
-               forte_channel_free (chip, &chip->play);
-
-               spin_unlock_irq (&chip->lock);
-        }
-
-       if (file->f_mode & FMODE_READ) {
-               while (chip->rec.filled_frags > 0)
-                       interruptible_sleep_on (&chip->rec.wait);
-
-               spin_lock_irq (&chip->lock);
-
-               forte_channel_stop (&chip->rec);
-               forte_channel_free (chip, &chip->rec);
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       mutex_unlock(&chip->open_mutex);
-
-       return ret;
-}
-
-
-/**
- * forte_dsp_poll:
- *
- */
-
-static unsigned int 
-forte_dsp_poll (struct file *file, struct poll_table_struct *wait)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int mask = 0;
-
-       chip = file->private_data;
-
-       if (file->f_mode & FMODE_WRITE) {
-               channel = &chip->play;
-
-               if (channel->active)
-                       poll_wait (file, &channel->wait, wait);
-
-               spin_lock_irq (&chip->lock);
-
-               if (channel->frag_num - channel->filled_frags > 0)
-                       mask |= POLLOUT | POLLWRNORM;
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       if (file->f_mode & FMODE_READ) {
-               channel = &chip->rec;
-
-               if (channel->active)
-                       poll_wait (file, &channel->wait, wait);
-
-               spin_lock_irq (&chip->lock);
-
-               if (channel->filled_frags > 0)
-                       mask |= POLLIN | POLLRDNORM;
-
-               spin_unlock_irq (&chip->lock);
-       }
-
-       return mask;
-}
-
-
-/**
- * forte_dsp_mmap:
- */
-
-static int
-forte_dsp_mmap (struct file *file, struct vm_area_struct *vma)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned long size;
-       int ret;
-
-       chip = file->private_data;
-
-       DPRINTK ("%s: start %lXh, size %ld, pgoff %ld\n", __FUNCTION__,
-                 vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_pgoff);
-
-       spin_lock_irq (&chip->lock);
-
-       if (vma->vm_flags & VM_WRITE && chip->play.active) {
-               ret = -EBUSY;
-               goto out;
-       }
-
-        if (vma->vm_flags & VM_READ && chip->rec.active) {
-               ret = -EBUSY;
-               goto out;
-        }
-
-       if (file->f_mode & FMODE_WRITE)
-               channel = &chip->play;
-       else if (file->f_mode & FMODE_READ)
-               channel = &chip->rec;
-       else {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       forte_channel_prep (channel);
-       channel->mapped = 1;
-
-        if (vma->vm_pgoff != 0) {
-               ret = -EINVAL;
-                goto out;
-       }
-
-        size = vma->vm_end - vma->vm_start;
-
-        if (size > channel->buf_pages * PAGE_SIZE) {
-               DPRINTK ("%s: size (%ld) > buf_sz (%d) \n", __FUNCTION__,
-                        size, channel->buf_sz);
-               ret = -EINVAL;
-                goto out;
-       }
-
-        if (remap_pfn_range(vma, vma->vm_start,
-                             virt_to_phys(channel->buf) >> PAGE_SHIFT,
-                             size, vma->vm_page_prot)) {
-               DPRINTK ("%s: remap el a no worko\n", __FUNCTION__);
-               ret = -EAGAIN;
-                goto out;
-       }
-
-        ret = 0;
-
- out:
-       spin_unlock_irq (&chip->lock);
-        return ret;
-}
-
-
-/**
- * forte_dsp_write:
- */
-
-static ssize_t 
-forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes, 
-                loff_t *ppos)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int i = bytes, sz = 0;
-       unsigned long flags;
-
-       if (!access_ok (VERIFY_READ, buffer, bytes))
-               return -EFAULT;
-
-       chip = (struct forte_chip *) file->private_data;
-
-       if (!chip)
-               BUG();
-
-       channel = &chip->play;
-
-       if (!channel)
-               BUG();
-
-       spin_lock_irqsave (&chip->lock, flags);
-
-       /* Set up buffers with the right fragment size */
-       forte_channel_prep (channel);
-
-       while (i) {
-               /* All fragment buffers in use -> wait */
-               if (channel->frag_num - channel->filled_frags == 0) {
-                       DECLARE_WAITQUEUE (wait, current);
-
-                       /* For trigger or non-blocking operation, get out */
-                       if (chip->trigger || file->f_flags & O_NONBLOCK) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -EAGAIN;
-                       }
-
-                       /* Otherwise wait for buffers */
-                       add_wait_queue (&channel->wait, &wait);
-
-                       for (;;) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-
-                               set_current_state (TASK_INTERRUPTIBLE);
-                               schedule();
-
-                               spin_lock_irqsave (&chip->lock, flags);
-
-                               if (channel->frag_num - channel->filled_frags)
-                                       break;
-                       }
-
-                       remove_wait_queue (&channel->wait, &wait);
-                       set_current_state (TASK_RUNNING);
-
-                       if (signal_pending (current)) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -ERESTARTSYS;
-                       }
-               }
-
-               if (channel->residue)
-                       sz = channel->residue;
-               else if (i > channel->frag_sz)
-                       sz = channel->frag_sz;
-               else
-                       sz = i;
-
-               spin_unlock_irqrestore (&chip->lock, flags);
-
-               if (copy_from_user ((void *) channel->buf + channel->swptr, buffer, sz))
-                       return -EFAULT;
-
-               spin_lock_irqsave (&chip->lock, flags);
-
-               /* Advance software pointer */
-               buffer += sz;
-               channel->swptr += sz;
-               channel->swptr %= channel->buf_sz;
-               i -= sz;
-
-               /* Only bump filled_frags if a full fragment has been written */
-               if (channel->swptr % channel->frag_sz == 0) {
-                       channel->filled_frags++;
-                       channel->residue = 0;
-               }
-               else
-                       channel->residue = channel->frag_sz - sz;
-
-               /* If playback isn't active, start it */
-               if (channel->active == 0 && chip->trigger == 0)
-                       forte_channel_start (channel);
-       }
-
-       spin_unlock_irqrestore (&chip->lock, flags);
-
-       return bytes - i;
-}
-
-
-/**
- * forte_dsp_read:
- */
-
-static ssize_t 
-forte_dsp_read (struct file *file, char __user *buffer, size_t bytes, 
-               loff_t *ppos)
-{
-       struct forte_chip *chip;
-       struct forte_channel *channel;
-       unsigned int i = bytes, sz;
-       unsigned long flags;
-
-       if (!access_ok (VERIFY_WRITE, buffer, bytes))
-               return -EFAULT;
-
-       chip = (struct forte_chip *) file->private_data;
-
-       if (!chip)
-               BUG();
-
-       channel = &chip->rec;
-
-       if (!channel)
-               BUG();
-
-       spin_lock_irqsave (&chip->lock, flags);
-
-       /* Set up buffers with the right fragment size */
-       forte_channel_prep (channel);
-
-       /* Start recording */
-       if (!chip->trigger)
-               forte_channel_start (channel);
-
-       while (i) {
-               /* No fragment buffers in use -> wait */
-               if (channel->filled_frags == 0) {
-                       DECLARE_WAITQUEUE (wait, current);
-
-                       /* For trigger mode operation, get out */
-                       if (chip->trigger) {
-                               spin_unlock_irqrestore (&chip->lock, flags);
-                               return -EAGAIN;
-                       }
-
-                       add_wait_queue (&channel->wait, &wait);
-
-                       for (;;) {
-                               if (channel->active == 0)
-                                       break;
-
-                               if (channel->filled_frags)
-                                       break;
-                                               
-                               spin_unlock_irqrestore (&chip->lock, flags);
-
-                               set_current_state (TASK_INTERRUPTIBLE);
-                               schedule();
-
-                               spin_lock_irqsave (&chip->lock, flags);
-                       }
-
-                       set_current_state (TASK_RUNNING);
-                       remove_wait_queue (&channel->wait, &wait);
-               }
-
-               if (i > channel->frag_sz)
-                       sz = channel->frag_sz;
-               else
-                       sz = i;
-
-               spin_unlock_irqrestore (&chip->lock, flags);
-
-               if (copy_to_user (buffer, (void *)channel->buf+channel->swptr, sz)) {
-                       DPRINTK ("%s: copy_to_user failed\n", __FUNCTION__);
-                       return -EFAULT;
-               }
-
-               spin_lock_irqsave (&chip->lock, flags);
-
-               /* Advance software pointer */
-               buffer += sz;
-               if (channel->filled_frags > 0)
-                       channel->filled_frags--;
-               channel->swptr += channel->frag_sz;
-               channel->swptr %= channel->buf_sz;
-               i -= sz;
-       }
-
-       spin_unlock_irqrestore (&chip->lock, flags);
-
-       return bytes - i;
-}
-
-
-static struct file_operations forte_dsp_fops = {
-       .owner                  = THIS_MODULE,
-       .llseek                 = &no_llseek,
-       .read                   = &forte_dsp_read,
-       .write                  = &forte_dsp_write,
-       .poll                   = &forte_dsp_poll,
-       .ioctl                  = &forte_dsp_ioctl,
-       .open                   = &forte_dsp_open,
-       .release                = &forte_dsp_release,
-       .mmap                   = &forte_dsp_mmap,
-};
-
-
-/* Common ------------------------------------------------------------------ */
-
-
-/**
- * forte_interrupt:
- */
-
-static irqreturn_t
-forte_interrupt (int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct forte_chip *chip = dev_id;
-       struct forte_channel *channel = NULL;
-       u16 status, count; 
-
-       status = inw (chip->iobase + FORTE_IRQ_STATUS);
-
-       /* If this is not for us, get outta here ASAP */
-       if ((status & (FORTE_IRQ_PLAYBACK | FORTE_IRQ_CAPTURE)) == 0)
-               return IRQ_NONE;
-       
-       if (status & FORTE_IRQ_PLAYBACK) {
-               channel = &chip->play;
-
-               spin_lock (&chip->lock);
-
-               if (channel->frag_sz == 0)
-                       goto pack;
-
-               /* Declare a fragment done */
-               if (channel->filled_frags > 0)
-                       channel->filled_frags--;
-               channel->bytes += channel->frag_sz;
-               channel->nr_irqs++;
-               
-               /* Flip-flop between buffer I and II */
-               channel->next_buf ^= 1;
-
-               /* Advance hardware pointer by fragment size and wrap around */
-               channel->hwptr += channel->frag_sz;
-               channel->hwptr %= channel->buf_sz;
-
-               /* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-                     channel->next_buf == 0 ?
-                     channel->iobase + FORTE_PLY_BUF1 :
-                     channel->iobase + FORTE_PLY_BUF2);
-
-               /* If the currently playing fragment is last, schedule pause */
-               if (channel->filled_frags == 1) 
-                       forte_channel_pause (channel);
-
-       pack:
-               /* Acknowledge interrupt */
-                outw (FORTE_IRQ_PLAYBACK, chip->iobase + FORTE_IRQ_STATUS);
-
-               if (waitqueue_active (&channel->wait)) 
-                       wake_up_all (&channel->wait);
-
-               spin_unlock (&chip->lock);
-       }
-
-       if (status & FORTE_IRQ_CAPTURE) {
-               channel = &chip->rec;
-               spin_lock (&chip->lock);
-
-               /* One fragment filled */
-               channel->filled_frags++;
-
-               /* Get # of completed bytes */
-               count = inw (channel->iobase + FORTE_PLY_COUNT) + 1;
-
-               if (count == 0) {
-                       DPRINTK ("%s: last, filled_frags = %d\n", __FUNCTION__,
-                                channel->filled_frags);
-                       channel->filled_frags = 0;
-                       goto rack;
-               }
-
-               /* Buffer I or buffer II BAR */
-                outl (channel->buf_handle + channel->hwptr, 
-                     channel->next_buf == 0 ?
-                     channel->iobase + FORTE_PLY_BUF1 :
-                     channel->iobase + FORTE_PLY_BUF2);
-
-               /* Flip-flop between buffer I and II */
-               channel->next_buf ^= 1;
-
-               /* Advance hardware pointer by fragment size and wrap around */
-               channel->hwptr += channel->frag_sz;
-               channel->hwptr %= channel->buf_sz;
-
-               /* Out of buffers */
-               if (channel->filled_frags == channel->frag_num - 1)
-                       forte_channel_stop (channel);
-       rack:
-               /* Acknowledge interrupt */
-                outw (FORTE_IRQ_CAPTURE, chip->iobase + FORTE_IRQ_STATUS);
-
-               spin_unlock (&chip->lock);
-
-               if (waitqueue_active (&channel->wait))
-                       wake_up_all (&channel->wait);           
-       }
-
-       return IRQ_HANDLED;
-}
-
-
-/**
- * forte_proc_read:
- */
-
-static int
-forte_proc_read (char *page, char **start, off_t off, int count, 
-                int *eof, void *data)
-{
-       int i = 0, p_rate, p_chan, r_rate;
-       unsigned short p_reg, r_reg;
-
-       i += sprintf (page, "ForteMedia FM801 OSS Lite driver\n%s\n \n", 
-                     DRIVER_VERSION);
-
-       if (!forte->iobase)
-               return i;
-
-       p_rate = p_chan = -1;
-       p_reg  = inw (forte->iobase + FORTE_PLY_CTRL);
-       p_rate = (p_reg >> 8) & 15;
-       p_chan = (p_reg >> 12) & 3;
-
-       if (p_rate >= 0 || p_rate <= 10)
-               p_rate = rates[p_rate];
-
-       if (p_chan >= 0 || p_chan <= 2)
-               p_chan = channels[p_chan];
-
-       r_rate = -1;
-       r_reg  = inw (forte->iobase + FORTE_CAP_CTRL);
-       r_rate = (r_reg >> 8) & 15;
-
-       if (r_rate >= 0 || r_rate <= 10)
-               r_rate = rates[r_rate]; 
-
-       i += sprintf (page + i,
-                     "             Playback  Capture\n"
-                     "FIFO empty : %-3s       %-3s\n"
-                     "Buf1 Last  : %-3s       %-3s\n"
-                     "Buf2 Last  : %-3s       %-3s\n"
-                     "Started    : %-3s       %-3s\n"
-                     "Paused     : %-3s       %-3s\n"
-                     "Immed Stop : %-3s       %-3s\n"
-                     "Rate       : %-5d     %-5d\n"
-                     "Channels   : %-5d     -\n"
-                     "16-bit     : %-3s       %-3s\n"
-                     "Stereo     : %-3s       %-3s\n"
-                     " \n"
-                     "Buffer Sz  : %-6d    %-6d\n"
-                     "Frag Sz    : %-6d    %-6d\n"
-                     "Frag Num   : %-6d    %-6d\n"
-                     "Frag msecs : %-6d    %-6d\n"
-                     "Used Frags : %-6d    %-6d\n"
-                     "Mapped     : %-3s       %-3s\n",
-                     p_reg & 1<<0  ? "yes" : "no",
-                     r_reg & 1<<0  ? "yes" : "no",
-                     p_reg & 1<<1  ? "yes" : "no",
-                     r_reg & 1<<1  ? "yes" : "no",
-                     p_reg & 1<<2  ? "yes" : "no",
-                     r_reg & 1<<2  ? "yes" : "no",
-                     p_reg & 1<<5  ? "yes" : "no",
-                     r_reg & 1<<5  ? "yes" : "no",
-                     p_reg & 1<<6  ? "yes" : "no",
-                     r_reg & 1<<6  ? "yes" : "no",
-                     p_reg & 1<<7  ? "yes" : "no",
-                     r_reg & 1<<7  ? "yes" : "no",
-                     p_rate, r_rate,
-                     p_chan,
-                     p_reg & 1<<14 ? "yes" : "no",
-                     r_reg & 1<<14 ? "yes" : "no",
-                     p_reg & 1<<15 ? "yes" : "no",
-                     r_reg & 1<<15 ? "yes" : "no",
-                     forte->play.buf_sz,       forte->rec.buf_sz,
-                     forte->play.frag_sz,      forte->rec.frag_sz,
-                     forte->play.frag_num,     forte->rec.frag_num,
-                     forte->play.frag_msecs,   forte->rec.frag_msecs,
-                     forte->play.filled_frags, forte->rec.filled_frags,
-                     forte->play.mapped ? "yes" : "no",
-                     forte->rec.mapped ? "yes" : "no"
-               );
-
-       return i;
-}
-
-
-/**
- * forte_proc_init:
- *
- * Creates driver info entries in /proc
- */
-
-static int __init 
-forte_proc_init (void)
-{
-       if (!proc_mkdir ("driver/forte", NULL))
-               return -EIO;
-
-       if (!create_proc_read_entry ("driver/forte/chip", 0, NULL, forte_proc_read, forte)) {
-               remove_proc_entry ("driver/forte", NULL);
-               return -EIO;
-       }
-
-       if (!create_proc_read_entry("driver/forte/ac97", 0, NULL, ac97_read_proc, forte->ac97)) {
-               remove_proc_entry ("driver/forte/chip", NULL);
-               remove_proc_entry ("driver/forte", NULL);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-
-/**
- * forte_proc_remove:
- *
- * Removes driver info entries in /proc
- */
-
-static void
-forte_proc_remove (void)
-{
-       remove_proc_entry ("driver/forte/ac97", NULL);
-       remove_proc_entry ("driver/forte/chip", NULL);
-       remove_proc_entry ("driver/forte", NULL);       
-}
-
-
-/**
- * forte_chip_init:
- * @chip:      Chip instance to initialize
- *
- * Description:
- *             Resets chip, configures codec and registers the driver with
- *             the sound subsystem.
- *
- *             Press and hold Start for 8 secs, then switch on Run
- *             and hold for 4 seconds.  Let go of Start.  Numbers
- *             assume a properly oiled TWG.
- */
-
-static int __devinit
-forte_chip_init (struct forte_chip *chip)
-{
-       u8 revision;
-       u16 cmdw;
-       struct ac97_codec *codec;
-
-       pci_read_config_byte (chip->pci_dev, PCI_REVISION_ID, &revision);
-
-       if (revision >= 0xB1) {
-               chip->multichannel = 1;
-               printk (KERN_INFO PFX "Multi-channel device detected.\n");
-       }
-
-       /* Reset chip */
-       outw (FORTE_CC_CODEC_RESET | FORTE_CC_AC97_RESET, 
-             chip->iobase + FORTE_CODEC_CTRL);
-       udelay(100);
-       outw (0, chip->iobase + FORTE_CODEC_CTRL);
-
-       /* Request read from AC97 */
-       outw (FORTE_AC97_READ | (0 << FORTE_AC97_ADDR_SHIFT), 
-             chip->iobase + FORTE_AC97_CMD);
-       mdelay(750);
-
-       if ((inw (chip->iobase + FORTE_AC97_CMD) & (3<<8)) != (1<<8)) {
-               printk (KERN_INFO PFX "AC97 codec not responding");
-               return -EIO;
-       }
-
-       /* Init volume */
-       outw (0x0808, chip->iobase + FORTE_PCM_VOL);
-       outw (0x9f1f, chip->iobase + FORTE_FM_VOL);
-       outw (0x8808, chip->iobase + FORTE_I2S_VOL);
-
-       /* I2S control - I2S mode */
-       outw (0x0003, chip->iobase + FORTE_I2S_MODE);
-
-       /* Interrupt setup - unmask PLAYBACK & CAPTURE */
-       cmdw = inw (chip->iobase + FORTE_IRQ_MASK);
-       cmdw &= ~0x0003;
-       outw (cmdw, chip->iobase + FORTE_IRQ_MASK);
-
-       /* Interrupt clear */
-       outw (FORTE_IRQ_PLAYBACK|FORTE_IRQ_CAPTURE, 
-             chip->iobase + FORTE_IRQ_STATUS);
-
-       /* Set up the AC97 codec */
-       if ((codec = ac97_alloc_codec()) == NULL)
-               return -ENOMEM;
-       codec->private_data = chip;
-       codec->codec_read = forte_ac97_read;
-       codec->codec_write = forte_ac97_write;
-       codec->id = 0;
-
-       if (ac97_probe_codec (codec) == 0) {
-               printk (KERN_ERR PFX "codec probe failed\n");
-               ac97_release_codec(codec);
-               return -1;
-       }
-
-       /* Register mixer */
-       if ((codec->dev_mixer = 
-            register_sound_mixer (&forte_mixer_fops, -1)) < 0) {
-               printk (KERN_ERR PFX "couldn't register mixer!\n");
-               ac97_release_codec(codec);
-               return -1;
-       }
-
-       chip->ac97 = codec;
-
-       /* Register DSP */
-       if ((chip->dsp = register_sound_dsp (&forte_dsp_fops, -1) ) < 0) {
-               printk (KERN_ERR PFX "couldn't register dsp!\n");
-               return -1;
-       }
-
-       /* Register with /proc */
-       if (forte_proc_init()) {
-               printk (KERN_ERR PFX "couldn't add entries to /proc!\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/**
- * forte_probe:
- * @pci_dev:   PCI struct for probed device
- * @pci_id:    
- *
- * Description:
- *             Allocates chip instance, I/O region, and IRQ
- */
-static int __init 
-forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-       struct forte_chip *chip;
-       int ret = 0;
-
-       /* FIXME: Support more than one chip */
-       if (found++)
-               return -EIO;
-
-       /* Ignition */
-       if (pci_enable_device (pci_dev))
-               return -EIO;
-
-       pci_set_master (pci_dev);
-
-       /* Allocate chip instance and configure */
-       forte = (struct forte_chip *) 
-               kmalloc (sizeof (struct forte_chip), GFP_KERNEL);
-       chip = forte;
-
-       if (chip == NULL) {
-               printk (KERN_WARNING PFX "Out of memory");
-               return -ENOMEM;
-       }
-
-       memset (chip, 0, sizeof (struct forte_chip));
-       chip->pci_dev = pci_dev;
-
-       mutex_init(&chip->open_mutex);
-       spin_lock_init (&chip->lock);
-       spin_lock_init (&chip->ac97_lock);
-
-       if (! request_region (pci_resource_start (pci_dev, 0),
-                             pci_resource_len (pci_dev, 0), DRIVER_NAME)) {
-               printk (KERN_WARNING PFX "Unable to reserve I/O space");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       chip->iobase = pci_resource_start (pci_dev, 0);
-       chip->irq = pci_dev->irq;
-
-       if (request_irq (chip->irq, forte_interrupt, IRQF_SHARED, DRIVER_NAME,
-                        chip)) {
-               printk (KERN_WARNING PFX "Unable to reserve IRQ");
-               ret = -EIO;
-               goto error;
-       }               
-       
-       pci_set_drvdata (pci_dev, chip);
-
-       printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%16llX IRQ %u\n",
-               chip->iobase, (unsigned long long)pci_resource_end (pci_dev, 0),
-               chip->irq);
-
-       /* Power it up */
-       if ((ret = forte_chip_init (chip)) == 0)
-               return 0;
-
- error:
-       if (chip->irq)
-               free_irq (chip->irq, chip);
-
-       if (chip->iobase) 
-               release_region (pci_resource_start (pci_dev, 0),
-                               pci_resource_len (pci_dev, 0));
-               
-       kfree (chip);
-
-       return ret;
-}
-
-
-/**
- * forte_remove:
- * @pci_dev:   PCI device to unclaim
- *
- */
-
-static void 
-forte_remove (struct pci_dev *pci_dev)
-{
-       struct forte_chip *chip = pci_get_drvdata (pci_dev);
-
-       if (chip == NULL)
-               return;
-
-       /* Turn volume down to avoid popping */
-       outw (0x1f1f, chip->iobase + FORTE_PCM_VOL);
-       outw (0x1f1f, chip->iobase + FORTE_FM_VOL);
-       outw (0x1f1f, chip->iobase + FORTE_I2S_VOL);
-
-       forte_proc_remove();
-       free_irq (chip->irq, chip);
-       release_region (chip->iobase, pci_resource_len (pci_dev, 0));
-
-       unregister_sound_dsp (chip->dsp);
-       unregister_sound_mixer (chip->ac97->dev_mixer);
-       ac97_release_codec(chip->ac97);
-       kfree (chip);
-
-       printk (KERN_INFO PFX "driver released\n");
-}
-
-
-static struct pci_device_id forte_pci_ids[] = {
-       { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
-       { 0, }
-};
-
-
-static struct pci_driver forte_pci_driver = {
-       .name                   = DRIVER_NAME,
-       .id_table               = forte_pci_ids,
-       .probe                  = forte_probe,
-       .remove                 = forte_remove,
-
-};
-
-
-/**
- * forte_init_module:
- *
- */
-
-static int __init
-forte_init_module (void)
-{
-       printk (KERN_INFO PFX DRIVER_VERSION "\n");
-
-       return pci_register_driver (&forte_pci_driver);
-}
-
-
-/**
- * forte_cleanup_module:
- *
- */
-
-static void __exit 
-forte_cleanup_module (void)
-{
-       pci_unregister_driver (&forte_pci_driver);
-}
-
-
-module_init(forte_init_module);
-module_exit(forte_cleanup_module);
-
-MODULE_AUTHOR("Martin K. Petersen <mkp@mkp.net>");
-MODULE_DESCRIPTION("ForteMedia FM801 OSS Driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE (pci, forte_pci_ids);
diff --git a/sound/oss/gus.h b/sound/oss/gus.h
deleted file mode 100644 (file)
index 3d5271b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-
-#include "ad1848.h"
-
-/*     From gus_card.c */
-int gus_set_midi_irq(int num);
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs * dummy);
-
-/*     From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-void gus_wave_init(struct address_info *hw_config);
-void gus_wave_unload (struct address_info *hw_config);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, void __user *arg);
-void gus_timer_command (unsigned int addr, unsigned int val);
-
-/*     From gus_midi.c */
-void gus_midi_init(struct address_info *hw_config);
-void gus_midi_interrupt(int dummy);
-
-/*     From ics2101.c */
-int ics2101_mixer_init(void);
diff --git a/sound/oss/gus_card.c b/sound/oss/gus_card.c
deleted file mode 100644 (file)
index a3d6ae3..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * sound/oss/gus_card.c
- *
- * Detection routine for the Gravis Ultrasound.
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- *
- * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups.
- *
- * Status:
- *              Tested... 
- */
-      
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy);
-
-int             gus_base = 0, gus_irq = 0, gus_dma = 0;
-int             gus_no_wave_dma = 0; 
-extern int      gus_wave_volume;
-extern int      gus_pcm_volume;
-extern int      have_gus_max;
-int             gus_pnp_flag = 0;
-#ifdef CONFIG_SOUND_GUS16
-static int      db16;  /* Has a Gus16 AD1848 on it */
-#endif
-
-static void __init attach_gus(struct address_info *hw_config)
-{
-       gus_wave_init(hw_config);
-
-       if (sound_alloc_dma(hw_config->dma, "GUS"))
-               printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);
-       if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-               if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))
-                       printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);
-       gus_midi_init(hw_config);
-       if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)
-               printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);
-
-       return;
-}
-
-static int __init probe_gus(struct address_info *hw_config)
-{
-       int             irq;
-       int             io_addr;
-
-       if (hw_config->card_subtype == 1)
-               gus_pnp_flag = 1;
-
-       irq = hw_config->irq;
-
-       if (hw_config->card_subtype == 0)       /* GUS/MAX/ACE */
-               if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
-                   irq != 11 && irq != 12 && irq != 15)
-                 {
-                         printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);
-                         return 0;
-                 }
-       if (gus_wave_detect(hw_config->io_base))
-               return 1;
-
-#ifndef EXCLUDE_GUS_IODETECT
-
-       /*
-        * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
-        */
-
-       for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) {
-               if (io_addr == hw_config->io_base)      /* Already tested */
-                       continue;
-               if (gus_wave_detect(io_addr)) {
-                       hw_config->io_base = io_addr;
-                       return 1;
-               }
-       }
-#endif
-
-       printk("NO GUS card found !\n");
-       return 0;
-}
-
-static void __exit unload_gus(struct address_info *hw_config)
-{
-       DDB(printk("unload_gus(%x)\n", hw_config->io_base));
-
-       gus_wave_unload(hw_config);
-
-       release_region(hw_config->io_base, 16);
-       release_region(hw_config->io_base + 0x100, 12);         /* 0x10c-> is MAX */
-       free_irq(hw_config->irq, hw_config);
-
-       sound_free_dma(hw_config->dma);
-
-       if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)
-               sound_free_dma(hw_config->dma2);
-}
-
-irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       unsigned char src;
-       extern int gus_timer_enabled;
-       int handled = 0;
-
-#ifdef CONFIG_SOUND_GUSMAX
-       if (have_gus_max) {
-               struct address_info *hw_config = dev_id;
-               adintr(irq, (void *)hw_config->slots[1], NULL);
-       }
-#endif
-#ifdef CONFIG_SOUND_GUS16
-       if (db16) {
-               struct address_info *hw_config = dev_id;
-               adintr(irq, (void *)hw_config->slots[3], NULL);
-       }
-#endif
-
-       while (1)
-       {
-               if (!(src = inb(u_IrqStatus)))
-                       break;
-               handled = 1;
-               if (src & DMA_TC_IRQ)
-               {
-                       guswave_dma_irq();
-               }
-               if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
-               {
-                       gus_midi_interrupt(0);
-               }
-               if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
-               {
-                       if (gus_timer_enabled)
-                               sound_timer_interrupt();
-                       gus_write8(0x45, 0);    /* Ack IRQ */
-                       gus_timer_command(4, 0x80);             /* Reset IRQ flags */
-               }
-               if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
-                       gus_voice_irq();
-       }
-       return IRQ_RETVAL(handled);
-}
-
-/*
- *     Some extra code for the 16 bit sampling option
- */
-
-#ifdef CONFIG_SOUND_GUS16
-
-static int __init init_gus_db16(struct address_info *hw_config)
-{
-       struct resource *ports;
-
-       ports = request_region(hw_config->io_base, 4, "ad1848");
-       if (!ports)
-               return 0;
-
-       if (!ad1848_detect(ports, NULL, hw_config->osp)) {
-               release_region(hw_config->io_base, 4);
-               return 0;
-       }
-
-       gus_pcm_volume = 100;
-       gus_wave_volume = 90;
-
-       hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports,
-                                         hw_config->irq,
-                                         hw_config->dma,
-                                         hw_config->dma, 0,
-                                         hw_config->osp,
-                                         THIS_MODULE);
-       return 1;
-}
-
-static void __exit unload_gus_db16(struct address_info *hw_config)
-{
-
-       ad1848_unload(hw_config->io_base,
-                     hw_config->irq,
-                     hw_config->dma,
-                     hw_config->dma, 0);
-       sound_unload_audiodev(hw_config->slots[3]);
-}
-#endif
-
-#ifdef CONFIG_SOUND_GUS16
-static int gus16;
-#endif
-#ifdef CONFIG_SOUND_GUSMAX
-static int no_wave_dma;   /* Set if no dma is to be used for the
-                                   wave table (GF1 chip) */
-#endif
-
-
-/*
- *    Note DMA2 of -1 has the right meaning in the GUS driver as well
- *      as here. 
- */
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1;      /* Set this for modules that need it */
-static int __initdata type = 0;                /* 1 for PnP */
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(type, int, 0);
-#ifdef CONFIG_SOUND_GUSMAX
-module_param(no_wave_dma, int, 0);
-#endif
-#ifdef CONFIG_SOUND_GUS16
-module_param(db16, int, 0);
-module_param(gus16, int, 0);
-#endif
-MODULE_LICENSE("GPL");
-
-static int __init init_gus(void)
-{
-       printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma16;
-       cfg.card_subtype = type;
-#ifdef CONFIG_SOUND_GUSMAX
-       gus_no_wave_dma = no_wave_dma;
-#endif
-
-       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-               printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");
-               return -EINVAL;
-       }
-
-#ifdef CONFIG_SOUND_GUS16
-       if (gus16 && init_gus_db16(&cfg))
-               db16 = 1;
-#endif
-       if (!probe_gus(&cfg))
-               return -ENODEV;
-       attach_gus(&cfg);
-
-       return 0;
-}
-
-static void __exit cleanup_gus(void)
-{
-#ifdef CONFIG_SOUND_GUS16
-       if (db16)
-               unload_gus_db16(&cfg);
-#endif
-       unload_gus(&cfg);
-}
-
-module_init(init_gus);
-module_exit(cleanup_gus);
-
-#ifndef MODULE
-static int __init setup_gus(char *str)
-{
-       /* io, irq, dma, dma2 */
-       int ints[5];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma16   = ints[4];
-
-       return 1;
-}
-
-__setup("gus=", setup_gus);
-#endif
diff --git a/sound/oss/gus_hw.h b/sound/oss/gus_hw.h
deleted file mode 100644 (file)
index f97a0b8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * I/O addresses
- */
-
-#define u_Base                 (gus_base + 0x000)
-#define u_Mixer                        u_Base
-#define u_Status               (gus_base + 0x006)
-#define u_TimerControl         (gus_base + 0x008)
-#define u_TimerData            (gus_base + 0x009)
-#define u_IRQDMAControl                (gus_base + 0x00b)
-#define u_MidiControl          (gus_base + 0x100)
-#define        MIDI_RESET              0x03
-#define                MIDI_ENABLE_XMIT        0x20
-#define                MIDI_ENABLE_RCV         0x80
-#define u_MidiStatus           u_MidiControl
-#define                MIDI_RCV_FULL           0x01
-#define        MIDI_XMIT_EMPTY         0x02
-#define        MIDI_FRAME_ERR          0x10
-#define        MIDI_OVERRUN            0x20
-#define        MIDI_IRQ_PEND           0x80
-#define u_MidiData             (gus_base + 0x101)
-#define u_Voice                        (gus_base + 0x102)
-#define u_Command              (gus_base + 0x103)
-#define u_DataLo               (gus_base + 0x104)
-#define u_DataHi               (gus_base + 0x105)
-#define u_MixData               (gus_base + 0x106)   /* Rev. 3.7+ mixing */
-#define u_MixSelect             (gus_base + 0x506)   /* registers.       */
-#define u_IrqStatus            u_Status
-#      define MIDI_TX_IRQ              0x01    /* pending MIDI xmit IRQ */
-#      define MIDI_RX_IRQ              0x02    /* pending MIDI recv IRQ */
-#      define GF1_TIMER1_IRQ           0x04    /* general purpose timer */
-#      define GF1_TIMER2_IRQ           0x08    /* general purpose timer */
-#      define WAVETABLE_IRQ            0x20    /* pending wavetable IRQ */
-#      define ENVELOPE_IRQ             0x40    /* pending volume envelope IRQ */
-#      define DMA_TC_IRQ               0x80    /* pending dma tc IRQ */
-
-#define ICS2101                1
-#      define ICS_MIXDEVS      6
-#      define DEV_MIC          0
-#      define DEV_LINE         1
-#      define DEV_CD           2
-#      define DEV_GF1          3
-#      define DEV_UNUSED       4
-#      define DEV_VOL          5
-
-#      define CHN_LEFT         0
-#      define CHN_RIGHT        1
-#define CS4231         2
-#define u_DRAMIO               (gus_base + 0x107)
diff --git a/sound/oss/gus_linearvol.h b/sound/oss/gus_linearvol.h
deleted file mode 100644 (file)
index 7ad0c30..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-static unsigned short gus_linearvol[128] = {
- 0x0000, 0x08ff, 0x09ff, 0x0a80, 0x0aff, 0x0b40, 0x0b80, 0x0bc0,
- 0x0bff, 0x0c20, 0x0c40, 0x0c60, 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0,
- 0x0cff, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70,
- 0x0d80, 0x0d90, 0x0da0, 0x0db0, 0x0dc0, 0x0dd0, 0x0de0, 0x0df0,
- 0x0dff, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38,
- 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78,
- 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8,
- 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8,
- 0x0eff, 0x0f04, 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c,
- 0x0f20, 0x0f24, 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3c,
- 0x0f40, 0x0f44, 0x0f48, 0x0f4c, 0x0f50, 0x0f54, 0x0f58, 0x0f5c,
- 0x0f60, 0x0f64, 0x0f68, 0x0f6c, 0x0f70, 0x0f74, 0x0f78, 0x0f7c,
- 0x0f80, 0x0f84, 0x0f88, 0x0f8c, 0x0f90, 0x0f94, 0x0f98, 0x0f9c,
- 0x0fa0, 0x0fa4, 0x0fa8, 0x0fac, 0x0fb0, 0x0fb4, 0x0fb8, 0x0fbc,
- 0x0fc0, 0x0fc4, 0x0fc8, 0x0fcc, 0x0fd0, 0x0fd4, 0x0fd8, 0x0fdc,
- 0x0fe0, 0x0fe4, 0x0fe8, 0x0fec, 0x0ff0, 0x0ff4, 0x0ff8, 0x0ffc
-};
diff --git a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c
deleted file mode 100644 (file)
index d1997a4..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * sound/oss/gus_midi.c
- *
- * The low level driver for the GUS Midi Interface.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added __init to gus_midi_init()
- */
-
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_hw.h"
-
-static int      midi_busy, input_opened;
-static int      my_dev;
-static int      output_used;
-static volatile unsigned char gus_midi_control;
-static void     (*midi_input_intr) (int dev, unsigned char data);
-
-static unsigned char tmp_queue[256];
-extern int      gus_pnp_flag;
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-extern int      gus_base, gus_irq, gus_dma;
-extern int     *gus_osp;
-extern spinlock_t gus_lock;
-
-static int GUS_MIDI_STATUS(void)
-{
-       return inb(u_MidiStatus);
-}
-
-static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev))
-{
-       if (midi_busy)
-       {
-/*             printk("GUS: Midi busy\n");*/
-               return -EBUSY;
-       }
-       outb((MIDI_RESET), u_MidiControl);
-       gus_delay();
-
-       gus_midi_control = 0;
-       input_opened = 0;
-
-       if (mode == OPEN_READ || mode == OPEN_READWRITE)
-               if (!gus_pnp_flag)
-               {
-                       gus_midi_control |= MIDI_ENABLE_RCV;
-                       input_opened = 1;
-               }
-       outb((gus_midi_control), u_MidiControl);        /* Enable */
-
-       midi_busy = 1;
-       qlen = qhead = qtail = output_used = 0;
-       midi_input_intr = input;
-
-       return 0;
-}
-
-static int dump_to_midi(unsigned char midi_byte)
-{
-       unsigned long   flags;
-       int             ok = 0;
-
-       output_used = 1;
-
-       spin_lock_irqsave(&gus_lock, flags);
-
-       if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY)
-       {
-               ok = 1;
-               outb((midi_byte), u_MidiData);
-       }
-       else
-       {
-               /*
-                * Enable Midi xmit interrupts (again)
-                */
-               gus_midi_control |= MIDI_ENABLE_XMIT;
-               outb((gus_midi_control), u_MidiControl);
-       }
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return ok;
-}
-
-static void gus_midi_close(int dev)
-{
-       /*
-        * Reset FIFO pointers, disable intrs
-        */
-
-       outb((MIDI_RESET), u_MidiControl);
-       midi_busy = 0;
-}
-
-static int gus_midi_out(int dev, unsigned char midi_byte)
-{
-       unsigned long   flags;
-
-       /*
-        * Drain the local queue first
-        */
-       spin_lock_irqsave(&gus_lock, flags);
-
-       while (qlen && dump_to_midi(tmp_queue[qhead]))
-       {
-               qlen--;
-               qhead++;
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       /*
-        *      Output the byte if the local queue is empty.
-        */
-
-       if (!qlen)
-               if (dump_to_midi(midi_byte))
-                       return 1;       /*
-                                        * OK
-                                        */
-
-       /*
-        *      Put to the local queue
-        */
-
-       if (qlen >= 256)
-               return 0;       /*
-                                * Local queue full
-                                */
-       spin_lock_irqsave(&gus_lock, flags);
-
-       tmp_queue[qtail] = midi_byte;
-       qlen++;
-       qtail++;
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return 1;
-}
-
-static int gus_midi_start_read(int dev)
-{
-       return 0;
-}
-
-static int gus_midi_end_read(int dev)
-{
-       return 0;
-}
-
-static void gus_midi_kick(int dev)
-{
-}
-
-static int gus_midi_buffer_status(int dev)
-{
-       unsigned long   flags;
-
-       if (!output_used)
-               return 0;
-
-       spin_lock_irqsave(&gus_lock, flags);
-
-       if (qlen && dump_to_midi(tmp_queue[qhead]))
-       {
-               qlen--;
-               qhead++;
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY);
-}
-
-#define MIDI_SYNTH_NAME        "Gravis Ultrasound Midi"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct midi_operations gus_midi_operations =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
-       .converter      = &std_midi_synth,
-       .in_info        = {0},
-       .open           = gus_midi_open,
-       .close          = gus_midi_close,
-       .outputc        = gus_midi_out,
-       .start_read     = gus_midi_start_read,
-       .end_read       = gus_midi_end_read,
-       .kick           = gus_midi_kick,
-       .buffer_status  = gus_midi_buffer_status,
-};
-
-void __init gus_midi_init(struct address_info *hw_config)
-{
-       int dev = sound_alloc_mididev();
-
-       if (dev == -1)
-       {
-               printk(KERN_INFO "gus_midi: Too many midi devices detected\n");
-               return;
-       }
-       outb((MIDI_RESET), u_MidiControl);
-
-       std_midi_synth.midi_dev = my_dev = dev;
-       hw_config->slots[2] = dev;
-       midi_devs[dev] = &gus_midi_operations;
-       sequencer_init();
-       return;
-}
-
-void gus_midi_interrupt(int dummy)
-{
-       volatile unsigned char stat, data;
-       int timeout = 10;
-
-       spin_lock(&gus_lock);
-
-       while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
-       {
-               if (stat & MIDI_RCV_FULL)
-               {
-                       data = inb(u_MidiData);
-                       if (input_opened)
-                               midi_input_intr(my_dev, data);
-               }
-               if (stat & MIDI_XMIT_EMPTY)
-               {
-                       while (qlen && dump_to_midi(tmp_queue[qhead]))
-                       {
-                               qlen--;
-                               qhead++;
-                       }
-                       if (!qlen)
-                       {
-                             /*
-                              * Disable Midi output interrupts, since no data in the buffer
-                              */
-                             gus_midi_control &= ~MIDI_ENABLE_XMIT;
-                             outb((gus_midi_control), u_MidiControl);
-                             outb((gus_midi_control), u_MidiControl);
-                       }
-               }
-       }
-       spin_unlock(&gus_lock);
-}
diff --git a/sound/oss/gus_vol.c b/sound/oss/gus_vol.c
deleted file mode 100644 (file)
index 6ae6924..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-
-/*
- * gus_vol.c - Compute volume for GUS.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-#include "sound_config.h"
-
-#include "gus.h"
-#include "gus_linearvol.h"
-
-#define GUS_VOLUME     gus_wave_volume
-
-
-extern int      gus_wave_volume;
-
-/*
- * Calculate gus volume from note velocity, main volume, expression, and
- * intrinsic patch volume given in patch library.  Expression is multiplied
- * in, so it emphasizes differences in note velocity, while main volume is
- * added in -- I don't know whether this is right, but it seems reasonable to
- * me.  (In the previous stage, main volume controller messages were changed
- * to expression controller messages, if they were found to be used for
- * dynamic volume adjustments, so here, main volume can be assumed to be
- * constant throughout a song.)
- *
- * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
- * we can give a big boost to very weak voices like nylon guitar and the
- * basses.  The normal value is 64.  Strings are assigned lower values.
- */
-
-unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev)
-{
-       int i, m, n, x;
-
-
-       /*
-        * A voice volume of 64 is considered neutral, so adjust the main volume if
-        * something other than this neutral value was assigned in the patch
-        * library.
-        */
-       x = 256 + 6 * (voicev - 64);
-
-       /*
-        * Boost expression by voice volume above neutral.
-        */
-        
-       if (voicev > 65)
-               xpn += voicev - 64;
-       xpn += (voicev - 64) / 2;
-
-       /*
-        * Combine multiplicative and level components.
-        */
-       x = vel * xpn * 6 + (voicev / 4) * x;
-
-#ifdef GUS_VOLUME
-       /*
-        * Further adjustment by installation-specific master volume control
-        * (default 60).
-        */
-       x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-       /*
-        * Experimental support for the channel main volume
-        */
-
-       mainv = (mainv / 2) + 64;       /* Scale to 64 to 127 */
-       x = (x * mainv * mainv) / 16384;
-#endif
-
-       if (x < 2)
-               return (0);
-       else if (x >= 65535)
-               return ((15 << 8) | 255);
-
-       /*
-        * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit
-        * mantissa m.
-        */
-        
-       n = x;
-       i = 7;
-       if (n < 128)
-       {
-                 while (i > 0 && n < (1 << i))
-                         i--;
-       }
-       else
-       {
-               while (n > 255)
-               {
-                         n >>= 1;
-                         i++;
-               }
-       }
-       /*
-        * Mantissa is part of linear volume not expressed in exponent.  (This is
-        * not quite like real logs -- I wonder if it's right.)
-        */
-       m = x - (1 << i);
-
-       /*
-        * Adjust mantissa to 8 bits.
-        */
-       if (m > 0)
-       {
-               if (i > 8)
-                       m >>= i - 8;
-               else if (i < 8)
-                       m <<= 8 - i;
-       }
-       return ((i << 8) + m);
-}
-
-/*
- * Volume-values are interpreted as linear values. Volume is based on the
- * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
- * and the volume set by the mixer-device (default 60%).
- */
-
-unsigned short gus_linear_vol(int vol, int mainvol)
-{
-       int mixer_mainvol;
-
-       if (vol <= 0)
-               vol = 0;
-       else if (vol >= 127)
-               vol = 127;
-
-#ifdef GUS_VOLUME
-       mixer_mainvol = GUS_VOLUME;
-#else
-       mixer_mainvol = 100;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
-       if (mainvol <= 0)
-               mainvol = 0;
-       else if (mainvol >= 127)
-               mainvol = 127;
-#else
-       mainvol = 127;
-#endif
-       return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100];
-}
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c
deleted file mode 100644 (file)
index 597db7a..0000000
+++ /dev/null
@@ -1,3464 +0,0 @@
-/*
- * sound/oss/gus_wave.c
- *
- * Driver for the Gravis UltraSound wave table synth.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer    : ioctl code reworked (vmalloc/vfree removed)
- * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious
- *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX.
- * Bartlomiej Zolnierkiewicz : added some __init/__exit
- */
-#include <linux/init.h> 
-#include <linux/config.h>
-#include <linux/spinlock.h>
-
-#define GUSPNP_AUTODETECT
-
-#include "sound_config.h"
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024))
-
-#define MAX_SAMPLE     150
-#define MAX_PATCH      256
-
-#define NOT_SAMPLE     0xffff
-
-struct voice_info
-{
-       unsigned long   orig_freq;
-       unsigned long   current_freq;
-       unsigned long   mode;
-       int             fixed_pitch;
-       int             bender;
-       int             bender_range;
-       int             panning;
-       int             midi_volume;
-       unsigned int    initial_volume;
-       unsigned int    current_volume;
-       int             loop_irq_mode, loop_irq_parm;
-#define LMODE_FINISH           1
-#define LMODE_PCM              2
-#define LMODE_PCM_STOP         3
-       int             volume_irq_mode, volume_irq_parm;
-#define VMODE_HALT             1
-#define VMODE_ENVELOPE         2
-#define VMODE_START_NOTE       3
-
-       int             env_phase;
-       unsigned char   env_rate[6];
-       unsigned char   env_offset[6];
-
-       /*
-        * Volume computation parameters for gus_adagio_vol()
-        */
-       int             main_vol, expression_vol, patch_vol;
-
-       /* Variables for "Ultraclick" removal */
-       int             dev_pending, note_pending, volume_pending,
-                       sample_pending;
-       char            kill_pending;
-       long            offset_pending;
-
-};
-
-static struct voice_alloc_info *voice_alloc;
-static struct address_info *gus_hw_config;
-extern int      gus_base;
-extern int      gus_irq, gus_dma;
-extern int      gus_pnp_flag;
-extern int      gus_no_wave_dma;
-static int      gus_dma2 = -1;
-static int      dual_dma_mode;
-static long     gus_mem_size;
-static long     free_mem_ptr;
-static int      gus_busy;
-static int      gus_no_dma;
-static int      nr_voices;
-static int      gus_devnum;
-static int      volume_base, volume_scale, volume_method;
-static int      gus_recmask = SOUND_MASK_MIC;
-static int      recording_active;
-static int      only_read_access;
-static int      only_8_bits;
-
-static int      iw_mode = 0;
-int             gus_wave_volume = 60;
-int             gus_pcm_volume = 80;
-int             have_gus_max = 0;
-static int      gus_line_vol = 100, gus_mic_vol;
-static unsigned char mix_image = 0x00;
-
-int             gus_timer_enabled = 0;
-
-/*
- * Current version of this driver doesn't allow synth and PCM functions
- * at the same time. The active_device specifies the active driver
- */
-
-static int      active_device;
-
-#define GUS_DEV_WAVE           1       /* Wave table synth */
-#define GUS_DEV_PCM_DONE       2       /* PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE   3       /* PCM device, transfer done ch. 1/2 */
-
-static int      gus_audio_speed;
-static int      gus_audio_channels;
-static int      gus_audio_bits;
-static int      gus_audio_bsize;
-static char     bounce_buf[8 * 1024];  /* Must match value set to max_fragment */
-
-static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper);
-
-/*
- * Variables and buffers for PCM output
- */
-
-#define MAX_PCM_BUFFERS                (128*MAX_REALTIME_FACTOR)       /* Don't change */
-
-static int      pcm_bsize, pcm_nblk, pcm_banksize;
-static int      pcm_datasize[MAX_PCM_BUFFERS];
-static volatile int pcm_head, pcm_tail, pcm_qlen;
-static volatile int pcm_active;
-static volatile int dma_active;
-static int      pcm_opened;
-static int      pcm_current_dev;
-static int      pcm_current_block;
-static unsigned long pcm_current_buf;
-static int      pcm_current_count;
-static int      pcm_current_intrflag;
-DEFINE_SPINLOCK(gus_lock);
-
-extern int     *gus_osp;
-
-static struct voice_info voices[32];
-
-static int      freq_div_table[] =
-{
-       44100,                  /* 14 */
-       41160,                  /* 15 */
-       38587,                  /* 16 */
-       36317,                  /* 17 */
-       34300,                  /* 18 */
-       32494,                  /* 19 */
-       30870,                  /* 20 */
-       29400,                  /* 21 */
-       28063,                  /* 22 */
-       26843,                  /* 23 */
-       25725,                  /* 24 */
-       24696,                  /* 25 */
-       23746,                  /* 26 */
-       22866,                  /* 27 */
-       22050,                  /* 28 */
-       21289,                  /* 29 */
-       20580,                  /* 30 */
-       19916,                  /* 31 */
-       19293                   /* 32 */
-};
-
-static struct patch_info *samples;
-static long     sample_ptrs[MAX_SAMPLE + 1];
-static int      sample_map[32];
-static int      free_sample;
-static int      mixer_type;
-
-
-static int      patch_table[MAX_PATCH];
-static int      patch_map[32];
-
-static struct synth_info gus_info = {
-       "Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 
-       0, 16, 0, MAX_PATCH
-};
-
-static void     gus_poke(long addr, unsigned char data);
-static void     compute_and_set_volume(int voice, int volume, int ramp_time);
-extern unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol(int vol, int mainvol);
-static void     compute_volume(int voice, int volume);
-static void     do_volume_irq(int voice);
-static void     set_input_volumes(void);
-static void     gus_tmr_install(int io_base);
-
-#define        INSTANT_RAMP            -1      /* Instant change. No ramping */
-#define FAST_RAMP              0       /* Fastest possible ramp */
-
-static void reset_sample_memory(void)
-{
-       int i;
-
-       for (i = 0; i <= MAX_SAMPLE; i++)
-               sample_ptrs[i] = -1;
-       for (i = 0; i < 32; i++)
-               sample_map[i] = -1;
-       for (i = 0; i < 32; i++)
-               patch_map[i] = -1;
-
-       gus_poke(0, 0);         /* Put a silent sample to the beginning */
-       gus_poke(1, 0);
-       free_mem_ptr = 2;
-
-       free_sample = 0;
-
-       for (i = 0; i < MAX_PATCH; i++)
-               patch_table[i] = NOT_SAMPLE;
-}
-
-void gus_delay(void)
-{
-       int i;
-
-       for (i = 0; i < 7; i++)
-               inb(u_DRAMIO);
-}
-
-static void gus_poke(long addr, unsigned char data)
-{                              /* Writes a byte to the DRAM */
-       outb((0x43), u_Command);
-       outb((addr & 0xff), u_DataLo);
-       outb(((addr >> 8) & 0xff), u_DataHi);
-
-       outb((0x44), u_Command);
-       outb(((addr >> 16) & 0xff), u_DataHi);
-       outb((data), u_DRAMIO);
-}
-
-static unsigned char gus_peek(long addr)
-{                              /* Reads a byte from the DRAM */
-       unsigned char   tmp;
-
-       outb((0x43), u_Command);
-       outb((addr & 0xff), u_DataLo);
-       outb(((addr >> 8) & 0xff), u_DataHi);
-
-       outb((0x44), u_Command);
-       outb(((addr >> 16) & 0xff), u_DataHi);
-       tmp = inb(u_DRAMIO);
-
-       return tmp;
-}
-
-void gus_write8(int reg, unsigned int data)
-{                              /* Writes to an indirect register (8 bit) */
-       outb((reg), u_Command);
-       outb(((unsigned char) (data & 0xff)), u_DataHi);
-}
-
-static unsigned char gus_read8(int reg)
-{                              
-       /* Reads from an indirect register (8 bit). Offset 0x80. */
-       unsigned char   val;
-
-       outb((reg | 0x80), u_Command);
-       val = inb(u_DataHi);
-
-       return val;
-}
-
-static unsigned char gus_look8(int reg)
-{
-       /* Reads from an indirect register (8 bit). No additional offset. */
-       unsigned char   val;
-
-       outb((reg), u_Command);
-       val = inb(u_DataHi);
-
-       return val;
-}
-
-static void gus_write16(int reg, unsigned int data)
-{
-       /* Writes to an indirect register (16 bit) */
-       outb((reg), u_Command);
-
-       outb(((unsigned char) (data & 0xff)), u_DataLo);
-       outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi);
-}
-
-static unsigned short gus_read16(int reg)
-{
-       /* Reads from an indirect register (16 bit). Offset 0x80. */
-       unsigned char   hi, lo;
-
-       outb((reg | 0x80), u_Command);
-
-       lo = inb(u_DataLo);
-       hi = inb(u_DataHi);
-
-       return ((hi << 8) & 0xff00) | lo;
-}
-
-static unsigned short gus_look16(int reg)
-{              
-       /* Reads from an indirect register (16 bit). No additional offset. */
-       unsigned char   hi, lo;
-
-       outb((reg), u_Command);
-
-       lo = inb(u_DataLo);
-       hi = inb(u_DataHi);
-
-       return ((hi << 8) & 0xff00) | lo;
-}
-
-static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit)
-{
-       /* Writes an 24 bit memory address */
-       unsigned long   hold_address;
-
-       if (is16bit)
-       {
-               if (iw_mode)
-               {
-                       /* Interwave spesific address translations */
-                       address >>= 1;
-               }
-               else
-               {
-                       /*
-                        * Special processing required for 16 bit patches
-                        */
-
-                       hold_address = address;
-                       address = address >> 1;
-                       address &= 0x0001ffffL;
-                       address |= (hold_address & 0x000c0000L);
-               }
-       }
-       gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-       gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-                   + (frac << 5));
-       /* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */
-       gus_delay();
-       gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff));
-       gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff)
-                   + (frac << 5));
-}
-
-static void gus_select_voice(int voice)
-{
-       if (voice < 0 || voice > 31)
-               return;
-       outb((voice), u_Voice);
-}
-
-static void gus_select_max_voices(int nvoices)
-{
-       if (iw_mode)
-               nvoices = 32;
-       if (nvoices < 14)
-               nvoices = 14;
-       if (nvoices > 32)
-               nvoices = 32;
-
-       voice_alloc->max_voice = nr_voices = nvoices;
-       gus_write8(0x0e, (nvoices - 1) | 0xc0);
-}
-
-static void gus_voice_on(unsigned int mode)
-{
-       gus_write8(0x00, (unsigned char) (mode & 0xfc));
-       gus_delay();
-       gus_write8(0x00, (unsigned char) (mode & 0xfc));
-}
-
-static void gus_voice_off(void)
-{
-       gus_write8(0x00, gus_read8(0x00) | 0x03);
-}
-
-static void gus_voice_mode(unsigned int m)
-{
-       unsigned char   mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x00, (gus_read8(0x00) & 0x03) |
-                  (mode & 0xfc));      /* Don't touch last two bits */
-       gus_delay();
-       gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_voice_freq(unsigned long freq)
-{
-       unsigned long   divisor = freq_div_table[nr_voices - 14];
-       unsigned short  fc;
-
-       /* Interwave plays at 44100 Hz with any number of voices */
-       if (iw_mode)
-               fc = (unsigned short) (((freq << 9) + (44100 >> 1)) / 44100);
-       else
-               fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
-       fc = fc << 1;
-
-       gus_write16(0x01, fc);
-}
-
-static void gus_voice_volume(unsigned int vol)
-{
-       gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */
-       gus_write16(0x09, (unsigned short) (vol << 4));
-}
-
-static void gus_voice_balance(unsigned int balance)
-{
-       gus_write8(0x0c, (unsigned char) (balance & 0xff));
-}
-
-static void gus_ramp_range(unsigned int low, unsigned int high)
-{
-       gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff));
-       gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff));
-}
-
-static void gus_ramp_rate(unsigned int scale, unsigned int rate)
-{
-       gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
-}
-
-static void gus_rampon(unsigned int m)
-{
-       unsigned char   mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x0d, mode & 0xfc);
-       gus_delay();
-       gus_write8(0x0d, mode & 0xfc);
-}
-
-static void gus_ramp_mode(unsigned int m)
-{
-       unsigned char mode = (unsigned char) (m & 0xff);
-
-       gus_write8(0x0d, (gus_read8(0x0d) & 0x03) |
-                  (mode & 0xfc));      /* Leave the last 2 bits alone */
-       gus_delay();
-       gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc));
-}
-
-static void gus_rampoff(void)
-{
-       gus_write8(0x0d, 0x03);
-}
-
-static void gus_set_voice_pos(int voice, long position)
-{
-       int sample_no;
-
-       if ((sample_no = sample_map[voice]) != -1) {
-               if (position < samples[sample_no].len) {
-                       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-                               voices[voice].offset_pending = position;
-                       else
-                               gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0,
-                                samples[sample_no].mode & WAVE_16_BITS);
-               }
-       }
-}
-
-static void gus_voice_init(int voice)
-{
-       unsigned long   flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_volume(0);
-       gus_voice_off();
-       gus_write_addr(0x0a, 0, 0, 0);  /* Set current position to 0 */
-       gus_write8(0x00, 0x03); /* Voice off */
-       gus_write8(0x0d, 0x03); /* Ramping off */
-       voice_alloc->map[voice] = 0;
-       voice_alloc->alloc_times[voice] = 0;
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-}
-
-static void gus_voice_init2(int voice)
-{
-       voices[voice].panning = 0;
-       voices[voice].mode = 0;
-       voices[voice].orig_freq = 20000;
-       voices[voice].current_freq = 20000;
-       voices[voice].bender = 0;
-       voices[voice].bender_range = 200;
-       voices[voice].initial_volume = 0;
-       voices[voice].current_volume = 0;
-       voices[voice].loop_irq_mode = 0;
-       voices[voice].loop_irq_parm = 0;
-       voices[voice].volume_irq_mode = 0;
-       voices[voice].volume_irq_parm = 0;
-       voices[voice].env_phase = 0;
-       voices[voice].main_vol = 127;
-       voices[voice].patch_vol = 127;
-       voices[voice].expression_vol = 127;
-       voices[voice].sample_pending = -1;
-       voices[voice].fixed_pitch = 0;
-}
-
-static void step_envelope(int voice)
-{
-       unsigned        vol, prev_vol, phase;
-       unsigned char   rate;
-       unsigned long flags;
-
-       if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
-       {
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(voice);
-               gus_rampoff();
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-               /*
-                * Sustain phase begins. Continue envelope after receiving note off.
-                */
-       }
-       if (voices[voice].env_phase >= 5)
-       {
-               /* Envelope finished. Shoot the voice down */
-               gus_voice_init(voice);
-               return;
-       }
-       prev_vol = voices[voice].current_volume;
-       phase = ++voices[voice].env_phase;
-       compute_volume(voice, voices[voice].midi_volume);
-       vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
-       rate = voices[voice].env_rate[phase];
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       gus_voice_volume(prev_vol);
-
-
-       gus_write8(0x06, rate); /* Ramping rate */
-
-       voices[voice].volume_irq_mode = VMODE_ENVELOPE;
-
-       if (((vol - prev_vol) / 64) == 0)       /* No significant volume change */
-       {
-               spin_unlock_irqrestore(&gus_lock,flags);
-               step_envelope(voice);           /* Continue the envelope on the next step */
-               return;
-       }
-       if (vol > prev_vol)
-       {
-               if (vol >= (4096 - 64))
-                       vol = 4096 - 65;
-               gus_ramp_range(0, vol);
-               gus_rampon(0x20);       /* Increasing volume, with IRQ */
-       }
-       else
-       {
-               if (vol <= 64)
-                       vol = 65;
-               gus_ramp_range(vol, 4030);
-               gus_rampon(0x60);       /* Decreasing volume, with IRQ */
-       }
-       voices[voice].current_volume = vol;
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void init_envelope(int voice)
-{
-       voices[voice].env_phase = -1;
-       voices[voice].current_volume = 64;
-
-       step_envelope(voice);
-}
-
-static void start_release(int voice)
-{
-       if (gus_read8(0x00) & 0x03)
-               return;         /* Voice already stopped */
-
-       voices[voice].env_phase = 2;    /* Will be incremented by step_envelope */
-
-       voices[voice].current_volume = voices[voice].initial_volume =
-                                               gus_read16(0x09) >> 4;  /* Get current volume */
-
-       voices[voice].mode &= ~WAVE_SUSTAIN_ON;
-       gus_rampoff();
-       step_envelope(voice);
-}
-
-static void gus_voice_fade(int voice)
-{
-       int instr_no = sample_map[voice], is16bits;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       if (instr_no < 0 || instr_no > MAX_SAMPLE)
-       {
-               gus_write8(0x00, 0x03); /* Hard stop */
-               voice_alloc->map[voice] = 0;
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0;     /* 8 or 16 bits */
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               start_release(voice);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       /*
-        * Ramp the volume down but not too quickly.
-        */
-       if ((int) (gus_read16(0x09) >> 4) < 100)        /* Get current volume */
-       {
-               gus_voice_off();
-               gus_rampoff();
-               gus_voice_init(voice);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       gus_ramp_range(65, 4030);
-       gus_ramp_rate(2, 4);
-       gus_rampon(0x40 | 0x20);        /* Down, once, with IRQ */
-       voices[voice].volume_irq_mode = VMODE_HALT;
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_reset(void)
-{
-       int i;
-
-       gus_select_max_voices(24);
-       volume_base = 3071;
-       volume_scale = 4;
-       volume_method = VOL_METHOD_ADAGIO;
-
-       for (i = 0; i < 32; i++)
-       {
-               gus_voice_init(i);      /* Turn voice off */
-               gus_voice_init2(i);
-       }
-}
-
-static void gus_initialize(void)
-{
-       unsigned long flags;
-       unsigned char dma_image, irq_image, tmp;
-
-       static unsigned char gus_irq_map[16] =  {
-               0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7
-       };
-
-       static unsigned char gus_dma_map[8] = {
-               0, 1, 0, 2, 0, 3, 4, 5
-       };
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_write8(0x4c, 0);    /* Reset GF1 */
-       gus_delay();
-       gus_delay();
-
-       gus_write8(0x4c, 1);    /* Release Reset */
-       gus_delay();
-       gus_delay();
-
-       /*
-        * Clear all interrupts
-        */
-
-       gus_write8(0x41, 0);    /* DMA control */
-       gus_write8(0x45, 0);    /* Timer control */
-       gus_write8(0x49, 0);    /* Sample control */
-
-       gus_select_max_voices(24);
-
-       inb(u_Status);          /* Touch the status register */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       gus_reset();            /* Resets all voices */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       gus_write8(0x4c, 7);    /* Master reset | DAC enable | IRQ enable */
-
-       /*
-        * Set up for Digital ASIC
-        */
-
-       outb((0x05), gus_base + 0x0f);
-
-       mix_image |= 0x02;      /* Disable line out (for a moment) */
-       outb((mix_image), u_Mixer);
-
-       outb((0x00), u_IRQDMAControl);
-
-       outb((0x00), gus_base + 0x0f);
-
-       /*
-        * Now set up the DMA and IRQ interface
-        *
-        * The GUS supports two IRQs and two DMAs.
-        *
-        * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
-        * Adding this support requires significant changes to the dmabuf.c, dsp.c
-        * and audio.c also.
-        */
-
-       irq_image = 0;
-       tmp = gus_irq_map[gus_irq];
-       if (!gus_pnp_flag && !tmp)
-               printk(KERN_WARNING "Warning! GUS IRQ not selected\n");
-       irq_image |= tmp;
-       irq_image |= 0x40;      /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
-
-       dual_dma_mode = 1;
-       if (gus_dma2 == gus_dma || gus_dma2 == -1)
-       {
-               dual_dma_mode = 0;
-               dma_image = 0x40;       /* Combine DMA1 (DRAM) and IRQ2 (ADC) */
-
-               tmp = gus_dma_map[gus_dma];
-               if (!tmp)
-                       printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-               dma_image |= tmp;
-       }
-       else
-       {
-               /* Setup dual DMA channel mode for GUS MAX */
-
-               dma_image = gus_dma_map[gus_dma];
-               if (!dma_image)
-                       printk(KERN_WARNING "Warning! GUS DMA not selected\n");
-
-               tmp = gus_dma_map[gus_dma2] << 3;
-               if (!tmp)
-               {
-                       printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n");
-                       tmp = 0x40;             /* Combine DMA channels */
-                           dual_dma_mode = 0;
-               }
-               dma_image |= tmp;
-       }
-
-       /*
-        * For some reason the IRQ and DMA addresses must be written twice
-        */
-
-       /*
-        * Doing it first time
-        */
-
-       outb((mix_image), u_Mixer);     /* Select DMA control */
-       outb((dma_image | 0x80), u_IRQDMAControl);      /* Set DMA address */
-
-       outb((mix_image | 0x40), u_Mixer);      /* Select IRQ control */
-       outb((irq_image), u_IRQDMAControl);     /* Set IRQ address */
-
-       /*
-        * Doing it second time
-        */
-
-       outb((mix_image), u_Mixer);     /* Select DMA control */
-       outb((dma_image), u_IRQDMAControl);     /* Set DMA address */
-
-       outb((mix_image | 0x40), u_Mixer);      /* Select IRQ control */
-       outb((irq_image), u_IRQDMAControl);     /* Set IRQ address */
-
-       gus_select_voice(0);    /* This disables writes to IRQ/DMA reg */
-
-       mix_image &= ~0x02;     /* Enable line out */
-       mix_image |= 0x08;      /* Enable IRQ */
-       outb((mix_image), u_Mixer);     /*
-                                        * Turn mixer channels on
-                                        * Note! Mic in is left off.
-                                        */
-
-       gus_select_voice(0);    /* This disables writes to IRQ/DMA reg */
-
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-
-       inb(u_Status);          /* Touch the status register */
-
-       gus_look8(0x41);        /* Clear any pending DMA IRQs */
-       gus_look8(0x49);        /* Clear any pending sample IRQs */
-
-       gus_read8(0x0f);        /* Clear pending IRQs */
-
-       if (iw_mode)
-               gus_write8(0x19, gus_read8(0x19) | 0x01);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-
-static void __init pnp_mem_init(void)
-{
-#include "iwmem.h"
-#define CHUNK_SIZE (256*1024)
-#define BANK_SIZE (4*1024*1024)
-#define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE)
-
-       int bank, chunk, addr, total = 0;
-       int bank_sizes[4];
-       int i, j, bits = -1, testbits = -1, nbanks = 0;
-
-       /*
-        * This routine determines what kind of RAM is installed in each of the four
-        * SIMM banks and configures the DRAM address decode logic accordingly.
-        */
-
-       /*
-        *    Place the chip into enhanced mode
-        */
-       gus_write8(0x19, gus_read8(0x19) | 0x01);
-       gus_write8(0x53, gus_look8(0x53) & ~0x02);      /* Select DRAM I/O access */
-
-       /*
-        * Set memory configuration to 4 DRAM banks of 4M in each (16M total).
-        */
-
-       gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c);
-
-       /*
-        * Perform the DRAM size detection for each bank individually.
-        */
-       for (bank = 0; bank < 4; bank++)
-       {
-               int size = 0;
-
-               addr = bank * BANK_SIZE;
-
-               /* Clean check points of each chunk */
-               for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-               {
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-               }
-
-               /* Write a value to each chunk point and verify the result */
-               for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++)
-               {
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA);
-
-                       if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 &&
-                               gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA)
-                       {
-                               /* OK. There is RAM. Now check for possible shadows */
-                               int ok = 1, chunk2;
-
-                               for (chunk2 = 0; ok && chunk2 < chunk; chunk2++)
-                                       if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) ||
-                                                       gus_peek(addr + chunk2 * CHUNK_SIZE + 1L))
-                                               ok = 0; /* Addressing wraps */
-
-                               if (ok)
-                                       size = (chunk + 1) * CHUNK_SIZE;
-                       }
-                       gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00);
-                       gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00);
-               }
-               bank_sizes[bank] = size;
-               if (size)
-                       nbanks = bank + 1;
-               DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024));
-       }
-
-       if (nbanks == 0)        /* No RAM - Give up */
-       {
-               printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n");
-               printk(KERN_ERR "Sound: Unable to work with this card.\n");
-               gus_write8(0x19, gus_read8(0x19) & ~0x01);
-               gus_mem_size = 0;
-               return;
-       }
-
-       /*
-        * Now we know how much DRAM there is in each bank. The next step is
-        * to find a DRAM size encoding (0 to 12) which is best for the combination
-        * we have.
-        *
-        * First try if any of the possible alternatives matches exactly the amount
-        * of memory we have.
-        */
-
-       for (i = 0; bits == -1 && i < 13; i++)
-       {
-               bits = i;
-
-               for (j = 0; bits != -1 && j < 4; j++)
-                       if (mem_decode[i][j] != bank_sizes[j])
-                               bits = -1;      /* No hit */
-       }
-
-       /*
-        * If necessary, try to find a combination where other than the last
-        * bank matches our configuration and the last bank is left oversized.
-        * In this way we don't leave holes in the middle of memory.
-        */
-
-       if (bits == -1)         /* No luck yet */
-       {
-               for (i = 0; bits == -1 && i < 13; i++)
-               {
-                       bits = i;
-
-                       for (j = 0; bits != -1 && j < nbanks - 1; j++)
-                               if (mem_decode[i][j] != bank_sizes[j])
-                                       bits = -1;      /* No hit */
-                       if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1])
-                               bits = -1;      /* The last bank is too small */
-               }
-       }
-       /*
-        * The last resort is to search for a combination where the banks are
-        * smaller than the actual SIMMs. This leaves some memory in the banks
-        * unused but doesn't leave holes in the DRAM address space.
-        */
-       if (bits == -1)         /* No luck yet */
-       {
-               for (i = 0; i < 13; i++)
-               {
-                       testbits = i;
-                       for (j = 0; testbits != -1 && j < nbanks - 1; j++)
-                               if (mem_decode[i][j] > bank_sizes[j]) {
-                                       testbits = -1;
-                               }
-                       if(testbits > bits) bits = testbits;
-               }
-               if (bits != -1)
-               {
-                       printk(KERN_INFO "Interwave: Can't use all installed RAM.\n");
-                       printk(KERN_INFO "Interwave: Try reordering SIMMS.\n");
-               }
-               printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n");
-               printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n");
-               bits = 0;
-       }
-       DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits));
-
-       for (bank = 0; bank < 4; bank++)
-       {
-               DDB(printk("  Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024));
-
-               if (bank_sizes[bank] > mem_decode[bits][bank])
-                       total += mem_decode[bits][bank];
-               else
-                       total += bank_sizes[bank];
-       }
-
-       DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024));
-
-       /*
-        *    Set the memory addressing mode.
-        */
-       gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits);
-
-/*      Leave the chip into enhanced mode. Disable LFO  */
-       gus_mem_size = total;
-       iw_mode = 1;
-       gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02);
-}
-
-int __init gus_wave_detect(int baseaddr)
-{
-       unsigned long   i, max_mem = 1024L;
-       unsigned long   loc;
-       unsigned char   val;
-
-       if (!request_region(baseaddr, 16, "GUS"))
-               return 0;
-       if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */
-               release_region(baseaddr, 16);
-               return 0;
-       }
-
-       gus_base = baseaddr;
-
-       gus_write8(0x4c, 0);    /* Reset GF1 */
-       gus_delay();
-       gus_delay();
-
-       gus_write8(0x4c, 1);    /* Release Reset */
-       gus_delay();
-       gus_delay();
-
-#ifdef GUSPNP_AUTODETECT
-       val = gus_look8(0x5b);  /* Version number register */
-       gus_write8(0x5b, ~val); /* Invert all bits */
-
-       if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0))   /* No change */
-       {
-               if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f))        /* Change */
-               {
-                       DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4));
-                       gus_pnp_flag = 1;
-               }
-               else
-               {
-                       DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b)));
-                       gus_pnp_flag = 0;
-               }
-       }
-       gus_write8(0x5b, val);  /* Restore all bits */
-#endif
-
-       if (gus_pnp_flag)
-               pnp_mem_init();
-       if (iw_mode)
-               return 1;
-
-       /* See if there is first block there.... */
-       gus_poke(0L, 0xaa);
-       if (gus_peek(0L) != 0xaa) {
-               release_region(baseaddr + 0x100, 12);
-               release_region(baseaddr, 16);
-               return 0;
-       }
-
-       /* Now zero it out so that I can check for mirroring .. */
-       gus_poke(0L, 0x00);
-       for (i = 1L; i < max_mem; i++)
-       {
-               int n, failed;
-
-               /* check for mirroring ... */
-               if (gus_peek(0L) != 0)
-                       break;
-               loc = i << 10;
-
-               for (n = loc - 1, failed = 0; n <= loc; n++)
-               {
-                       gus_poke(loc, 0xaa);
-                       if (gus_peek(loc) != 0xaa)
-                               failed = 1;
-                       gus_poke(loc, 0x55);
-                       if (gus_peek(loc) != 0x55)
-                               failed = 1;
-               }
-               if (failed)
-                       break;
-       }
-       gus_mem_size = i << 10;
-       return 1;
-}
-
-static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-
-       switch (cmd) 
-       {
-               case SNDCTL_SYNTH_INFO:
-                       gus_info.nr_voices = nr_voices;
-                       if (copy_to_user(arg, &gus_info, sizeof(gus_info)))
-                               return -EFAULT;
-                       return 0;
-
-               case SNDCTL_SEQ_RESETSAMPLES:
-                       reset_sample_memory();
-                       return 0;
-
-               case SNDCTL_SEQ_PERCMODE:
-                       return 0;
-
-               case SNDCTL_SYNTH_MEMAVL:
-                       return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32;
-
-               default:
-                       return -EINVAL;
-       }
-}
-
-static int guswave_set_instr(int dev, int voice, int instr_no)
-{
-       int sample_no;
-
-       if (instr_no < 0 || instr_no > MAX_PATCH)
-               instr_no = 0;   /* Default to acoustic piano */
-
-       if (voice < 0 || voice > 31)
-               return -EINVAL;
-
-       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-       {
-               voices[voice].sample_pending = instr_no;
-               return 0;
-       }
-       sample_no = patch_table[instr_no];
-       patch_map[voice] = -1;
-
-       if (sample_no == NOT_SAMPLE)
-       {
-/*             printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/
-               return -EINVAL; /* Patch not defined */
-       }
-       if (sample_ptrs[sample_no] == -1)       /* Sample not loaded */
-       {
-/*             printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/
-               return -EINVAL;
-       }
-       sample_map[voice] = sample_no;
-       patch_map[voice] = instr_no;
-       return 0;
-}
-
-static int guswave_kill_note(int dev, int voice, int note, int velocity)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       /* voice_alloc->map[voice] = 0xffff; */
-       if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-       {
-               voices[voice].kill_pending = 1;
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       else
-       {
-               spin_unlock_irqrestore(&gus_lock,flags);
-               gus_voice_fade(voice);
-       }
-
-       return 0;
-}
-
-static void guswave_aftertouch(int dev, int voice, int pressure)
-{
-}
-
-static void guswave_panning(int dev, int voice, int value)
-{
-       if (voice >= 0 || voice < 32)
-               voices[voice].panning = value;
-}
-
-static void guswave_volume_method(int dev, int mode)
-{
-       if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
-               volume_method = mode;
-}
-
-static void compute_volume(int voice, int volume)
-{
-       if (volume < 128)
-               voices[voice].midi_volume = volume;
-
-       switch (volume_method)
-       {
-               case VOL_METHOD_ADAGIO:
-                       voices[voice].initial_volume =
-                               gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol,
-                                       voices[voice].expression_vol,
-                                       voices[voice].patch_vol);
-                       break;
-
-               case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
-                       voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol);
-                       break;
-
-               default:
-                       voices[voice].initial_volume = volume_base +
-                               (voices[voice].midi_volume * volume_scale);
-       }
-
-       if (voices[voice].initial_volume > 4030)
-               voices[voice].initial_volume = 4030;
-}
-
-static void compute_and_set_volume(int voice, int volume, int ramp_time)
-{
-       int curr, target, rate;
-       unsigned long flags;
-
-       compute_volume(voice, volume);
-       voices[voice].current_volume = voices[voice].initial_volume;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       /*
-        * CAUTION! Interrupts disabled. Enable them before returning
-        */
-
-       gus_select_voice(voice);
-
-       curr = gus_read16(0x09) >> 4;
-       target = voices[voice].initial_volume;
-
-       if (ramp_time == INSTANT_RAMP)
-       {
-               gus_rampoff();
-               gus_voice_volume(target);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       if (ramp_time == FAST_RAMP)
-               rate = 63;
-       else
-               rate = 16;
-       gus_ramp_rate(0, rate);
-
-       if ((target - curr) / 64 == 0)  /* Close enough to target. */
-       {
-               gus_rampoff();
-               gus_voice_volume(target);
-               spin_unlock_irqrestore(&gus_lock,flags);
-               return;
-       }
-       if (target > curr)
-       {
-               if (target > (4095 - 65))
-                       target = 4095 - 65;
-               gus_ramp_range(curr, target);
-               gus_rampon(0x00);       /* Ramp up, once, no IRQ */
-       }
-       else
-       {
-               if (target < 65)
-                       target = 65;
-
-               gus_ramp_range(target, curr);
-               gus_rampon(0x40);       /* Ramp down, once, no irq */
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void dynamic_volume_change(int voice)
-{
-       unsigned char status;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       status = gus_read8(0x00);       /* Get voice status */
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (status & 0x03)
-               return;         /* Voice was not running */
-
-       if (!(voices[voice].mode & WAVE_ENVELOPES))
-       {
-               compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-               return;
-       }
-       
-       /*
-        * Voice is running and has envelopes.
-        */
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       status = gus_read8(0x0d);       /* Ramping status */
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (status & 0x03)      /* Sustain phase? */
-       {
-               compute_and_set_volume(voice, voices[voice].midi_volume, 1);
-               return;
-       }
-       if (voices[voice].env_phase < 0)
-               return;
-
-       compute_volume(voice, voices[voice].midi_volume);
-
-}
-
-static void guswave_controller(int dev, int voice, int ctrl_num, int value)
-{
-       unsigned long   flags;
-       unsigned long   freq;
-
-       if (voice < 0 || voice > 31)
-               return;
-
-       switch (ctrl_num)
-       {
-               case CTRL_PITCH_BENDER:
-                       voices[voice].bender = value;
-
-                       if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                       {
-                               freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0);
-                               voices[voice].current_freq = freq;
-
-                               spin_lock_irqsave(&gus_lock,flags);
-                               gus_select_voice(voice);
-                               gus_voice_freq(freq);
-                               spin_unlock_irqrestore(&gus_lock,flags);
-                       }
-                       break;
-
-               case CTRL_PITCH_BENDER_RANGE:
-                       voices[voice].bender_range = value;
-                       break;
-               case CTL_EXPRESSION:
-                       value /= 128;
-               case CTRL_EXPRESSION:
-                       if (volume_method == VOL_METHOD_ADAGIO)
-                       {
-                               voices[voice].expression_vol = value;
-                               if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                                       dynamic_volume_change(voice);
-                       }
-                       break;
-
-               case CTL_PAN:
-                       voices[voice].panning = (value * 2) - 128;
-                       break;
-
-               case CTL_MAIN_VOLUME:
-                       value = (value * 100) / 16383;
-
-               case CTRL_MAIN_VOLUME:
-                       voices[voice].main_vol = value;
-                       if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
-                               dynamic_volume_change(voice);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-static int guswave_start_note2(int dev, int voice, int note_num, int volume)
-{
-       int sample, best_sample, best_delta, delta_freq;
-       int is16bits, samplep, patch, pan;
-       unsigned long   note_freq, base_note, freq, flags;
-       unsigned char   mode = 0;
-
-       if (voice < 0 || voice > 31)
-       {
-/*             printk("GUS: Invalid voice\n");*/
-               return -EINVAL;
-       }
-       if (note_num == 255)
-       {
-               if (voices[voice].mode & WAVE_ENVELOPES)
-               {
-                       voices[voice].midi_volume = volume;
-                       dynamic_volume_change(voice);
-                       return 0;
-               }
-               compute_and_set_volume(voice, volume, 1);
-               return 0;
-       }
-       if ((patch = patch_map[voice]) == -1)
-               return -EINVAL;
-       if ((samplep = patch_table[patch]) == NOT_SAMPLE)
-       {
-               return -EINVAL;
-       }
-       note_freq = note_to_freq(note_num);
-
-       /*
-        * Find a sample within a patch so that the note_freq is between low_note
-        * and high_note.
-        */
-       sample = -1;
-
-       best_sample = samplep;
-       best_delta = 1000000;
-       while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1)
-       {
-               delta_freq = note_freq - samples[samplep].base_note;
-               if (delta_freq < 0)
-                       delta_freq = -delta_freq;
-               if (delta_freq < best_delta)
-               {
-                       best_sample = samplep;
-                       best_delta = delta_freq;
-               }
-               if (samples[samplep].low_note <= note_freq &&
-                       note_freq <= samples[samplep].high_note)
-               {
-                       sample = samplep;
-               }
-               else
-                       samplep = samples[samplep].key; /* Link to next sample */
-         }
-       if (sample == -1)
-               sample = best_sample;
-
-       if (sample == -1)
-       {
-/*             printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/
-               return 0;       /* Should play default patch ??? */
-       }
-       is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
-       voices[voice].mode = samples[sample].mode;
-       voices[voice].patch_vol = samples[sample].volume;
-
-       if (iw_mode)
-               gus_write8(0x15, 0x00);         /* RAM, Reset voice deactivate bit of SMSI */
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               int i;
-
-               for (i = 0; i < 6; i++)
-               {
-                       voices[voice].env_rate[i] = samples[sample].env_rate[i];
-                       voices[voice].env_offset[i] = samples[sample].env_offset[i];
-               }
-       }
-       sample_map[voice] = sample;
-
-       if (voices[voice].fixed_pitch)  /* Fixed pitch */
-       {
-                 freq = samples[sample].base_freq;
-       }
-       else
-       {
-               base_note = samples[sample].base_note / 100;
-               note_freq /= 100;
-
-               freq = samples[sample].base_freq * note_freq / base_note;
-       }
-
-       voices[voice].orig_freq = freq;
-
-       /*
-        * Since the pitch bender may have been set before playing the note, we
-        * have to calculate the bending now.
-        */
-
-       freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender,
-                               voices[voice].bender_range, 0);
-       voices[voice].current_freq = freq;
-
-       pan = (samples[sample].panning + voices[voice].panning) / 32;
-       pan += 7;
-       if (pan < 0)
-               pan = 0;
-       if (pan > 15)
-               pan = 15;
-
-       if (samples[sample].mode & WAVE_16_BITS)
-       {
-               mode |= 0x04;   /* 16 bits */
-               if ((sample_ptrs[sample] / GUS_BANK_SIZE) !=
-                       ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE))
-                               printk(KERN_ERR "GUS: Sample address error\n");
-       }
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_off();
-       gus_rampoff();
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (voices[voice].mode & WAVE_ENVELOPES)
-       {
-               compute_volume(voice, volume);
-               init_envelope(voice);
-       }
-       else
-       {
-               compute_and_set_volume(voice, volume, 0);
-       }
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-
-       if (samples[sample].mode & WAVE_LOOP_BACK)
-               gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len -
-                       voices[voice].offset_pending, 0, is16bits);     /* start=end */
-       else
-               gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits);  /* Sample start=begin */
-
-       if (samples[sample].mode & WAVE_LOOPING)
-       {
-               mode |= 0x08;
-
-               if (samples[sample].mode & WAVE_BIDIR_LOOP)
-                       mode |= 0x10;
-
-               if (samples[sample].mode & WAVE_LOOP_BACK)
-               {
-                       gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end -
-                                          voices[voice].offset_pending,
-                                          (samples[sample].fractions >> 4) & 0x0f, is16bits);
-                       mode |= 0x40;
-               }
-               gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start,
-                       samples[sample].fractions & 0x0f, is16bits);    /* Loop start location */
-               gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end,
-                       (samples[sample].fractions >> 4) & 0x0f, is16bits);     /* Loop end location */
-       }
-       else
-       {
-               mode |= 0x20;   /* Loop IRQ at the end */
-               voices[voice].loop_irq_mode = LMODE_FINISH;     /* Ramp down at the end */
-               voices[voice].loop_irq_parm = 1;
-               gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits); /* Loop start location */
-               gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1,
-                       (samples[sample].fractions >> 4) & 0x0f, is16bits);     /* Loop end location */
-       }
-       gus_voice_freq(freq);
-       gus_voice_balance(pan);
-       gus_voice_on(mode);
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       return 0;
-}
-
-/*
- * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
- * when the note playing on the voice is changed.  It uses volume
- * ramping.
- */
-
-static int guswave_start_note(int dev, int voice, int note_num, int volume)
-{
-       unsigned long flags;
-       int mode;
-       int ret_val = 0;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       if (note_num == 255)
-       {
-               if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
-               {
-                       voices[voice].volume_pending = volume;
-               }
-               else
-               {
-                       ret_val = guswave_start_note2(dev, voice, note_num, volume);
-               }
-       }
-       else
-       {
-               gus_select_voice(voice);
-               mode = gus_read8(0x00);
-               if (mode & 0x20)
-                       gus_write8(0x00, mode & 0xdf);  /* No interrupt! */
-
-               voices[voice].offset_pending = 0;
-               voices[voice].kill_pending = 0;
-               voices[voice].volume_irq_mode = 0;
-               voices[voice].loop_irq_mode = 0;
-
-               if (voices[voice].sample_pending >= 0)
-               {
-                       spin_unlock_irqrestore(&gus_lock,flags);        /* Run temporarily with interrupts enabled */
-                       guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending);
-                       voices[voice].sample_pending = -1;
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);        /* Reselect the voice (just to be sure) */
-               }
-               if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065))
-               {
-                       ret_val = guswave_start_note2(dev, voice, note_num, volume);
-               }
-               else
-               {
-                       voices[voice].dev_pending = dev;
-                       voices[voice].note_pending = note_num;
-                       voices[voice].volume_pending = volume;
-                       voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
-                       gus_rampoff();
-                       gus_ramp_range(2000, 4065);
-                       gus_ramp_rate(0, 63);   /* Fastest possible rate */
-                       gus_rampon(0x20 | 0x40);        /* Ramp down, once, irq */
-               }
-       }
-       spin_unlock_irqrestore(&gus_lock,flags);
-       return ret_val;
-}
-
-static void guswave_reset(int dev)
-{
-       int i;
-
-       for (i = 0; i < 32; i++)
-       {
-               gus_voice_init(i);
-               gus_voice_init2(i);
-       }
-}
-
-static int guswave_open(int dev, int mode)
-{
-       int err;
-
-       if (gus_busy)
-               return -EBUSY;
-
-       voice_alloc->timestamp = 0;
-
-       if (gus_no_wave_dma) {
-               gus_no_dma = 1;
-       } else {
-               if ((err = DMAbuf_open_dma(gus_devnum)) < 0)
-               {
-                       /* printk( "GUS: Loading samples without DMA\n"); */
-                       gus_no_dma = 1; /* Upload samples using PIO */
-               }
-               else
-                       gus_no_dma = 0;
-       }
-
-       init_waitqueue_head(&dram_sleeper);
-       gus_busy = 1;
-       active_device = GUS_DEV_WAVE;
-
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-       gus_initialize();
-       gus_reset();
-       gusintr(gus_irq, (void *)gus_hw_config, NULL);  /* Serve pending interrupts */
-
-       return 0;
-}
-
-static void guswave_close(int dev)
-{
-       gus_busy = 0;
-       active_device = 0;
-       gus_reset();
-
-       if (!gus_no_dma)
-               DMAbuf_close_dma(gus_devnum);
-}
-
-static int guswave_load_patch(int dev, int format, const char __user *addr,
-                  int offs, int count, int pmgr_flag)
-{
-       struct patch_info patch;
-       int instr;
-       long sizeof_patch;
-
-       unsigned long blk_sz, blk_end, left, src_offs, target;
-
-       sizeof_patch = (long) &patch.data[0] - (long) &patch;   /* Header size */
-
-       if (format != GUS_PATCH)
-       {
-/*             printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/
-               return -EINVAL;
-       }
-       if (count < sizeof_patch)
-       {
-/*               printk("GUS Error: Patch header too short\n");*/
-                 return -EINVAL;
-       }
-       count -= sizeof_patch;
-
-       if (free_sample >= MAX_SAMPLE)
-       {
-/*               printk("GUS: Sample table full\n");*/
-                 return -ENOSPC;
-       }
-       /*
-        * Copy the header from user space but ignore the first bytes which have
-        * been transferred already.
-        */
-
-       if (copy_from_user(&((char *) &patch)[offs], &(addr)[offs],
-                          sizeof_patch - offs))
-               return -EFAULT;
-
-       if (patch.mode & WAVE_ROM)
-               return -EINVAL;
-       if (gus_mem_size == 0)
-               return -ENOSPC;
-
-       instr = patch.instr_no;
-
-       if (instr < 0 || instr > MAX_PATCH)
-       {
-/*             printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/
-               return -EINVAL;
-       }
-       if (count < patch.len)
-       {
-/*             printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/
-               patch.len = count;
-       }
-       if (patch.len <= 0 || patch.len > gus_mem_size)
-       {
-/*             printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/
-               return -EINVAL;
-       }
-       if (patch.mode & WAVE_LOOPING)
-       {
-               if (patch.loop_start < 0 || patch.loop_start >= patch.len)
-               {
-/*                     printk(KERN_ERR "GUS: Invalid loop start\n");*/
-                       return -EINVAL;
-               }
-               if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
-               {
-/*                     printk(KERN_ERR "GUS: Invalid loop end\n");*/
-                       return -EINVAL;
-               }
-       }
-       free_mem_ptr = (free_mem_ptr + 31) & ~31;       /* 32 byte alignment */
-
-       if (patch.mode & WAVE_16_BITS)
-       {
-               /*
-                * 16 bit samples must fit one 256k bank.
-                */
-               if (patch.len >= GUS_BANK_SIZE)
-               {
-/*                      printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/
-                       return -ENOSPC;
-               }
-               if ((free_mem_ptr / GUS_BANK_SIZE) !=
-                       ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
-               {
-                       unsigned long   tmp_mem =       
-                               /* Align to 256K */
-                                       ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
-
-                       if ((tmp_mem + patch.len) > gus_mem_size)
-                               return -ENOSPC;
-
-                       free_mem_ptr = tmp_mem;         /* This leaves unusable memory */
-               }
-       }
-       if ((free_mem_ptr + patch.len) > gus_mem_size)
-               return -ENOSPC;
-
-       sample_ptrs[free_sample] = free_mem_ptr;
-
-       /*
-        * Tremolo is not possible with envelopes
-        */
-
-       if (patch.mode & WAVE_ENVELOPES)
-               patch.mode &= ~WAVE_TREMOLO;
-
-       if (!(patch.mode & WAVE_FRACTIONS))
-       {
-                 patch.fractions = 0;
-       }
-       memcpy((char *) &samples[free_sample], &patch, sizeof_patch);
-
-       /*
-        * Link this_one sample to the list of samples for patch 'instr'.
-        */
-
-       samples[free_sample].key = patch_table[instr];
-       patch_table[instr] = free_sample;
-
-       /*
-        * Use DMA to transfer the wave data to the DRAM
-        */
-
-       left = patch.len;
-       src_offs = 0;
-       target = free_mem_ptr;
-
-       while (left)            /* Not completely transferred yet */
-       {
-               blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use;
-               if (blk_sz > left)
-                       blk_sz = left;
-
-               /*
-                * DMA cannot cross bank (256k) boundaries. Check for that.
-                */
-                
-               blk_end = target + blk_sz;
-
-               if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE))
-               {
-                       /* Split the block */
-                       blk_end &= ~(GUS_BANK_SIZE - 1);
-                       blk_sz = blk_end - target;
-               }
-               if (gus_no_dma)
-               {
-                       /*
-                        * For some reason the DMA is not possible. We have to use PIO.
-                        */
-                       long i;
-                       unsigned char data;
-
-                       for (i = 0; i < blk_sz; i++)
-                       {
-                               get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[sizeof_patch + i]));
-                               if (patch.mode & WAVE_UNSIGNED)
-                                       if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
-                                               data ^= 0x80;   /* Convert to signed */
-                               gus_poke(target + i, data);
-                       }
-               }
-               else
-               {
-                       unsigned long address, hold_address;
-                       unsigned char dma_command;
-                       unsigned long flags;
-
-                       if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL)
-                       {
-                               printk(KERN_ERR "GUS: DMA buffer == NULL\n");
-                               return -ENOSPC;
-                       }
-                       /*
-                        * OK, move now. First in and then out.
-                        */
-
-                       if (copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf,
-                                          &(addr)[sizeof_patch + src_offs],
-                                          blk_sz))
-                               return -EFAULT;
-
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                       DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys,
-                               blk_sz, DMA_MODE_WRITE);
-
-                       /*
-                        * Set the DRAM address for the wave data
-                        */
-
-                       if (iw_mode)
-                       {
-                               /* Different address translation in enhanced mode */
-
-                               unsigned char   hi;
-
-                               if (gus_dma > 4)
-                                       address = target >> 1;  /* Convert to 16 bit word address */
-                               else
-                                       address = target;
-
-                               hi = (unsigned char) ((address >> 16) & 0xf0);
-                               hi += (unsigned char) (address & 0x0f);
-
-                               gus_write16(0x42, (address >> 4) & 0xffff);     /* DMA address (low) */
-                               gus_write8(0x50, hi);
-                       }
-                       else
-                       {
-                               address = target;
-                               if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-                               {
-                                       hold_address = address;
-                                       address = address >> 1;
-                                       address &= 0x0001ffffL;
-                                       address |= (hold_address & 0x000c0000L);
-                               }
-                               gus_write16(0x42, (address >> 4) & 0xffff);     /* DRAM DMA address */
-                       }
-
-                       /*
-                        * Start the DMA transfer
-                        */
-
-                       dma_command = 0x21;             /* IRQ enable, DMA start */
-                       if (patch.mode & WAVE_UNSIGNED)
-                               dma_command |= 0x80;    /* Invert MSB */
-                       if (patch.mode & WAVE_16_BITS)
-                               dma_command |= 0x40;    /* 16 bit _DATA_ */
-                       if (audio_devs[gus_devnum]->dmap_out->dma > 3)
-                               dma_command |= 0x04;    /* 16 bit DMA _channel_ */
-                       
-                       /*
-                        * Sleep here until the DRAM DMA done interrupt is served
-                        */
-                       active_device = GUS_DEV_WAVE;
-                       gus_write8(0x41, dma_command);  /* Lets go luteet (=bugs) */
-
-                       spin_unlock_irqrestore(&gus_lock,flags); /* opens a race */
-                       if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ))
-                               printk("GUS: DMA Transfer timed out\n");
-               }
-
-               /*
-                * Now the next part
-                */
-
-               left -= blk_sz;
-               src_offs += blk_sz;
-               target += blk_sz;
-
-               gus_write8(0x41, 0);    /* Stop DMA */
-       }
-
-       free_mem_ptr += patch.len;
-       free_sample++;
-       return 0;
-}
-
-static void guswave_hw_control(int dev, unsigned char *event_rec)
-{
-       int voice, cmd;
-       unsigned short p1, p2;
-       unsigned int plong;
-       unsigned long flags;
-
-       cmd = event_rec[2];
-       voice = event_rec[3];
-       p1 = *(unsigned short *) &event_rec[4];
-       p2 = *(unsigned short *) &event_rec[6];
-       plong = *(unsigned int *) &event_rec[4];
-
-       if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
-               (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
-               do_volume_irq(voice);
-
-       switch (cmd)
-       {
-               case _GUS_NUMVOICES:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_select_max_voices(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICESAMPLE:
-                       guswave_set_instr(dev, voice, p1);
-                       break;
-
-               case _GUS_VOICEON:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_voice_on(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEOFF:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_off();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEFADE:
-                       gus_voice_fade(voice);
-                       break;
-
-               case _GUS_VOICEMODE:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_voice_mode(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEBALA:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_balance(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEFREQ:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_freq(plong);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEVOL:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_voice_volume(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOICEVOL2:    /* Just update the software voice level */
-                       voices[voice].initial_volume = voices[voice].current_volume = p1;
-                       break;
-
-               case _GUS_RAMPRANGE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NO-NO */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_ramp_range(p1, p2);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPRATE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NJET-NJET */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_ramp_rate(p1, p2);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPMODE:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NO-NO */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_ramp_mode(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPON:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* EI-EI */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       p1 &= ~0x20;    /* Don't allow interrupts */
-                       gus_rampon(p1);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_RAMPOFF:
-                       if (voices[voice].mode & WAVE_ENVELOPES)
-                               break;  /* NEJ-NEJ */
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_rampoff();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               case _GUS_VOLUME_SCALE:
-                       volume_base = p1;
-                       volume_scale = p2;
-                       break;
-
-               case _GUS_VOICE_POS:
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_set_voice_pos(voice, plong);
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       break;
-
-               default:
-                       break;
-       }
-}
-
-static int gus_audio_set_speed(int speed)
-{
-       if (speed <= 0)
-               speed = gus_audio_speed;
-
-       if (speed < 4000)
-               speed = 4000;
-
-       if (speed > 44100)
-               speed = 44100;
-
-       gus_audio_speed = speed;
-
-       if (only_read_access)
-       {
-               /* Compute nearest valid recording speed  and return it */
-
-               /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */
-               speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-               speed = (9878400 / (speed * 16)) - 2;
-       }
-       return speed;
-}
-
-static int gus_audio_set_channels(int channels)
-{
-       if (!channels)
-               return gus_audio_channels;
-       if (channels > 2)
-               channels = 2;
-       if (channels < 1)
-               channels = 1;
-       gus_audio_channels = channels;
-       return channels;
-}
-
-static int gus_audio_set_bits(int bits)
-{
-       if (!bits)
-               return gus_audio_bits;
-
-       if (bits != 8 && bits != 16)
-               bits = 8;
-
-       if (only_8_bits)
-               bits = 8;
-
-       gus_audio_bits = bits;
-       return bits;
-}
-
-static int gus_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int val;
-
-       switch (cmd) 
-       {
-               case SOUND_PCM_WRITE_RATE:
-                       if (get_user(val, (int __user*)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_speed(val);
-                       break;
-
-               case SOUND_PCM_READ_RATE:
-                       val = gus_audio_speed;
-                       break;
-
-               case SNDCTL_DSP_STEREO:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_channels(val + 1) - 1;
-                       break;
-
-               case SOUND_PCM_WRITE_CHANNELS:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_channels(val);
-                       break;
-
-               case SOUND_PCM_READ_CHANNELS:
-                       val = gus_audio_channels;
-                       break;
-               
-               case SNDCTL_DSP_SETFMT:
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       val = gus_audio_set_bits(val);
-                       break;
-               
-               case SOUND_PCM_READ_BITS:
-                       val = gus_audio_bits;
-                       break;
-               
-               case SOUND_PCM_WRITE_FILTER:            /* NOT POSSIBLE */
-               case SOUND_PCM_READ_FILTER:
-                       val = -EINVAL;
-                       break;
-               default:
-                       return -EINVAL;
-       }
-       return put_user(val, (int __user *)arg);
-}
-
-static void gus_audio_reset(int dev)
-{
-       if (recording_active)
-       {
-               gus_write8(0x49, 0x00); /* Halt recording */
-               set_input_volumes();
-       }
-}
-
-static int saved_iw_mode;      /* A hack hack hack */
-
-static int gus_audio_open(int dev, int mode)
-{
-       if (gus_busy)
-               return -EBUSY;
-
-       if (gus_pnp_flag && mode & OPEN_READ)
-       {
-/*             printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/
-               return -EIO;
-       }
-       gus_initialize();
-
-       gus_busy = 1;
-       active_device = 0;
-
-       saved_iw_mode = iw_mode;
-       if (iw_mode)
-       {
-               /* There are some problems with audio in enhanced mode so disable it */
-               gus_write8(0x19, gus_read8(0x19) & ~0x01);      /* Disable enhanced mode */
-               iw_mode = 0;
-       }
-
-       gus_reset();
-       reset_sample_memory();
-       gus_select_max_voices(14);
-
-       pcm_active = 0;
-       dma_active = 0;
-       pcm_opened = 1;
-       if (mode & OPEN_READ)
-       {
-               recording_active = 1;
-               set_input_volumes();
-       }
-       only_read_access = !(mode & OPEN_WRITE);
-       only_8_bits = mode & OPEN_READ;
-       if (only_8_bits)
-               audio_devs[dev]->format_mask = AFMT_U8;
-       else
-               audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE;
-
-       return 0;
-}
-
-static void gus_audio_close(int dev)
-{
-       iw_mode = saved_iw_mode;
-       gus_reset();
-       gus_busy = 0;
-       pcm_opened = 0;
-       active_device = 0;
-
-       if (recording_active)
-       {
-               gus_write8(0x49, 0x00); /* Halt recording */
-               set_input_volumes();
-       }
-       recording_active = 0;
-}
-
-static void gus_audio_update_volume(void)
-{
-       unsigned long flags;
-       int voice;
-
-       if (pcm_active && pcm_opened)
-               for (voice = 0; voice < gus_audio_channels; voice++)
-               {
-                       spin_lock_irqsave(&gus_lock,flags);
-                       gus_select_voice(voice);
-                       gus_rampoff();
-                       gus_voice_volume(1530 + (25 * gus_pcm_volume));
-                       gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-                       spin_unlock_irqrestore(&gus_lock,flags);
-               }
-}
-
-static void play_next_pcm_block(void)
-{
-       unsigned long flags;
-       int speed = gus_audio_speed;
-       int this_one, is16bits, chn;
-       unsigned long dram_loc;
-       unsigned char mode[2], ramp_mode[2];
-
-       if (!pcm_qlen)
-               return;
-
-       this_one = pcm_head;
-
-       for (chn = 0; chn < gus_audio_channels; chn++)
-       {
-               mode[chn] = 0x00;
-               ramp_mode[chn] = 0x03;  /* Ramping and rollover off */
-
-               if (chn == 0)
-               {
-                       mode[chn] |= 0x20;      /* Loop IRQ */
-                       voices[chn].loop_irq_mode = LMODE_PCM;
-               }
-               if (gus_audio_bits != 8)
-               {
-                       is16bits = 1;
-                       mode[chn] |= 0x04;      /* 16 bit data */
-               }
-               else
-                       is16bits = 0;
-
-               dram_loc = this_one * pcm_bsize;
-               dram_loc += chn * pcm_banksize;
-
-               if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */
-               {
-                       mode[chn] |= 0x08;      /* Enable loop */
-                       ramp_mode[chn] = 0x03;  /* Disable rollover bit */
-               }
-               else
-               {
-                       if (chn == 0)
-                               ramp_mode[chn] = 0x04;  /* Enable rollover bit */
-               }
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(chn);
-               gus_voice_freq(speed);
-
-               if (gus_audio_channels == 1)
-                       gus_voice_balance(7);           /* mono */
-               else if (chn == 0)
-                       gus_voice_balance(0);           /* left */
-               else
-                       gus_voice_balance(15);          /* right */
-
-               if (!pcm_active)        /* Playback not already active */
-               {
-                       /*
-                        * The playback was not started yet (or there has been a pause).
-                        * Start the voice (again) and ask for a rollover irq at the end of
-                        * this_one block. If this_one one is last of the buffers, use just
-                        * the normal loop with irq.
-                        */
-
-                       gus_voice_off();
-                       gus_rampoff();
-                       gus_voice_volume(1530 + (25 * gus_pcm_volume));
-                       gus_ramp_range(65, 1530 + (25 * gus_pcm_volume));
-
-                       gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits);  /* Starting position */
-                       gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits);  /* Loop start */
-
-                       if (chn != 0)
-                               gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
-                                                  0, is16bits);        /* Loop end location */
-               }
-               if (chn == 0)
-                       gus_write_addr(0x04, dram_loc + pcm_bsize - 1,
-                                        0, is16bits);  /* Loop end location */
-               else
-                       mode[chn] |= 0x08;      /* Enable looping */
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       for (chn = 0; chn < gus_audio_channels; chn++)
-       {
-               spin_lock_irqsave(&gus_lock,flags);
-               gus_select_voice(chn);
-               gus_write8(0x0d, ramp_mode[chn]);
-               if (iw_mode)
-                       gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */
-               gus_voice_on(mode[chn]);
-               spin_unlock_irqrestore(&gus_lock,flags);
-       }
-       pcm_active = 1;
-}
-
-static void gus_transfer_output_block(int dev, unsigned long buf,
-                         int total_count, int intrflag, int chn)
-{
-       /*
-        * This routine transfers one block of audio data to the DRAM. In mono mode
-        * it's called just once. When in stereo mode, this_one routine is called
-        * once for both channels.
-        *
-        * The left/mono channel data is transferred to the beginning of dram and the
-        * right data to the area pointed by gus_page_size.
-        */
-
-       int this_one, count;
-       unsigned long flags;
-       unsigned char dma_command;
-       unsigned long address, hold_address;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       count = total_count / gus_audio_channels;
-
-       if (chn == 0)
-       {
-               if (pcm_qlen >= pcm_nblk)
-                       printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n");
-
-               this_one = pcm_current_block = pcm_tail;
-               pcm_qlen++;
-               pcm_tail = (pcm_tail + 1) % pcm_nblk;
-               pcm_datasize[this_one] = count;
-       }
-       else
-               this_one = pcm_current_block;
-
-       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-       DMAbuf_start_dma(dev, buf + (chn * count), count, DMA_MODE_WRITE);
-
-       address = this_one * pcm_bsize;
-       address += chn * pcm_banksize;
-
-       if (audio_devs[dev]->dmap_out->dma > 3)
-       {
-               hold_address = address;
-               address = address >> 1;
-               address &= 0x0001ffffL;
-               address |= (hold_address & 0x000c0000L);
-       }
-       gus_write16(0x42, (address >> 4) & 0xffff);     /* DRAM DMA address */
-
-       dma_command = 0x21;     /* IRQ enable, DMA start */
-
-       if (gus_audio_bits != 8)
-               dma_command |= 0x40;    /* 16 bit _DATA_ */
-       else
-               dma_command |= 0x80;    /* Invert MSB */
-
-       if (audio_devs[dev]->dmap_out->dma > 3)
-               dma_command |= 0x04;    /* 16 bit DMA channel */
-
-       gus_write8(0x41, dma_command);  /* Kick start */
-
-       if (chn == (gus_audio_channels - 1))    /* Last channel */
-       {
-               /*
-                * Last (right or mono) channel data
-                */
-               dma_active = 1; /* DMA started. There is a unacknowledged buffer */
-               active_device = GUS_DEV_PCM_DONE;
-               if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize))
-               {
-                       play_next_pcm_block();
-               }
-       }
-       else
-       {
-               /*
-                * Left channel data. The right channel
-                * is transferred after DMA interrupt
-                */
-               active_device = GUS_DEV_PCM_CONTINUE;
-       }
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static void gus_uninterleave8(char *buf, int l)
-{
-/* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */
-       int i, p = 0, halfsize = l / 2;
-       char *buf2 = buf + halfsize, *src = bounce_buf;
-
-       memcpy(bounce_buf, buf, l);
-
-       for (i = 0; i < halfsize; i++)
-       {
-               buf[i] = src[p++];      /* Left channel */
-               buf2[i] = src[p++];     /* Right channel */
-       }
-}
-
-static void gus_uninterleave16(short *buf, int l)
-{
-/* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */
-       int i, p = 0, halfsize = l / 2;
-       short *buf2 = buf + halfsize, *src = (short *) bounce_buf;
-
-       memcpy(bounce_buf, (char *) buf, l * 2);
-
-       for (i = 0; i < halfsize; i++)
-       {
-               buf[i] = src[p++];      /* Left channel */
-               buf2[i] = src[p++];     /* Right channel */
-       }
-}
-
-static void gus_audio_output_block(int dev, unsigned long buf, int total_count,
-                      int intrflag)
-{
-       struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;
-
-       dmap->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-
-       pcm_current_buf = buf;
-       pcm_current_count = total_count;
-       pcm_current_intrflag = intrflag;
-       pcm_current_dev = dev;
-       if (gus_audio_channels == 2)
-       {
-               char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys);
-
-               if (gus_audio_bits == 8)
-                       gus_uninterleave8(b, total_count);
-               else
-                       gus_uninterleave16((short *) b, total_count / 2);
-       }
-       gus_transfer_output_block(dev, buf, total_count, intrflag, 0);
-}
-
-static void gus_audio_start_input(int dev, unsigned long buf, int count,
-                     int intrflag)
-{
-       unsigned long flags;
-       unsigned char mode;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ);
-       mode = 0xa0;            /* DMA IRQ enabled, invert MSB */
-
-       if (audio_devs[dev]->dmap_in->dma > 3)
-               mode |= 0x04;   /* 16 bit DMA channel */
-       if (gus_audio_channels > 1)
-               mode |= 0x02;   /* Stereo */
-       mode |= 0x01;           /* DMA enable */
-
-       gus_write8(0x49, mode);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int gus_audio_prepare_for_input(int dev, int bsize, int bcount)
-{
-       unsigned int rate;
-
-       gus_audio_bsize = bsize;
-       audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
-       rate = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16;
-
-       gus_write8(0x48, rate & 0xff);  /* Set sampling rate */
-
-       if (gus_audio_bits != 8)
-       {
-/*             printk("GUS Error: 16 bit recording not supported\n");*/
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int gus_audio_prepare_for_output(int dev, int bsize, int bcount)
-{
-       int i;
-
-       long mem_ptr, mem_size;
-
-       audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT;
-       mem_ptr = 0;
-       mem_size = gus_mem_size / gus_audio_channels;
-
-       if (mem_size > (256 * 1024))
-               mem_size = 256 * 1024;
-
-       pcm_bsize = bsize / gus_audio_channels;
-       pcm_head = pcm_tail = pcm_qlen = 0;
-
-       pcm_nblk = 2;           /* MAX_PCM_BUFFERS; */
-       if ((pcm_bsize * pcm_nblk) > mem_size)
-               pcm_nblk = mem_size / pcm_bsize;
-
-       for (i = 0; i < pcm_nblk; i++)
-               pcm_datasize[i] = 0;
-
-       pcm_banksize = pcm_nblk * pcm_bsize;
-
-       if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024))
-               pcm_nblk--;
-       gus_write8(0x41, 0);    /* Disable GF1 DMA */
-       return 0;
-}
-
-static int gus_local_qlen(int dev)
-{
-       return pcm_qlen;
-}
-
-
-static struct audio_driver gus_audio_driver =
-{
-       .owner                  = THIS_MODULE,
-       .open                   = gus_audio_open,
-       .close                  = gus_audio_close,
-       .output_block           = gus_audio_output_block,
-       .start_input            = gus_audio_start_input,
-       .ioctl                  = gus_audio_ioctl,
-       .prepare_for_input      = gus_audio_prepare_for_input,
-       .prepare_for_output     = gus_audio_prepare_for_output,
-       .halt_io                = gus_audio_reset,
-       .local_qlen             = gus_local_qlen,
-};
-
-static void guswave_setup_voice(int dev, int voice, int chn)
-{
-       struct channel_info *info = &synth_devs[dev]->chn_info[chn];
-
-       guswave_set_instr(dev, voice, info->pgm_num);
-       voices[voice].expression_vol = info->controllers[CTL_EXPRESSION];       /* Just MSB */
-       voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
-       voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128;
-       voices[voice].bender = 0;
-       voices[voice].bender_range = info->bender_range;
-
-       if (chn == 9)
-               voices[voice].fixed_pitch = 1;
-}
-
-static void guswave_bender(int dev, int voice, int value)
-{
-       int freq;
-       unsigned long   flags;
-
-       voices[voice].bender = value - 8192;
-       freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0);
-       voices[voice].current_freq = freq;
-
-       spin_lock_irqsave(&gus_lock,flags);
-       gus_select_voice(voice);
-       gus_voice_freq(freq);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
-       int i, p, best = -1, best_time = 0x7fffffff;
-
-       p = alloc->ptr;
-       /*
-        * First look for a completely stopped voice
-        */
-
-       for (i = 0; i < alloc->max_voice; i++)
-       {
-               if (alloc->map[p] == 0)
-               {
-                       alloc->ptr = p;
-                       return p;
-               }
-               if (alloc->alloc_times[p] < best_time)
-               {
-                       best = p;
-                       best_time = alloc->alloc_times[p];
-               }
-               p = (p + 1) % alloc->max_voice;
-       }
-
-       /*
-        * Then look for a releasing voice
-        */
-
-       for (i = 0; i < alloc->max_voice; i++)
-       {
-               if (alloc->map[p] == 0xffff)
-               {
-                       alloc->ptr = p;
-                       return p;
-               }
-               p = (p + 1) % alloc->max_voice;
-       }
-       if (best >= 0)
-               p = best;
-
-       alloc->ptr = p;
-       return p;
-}
-
-static struct synth_operations guswave_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "GUS",
-       .info           = &gus_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_GUS,
-       .open           = guswave_open,
-       .close          = guswave_close,
-       .ioctl          = guswave_ioctl,
-       .kill_note      = guswave_kill_note,
-       .start_note     = guswave_start_note,
-       .set_instr      = guswave_set_instr,
-       .reset          = guswave_reset,
-       .hw_control     = guswave_hw_control,
-       .load_patch     = guswave_load_patch,
-       .aftertouch     = guswave_aftertouch,
-       .controller     = guswave_controller,
-       .panning        = guswave_panning,
-       .volume_method  = guswave_volume_method,
-       .bender         = guswave_bender,
-       .alloc_voice    = guswave_alloc,
-       .setup_voice    = guswave_setup_voice
-};
-
-static void set_input_volumes(void)
-{
-       unsigned long flags;
-       unsigned char mask = 0xff & ~0x06;      /* Just line out enabled */
-
-       if (have_gus_max)       /* Don't disturb GUS MAX */
-               return;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       /*
-        *    Enable channels having vol > 10%
-        *      Note! bit 0x01 means the line in DISABLED while 0x04 means
-        *            the mic in ENABLED.
-        */
-       if (gus_line_vol > 10)
-               mask &= ~0x01;
-       if (gus_mic_vol > 10)
-               mask |= 0x04;
-
-       if (recording_active)
-       {
-               /*
-                *    Disable channel, if not selected for recording
-                */
-               if (!(gus_recmask & SOUND_MASK_LINE))
-                       mask |= 0x01;
-               if (!(gus_recmask & SOUND_MASK_MIC))
-                       mask &= ~0x04;
-       }
-       mix_image &= ~0x07;
-       mix_image |= mask & 0x07;
-       outb((mix_image), u_Mixer);
-
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-#define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
-                        SOUND_MASK_SYNTH|SOUND_MASK_PCM)
-
-int gus_default_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int vol, val;
-
-       if (((cmd >> 8) & 0xff) != 'M')
-               return -EINVAL;
-
-       if (!access_ok(VERIFY_WRITE, arg, sizeof(int)))
-               return -EFAULT;
-
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE) 
-       {
-               if (__get_user(val, (int __user *) arg))
-                       return -EFAULT;
-
-               switch (cmd & 0xff) 
-               {
-                       case SOUND_MIXER_RECSRC:
-                               gus_recmask = val & MIX_DEVS;
-                               if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
-                                       gus_recmask = SOUND_MASK_MIC;
-                               /* Note! Input volumes are updated during next open for recording */
-                               val = gus_recmask;
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               vol = val & 0xff;
-                               if (vol < 0)
-                                       vol = 0;
-                               if (vol > 100)
-                                       vol = 100;
-                               gus_mic_vol = vol;
-                               set_input_volumes();
-                               val = vol | (vol << 8);
-                               break;
-                               
-                       case SOUND_MIXER_LINE:
-                               vol = val & 0xff;
-                               if (vol < 0)
-                                       vol = 0;
-                               if (vol > 100)
-                                       vol = 100;
-                               gus_line_vol = vol;
-                               set_input_volumes();
-                               val = vol | (vol << 8);
-                               break;
-
-                       case SOUND_MIXER_PCM:
-                               gus_pcm_volume = val & 0xff;
-                               if (gus_pcm_volume < 0)
-                                       gus_pcm_volume = 0;
-                               if (gus_pcm_volume > 100)
-                                       gus_pcm_volume = 100;
-                               gus_audio_update_volume();
-                               val = gus_pcm_volume | (gus_pcm_volume << 8);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               gus_wave_volume = val & 0xff;
-                               if (gus_wave_volume < 0)
-                                       gus_wave_volume = 0;
-                               if (gus_wave_volume > 100)
-                                       gus_wave_volume = 100;
-                               if (active_device == GUS_DEV_WAVE) 
-                               {
-                                       int voice;
-                                       for (voice = 0; voice < nr_voices; voice++)
-                                       dynamic_volume_change(voice);   /* Apply the new vol */
-                               }
-                               val = gus_wave_volume | (gus_wave_volume << 8);
-                               break;
-
-                       default:
-                               return -EINVAL;
-               }
-       }
-       else
-       {
-               switch (cmd & 0xff) 
-               {
-                       /*
-                        * Return parameters
-                        */
-                       case SOUND_MIXER_RECSRC:
-                               val = gus_recmask;
-                               break;
-                                       
-                       case SOUND_MIXER_DEVMASK:
-                               val = MIX_DEVS;
-                               break;
-
-                       case SOUND_MIXER_STEREODEVS:
-                               val = 0;
-                               break;
-
-                       case SOUND_MIXER_RECMASK:
-                               val = SOUND_MASK_MIC | SOUND_MASK_LINE;
-                               break;
-
-                       case SOUND_MIXER_CAPS:
-                               val = 0;
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               val = gus_mic_vol | (gus_mic_vol << 8);
-                               break;
-
-                       case SOUND_MIXER_LINE:
-                               val = gus_line_vol | (gus_line_vol << 8);
-                               break;
-
-                       case SOUND_MIXER_PCM:
-                               val = gus_pcm_volume | (gus_pcm_volume << 8);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = gus_wave_volume | (gus_wave_volume << 8);
-                               break;
-
-                       default:
-                               return -EINVAL;
-               }
-       }
-       return __put_user(val, (int __user *)arg);
-}
-
-static struct mixer_operations gus_mixer_operations =
-{
-       .owner  = THIS_MODULE,
-       .id     = "GUS",
-       .name   = "Gravis Ultrasound",
-       .ioctl  = gus_default_mixer_ioctl
-};
-
-static int __init gus_default_mixer_init(void)
-{
-       int n;
-
-       if ((n = sound_alloc_mixerdev()) != -1)
-       {       
-               /*
-                * Don't install if there is another
-                * mixer
-                */
-               mixer_devs[n] = &gus_mixer_operations;
-       }
-       if (have_gus_max)
-       {
-               /*
-                *  Enable all mixer channels on the GF1 side. Otherwise recording will
-                *  not be possible using GUS MAX.
-                */
-               mix_image &= ~0x07;
-               mix_image |= 0x04;      /* All channels enabled */
-               outb((mix_image), u_Mixer);
-       }
-       return n;
-}
-
-void __init gus_wave_init(struct address_info *hw_config)
-{
-       unsigned long flags;
-       unsigned char val;
-       char *model_num = "2.4";
-       char tmp[64];
-       int gus_type = 0x24;    /* 2.4 */
-
-       int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2;
-       int sdev;
-
-       hw_config->slots[0] = -1;       /* No wave */
-       hw_config->slots[1] = -1;       /* No ad1848 */
-       hw_config->slots[4] = -1;       /* No audio */
-       hw_config->slots[5] = -1;       /* No mixer */
-
-       if (!gus_pnp_flag)
-       {
-               if (irq < 0 || irq > 15)
-               {
-                       printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq);
-                       return;
-               }
-       }
-       
-       if (dma < 0 || dma > 7 || dma == 4)
-       {
-               printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma);
-               return;
-       }
-       gus_irq = irq;
-       gus_dma = dma;
-       gus_dma2 = dma2;
-       gus_hw_config = hw_config;
-
-       if (gus_dma2 == -1)
-               gus_dma2 = dma;
-
-       /*
-        * Try to identify the GUS model.
-        *
-        *  Versions < 3.6 don't have the digital ASIC. Try to probe it first.
-        */
-
-       spin_lock_irqsave(&gus_lock,flags);
-       outb((0x20), gus_base + 0x0f);
-       val = inb(gus_base + 0x0f);
-       spin_unlock_irqrestore(&gus_lock,flags);
-
-       if (gus_pnp_flag || (val != 0xff && (val & 0x06)))      /* Should be 0x02?? */
-       {
-               int             ad_flags = 0;
-
-               if (gus_pnp_flag)
-                       ad_flags = 0x12345678;  /* Interwave "magic" */
-               /*
-                * It has the digital ASIC so the card is at least v3.4.
-                * Next try to detect the true model.
-                */
-
-               if (gus_pnp_flag)       /* Hack hack hack */
-                       val = 10;
-               else
-                       val = inb(u_MixSelect);
-
-               /*
-                * Value 255 means pre-3.7 which don't have mixer.
-                * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
-                * 10 and above is GUS MAX which has the CS4231 codec/mixer.
-                *
-                */
-
-               if (val == 255 || val < 5)
-               {
-                       model_num = "3.4";
-                       gus_type = 0x34;
-               }
-               else if (val < 10)
-               {
-                       model_num = "3.7";
-                       gus_type = 0x37;
-                       mixer_type = ICS2101;
-                       request_region(u_MixSelect, 1, "GUS mixer");
-               }
-               else
-               {
-                       struct resource *ports;
-                       ports = request_region(gus_base + 0x10c, 4, "ad1848");
-                       model_num = "MAX";
-                       gus_type = 0x40;
-                       mixer_type = CS4231;
-#ifdef CONFIG_SOUND_GUSMAX
-                       {
-                               unsigned char   max_config = 0x40;      /* Codec enable */
-
-                               if (gus_dma2 == -1)
-                                       gus_dma2 = gus_dma;
-
-                               if (gus_dma > 3)
-                                       max_config |= 0x10;             /* 16 bit capture DMA */
-
-                               if (gus_dma2 > 3)
-                                       max_config |= 0x20;             /* 16 bit playback DMA */
-
-                               max_config |= (gus_base >> 4) & 0x0f;   /* Extract the X from 2X0 */
-
-                               outb((max_config), gus_base + 0x106);   /* UltraMax control */
-                       }
-
-                       if (!ports)
-                               goto no_cs4231;
-
-                       if (ad1848_detect(ports, &ad_flags, hw_config->osp))
-                       {
-                               char           *name = "GUS MAX";
-                               int             old_num_mixers = num_mixers;
-
-                               if (gus_pnp_flag)
-                                       name = "GUS PnP";
-
-                               gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-                               gus_wave_volume = 90;
-                               have_gus_max = 1;
-                               if (hw_config->name)
-                                       name = hw_config->name;
-
-                               hw_config->slots[1] = ad1848_init(name, ports,
-                                                       -irq, gus_dma2, /* Playback DMA */
-                                                       gus_dma,        /* Capture DMA */
-                                                       1,              /* Share DMA channels with GF1 */
-                                                       hw_config->osp,
-                                                       THIS_MODULE);
-
-                               if (num_mixers > old_num_mixers)
-                               {
-                                       /* GUS has it's own mixer map */
-                                       AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH);
-                                       AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
-                                       AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-                               }
-                       }
-                       else {
-                               release_region(gus_base + 0x10c, 4);
-                       no_cs4231:
-                               printk(KERN_WARNING "GUS: No CS4231 ??");
-                       }
-#else
-                       printk(KERN_ERR "GUS MAX found, but not compiled in\n");
-#endif
-               }
-       }
-       else
-       {
-               /*
-                * ASIC not detected so the card must be 2.2 or 2.4.
-                * There could still be the 16-bit/mixer daughter card.
-                */
-       }
-
-       if (hw_config->name)
-               snprintf(tmp, sizeof(tmp), "%s (%dk)", hw_config->name,
-                        (int) gus_mem_size / 1024);
-       else if (gus_pnp_flag)
-               snprintf(tmp, sizeof(tmp), "Gravis UltraSound PnP (%dk)",
-                        (int) gus_mem_size / 1024);
-       else
-               snprintf(tmp, sizeof(tmp), "Gravis UltraSound %s (%dk)", model_num,
-                        (int) gus_mem_size / 1024);
-
-
-       samples = (struct patch_info *)vmalloc((MAX_SAMPLE + 1) * sizeof(*samples));
-       if (samples == NULL)
-       {
-               printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n");
-               return;
-       }
-       conf_printf(tmp, hw_config);
-       strlcpy(gus_info.name, tmp, sizeof(gus_info.name));
-
-       if ((sdev = sound_alloc_synthdev()) == -1)
-               printk(KERN_WARNING "gus_init: Too many synthesizers\n");
-       else
-       {
-               voice_alloc = &guswave_operations.alloc;
-               if (iw_mode)
-                       guswave_operations.id = "IWAVE";
-               hw_config->slots[0] = sdev;
-               synth_devs[sdev] = &guswave_operations;
-               sequencer_init();
-               gus_tmr_install(gus_base + 8);
-       }
-
-       reset_sample_memory();
-
-       gus_initialize();
-       
-       if ((gus_mem_size > 0) && !gus_no_wave_dma)
-       {
-               hw_config->slots[4] = -1;
-               if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION,
-                                       "Ultrasound",
-                                       &gus_audio_driver,
-                                       sizeof(struct audio_driver),
-                                       NEEDS_RESTART |
-                                       ((!iw_mode && dma2 != dma && dma2 != -1) ?
-                                               DMA_DUPLEX : 0),
-                                       AFMT_U8 | AFMT_S16_LE,
-                                       NULL, dma, dma2)) < 0)
-               {
-                       return;
-               }
-
-               hw_config->slots[4] = gus_devnum;
-               audio_devs[gus_devnum]->min_fragment = 9;       /* 512k */
-               audio_devs[gus_devnum]->max_fragment = 11;      /* 8k (must match size of bounce_buf */
-               audio_devs[gus_devnum]->mixer_dev = -1; /* Next mixer# */
-               audio_devs[gus_devnum]->flags |= DMA_HARDSTOP;
-       }
-       
-       /*
-        *  Mixer dependent initialization.
-        */
-
-       switch (mixer_type)
-       {
-               case ICS2101:
-                       gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
-                       gus_wave_volume = 90;
-                       request_region(u_MixSelect, 1, "GUS mixer");
-                       hw_config->slots[5] = ics2101_mixer_init();
-                       audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];        /* Next mixer# */
-                       return;
-
-               case CS4231:
-                       /* Initialized elsewhere (ad1848.c) */
-               default:
-                       hw_config->slots[5] = gus_default_mixer_init();
-                       audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5];        /* Next mixer# */
-                       return;
-       }
-}
-
-void __exit gus_wave_unload(struct address_info *hw_config)
-{
-#ifdef CONFIG_SOUND_GUSMAX
-       if (have_gus_max)
-       {
-               ad1848_unload(gus_base + 0x10c,
-                               -gus_irq,
-                               gus_dma2,       /* Playback DMA */
-                               gus_dma,        /* Capture DMA */
-                               1);     /* Share DMA channels with GF1 */
-       }
-#endif
-
-       if (mixer_type == ICS2101)
-       {
-               release_region(u_MixSelect, 1);
-       }
-       if (hw_config->slots[0] != -1)
-               sound_unload_synthdev(hw_config->slots[0]);
-       if (hw_config->slots[1] != -1)
-               sound_unload_audiodev(hw_config->slots[1]);
-       if (hw_config->slots[2] != -1)
-               sound_unload_mididev(hw_config->slots[2]);
-       if (hw_config->slots[4] != -1)
-               sound_unload_audiodev(hw_config->slots[4]);
-       if (hw_config->slots[5] != -1)
-               sound_unload_mixerdev(hw_config->slots[5]);
-       
-       vfree(samples);
-       samples=NULL;
-}
-/* called in interrupt context */
-static void do_loop_irq(int voice)
-{
-       unsigned char   tmp;
-       int             mode, parm;
-
-       spin_lock(&gus_lock);
-       gus_select_voice(voice);
-
-       tmp = gus_read8(0x00);
-       tmp &= ~0x20;           /*
-                                * Disable wave IRQ for this_one voice
-                                */
-       gus_write8(0x00, tmp);
-
-       if (tmp & 0x03)         /* Voice stopped */
-               voice_alloc->map[voice] = 0;
-
-       mode = voices[voice].loop_irq_mode;
-       voices[voice].loop_irq_mode = 0;
-       parm = voices[voice].loop_irq_parm;
-
-       switch (mode)
-       {
-               case LMODE_FINISH:      /*
-                                        * Final loop finished, shoot volume down
-                                        */
-
-                       if ((int) (gus_read16(0x09) >> 4) < 100)        /*
-                                                                        * Get current volume
-                                                                        */
-                       {
-                               gus_voice_off();
-                               gus_rampoff();
-                               gus_voice_init(voice);
-                               break;
-                       }
-                       gus_ramp_range(65, 4065);
-                       gus_ramp_rate(0, 63);           /*
-                                                        * Fastest possible rate
-                                                        */
-                       gus_rampon(0x20 | 0x40);        /*
-                                                        * Ramp down, once, irq
-                                                        */
-                       voices[voice].volume_irq_mode = VMODE_HALT;
-                       break;
-
-               case LMODE_PCM_STOP:
-                       pcm_active = 0; /* Signal to the play_next_pcm_block routine */
-               case LMODE_PCM:
-               {
-                       pcm_qlen--;
-                       pcm_head = (pcm_head + 1) % pcm_nblk;
-                       if (pcm_qlen && pcm_active)
-                       {
-                               play_next_pcm_block();
-                       }
-                       else
-                       {
-                               /* Underrun. Just stop the voice */
-                               gus_select_voice(0);    /* Left channel */
-                               gus_voice_off();
-                               gus_rampoff();
-                               gus_select_voice(1);    /* Right channel */
-                               gus_voice_off();
-                               gus_rampoff();
-                               pcm_active = 0;
-                       }
-
-                       /*
-                        * If the queue was full before this interrupt, the DMA transfer was
-                        * suspended. Let it continue now.
-                        */
-                       
-                       if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-                               DMAbuf_outputintr(gus_devnum, 0);
-               }
-               break;
-
-               default:
-                       break;
-       }
-       spin_unlock(&gus_lock);
-}
-
-static void do_volume_irq(int voice)
-{
-       unsigned char tmp;
-       int mode, parm;
-       unsigned long flags;
-
-       spin_lock_irqsave(&gus_lock,flags);
-
-       gus_select_voice(voice);
-       tmp = gus_read8(0x0d);
-       tmp &= ~0x20;           /*
-                                * Disable volume ramp IRQ
-                                */
-       gus_write8(0x0d, tmp);
-
-       mode = voices[voice].volume_irq_mode;
-       voices[voice].volume_irq_mode = 0;
-       parm = voices[voice].volume_irq_parm;
-
-       switch (mode)
-       {
-               case VMODE_HALT:        /* Decay phase finished */
-                       if (iw_mode)
-                               gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       gus_voice_init(voice);
-                       break;
-
-               case VMODE_ENVELOPE:
-                       gus_rampoff();
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       step_envelope(voice);
-                       break;
-
-               case VMODE_START_NOTE:
-                       spin_unlock_irqrestore(&gus_lock,flags);
-                       guswave_start_note2(voices[voice].dev_pending, voice,
-                                     voices[voice].note_pending, voices[voice].volume_pending);
-                       if (voices[voice].kill_pending)
-                               guswave_kill_note(voices[voice].dev_pending, voice,
-                                         voices[voice].note_pending, 0);
-
-                       if (voices[voice].sample_pending >= 0)
-                       {
-                               guswave_set_instr(voices[voice].dev_pending, voice,
-                                       voices[voice].sample_pending);
-                               voices[voice].sample_pending = -1;
-                       }
-                       break;
-
-               default:
-                       spin_unlock_irqrestore(&gus_lock,flags);
-       }
-}
-/* called in irq context */
-void gus_voice_irq(void)
-{
-       unsigned long wave_ignore = 0, volume_ignore = 0;
-       unsigned long voice_bit;
-
-       unsigned char src, voice;
-
-       while (1)
-       {
-               src = gus_read8(0x0f);  /*
-                                        * Get source info
-                                        */
-               voice = src & 0x1f;
-               src &= 0xc0;
-
-               if (src == (0x80 | 0x40))
-                       return; /*
-                                * No interrupt
-                                */
-
-               voice_bit = 1 << voice;
-
-               if (!(src & 0x80))      /*
-                                        * Wave IRQ pending
-                                        */
-                       if (!(wave_ignore & voice_bit) && (int) voice < nr_voices)      /*
-                                                                                        * Not done
-                                                                                        * yet
-                                                                                        */
-                       {
-                               wave_ignore |= voice_bit;
-                               do_loop_irq(voice);
-                       }
-               if (!(src & 0x40))      /*
-                                        * Volume IRQ pending
-                                        */
-                       if (!(volume_ignore & voice_bit) && (int) voice < nr_voices)    /*
-                                                                                          * Not done
-                                                                                          * yet
-                                                                                        */
-                       {
-                               volume_ignore |= voice_bit;
-                               do_volume_irq(voice);
-                       }
-       }
-}
-
-void guswave_dma_irq(void)
-{
-       unsigned char   status;
-
-       status = gus_look8(0x41);       /* Get DMA IRQ Status */
-       if (status & 0x40)      /* DMA interrupt pending */
-               switch (active_device)
-               {
-                       case GUS_DEV_WAVE:
-                               wake_up(&dram_sleeper);
-                               break;
-
-                       case GUS_DEV_PCM_CONTINUE:      /* Left channel data transferred */
-                               gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                               gus_transfer_output_block(pcm_current_dev, pcm_current_buf,
-                                               pcm_current_count,
-                                               pcm_current_intrflag, 1);
-                               break;
-
-                       case GUS_DEV_PCM_DONE:  /* Right or mono channel data transferred */
-                               gus_write8(0x41, 0);    /* Disable GF1 DMA */
-                               if (pcm_qlen < pcm_nblk)
-                               {
-                                       dma_active = 0;
-                                       if (gus_busy)
-                                       {
-                                               if (audio_devs[gus_devnum]->dmap_out->qlen > 0)
-                                                       DMAbuf_outputintr(gus_devnum, 0);
-                                       }
-                               }
-                               break;
-
-                       default:
-                               break;
-       }
-       status = gus_look8(0x49);       /*
-                                        * Get Sampling IRQ Status
-                                        */
-       if (status & 0x40)      /*
-                                * Sampling Irq pending
-                                */
-       {
-               DMAbuf_inputintr(gus_devnum);
-       }
-}
-
-/*
- * Timer stuff
- */
-
-static volatile int select_addr, data_addr;
-static volatile int curr_timer;
-
-void gus_timer_command(unsigned int addr, unsigned int val)
-{
-       int i;
-
-       outb(((unsigned char) (addr & 0xff)), select_addr);
-
-       for (i = 0; i < 2; i++)
-               inb(select_addr);
-
-       outb(((unsigned char) (val & 0xff)), data_addr);
-
-       for (i = 0; i < 2; i++)
-               inb(select_addr);
-}
-
-static void arm_timer(int timer, unsigned int interval)
-{
-       curr_timer = timer;
-
-       if (timer == 1)
-       {
-               gus_write8(0x46, 256 - interval);       /* Set counter for timer 1 */
-               gus_write8(0x45, 0x04);                 /* Enable timer 1 IRQ */
-               gus_timer_command(0x04, 0x01);          /* Start timer 1 */
-       }
-       else
-       {
-               gus_write8(0x47, 256 - interval);       /* Set counter for timer 2 */
-               gus_write8(0x45, 0x08);                 /* Enable timer 2 IRQ */
-               gus_timer_command(0x04, 0x02);          /* Start timer 2 */
-       }
-
-       gus_timer_enabled = 1;
-}
-
-static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick)
-{
-       int timer_no, resolution;
-       int divisor;
-
-       if (usecs_per_tick > (256 * 80))
-       {
-               timer_no = 2;
-               resolution = 320;       /* usec */
-       }
-       else
-       {
-               timer_no = 1;
-               resolution = 80;        /* usec */
-       }
-       divisor = (usecs_per_tick + (resolution / 2)) / resolution;
-       arm_timer(timer_no, divisor);
-
-       return divisor * resolution;
-}
-
-static void gus_tmr_disable(int dev)
-{
-       gus_write8(0x45, 0);    /* Disable both timers */
-       gus_timer_enabled = 0;
-}
-
-static void gus_tmr_restart(int dev)
-{
-       if (curr_timer == 1)
-               gus_write8(0x45, 0x04);         /* Start timer 1 again */
-       else
-               gus_write8(0x45, 0x08);         /* Start timer 2 again */
-       gus_timer_enabled = 1;
-}
-
-static struct sound_lowlev_timer gus_tmr =
-{
-       0,
-       1,
-       gus_tmr_start,
-       gus_tmr_disable,
-       gus_tmr_restart
-};
-
-static void gus_tmr_install(int io_base)
-{
-       struct sound_lowlev_timer *tmr;
-
-       select_addr = io_base;
-       data_addr = io_base + 1;
-
-       tmr = &gus_tmr;
-
-#ifdef THIS_GETS_FIXED
-       sound_timer_init(&gus_tmr, "GUS");
-#endif
-}
diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c
deleted file mode 100644 (file)
index 6601b28..0000000
+++ /dev/null
@@ -1,1330 +0,0 @@
-/*
-       sound/oss/harmony.c
-
-       This is a sound driver for ASP's and Lasi's Harmony sound chip
-       and is unlikely to be used for anything other than on a HP PA-RISC.
-
-       Harmony is found in HP 712s, 715/new and many other GSC based machines.
-       On older 715 machines you'll find the technically identical chip 
-       called 'Vivace'. Both Harmony and Vicace are supported by this driver.
-
-       Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@onefishtwo.ca>
-       Copyright 2000-2003 (c) Helge Deller <deller@gmx.de>
-       Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr>
-       Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr>
-       Copyright 2004 (c) Stuart Brady <sdbrady@ntlworld.com>
-
-                               
-TODO:
-       - fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to
-               return the real values
-       - add private ioctl for selecting line- or microphone input
-               (only one of them is available at the same time)
-       - add module parameters
-       - implement mmap functionality
-       - implement gain meter ?
-       - ...
-*/
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-
-#include <asm/parisc-device.h>
-#include <asm/io.h>
-
-#include "sound_config.h"
-
-
-#define PFX "harmony: "
-#define HARMONY_VERSION "V0.9a"
-
-#undef DEBUG
-#ifdef DEBUG
-# define DPRINTK printk 
-#else
-# define DPRINTK(x,...)
-#endif
-
-
-#define MAX_BUFS 10            /* maximum number of rotating buffers */
-#define HARMONY_BUF_SIZE 4096  /* needs to be a multiple of PAGE_SIZE (4096)! */
-
-#define CNTL_C         0x80000000
-#define        CNTL_ST         0x00000020
-#define CNTL_44100     0x00000015      /* HARMONY_SR_44KHZ */
-#define CNTL_8000      0x00000008      /* HARMONY_SR_8KHZ */
-
-#define GAINCTL_HE     0x08000000
-#define GAINCTL_LE     0x04000000
-#define GAINCTL_SE     0x02000000
-
-#define DSTATUS_PN     0x00000200
-#define DSTATUS_RN     0x00000002
-
-#define DSTATUS_IE     0x80000000
-
-#define HARMONY_DF_16BIT_LINEAR        0
-#define HARMONY_DF_8BIT_ULAW   1
-#define HARMONY_DF_8BIT_ALAW   2
-
-#define HARMONY_SS_MONO                0
-#define HARMONY_SS_STEREO      1
-
-#define HARMONY_SR_8KHZ                0x08
-#define HARMONY_SR_16KHZ       0x09
-#define HARMONY_SR_27KHZ       0x0A
-#define HARMONY_SR_32KHZ       0x0B
-#define HARMONY_SR_48KHZ       0x0E
-#define HARMONY_SR_9KHZ                0x0F
-#define HARMONY_SR_5KHZ                0x10
-#define HARMONY_SR_11KHZ       0x11
-#define HARMONY_SR_18KHZ       0x12
-#define HARMONY_SR_22KHZ       0x13
-#define HARMONY_SR_37KHZ       0x14
-#define HARMONY_SR_44KHZ       0x15
-#define HARMONY_SR_33KHZ       0x16
-#define HARMONY_SR_6KHZ                0x17
-
-/*
- * Some magics numbers used to auto-detect file formats
- */
-
-#define HARMONY_MAGIC_8B_ULAW  1
-#define HARMONY_MAGIC_8B_ALAW  27
-#define HARMONY_MAGIC_16B_LINEAR 3
-#define HARMONY_MAGIC_MONO     1
-#define HARMONY_MAGIC_STEREO   2
-
-/*
- * Channels Positions in mixer register
- */
-
-#define GAIN_HE_SHIFT   27
-#define GAIN_HE_MASK    ( 1 << GAIN_HE_SHIFT) 
-#define GAIN_LE_SHIFT   26
-#define GAIN_LE_MASK    ( 1 << GAIN_LE_SHIFT) 
-#define GAIN_SE_SHIFT   25
-#define GAIN_SE_MASK    ( 1 << GAIN_SE_SHIFT) 
-#define GAIN_IS_SHIFT   24
-#define GAIN_IS_MASK    ( 1 << GAIN_IS_SHIFT) 
-#define GAIN_MA_SHIFT   20
-#define GAIN_MA_MASK    ( 0x0f << GAIN_MA_SHIFT) 
-#define GAIN_LI_SHIFT   16
-#define GAIN_LI_MASK    ( 0x0f << GAIN_LI_SHIFT) 
-#define GAIN_RI_SHIFT   12
-#define GAIN_RI_MASK    ( 0x0f << GAIN_RI_SHIFT) 
-#define GAIN_LO_SHIFT   6
-#define GAIN_LO_MASK    ( 0x3f << GAIN_LO_SHIFT) 
-#define GAIN_RO_SHIFT   0
-#define GAIN_RO_MASK    ( 0x3f << GAIN_RO_SHIFT) 
-
-
-#define MAX_OUTPUT_LEVEL  (GAIN_RO_MASK >> GAIN_RO_SHIFT)
-#define MAX_INPUT_LEVEL   (GAIN_RI_MASK >> GAIN_RI_SHIFT)
-#define MAX_MONITOR_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT)
-
-#define MIXER_INTERNAL   SOUND_MIXER_LINE1
-#define MIXER_LINEOUT    SOUND_MIXER_LINE2
-#define MIXER_HEADPHONES SOUND_MIXER_LINE3
-
-#define MASK_INTERNAL   SOUND_MASK_LINE1
-#define MASK_LINEOUT    SOUND_MASK_LINE2
-#define MASK_HEADPHONES SOUND_MASK_LINE3
-
-/*
- * Channels Mask in mixer register
- */
-
-#define GAIN_TOTAL_SILENCE 0x00F00FFF
-#define GAIN_DEFAULT       0x0FF00000
-
-
-struct harmony_hpa {
-       u8      unused000;
-       u8      id;
-       u8      teleshare_id;
-       u8      unused003;
-       u32     reset;
-       u32     cntl;
-       u32     gainctl;
-       u32     pnxtadd;
-       u32     pcuradd;
-       u32     rnxtadd;
-       u32     rcuradd;
-       u32     dstatus;
-       u32     ov;
-       u32     pio;
-       u32     unused02c;
-       u32     unused030[3];
-       u32     diag;
-};
-
-struct harmony_dev {
-       struct harmony_hpa *hpa;
-       struct parisc_device *dev;
-       u32 current_gain;
-       u32 dac_rate;           /* 8000 ... 48000 (Hz) */
-       u8 data_format;         /* HARMONY_DF_xx_BIT_xxx */
-       u8 sample_rate;         /* HARMONY_SR_xx_KHZ */
-       u8 stereo_select;       /* HARMONY_SS_MONO or HARMONY_SS_STEREO */
-       int format_initialized  :1;
-       int suspended_playing   :1;
-       int suspended_recording :1;
-       
-       int blocked_playing     :1;
-       int blocked_recording   :1;
-       int audio_open          :1;
-       int mixer_open          :1;
-       
-       wait_queue_head_t wq_play, wq_record;
-       int first_filled_play;  /* first buffer containing data (next to play) */
-       int nb_filled_play; 
-       int play_offset;
-       int first_filled_record;
-       int nb_filled_record;
-               
-       int dsp_unit, mixer_unit;
-};
-
-
-static struct harmony_dev harmony;
-
-
-/*
- * Dynamic sound buffer allocation and DMA memory
- */
-
-struct harmony_buffer {
-       unsigned char *addr;
-       dma_addr_t dma_handle;
-       int dma_coherent;       /* Zero if dma_alloc_coherent() fails */
-       unsigned int len;
-};
-
-/*
- * Harmony memory buffers
- */
-
-static struct harmony_buffer played_buf, recorded_buf, silent, graveyard;
-
-
-#define CHECK_WBACK_INV_OFFSET(b,offset,len) \
-        do { if (!b.dma_coherent) \
-               dma_cache_wback_inv((unsigned long)b.addr+offset,len); \
-       } while (0) 
-
-       
-static int __init harmony_alloc_buffer(struct harmony_buffer *b, 
-               unsigned int buffer_count)
-{
-       b->len = buffer_count * HARMONY_BUF_SIZE;
-       b->addr = dma_alloc_coherent(&harmony.dev->dev, 
-                         b->len, &b->dma_handle, GFP_KERNEL|GFP_DMA);
-       if (b->addr && b->dma_handle) {
-               b->dma_coherent = 1;
-               DPRINTK(KERN_INFO PFX "coherent memory: 0x%lx, played_buf: 0x%lx\n",
-                               (unsigned long)b->dma_handle, (unsigned long)b->addr);
-       } else {
-               b->dma_coherent = 0;
-               /* kmalloc()ed memory will HPMC on ccio machines ! */
-               b->addr = kmalloc(b->len, GFP_KERNEL);
-               if (!b->addr) {
-                       printk(KERN_ERR PFX "couldn't allocate memory\n");
-                       return -EBUSY;
-               }
-               b->dma_handle = __pa(b->addr);
-       }
-       return 0;
-}
-
-static void __exit harmony_free_buffer(struct harmony_buffer *b)
-{
-       if (!b->addr)
-               return;
-
-       if (b->dma_coherent)
-               dma_free_coherent(&harmony.dev->dev,
-                               b->len, b->addr, b->dma_handle);
-       else
-               kfree(b->addr);
-
-       memset(b, 0, sizeof(*b));
-}
-
-
-
-/*
- * Low-Level sound-chip programming
- */
-
-static void __inline__ harmony_wait_CNTL(void)
-{
-       /* Wait until we're out of control mode */
-       while (gsc_readl(&harmony.hpa->cntl) & CNTL_C)
-               /* wait */ ;
-}
-
-
-static void harmony_update_control(void) 
-{
-       u32 default_cntl;
-       
-       /* Set CNTL */
-       default_cntl = (CNTL_C |                /* The C bit */
-               (harmony.data_format << 6) |    /* Set the data format */
-               (harmony.stereo_select << 5) |  /* Stereo select */
-               (harmony.sample_rate));         /* Set sample rate */
-       harmony.format_initialized = 1;
-       
-       /* initialize CNTL */
-       gsc_writel(default_cntl, &harmony.hpa->cntl);
-}
-
-static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) 
-{
-       harmony.sample_rate = sample_rate;
-       harmony.data_format = data_format;
-       harmony.stereo_select = stereo_select;
-       harmony_update_control();
-}
-
-static void harmony_set_rate(u8 data_rate) 
-{
-       harmony.sample_rate = data_rate;
-       harmony_update_control();
-}
-
-static int harmony_detect_rate(int *freq)
-{
-       int newrate;
-       switch (*freq) {
-       case 8000:      newrate = HARMONY_SR_8KHZ;      break;
-       case 16000:     newrate = HARMONY_SR_16KHZ;     break; 
-       case 27428:     newrate = HARMONY_SR_27KHZ;     break; 
-       case 32000:     newrate = HARMONY_SR_32KHZ;     break; 
-       case 48000:     newrate = HARMONY_SR_48KHZ;     break; 
-       case 9600:      newrate = HARMONY_SR_9KHZ;      break; 
-       case 5512:      newrate = HARMONY_SR_5KHZ;      break; 
-       case 11025:     newrate = HARMONY_SR_11KHZ;     break; 
-       case 18900:     newrate = HARMONY_SR_18KHZ;     break; 
-       case 22050:     newrate = HARMONY_SR_22KHZ;     break; 
-       case 37800:     newrate = HARMONY_SR_37KHZ;     break; 
-       case 44100:     newrate = HARMONY_SR_44KHZ;     break; 
-       case 33075:     newrate = HARMONY_SR_33KHZ;     break; 
-       case 6615:      newrate = HARMONY_SR_6KHZ;      break; 
-       default:        newrate = HARMONY_SR_8KHZ; 
-                       *freq = 8000;                   break;
-       }
-       return newrate;
-}
-
-static void harmony_set_format(u8 data_format) 
-{
-       harmony.data_format = data_format;
-       harmony_update_control();
-}
-
-static void harmony_set_stereo(u8 stereo_select) 
-{
-       harmony.stereo_select = stereo_select;
-       harmony_update_control();
-}
-
-static void harmony_disable_interrupts(void) 
-{
-       harmony_wait_CNTL();
-       gsc_writel(0, &harmony.hpa->dstatus); 
-}
-
-static void harmony_enable_interrupts(void) 
-{
-       harmony_wait_CNTL();
-       gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); 
-}
-
-/*
- * harmony_silence()
- *
- * This subroutine fills in a buffer starting at location start and
- * silences for length bytes.  This references the current
- * configuration of the audio format.
- *
- */
-
-static void harmony_silence(struct harmony_buffer *buffer, int start, int length) 
-{
-       u8 silence_char;
-
-       /* Despite what you hear, silence is different in
-          different audio formats.  */
-       switch (harmony.data_format) {
-               case HARMONY_DF_8BIT_ULAW:      silence_char = 0x55; break;
-               case HARMONY_DF_8BIT_ALAW:      silence_char = 0xff; break;
-               case HARMONY_DF_16BIT_LINEAR:   /* fall through */
-               default:                        silence_char = 0;
-       }
-
-       memset(buffer->addr+start, silence_char, length);
-}
-
-
-static int harmony_audio_open(struct inode *inode, struct file *file)
-{
-       if (harmony.audio_open) 
-               return -EBUSY;
-       
-       harmony.audio_open = 1;
-       harmony.suspended_playing = harmony.suspended_recording = 1;
-       harmony.blocked_playing   = harmony.blocked_recording   = 0;
-       harmony.first_filled_play = harmony.first_filled_record = 0;
-       harmony.nb_filled_play    = harmony.nb_filled_record    = 0;
-       harmony.play_offset = 0;
-       init_waitqueue_head(&harmony.wq_play);
-       init_waitqueue_head(&harmony.wq_record);
-       
-       /* Start off in a balanced mode. */
-       harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-       harmony_update_control();
-       harmony.format_initialized = 0;
-
-       /* Clear out all the buffers and flush to cache */
-       harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-       CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-       
-       return 0;
-}
-
-/*
- * Release (close) the audio device.
- */
-
-static int harmony_audio_release(struct inode *inode, struct file *file)
-{
-       if (!harmony.audio_open) 
-               return -EBUSY;
-       
-       harmony.audio_open = 0;
-
-       return 0;
-}
-
-/*
- * Read recorded data off the audio device.
- */
-
-static ssize_t harmony_audio_read(struct file *file,
-                                char *buffer,
-                                size_t size_count,
-                                loff_t *ppos)
-{
-       int total_count = (int) size_count;
-       int count = 0;
-       int buf_to_read;
-
-       while (count<total_count) {
-               /* Wait until we're out of control mode */
-               harmony_wait_CNTL();
-               
-               /* Figure out which buffer to fill in */
-               if (harmony.nb_filled_record <= 2) {
-                       harmony.blocked_recording = 1;
-                       if (harmony.suspended_recording) {
-                               harmony.suspended_recording = 0;
-                               harmony_enable_interrupts();
-                       }
-                                                       
-                       interruptible_sleep_on(&harmony.wq_record);
-                       harmony.blocked_recording = 0;
-               }
-               
-               if (harmony.nb_filled_record < 2)
-                       return -EBUSY;
-               
-               buf_to_read = harmony.first_filled_record;
-
-               /* Copy the page to an aligned buffer */
-               if (copy_to_user(buffer+count, recorded_buf.addr +
-                                (HARMONY_BUF_SIZE*buf_to_read),
-                                HARMONY_BUF_SIZE)) {
-                       count = -EFAULT;
-                       break;
-               }
-               
-               harmony.nb_filled_record--;
-               harmony.first_filled_record++;
-               harmony.first_filled_record %= MAX_BUFS;
-                               
-               count += HARMONY_BUF_SIZE;
-       }
-       return count;
-}
-
-
-
-
-/*
- * Here is the place where we try to recognize file format.
- * Sun/NeXT .au files begin with the string .snd
- * At offset 12 is specified the encoding.
- * At offset 16 is specified speed rate
- * At Offset 20 is specified the numbers of voices
- */
-
-#define four_bytes_to_u32(start) (file_header[start] << 24)|\
-                                  (file_header[start+1] << 16)|\
-                                  (file_header[start+2] << 8)|\
-                                  (file_header[start+3]);
-
-#define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\
-                                                    
-
-static int harmony_format_auto_detect(const char *buffer, int block_size)
-{
-       u8 file_header[24];
-       u32 start_string;
-       int ret = 0;
-       
-       if (block_size>24) {
-               if (copy_from_user(file_header, buffer, sizeof(file_header)))
-                       ret = -EFAULT;
-                       
-               start_string = four_bytes_to_u32(0);
-               
-               if ((file_header[4]==0) && (start_string==0x2E736E64)) {
-                       u32 format;
-                       u32 nb_voices;
-                       u32 speed;
-                       
-                       format = four_bytes_to_u32(12);
-                       nb_voices = four_bytes_to_u32(20);
-                       speed = four_bytes_to_u32(16);
-                       
-                       switch (format) {
-                       case HARMONY_MAGIC_8B_ULAW:
-                               harmony.data_format = HARMONY_DF_8BIT_ULAW;
-                               break;
-                       case HARMONY_MAGIC_8B_ALAW:
-                               harmony.data_format = HARMONY_DF_8BIT_ALAW;
-                               break;
-                       case HARMONY_MAGIC_16B_LINEAR:
-                               harmony.data_format = HARMONY_DF_16BIT_LINEAR;
-                               break;
-                       default:
-                               harmony_set_control(HARMONY_DF_16BIT_LINEAR,
-                                               HARMONY_SR_44KHZ, HARMONY_SS_STEREO);
-                               goto out;
-                       }
-                       switch (nb_voices) {
-                       case HARMONY_MAGIC_MONO:
-                               harmony.stereo_select = HARMONY_SS_MONO;
-                               break;
-                       case HARMONY_MAGIC_STEREO:
-                               harmony.stereo_select = HARMONY_SS_STEREO;
-                               break;
-                       default:
-                               harmony.stereo_select = HARMONY_SS_MONO;
-                               break;
-                       }
-                       harmony_set_rate(harmony_detect_rate(&speed));
-                       harmony.dac_rate = speed;
-                       goto out;
-               }
-       }
-       harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO);
-out:
-       return ret;
-}
-#undef four_bytes_to_u32
-
-
-static ssize_t harmony_audio_write(struct file *file,
-                                 const char *buffer,
-                                 size_t size_count,
-                                 loff_t *ppos)
-{
-       int total_count = (int) size_count;
-       int count = 0;
-       int frame_size;
-       int buf_to_fill;
-       int fresh_buffer;
-
-       if (!harmony.format_initialized) {
-               if (harmony_format_auto_detect(buffer, total_count))
-                       return -EFAULT;
-       }
-       
-       while (count<total_count) {
-               /* Wait until we're out of control mode */
-               harmony_wait_CNTL();
-
-               /* Figure out which buffer to fill in */
-               if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) {
-                       harmony.blocked_playing = 1;
-                       interruptible_sleep_on(&harmony.wq_play);
-                       harmony.blocked_playing = 0;
-               }
-               if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset)
-                       return -EBUSY;
-               
-               
-               buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); 
-               if (harmony.play_offset) {
-                       buf_to_fill--;
-                       buf_to_fill += MAX_BUFS;
-               }
-               buf_to_fill %= MAX_BUFS;
-               
-               fresh_buffer = (harmony.play_offset == 0);
-               
-               /* Figure out the size of the frame */
-               if ((total_count-count) >= HARMONY_BUF_SIZE - harmony.play_offset) {
-                       frame_size = HARMONY_BUF_SIZE - harmony.play_offset;
-               } else {
-                       frame_size = total_count - count;
-                       /* Clear out the buffer, since there we'll only be 
-                          overlaying part of the old buffer with the new one */
-                       harmony_silence(&played_buf, 
-                               HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset,
-                               HARMONY_BUF_SIZE-frame_size-harmony.play_offset);
-               }
-
-               /* Copy the page to an aligned buffer */
-               if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, 
-                                  buffer+count, frame_size))
-                       return -EFAULT;
-               CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), 
-                               frame_size);
-       
-               if (fresh_buffer)
-                       harmony.nb_filled_play++;
-               
-               count += frame_size;
-               harmony.play_offset += frame_size;
-               harmony.play_offset %= HARMONY_BUF_SIZE;
-               if (harmony.suspended_playing && (harmony.nb_filled_play>=4))
-                       harmony_enable_interrupts();
-       }
-       
-       return count;
-}
-
-static unsigned int harmony_audio_poll(struct file *file,
-                                     struct poll_table_struct *wait)
-{
-       unsigned int mask = 0;
-       
-       if (file->f_mode & FMODE_READ) {
-               if (!harmony.suspended_recording)
-                       poll_wait(file, &harmony.wq_record, wait);
-               if (harmony.nb_filled_record)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-
-       if (file->f_mode & FMODE_WRITE) {
-               if (!harmony.suspended_playing)
-                       poll_wait(file, &harmony.wq_play, wait);
-               if (harmony.nb_filled_play)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-
-       return mask;
-}
-
-static int harmony_audio_ioctl(struct inode *inode,
-                                struct file *file,
-                               unsigned int cmd,
-                                unsigned long arg)
-{
-       int ival, new_format;
-       int frag_size, frag_buf;
-       struct audio_buf_info info;
-       
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, (int *) arg);
-
-       case SNDCTL_DSP_GETCAPS:
-               ival = DSP_CAP_DUPLEX;
-               return put_user(ival, (int *) arg);
-
-       case SNDCTL_DSP_GETFMTS:
-               ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); 
-               return put_user(ival, (int *) arg);
-       
-       case SNDCTL_DSP_SETFMT:
-               if (get_user(ival, (int *) arg)) 
-                       return -EFAULT;
-               if (ival != AFMT_QUERY) {
-                       switch (ival) {
-                       case AFMT_MU_LAW:       new_format = HARMONY_DF_8BIT_ULAW; break;
-                       case AFMT_A_LAW:        new_format = HARMONY_DF_8BIT_ALAW; break;
-                       case AFMT_S16_BE:       new_format = HARMONY_DF_16BIT_LINEAR; break;
-                       default: {
-                               DPRINTK(KERN_WARNING PFX 
-                                       "unsupported sound format 0x%04x requested.\n",
-                                       ival);
-                               ival = AFMT_S16_BE;
-                               return put_user(ival, (int *) arg);
-                       }
-                       }
-                       harmony_set_format(new_format);
-                       return 0;
-               } else {
-                       switch (harmony.data_format) {
-                       case HARMONY_DF_8BIT_ULAW:      ival = AFMT_MU_LAW; break;
-                       case HARMONY_DF_8BIT_ALAW:      ival = AFMT_A_LAW;  break;
-                       case HARMONY_DF_16BIT_LINEAR:   ival = AFMT_U16_BE; break;
-                       default: ival = 0;
-                       }
-                       return put_user(ival, (int *) arg);
-               }
-
-       case SOUND_PCM_READ_RATE:
-               ival = harmony.dac_rate;
-               return put_user(ival, (int *) arg);
-
-       case SNDCTL_DSP_SPEED:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               harmony_set_rate(harmony_detect_rate(&ival));
-               harmony.dac_rate = ival;
-               return put_user(ival, (int*) arg);
-
-       case SNDCTL_DSP_STEREO:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               if (ival != 0 && ival != 1)
-                       return -EINVAL;
-               harmony_set_stereo(ival);
-               return 0;
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(ival, (int *) arg))
-                       return -EFAULT;
-               if (ival != 1 && ival != 2) {
-                       ival = harmony.stereo_select == HARMONY_SS_MONO ? 1 : 2;
-                       return put_user(ival, (int *) arg);
-               }
-               harmony_set_stereo(ival-1);
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               ival = HARMONY_BUF_SIZE;
-               return put_user(ival, (int *) arg);
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_RESET:
-               if (!harmony.suspended_recording) {
-                       /* TODO: stop_recording() */
-               }
-               return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(ival, (int *)arg))
-                       return -EFAULT;
-               frag_size = ival & 0xffff;
-               frag_buf = (ival>>16) & 0xffff;
-               /* TODO: We use hardcoded fragment sizes and numbers for now */
-               frag_size = 12;  /* 4096 == 2^12 */
-               frag_buf  = MAX_BUFS;
-               ival = (frag_buf << 16) + frag_size;
-               return put_user(ival, (int *) arg);
-               
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               info.fragstotal = MAX_BUFS;
-                info.fragments = MAX_BUFS - harmony.nb_filled_play;
-               info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-               return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               info.fragstotal = MAX_BUFS;
-                info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record;
-               info.fragsize = HARMONY_BUF_SIZE;
-                info.bytes = info.fragments * info.fragsize;
-               return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0;
-       
-       case SNDCTL_DSP_SYNC:
-               return 0;
-       }
-       
-       return -EINVAL;
-}
-
-
-/*
- * harmony_interrupt()
- *
- * harmony interruption service routine
- * 
- */
-
-static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
-{
-       u32 dstatus;
-       struct harmony_hpa *hpa;
-
-       /* Setup the hpa */
-       hpa = ((struct harmony_dev *)dev)->hpa;
-       harmony_wait_CNTL();
-
-       /* Read dstatus and pcuradd (the current address) */
-       dstatus = gsc_readl(&hpa->dstatus);
-       
-       /* Turn off interrupts */
-       harmony_disable_interrupts();
-       
-       /* Check if this is a request to get the next play buffer */
-       if (dstatus & DSTATUS_PN) {
-               if (!harmony.nb_filled_play) {
-                       harmony.suspended_playing = 1;
-                       gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd);
-                                               
-                       if (!harmony.suspended_recording)
-                               harmony_enable_interrupts();
-               } else {
-                       harmony.suspended_playing = 0;
-                       gsc_writel((unsigned long)played_buf.dma_handle + 
-                                       (HARMONY_BUF_SIZE*harmony.first_filled_play),
-                                       &hpa->pnxtadd);
-                       harmony.first_filled_play++;
-                       harmony.first_filled_play %= MAX_BUFS;
-                       harmony.nb_filled_play--;
-                       
-                       harmony_enable_interrupts();
-               }
-               
-               if (harmony.blocked_playing)
-                       wake_up_interruptible(&harmony.wq_play);
-       }
-       
-       /* Check if we're being asked to fill in a recording buffer */
-       if (dstatus & DSTATUS_RN) {
-               if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording)
-               {
-                       harmony.nb_filled_record = 0;
-                       harmony.first_filled_record = 0;
-                       harmony.suspended_recording = 1;
-                       gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd);
-                       if (!harmony.suspended_playing)
-                               harmony_enable_interrupts();
-               } else {
-                       int buf_to_fill;
-                       buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS;
-                       CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE);
-                       gsc_writel((unsigned long)recorded_buf.dma_handle +
-                                       HARMONY_BUF_SIZE*buf_to_fill,
-                                       &hpa->rnxtadd);
-                       harmony.nb_filled_record++;
-                       harmony_enable_interrupts();
-               }
-
-               if (harmony.blocked_recording && harmony.nb_filled_record>3)
-                       wake_up_interruptible(&harmony.wq_record);
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * Sound playing functions
- */
-
-static struct file_operations harmony_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = harmony_audio_read,
-       .write          = harmony_audio_write,
-       .poll           = harmony_audio_poll,
-       .ioctl          = harmony_audio_ioctl,
-       .open           = harmony_audio_open,
-       .release        = harmony_audio_release,
-};
-
-static int harmony_audio_init(void)
-{
-       /* Request that IRQ */
-       if (request_irq(harmony.dev->irq, harmony_interrupt, 0 ,"harmony", &harmony)) {
-               printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.dev->irq);
-               return -EFAULT;
-       }
-
-       harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1);
-       if (harmony.dsp_unit < 0) {
-               printk(KERN_ERR PFX "Error registering dsp\n");
-               free_irq(harmony.dev->irq, &harmony);
-               return -EFAULT;
-       }
-       
-       /* Clear the buffers so you don't end up with crap in the buffers. */ 
-       harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-       /* Make sure this makes it to cache */
-       CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS);
-
-       /* Clear out the silent buffer and flush to cache */
-       harmony_silence(&silent, 0, HARMONY_BUF_SIZE);
-       CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE);
-       
-       harmony.audio_open = 0;
-       
-       return 0;
-}
-
-
-/*
- * mixer functions 
- */
-
-static void harmony_mixer_set_gain(void)
-{
-       harmony_wait_CNTL();
-       gsc_writel(harmony.current_gain, &harmony.hpa->gainctl);
-}
-
-/* 
- *  Read gain of selected channel.
- *  The OSS rate is from 0 (silent) to 100 -> need some conversions
- *
- *  The harmony gain are attenuation for output and monitor gain.
- *                   is amplifaction for input gain
- */
-#define to_harmony_level(level,max) ((level)*max/100)
-#define to_oss_level(level,max) ((level)*100/max)
-
-static int harmony_mixer_get_level(int channel)
-{
-       int left_level;
-       int right_level;
-
-       switch (channel) {
-               case SOUND_MIXER_VOLUME:
-                       left_level  = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT;
-                       right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT;
-                       left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-                       right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-                       return (right_level << 8)+left_level;
-                       
-               case SOUND_MIXER_IGAIN:
-                       left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT;
-                       right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT;
-                       left_level = to_oss_level(left_level, MAX_INPUT_LEVEL);
-                       right_level= to_oss_level(right_level, MAX_INPUT_LEVEL);
-                       return (right_level << 8)+left_level;
-                       
-               case SOUND_MIXER_MONITOR:
-                       left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT;
-                       left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-                       return (left_level << 8)+left_level;
-       }
-       return -EINVAL;
-}
-
-
-
-/*
- * Some conversions for the same reasons.
- * We give back the new real value(s) due to
- * the rescale.
- */
-
-static int harmony_mixer_set_level(int channel, int value)
-{
-       int left_level;
-       int right_level;
-       int new_left_level;
-       int new_right_level;
-
-       right_level = (value & 0x0000ff00) >> 8;
-       left_level = value & 0x000000ff;
-       if (right_level > 100) right_level = 100;
-       if (left_level > 100) left_level = 100;
-  
-       switch (channel) {
-               case SOUND_MIXER_VOLUME:
-                       right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL);
-                       left_level  = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL);
-                       new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL);
-                       new_left_level  = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) 
-                                       | (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_right_level << 8) + new_left_level;
-                       
-               case SOUND_MIXER_IGAIN:
-                       right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL);
-                       left_level  = to_harmony_level(left_level, MAX_INPUT_LEVEL);
-                       new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL);
-                       new_left_level  = to_oss_level(left_level, MAX_INPUT_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK))
-                                       | (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_right_level << 8) + new_left_level;
-       
-               case SOUND_MIXER_MONITOR:
-                       left_level = to_harmony_level(100-left_level, MAX_MONITOR_LEVEL);
-                       new_left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL);
-                       harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK) | (left_level << GAIN_MA_SHIFT);
-                       harmony_mixer_set_gain();
-                       return (new_left_level << 8) + new_left_level;
-       }
-
-       return -EINVAL;
-}
-
-#undef to_harmony_level
-#undef to_oss_level
-
-/* 
- * Return the selected input device (mic or line)
- */
-
-static int harmony_mixer_get_recmask(void) 
-{
-       int current_input_line;
-       
-       current_input_line = (harmony.current_gain & GAIN_IS_MASK) 
-                                   >> GAIN_IS_SHIFT;
-       if (current_input_line) 
-               return SOUND_MASK_MIC;
-
-       return SOUND_MASK_LINE;
-}
-
-/*
- * Set the input (only one at time, arbitrary priority to line in)
- */
-
-static int harmony_mixer_set_recmask(int recmask)
-{
-       int new_input_line;
-       int new_input_mask;
-       int current_input_line;
-       
-       current_input_line = (harmony.current_gain & GAIN_IS_MASK)
-                                   >> GAIN_IS_SHIFT;
-       if ((current_input_line && ((recmask & SOUND_MASK_LINE) || !(recmask & SOUND_MASK_MIC))) ||
-               (!current_input_line && ((recmask & SOUND_MASK_LINE) && !(recmask & SOUND_MASK_MIC)))) {
-               new_input_line = 0;
-               new_input_mask = SOUND_MASK_LINE;
-       } else {
-               new_input_line = 1;
-               new_input_mask = SOUND_MASK_MIC;
-       }
-       harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | 
-                               (new_input_line << GAIN_IS_SHIFT ));
-       harmony_mixer_set_gain();
-       return new_input_mask;
-}
-
-
-/* 
- * give the active outlines
- */
-
-static int harmony_mixer_get_outmask(void)
-{
-       int outmask = 0;
-       
-       if (harmony.current_gain & GAIN_SE_MASK) outmask |= MASK_INTERNAL;
-       if (harmony.current_gain & GAIN_LE_MASK) outmask |= MASK_LINEOUT;
-       if (harmony.current_gain & GAIN_HE_MASK) outmask |= MASK_HEADPHONES;
-       
-       return outmask;
-}
-
-
-static int harmony_mixer_set_outmask(int outmask)
-{
-       if (outmask & MASK_INTERNAL) 
-               harmony.current_gain |= GAIN_SE_MASK;
-       else 
-               harmony.current_gain &= ~GAIN_SE_MASK;
-       
-       if (outmask & MASK_LINEOUT) 
-               harmony.current_gain |= GAIN_LE_MASK;
-       else 
-               harmony.current_gain &= ~GAIN_LE_MASK;
-       
-       if (outmask & MASK_HEADPHONES) 
-               harmony.current_gain |= GAIN_HE_MASK; 
-       else 
-               harmony.current_gain &= ~GAIN_HE_MASK;
-       
-       harmony_mixer_set_gain();
-
-       return (outmask & (MASK_INTERNAL | MASK_LINEOUT | MASK_HEADPHONES));
-}
-
-/*
- * This code is inspired from sb_mixer.c
- */
-
-static int harmony_mixer_ioctl(struct inode * inode, struct file * file,
-               unsigned int cmd, unsigned long arg)
-{
-       int val;
-       int ret;
-
-       if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-                strncpy(info.id, "harmony", sizeof(info.id)-1);
-                strncpy(info.name, "Harmony audio", sizeof(info.name)-1);
-                info.modify_counter = 1; /* ? */
-                if (copy_to_user((void *)arg, &info, sizeof(info)))
-                        return -EFAULT;
-               return 0;
-       }
-       
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, (int *)arg);
-
-       /* read */
-       val = 0;
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-               if (get_user(val, (int *)arg))
-                       return -EFAULT;
-
-       switch (cmd) {
-       case MIXER_READ(SOUND_MIXER_CAPS):
-               ret = SOUND_CAP_EXCL_INPUT;
-               break;
-       case MIXER_READ(SOUND_MIXER_STEREODEVS):
-               ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN;
-               break;
-               
-       case MIXER_READ(SOUND_MIXER_RECMASK):
-               ret = SOUND_MASK_MIC | SOUND_MASK_LINE;
-               break;
-       case MIXER_READ(SOUND_MIXER_DEVMASK):
-               ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN |
-                       SOUND_MASK_MONITOR;
-               break;
-       case MIXER_READ(SOUND_MIXER_OUTMASK):
-               ret = MASK_INTERNAL | MASK_LINEOUT |
-                       MASK_HEADPHONES;
-               break;
-               
-       case MIXER_WRITE(SOUND_MIXER_RECSRC):
-               ret = harmony_mixer_set_recmask(val);
-               break;
-       case MIXER_READ(SOUND_MIXER_RECSRC):
-               ret = harmony_mixer_get_recmask();
-               break;
-             
-       case MIXER_WRITE(SOUND_MIXER_OUTSRC):
-               ret = harmony_mixer_set_outmask(val);
-               break;
-       case MIXER_READ(SOUND_MIXER_OUTSRC):
-               ret = harmony_mixer_get_outmask();
-               break;
-       
-       case MIXER_WRITE(SOUND_MIXER_VOLUME):
-       case MIXER_WRITE(SOUND_MIXER_IGAIN):
-       case MIXER_WRITE(SOUND_MIXER_MONITOR):
-               ret = harmony_mixer_set_level(cmd & 0xff, val);
-               break;
-
-       case MIXER_READ(SOUND_MIXER_VOLUME):
-       case MIXER_READ(SOUND_MIXER_IGAIN):
-       case MIXER_READ(SOUND_MIXER_MONITOR):
-               ret = harmony_mixer_get_level(cmd & 0xff);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       if (put_user(ret, (int *)arg))
-               return -EFAULT;
-       return 0;
-}
-
-
-static int harmony_mixer_open(struct inode *inode, struct file *file)
-{
-       if (harmony.mixer_open) 
-               return -EBUSY;
-       harmony.mixer_open = 1;
-       return 0;
-}
-
-static int harmony_mixer_release(struct inode *inode, struct file *file)
-{
-       if (!harmony.mixer_open) 
-               return -EBUSY;
-       harmony.mixer_open = 0;
-       return 0;
-}
-
-static struct file_operations harmony_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .open           = harmony_mixer_open,
-       .release        = harmony_mixer_release,
-       .ioctl          = harmony_mixer_ioctl,
-};
-
-
-/*
- * Mute all the output and reset Harmony.
- */
-
-static void __init harmony_mixer_reset(void)
-{
-       harmony.current_gain = GAIN_TOTAL_SILENCE;
-       harmony_mixer_set_gain();
-       harmony_wait_CNTL();
-       gsc_writel(1, &harmony.hpa->reset);
-       mdelay(50);             /* wait 50 ms */
-       gsc_writel(0, &harmony.hpa->reset);
-       harmony.current_gain = GAIN_DEFAULT;
-       harmony_mixer_set_gain();
-}
-
-static int __init harmony_mixer_init(void)
-{
-       /* Register the device file operations */
-       harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1);
-       if (harmony.mixer_unit < 0) {
-               printk(KERN_WARNING PFX "Error Registering Mixer Driver\n");
-               return -EFAULT;
-       }
-  
-       harmony_mixer_reset();
-       harmony.mixer_open = 0;
-       
-       return 0;
-}
-
-
-
-/* 
- * This is the callback that's called by the inventory hardware code 
- * if it finds a match to the registered driver. 
- */
-static int __devinit
-harmony_driver_probe(struct parisc_device *dev)
-{
-       u8      id;
-       u8      rev;
-       u32     cntl;
-       int     ret;
-
-       if (harmony.hpa) {
-               /* We only support one Harmony at this time */
-               printk(KERN_ERR PFX "driver already registered\n");
-               return -EBUSY;
-       }
-
-       if (!dev->irq) {
-               printk(KERN_ERR PFX "no irq found\n");
-               return -ENODEV;
-       }
-
-       /* Set the HPA of harmony */
-       harmony.hpa = (struct harmony_hpa *)dev->hpa.start;
-       harmony.dev = dev;
-
-       /* Grab the ID and revision from the device */
-       id = gsc_readb(&harmony.hpa->id);
-       if ((id | 1) != 0x15) {
-               printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id);
-               return -EBUSY;
-       }
-       cntl = gsc_readl(&harmony.hpa->cntl);
-       rev = (cntl>>20) & 0xff;
-
-       printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
-                       "h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
-                       id, rev, dev->hpa.start, harmony.dev->irq);
-       
-       /* Make sure the control bit isn't set, although I don't think it 
-          ever is. */
-       if (cntl & CNTL_C) {
-               printk(KERN_WARNING PFX "CNTL busy\n");
-               harmony.hpa = 0;
-               return -EBUSY;
-       }
-
-       /* Initialize the memory buffers */
-       if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || 
-           harmony_alloc_buffer(&recorded_buf, MAX_BUFS) ||
-           harmony_alloc_buffer(&graveyard, 1) ||
-           harmony_alloc_buffer(&silent, 1)) {
-               ret = -EBUSY;
-               goto out_err;
-       }
-
-       /* Initialize /dev/mixer and /dev/audio  */
-       if ((ret=harmony_mixer_init())) 
-               goto out_err;
-       if ((ret=harmony_audio_init())) 
-               goto out_err;
-
-       return 0;
-
-out_err:
-       harmony.hpa = 0;
-       harmony_free_buffer(&played_buf);
-       harmony_free_buffer(&recorded_buf);
-       harmony_free_buffer(&graveyard);
-       harmony_free_buffer(&silent);
-       return ret;
-}
-
-
-static struct parisc_device_id harmony_tbl[] = {
- /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
- { 0, }
-};
-
-MODULE_DEVICE_TABLE(parisc, harmony_tbl);
-
-static struct parisc_driver harmony_driver = {
-       .name           = "Lasi Harmony",
-       .id_table       = harmony_tbl,
-       .probe          = harmony_driver_probe,
-};
-
-static int __init init_harmony(void)
-{
-       return register_parisc_driver(&harmony_driver);
-}
-
-static void __exit cleanup_harmony(void)
-{
-       free_irq(harmony.dev->irq, &harmony);
-       unregister_sound_mixer(harmony.mixer_unit);
-       unregister_sound_dsp(harmony.dsp_unit);
-       harmony_free_buffer(&played_buf);
-       harmony_free_buffer(&recorded_buf);
-       harmony_free_buffer(&graveyard);
-       harmony_free_buffer(&silent);
-       unregister_parisc_driver(&harmony_driver);
-}
-
-
-MODULE_AUTHOR("Alex DeVries <alex@onefishtwo.ca>");
-MODULE_DESCRIPTION("Harmony sound driver");
-MODULE_LICENSE("GPL");
-
-module_init(init_harmony);
-module_exit(cleanup_harmony);
-
diff --git a/sound/oss/ics2101.c b/sound/oss/ics2101.c
deleted file mode 100644 (file)
index 45918df..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * sound/oss/ics2101.c
- *
- * Driver for the ICS2101 mixer of GUS v3.7.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer   : ioctl code reworked (vmalloc/vfree removed)
- * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init()
- */
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/ultrasound.h>
-
-#include "gus.h"
-#include "gus_hw.h"
-
-#define MIX_DEVS       (SOUND_MASK_MIC|SOUND_MASK_LINE| \
-                        SOUND_MASK_SYNTH| \
-                        SOUND_MASK_CD | SOUND_MASK_VOLUME)
-
-extern int     *gus_osp;
-extern int      gus_base;
-extern spinlock_t gus_lock;
-static int      volumes[ICS_MIXDEVS];
-static int      left_fix[ICS_MIXDEVS] =
-{1, 1, 1, 2, 1, 2};
-static int      right_fix[ICS_MIXDEVS] =
-{2, 2, 2, 1, 2, 1};
-
-static int scale_vol(int vol)
-{
-       /*
-        *  Experimental volume scaling by Risto Kankkunen.
-        *  This should give smoother volume response than just
-        *  a plain multiplication.
-        */
-        
-       int e;
-
-       if (vol < 0)
-               vol = 0;
-       if (vol > 100)
-               vol = 100;
-       vol = (31 * vol + 50) / 100;
-       e = 0;
-       if (vol)
-       {
-               while (vol < 16)
-               {
-                       vol <<= 1;
-                       e--;
-               }
-               vol -= 16;
-               e += 7;
-       }
-       return ((e << 4) + vol);
-}
-
-static void write_mix(int dev, int chn, int vol)
-{
-       int *selector;
-       unsigned long flags;
-       int ctrl_addr = dev << 3;
-       int attn_addr = dev << 3;
-
-       vol = scale_vol(vol);
-
-       if (chn == CHN_LEFT)
-       {
-               selector = left_fix;
-               ctrl_addr |= 0x00;
-               attn_addr |= 0x02;
-       }
-       else
-       {
-               selector = right_fix;
-               ctrl_addr |= 0x01;
-               attn_addr |= 0x03;
-       }
-
-       spin_lock_irqsave(&gus_lock, flags);
-       outb((ctrl_addr), u_MixSelect);
-       outb((selector[dev]), u_MixData);
-       outb((attn_addr), u_MixSelect);
-       outb(((unsigned char) vol), u_MixData);
-       spin_unlock_irqrestore(&gus_lock,flags);
-}
-
-static int set_volumes(int dev, int vol)
-{
-       int left = vol & 0x00ff;
-       int right = (vol >> 8) & 0x00ff;
-
-       if (left < 0)
-               left = 0;
-       if (left > 100)
-               left = 100;
-       if (right < 0)
-               right = 0;
-       if (right > 100)
-               right = 100;
-
-       write_mix(dev, CHN_LEFT, left);
-       write_mix(dev, CHN_RIGHT, right);
-
-       vol = left + (right << 8);
-       volumes[dev] = vol;
-       return vol;
-}
-
-static int ics2101_mixer_ioctl(int dev, unsigned int cmd, void __user *arg)
-{
-       int val;
-       
-       if (((cmd >> 8) & 0xff) == 'M') {
-               if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
-                       
-                       if (get_user(val, (int __user *)arg))
-                               return -EFAULT;
-                       switch (cmd & 0xff) {
-                       case SOUND_MIXER_RECSRC:
-                               return gus_default_mixer_ioctl(dev, cmd, arg);
-
-                       case SOUND_MIXER_MIC:
-                               val = set_volumes(DEV_MIC, val);
-                               break;
-                               
-                       case SOUND_MIXER_CD:
-                               val = set_volumes(DEV_CD, val);
-                               break;
-
-                       case SOUND_MIXER_LINE:
-                               val = set_volumes(DEV_LINE, val);
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = set_volumes(DEV_GF1, val);
-                               break;
-
-                       case SOUND_MIXER_VOLUME:
-                               val = set_volumes(DEV_VOL, val);
-                               break;
-
-                       default:
-                               return -EINVAL;
-                       }
-                       return put_user(val, (int __user *)arg);
-               } else {
-                       switch (cmd & 0xff) {
-                               /*
-                                * Return parameters
-                                */
-                       case SOUND_MIXER_RECSRC:
-                               return gus_default_mixer_ioctl(dev, cmd, arg);
-
-                       case SOUND_MIXER_DEVMASK:
-                               val = MIX_DEVS; 
-                               break;
-
-                       case SOUND_MIXER_STEREODEVS:
-                               val = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC; 
-                               break;
-
-                       case SOUND_MIXER_RECMASK:
-                               val = SOUND_MASK_MIC | SOUND_MASK_LINE; 
-                               break;
-                               
-                       case SOUND_MIXER_CAPS:
-                               val = 0; 
-                               break;
-
-                       case SOUND_MIXER_MIC:
-                               val = volumes[DEV_MIC];
-                               break;
-                               
-                       case SOUND_MIXER_LINE:
-                               val = volumes[DEV_LINE];
-                               break;
-
-                       case SOUND_MIXER_CD:
-                               val = volumes[DEV_CD];
-                               break;
-
-                       case SOUND_MIXER_VOLUME:
-                               val = volumes[DEV_VOL];
-                               break;
-
-                       case SOUND_MIXER_SYNTH:
-                               val = volumes[DEV_GF1]; 
-                               break;
-
-                       default:
-                               return -EINVAL;
-                       }
-                       return put_user(val, (int __user *)arg);
-               }
-       }
-       return -EINVAL;
-}
-
-static struct mixer_operations ics2101_mixer_operations =
-{
-       .owner  = THIS_MODULE,
-       .id     = "ICS2101",
-       .name   = "ICS2101 Multimedia Mixer",
-       .ioctl  = ics2101_mixer_ioctl
-};
-
-int __init ics2101_mixer_init(void)
-{
-       int i;
-       int n;
-
-       if ((n = sound_alloc_mixerdev()) != -1)
-       {
-               mixer_devs[n] = &ics2101_mixer_operations;
-
-               /*
-                * Some GUS v3.7 cards had some channels flipped. Disable
-                * the flipping feature if the model id is other than 5.
-                */
-
-               if (inb(u_MixSelect) != 5)
-               {
-                       for (i = 0; i < ICS_MIXDEVS; i++)
-                               left_fix[i] = 1;
-                       for (i = 0; i < ICS_MIXDEVS; i++)
-                               right_fix[i] = 2;
-               }
-               set_volumes(DEV_GF1, 0x5a5a);
-               set_volumes(DEV_CD, 0x5a5a);
-               set_volumes(DEV_MIC, 0x0000);
-               set_volumes(DEV_LINE, 0x5a5a);
-               set_volumes(DEV_VOL, 0x5a5a);
-               set_volumes(DEV_UNUSED, 0x0000);
-       }
-       return n;
-}
diff --git a/sound/oss/iwmem.h b/sound/oss/iwmem.h
deleted file mode 100644 (file)
index 48d333c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * sound/oss/iwmem.h
- *
- * DRAM size encoding table for AMD Interwave chip.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * Bartlomiej Zolnierkiewicz   : added __initdata to mem_decode
- */
-
-
-#define K 1024
-#define M (1024*K)
-static int mem_decode[][4] __initdata =
-{
-/*     Bank0   Bank1   Bank2   Bank3   Encoding bits   */
-       {256*K, 0,      0,      0},             /*  0 */
-       {256*K, 256*K,  0,      0},             /*  1 */
-       {256*K, 256*K,  256*K,  256*K},         /*  2 */
-       {256*K, 1*M,    0,      0},             /*  3 */
-       {256*K, 1*M,    1*M,    1*M},           /*  4 */
-       {256*K, 256*K,  1*M,    0},             /*  5 */
-       {256*K, 256*K,  1*M,    1*M},           /*  6 */
-       {1*M,   0,      0,      0},             /*  7 */
-       {1*M,   1*M,    0,      0},             /*  8 */
-       {1*M,   1*M,    1*M,    1*M},           /*  9 */
-       {4*M,   0,      0,      0},             /* 10 */
-       {4*M,   4*M,    0,      0},             /* 11 */
-       {4*M,   4*M,    4*M,    4*M}            /* 12 */
-};
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c
deleted file mode 100644 (file)
index aa3c50d..0000000
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * mad16.c
- *
- * Initialization code for OPTi MAD16 compatible audio chips. Including
- *
- *      OPTi 82C928     MAD16           (replaced by C929)
- *      OAK OTI-601D    Mozart
- *      OAK OTI-605    Mozart          (later version with MPU401 Midi)
- *      OPTi 82C929     MAD16 Pro
- *      OPTi 82C930
- *      OPTi 82C924
- *
- * These audio interface chips don't produce sound themselves. They just
- * connect some other components (OPL-[234] and a WSS compatible codec)
- * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
- * also a UART for the MPU-401 mode (not 82C928/Mozart).
- * The Mozart chip appears to be compatible with the 82C928, although later
- * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi
- * port. This port is configured differently to that of the OPTi audio chips.
- *
- *     Changes
- *     
- *     Alan Cox                Clean up, added module selections.
- *
- *     A. Wik                  Added support for Opti924 PnP.
- *                             Improved debugging support.     16-May-1998
- *                             Fixed bug.                      16-Jun-1998
- *
- *      Torsten Duwe            Made Opti924 PnP support non-destructive
- *                                                                     23-Dec-1998
- *
- *     Paul Grayson            Added support for Midi on later Mozart cards.
- *                                                             25-Nov-1999
- *     Christoph Hellwig       Adapted to module_init/module_exit.
- *     Arnaldo C. de Melo      got rid of attach_uart401       21-Sep-2000
- *
- *     Pavel Rabel             Clean up                           Nov-2000
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gameport.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "sb.h"
-#include "mpu401.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-static int      mad16_conf;
-static int      mad16_cdsel;
-static DEFINE_SPINLOCK(lock);
-
-#define C928   1
-#define MOZART 2
-#define C929   3
-#define C930   4
-#define C924    5
-
-/*
- *    Registers
- *
- *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
- *      All ports are inactive by default. They can be activated by
- *      writing 0xE2 or 0xE3 to the password register. The password is valid
- *      only until the next I/O read or write.
- *
- *      82C930 uses 0xE4 as the password and indirect addressing to access
- *      the config registers.
- */
-
-#define MC0_PORT       0xf8c   /* Dummy port */
-#define MC1_PORT       0xf8d   /* SB address, CD-ROM interface type, joystick */
-#define MC2_PORT       0xf8e   /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
-#define MC3_PORT       0xf8f
-#define PASSWD_REG     0xf8f
-#define MC4_PORT       0xf90
-#define MC5_PORT       0xf91
-#define MC6_PORT       0xf92
-#define MC7_PORT       0xf93
-#define MC8_PORT       0xf94
-#define MC9_PORT       0xf95
-#define MC10_PORT      0xf96
-#define MC11_PORT      0xf97
-#define MC12_PORT      0xf98
-
-static int      board_type = C928;
-
-static int     *mad16_osp;
-static int     c931_detected;  /* minor differences from C930 */
-static char    c924pnp;        /* "     "           "    C924 */
-static int     debug;          /* debugging output */
-
-#ifdef DDB
-#undef DDB
-#endif
-#define DDB(x) do {if (debug) x;} while (0)
-
-static unsigned char mad_read(int port)
-{
-       unsigned long flags;
-       unsigned char tmp;
-
-       spin_lock_irqsave(&lock,flags);
-
-       switch (board_type)     /* Output password */
-       {
-               case C928:
-               case MOZART:
-                       outb((0xE2), PASSWD_REG);
-                       break;
-
-               case C929:
-                       outb((0xE3), PASSWD_REG);
-                       break;
-
-               case C930:
-                       /* outb(( 0xE4),  PASSWD_REG); */
-                       break;
-
-               case C924:
-                       /* the c924 has its ports relocated by -128 if
-                          PnP is enabled  -aw */
-                       if (!c924pnp)
-                               outb((0xE5), PASSWD_REG); else
-                               outb((0xE5), PASSWD_REG - 0x80);
-                       break;
-       }
-
-       if (board_type == C930)
-       {
-               outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
-               tmp = inb(0xe0f);       /* Read from data reg */
-       }
-       else
-               if (!c924pnp)
-                       tmp = inb(port); else
-                       tmp = inb(port-0x80);
-       spin_unlock_irqrestore(&lock,flags);
-
-       return tmp;
-}
-
-static void mad_write(int port, int value)
-{
-       unsigned long   flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       switch (board_type)     /* Output password */
-       {
-               case C928:
-               case MOZART:
-                       outb((0xE2), PASSWD_REG);
-                       break;
-
-               case C929:
-                       outb((0xE3), PASSWD_REG);
-                       break;
-
-               case C930:
-                       /* outb(( 0xE4),  PASSWD_REG); */
-                       break;
-
-               case C924:
-                       if (!c924pnp)
-                               outb((0xE5), PASSWD_REG); else
-                               outb((0xE5), PASSWD_REG - 0x80);
-                       break;
-       }
-
-       if (board_type == C930)
-       {
-               outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
-               outb(((unsigned char) (value & 0xff)), 0xe0f);
-       }
-       else
-               if (!c924pnp)
-                       outb(((unsigned char) (value & 0xff)), port); else
-                       outb(((unsigned char) (value & 0xff)), port-0x80);
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init detect_c930(void)
-{
-       unsigned char   tmp = mad_read(MC1_PORT);
-
-       if ((tmp & 0x06) != 0x06)
-       {
-               DDB(printk("Wrong C930 signature (%x)\n", tmp));
-               /* return 0; */
-       }
-       mad_write(MC1_PORT, 0);
-
-       if (mad_read(MC1_PORT) != 0x06)
-       {
-               DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
-               /* return 0; */
-       }
-       mad_write(MC1_PORT, tmp);       /* Restore bits */
-
-       mad_write(MC7_PORT, 0);
-       if ((tmp = mad_read(MC7_PORT)) != 0)
-       {
-               DDB(printk("MC7 not writable (%x)\n", tmp));
-               return 0;
-       }
-       mad_write(MC7_PORT, 0xcb);
-       if ((tmp = mad_read(MC7_PORT)) != 0xcb)
-       {
-               DDB(printk("MC7 not writable2 (%x)\n", tmp));
-               return 0;
-       }
-
-       tmp = mad_read(MC0_PORT+18);
-       if (tmp == 0xff || tmp == 0x00)
-               return 1;
-       /* We probably have a C931 */
-       DDB(printk("Detected C931 config=0x%02x\n", tmp));
-       c931_detected = 1;
-
-       /*
-         * We cannot configure the chip if it is in PnP mode.
-         * If we have a CSN assigned (bit 8 in MC13) we first try
-         * a software reset, then a software power off, finally
-         * Clearing PnP mode. The last option is not
-        * Bit 8 in MC13 
-         */
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-
-       /* Software reset */
-       mad_write(MC9_PORT, 0x02);
-       mad_write(MC9_PORT, 0x00);
-
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-       
-       /* Power off, and on again */
-       mad_write(MC9_PORT, 0xc2);
-       mad_write(MC9_PORT, 0xc0);
-
-       if ((mad_read(MC0_PORT+13) & 0x80) == 0)
-               return 1;
-       
-#if 0  
-       /* Force off PnP mode. This is not recommended because
-        * the PnP bios will not recognize the chip on the next
-        * warm boot and may assignd different resources to other
-        * PnP/PCI cards.
-        */
-       mad_write(MC0_PORT+17, 0x04);
-#endif
-       return 1;
-}
-
-static int __init detect_mad16(void)
-{
-       unsigned char tmp, tmp2, bit;
-       int i, port;
-
-       /*
-        * Check that reading a register doesn't return bus float (0xff)
-        * when the card is accessed using password. This may fail in case
-        * the card is in low power mode. Normally at least the power saving
-        * mode bit should be 0.
-        */
-
-       if ((tmp = mad_read(MC1_PORT)) == 0xff)
-       {
-               DDB(printk("MC1_PORT returned 0xff\n"));
-               return 0;
-       }
-       for (i = 0xf8d; i <= 0xf98; i++)
-               if (!c924pnp)
-                       DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
-               else
-                       DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));
-
-       if (board_type == C930)
-               return detect_c930();
-
-       /*
-        * Now check that the gate is closed on first I/O after writing
-        * the password. (This is how a MAD16 compatible card works).
-        */
-
-       if ((tmp2 = inb(MC1_PORT)) == tmp)      /* It didn't close */
-       {
-               DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
-               return 0;
-       }
-
-       bit  = (c924pnp) ?     0x20 : 0x80;
-       port = (c924pnp) ? MC2_PORT : MC1_PORT;
-
-       tmp = mad_read(port);
-       mad_write(port, tmp ^ bit);     /* Toggle a bit */
-       if ((tmp2 = mad_read(port)) != (tmp ^ bit))     /* Compare the bit */
-       {
-               mad_write(port, tmp);   /* Restore */
-               DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
-               return 0;
-       }
-       mad_write(port, tmp);   /* Restore */
-       return 1;               /* Bingo */
-}
-
-static int __init wss_init(struct address_info *hw_config)
-{
-       /*
-        * Check if the IO port returns valid signature. The original MS Sound
-        * system returns 0x04 while some cards (AudioTrix Pro for example)
-        * return 0x00.
-        */
-
-       if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
-           (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
-       {
-               DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
-               return 0;
-       }
-       /*
-        * Check that DMA0 is not in use with a 8 bit board.
-        */
-       if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
-       {
-               printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
-               return 0;
-       }
-       if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80)
-               printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
-       return 1;
-}
-
-static void __init init_c930(struct address_info *hw_config, int base)
-{
-       unsigned char cfg = 0;
-
-       cfg |= (0x0f & mad16_conf);
-
-       if(c931_detected)
-       {
-               /* Bit 0 has reversd meaning. Bits 1 and 2 sese
-                  reversed on write.
-                  Support only IDE cdrom. IDE port programmed
-                  somewhere else. */
-               cfg =  (cfg & 0x09) ^ 0x07;
-       }
-       cfg |= base << 4;
-       mad_write(MC1_PORT, cfg);
-
-       /* MC2 is CD configuration. Don't touch it. */
-
-       mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
-
-       /* bit 2 of MC4 reverses it's meaning between the C930
-          and the C931. */
-       cfg = c931_detected ? 0x04 : 0x00;
-
-       if(mad16_cdsel & 0x20)
-               mad_write(MC4_PORT, 0x62|cfg);  /* opl4 */
-       else
-               mad_write(MC4_PORT, 0x52|cfg);  /* opl3 */
-
-       mad_write(MC5_PORT, 0x3C);      /* Init it into mode2 */
-       mad_write(MC6_PORT, 0x02);      /* Enable WSS, Disable MPU and SB */
-       mad_write(MC7_PORT, 0xCB);
-       mad_write(MC10_PORT, 0x11);
-}
-
-static int __init chip_detect(void)
-{
-       int i;
-
-       /*
-        *    Then try to detect with the old password
-        */
-       board_type = C924;
-
-       DDB(printk("Detect using password = 0xE5\n"));
-       
-       if (detect_mad16()) {
-               return 1;
-       }
-       
-       board_type = C928;
-
-       DDB(printk("Detect using password = 0xE2\n"));
-
-       if (detect_mad16())
-       {
-               unsigned char model;
-
-               if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
-                       DDB(printk("mad16.c: Mozart detected\n"));
-                       board_type = MOZART;
-               } else {
-                       DDB(printk("mad16.c: 82C928 detected???\n"));
-                       board_type = C928;
-               }
-               return 1;
-       }
-
-       board_type = C929;
-
-       DDB(printk("Detect using password = 0xE3\n"));
-
-       if (detect_mad16())
-       {
-               DDB(printk("mad16.c: 82C929 detected\n"));
-               return 1;
-       }
-
-       if (inb(PASSWD_REG) != 0xff)
-               return 0;
-
-       /*
-        * First relocate MC# registers to 0xe0e/0xe0f, disable password 
-        */
-
-       outb((0xE4), PASSWD_REG);
-       outb((0x80), PASSWD_REG);
-
-       board_type = C930;
-
-       DDB(printk("Detect using password = 0xE4\n"));
-
-       for (i = 0xf8d; i <= 0xf93; i++)
-               DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-
-        if(detect_mad16()) {
-               DDB(printk("mad16.c: 82C930 detected\n"));
-               return 1;
-       }
-
-       /* The C931 has the password reg at F8D */
-       outb((0xE4), 0xF8D);
-       outb((0x80), 0xF8D);
-       DDB(printk("Detect using password = 0xE4 for C931\n"));
-
-       if (detect_mad16()) {
-               return 1;
-       }
-
-       board_type = C924;
-       c924pnp++;
-       DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
-       if (detect_mad16()) {
-               DDB(printk("mad16.c: 82C924 PnP detected\n"));
-               return 1;
-       }
-       
-       c924pnp=0;
-
-       return 0;
-}
-
-static int __init probe_mad16(struct address_info *hw_config)
-{
-       int i;
-       unsigned char tmp;
-       unsigned char cs4231_mode = 0;
-
-       int ad_flags = 0;
-
-       signed char bits;
-
-       static char     dma_bits[4] = {
-               1, 2, 0, 3
-       };
-
-       int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
-       int dma = hw_config->dma, dma2 = hw_config->dma2;
-       unsigned char dma2_bit = 0;
-       int base;
-       struct resource *ports;
-
-       mad16_osp = hw_config->osp;
-
-       switch (hw_config->io_base) {
-       case 0x530:
-               base = 0;
-               break;
-       case 0xe80:
-               base = 1;
-               break;
-       case 0xf40:
-               base = 2;
-               break;
-       case 0x604:
-               base = 3;
-               break;
-       default:
-               printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
-               return 0;
-       }
-
-       if (dma != 0 && dma != 1 && dma != 3) {
-               printk(KERN_ERR "MSS: Bad DMA %d\n", dma);
-               return 0;
-       }
-
-       /*
-        *    Check that all ports return 0xff (bus float) when no password
-        *      is written to the password register.
-        */
-
-       DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
-       if (!chip_detect())
-               return 0;
-
-       switch (hw_config->irq) {
-       case 7:
-               bits = 8;
-               break;
-       case 9:
-               bits = 0x10;
-               break;
-       case 10:
-               bits = 0x18;
-               break;
-       case 12:
-               bits = 0x20;
-               break;
-       case 5: /* Also IRQ5 is possible on C930 */
-               if (board_type == C930 || c924pnp) {
-                       bits = 0x28;
-                       break;
-               }
-       default:
-               printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-
-       ports = request_region(hw_config->io_base + 4, 4, "ad1848");
-       if (!ports) {
-               printk(KERN_ERR "MSS: I/O port conflict\n");
-               return 0;
-       }
-       if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) {
-               release_region(hw_config->io_base + 4, 4);
-               printk(KERN_ERR "MSS: I/O port conflict\n");
-               return 0;
-       }
-
-       if (board_type == C930) {
-               init_c930(hw_config, base);
-               goto got_it;
-       }
-
-       for (i = 0xf8d; i <= 0xf93; i++) {
-               if (!c924pnp)
-                       DDB(printk("port %03x = %02x\n", i, mad_read(i)));
-               else
-                       DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));
-       }
-
-/*
- * Set the WSS address
- */
-
-       tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80;       /* Enable WSS, Disable SB */
-       tmp |= base << 4;       /* WSS port select bits */
-
-       /*
-        * Set optional CD-ROM and joystick settings.
-        */
-
-       tmp &= ~0x0f;
-       tmp |= (mad16_conf & 0x0f);     /* CD-ROM and joystick bits */
-       mad_write(MC1_PORT, tmp);
-
-       tmp = mad16_cdsel;
-       mad_write(MC2_PORT, tmp);
-       mad_write(MC3_PORT, 0xf0);      /* Disable SB */
-
-       if (board_type == C924) /* Specific C924 init values */
-       {
-               mad_write(MC4_PORT, 0xA0);
-               mad_write(MC5_PORT, 0x05);
-               mad_write(MC6_PORT, 0x03);
-       }
-       if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-               goto fail;
-
-       if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
-               cs4231_mode = 0x02;     /* CS4248/CS4231 sync delay switch */
-
-       if (board_type == C929)
-       {
-               mad_write(MC4_PORT, 0xa2);
-               mad_write(MC5_PORT, 0xA5 | cs4231_mode);
-               mad_write(MC6_PORT, 0x03);      /* Disable MPU401 */
-       }
-       else
-       {
-               mad_write(MC4_PORT, 0x02);
-               mad_write(MC5_PORT, 0x30 | cs4231_mode);
-       }
-
-       for (i = 0xf8d; i <= 0xf93; i++) {
-               if (!c924pnp)
-                       DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
-               else
-                       DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
-       }
-
-got_it:
-       ad_flags = 0;
-       if (!ad1848_detect(ports, &ad_flags, mad16_osp))
-               goto fail;
-
-       if (!wss_init(hw_config))
-               goto fail;
-
-       /*
-        * Set the IRQ and DMA addresses.
-        */
-       
-       outb((bits | 0x40), config_port);
-       if ((inb(version_port) & 0x40) == 0)
-               printk(KERN_ERR "[IRQ Conflict?]\n");
-
-       /*
-        * Handle the capture DMA channel
-        */
-
-       if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
-       {
-               if (!((dma == 0 && dma2 == 1) ||
-                       (dma == 1 && dma2 == 0) ||
-                       (dma == 3 && dma2 == 0)))
-               {               /* Unsupported combination. Try to swap channels */
-                       int tmp = dma;
-
-                       dma = dma2;
-                       dma2 = tmp;
-               }
-               if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
-                       (dma == 3 && dma2 == 0))
-               {
-                       dma2_bit = 0x04;        /* Enable capture DMA */
-               }
-               else
-               {
-                       printk("MAD16: Invalid capture DMA\n");
-                       dma2 = dma;
-               }
-       }
-       else dma2 = dma;
-
-       outb((bits | dma_bits[dma] | dma2_bit), config_port);   /* Write IRQ+DMA setup */
-
-       hw_config->slots[0] = ad1848_init("mad16 WSS", ports,
-                                         hw_config->irq,
-                                         dma,
-                                         dma2, 0,
-                                         hw_config->osp,
-                                         THIS_MODULE);
-       return 1;
-
-fail:
-       release_region(hw_config->io_base + 4, 4);
-       release_region(hw_config->io_base, 4);
-       return 0;
-}
-
-static int __init probe_mad16_mpu(struct address_info *hw_config)
-{
-       unsigned char tmp;
-
-       if (board_type < C929)  /* Early chip. No MPU support. Just SB MIDI */
-       {
-
-#ifdef CONFIG_MAD16_OLDCARD
-
-               tmp = mad_read(MC3_PORT);
-
-               /* 
-                * MAD16 SB base is defined by the WSS base. It cannot be changed 
-                * alone.
-                * Ignore configured I/O base. Use the active setting. 
-                */
-
-               if (mad_read(MC1_PORT) & 0x20)
-                       hw_config->io_base = 0x240;
-               else
-                       hw_config->io_base = 0x220;
-
-               switch (hw_config->irq)
-               {
-                       case 5:
-                               tmp = (tmp & 0x3f) | 0x80;
-                               break;
-                       case 7:
-                               tmp = (tmp & 0x3f);
-                               break;
-                       case 11:
-                               tmp = (tmp & 0x3f) | 0x40;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
-                               return 0;
-               }
-
-               mad_write(MC3_PORT, tmp | 0x04);
-               hw_config->driver_use_1 = SB_MIDI_ONLY;
-               if (!request_region(hw_config->io_base, 16, "soundblaster"))
-                       return 0;
-               if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
-                       release_region(hw_config->io_base, 16);
-                       return 0;
-               }
-
-               if (mad_read(MC1_PORT) & 0x20)
-                       hw_config->io_base = 0x240;
-               else
-                       hw_config->io_base = 0x220;
-
-               hw_config->name = "Mad16/Mozart";
-               sb_dsp_init(hw_config, THIS_MODULE);
-               return 1;
-#else
-               /* assuming all later Mozart cards are identified as
-                * either 82C928 or Mozart. If so, following code attempts
-                * to set MPU register. TODO - add probing
-                */
-
-               tmp = mad_read(MC8_PORT);
-
-               switch (hw_config->irq)
-               {
-                       case 5:
-                               tmp |= 0x08;
-                               break;
-                       case 7:
-                               tmp |= 0x10;
-                               break;
-                       case 9:
-                               tmp |= 0x18;
-                               break;
-                       case 10:
-                               tmp |= 0x20;
-                               break;
-                       case 11:
-                               tmp |= 0x28;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
-                               return 0;
-               }
-
-               switch (hw_config->io_base)
-               {
-                       case 0x300:
-                               tmp |= 0x01;
-                               break;
-                       case 0x310:
-                               tmp |= 0x03;
-                               break;
-                       case 0x320:
-                               tmp |= 0x05;
-                               break;
-                       case 0x330:
-                               tmp |= 0x07;
-                               break;
-                       default:
-                               printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
-                               return 0;
-               }
-
-               mad_write(MC8_PORT, tmp);       /* write MPU port parameters */
-               goto probe_401;
-#endif
-       }
-       tmp = mad_read(MC6_PORT) & 0x83;
-       tmp |= 0x80;            /* MPU-401 enable */
-
-       /* Set the MPU base bits */
-
-       switch (hw_config->io_base)
-       {
-               case 0x300:
-                       tmp |= 0x60;
-                       break;
-               case 0x310:
-                       tmp |= 0x40;
-                       break;
-               case 0x320:
-                       tmp |= 0x20;
-                       break;
-               case 0x330:
-                       tmp |= 0x00;
-                       break;
-               default:
-                       printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
-                       return 0;
-       }
-
-       /* Set the MPU IRQ bits */
-
-       switch (hw_config->irq)
-       {
-               case 5:
-                       tmp |= 0x10;
-                       break;
-               case 7:
-                       tmp |= 0x18;
-                       break;
-               case 9:
-                       tmp |= 0x00;
-                       break;
-               case 10:
-                       tmp |= 0x08;
-                       break;
-               default:
-                       printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
-                       break;
-       }
-                       
-       mad_write(MC6_PORT, tmp);       /* Write MPU401 config */
-
-#ifndef CONFIG_MAD16_OLDCARD
-probe_401:
-#endif
-       hw_config->driver_use_1 = SB_MIDI_ONLY;
-       hw_config->name = "Mad16/Mozart";
-       return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_mad16(struct address_info *hw_config)
-{
-       ad1848_unload(hw_config->io_base + 4,
-                       hw_config->irq,
-                       hw_config->dma,
-                       hw_config->dma2, 0);
-       release_region(hw_config->io_base, 4);
-       sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static void __exit unload_mad16_mpu(struct address_info *hw_config)
-{
-#ifdef CONFIG_MAD16_OLDCARD
-       if (board_type < C929)  /* Early chip. No MPU support. Just SB MIDI */
-       {
-               sb_dsp_unload(hw_config, 0);
-               return;
-       }
-#endif
-
-       unload_uart401(hw_config);
-}
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int found_mpu;
-
-static int __initdata mpu_io = 0;
-static int __initdata mpu_irq = 0;
-static int __initdata io = -1;
-static int __initdata dma = -1;
-static int __initdata dma16 = -1; /* Set this for modules that need it */
-static int __initdata irq = -1;
-static int __initdata cdtype = 0;
-static int __initdata cdirq = 0;
-static int __initdata cdport = 0x340;
-static int __initdata cddma = -1;
-static int __initdata opl4 = 0;
-static int __initdata joystick = 0;
-
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-module_param(io, int, 0);
-module_param(dma, int, 0);
-module_param(dma16, int, 0);
-module_param(irq, int, 0);
-module_param(cdtype, int, 0);
-module_param(cdirq, int, 0);
-module_param(cdport, int, 0);
-module_param(cddma, int, 0);
-module_param(opl4, int, 0);
-module_param(joystick, bool, 0);
-module_param(debug, bool, 0644);
-
-static int __initdata dma_map[2][8] =
-{
-       {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
-       {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
-};
-
-static int __initdata irq_map[16] =
-{
-       0x00, -1, -1, 0x0A,
-       -1, 0x04, -1, 0x08,
-       -1, 0x10, 0x14, 0x18,
-       -1, -1, -1, -1
-};
-
-#ifdef SUPPORT_JOYSTICK
-
-static struct gameport *gameport;
-
-static int __devinit mad16_register_gameport(int io_port)
-{
-       if (!request_region(io_port, 1, "mad16 gameport")) {
-               printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
-               return -EBUSY;
-       }
-
-       gameport = gameport_allocate_port();
-       if (!gameport) {
-               printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
-               release_region(io_port, 1);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gameport, "MAD16 Gameport");
-       gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
-       gameport->io = io_port;
-
-       gameport_register_port(gameport);
-
-       return 0;
-}
-
-static inline void mad16_unregister_gameport(void)
-{
-       if (gameport) {
-               /* the gameport was initialized so we must free it up */
-               gameport_unregister_port(gameport);
-               gameport = NULL;
-               release_region(0x201, 1);
-       }
-}
-#else
-static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
-static inline void mad16_unregister_gameport(void) { }
-#endif
-
-static int __devinit init_mad16(void)
-{
-       int dmatype = 0;
-
-       printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       printk(KERN_INFO "CDROM ");
-       switch (cdtype)
-       {
-               case 0x00:
-                       printk("Disabled");
-                       cdirq = 0;
-                       break;
-               case 0x02:
-                       printk("Sony CDU31A");
-                       dmatype = 1;
-                       if(cddma == -1) cddma = 3;
-                       break;
-               case 0x04:
-                       printk("Mitsumi");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               case 0x06:
-                       printk("Panasonic Lasermate");
-                       dmatype = 1;
-                       if(cddma == -1) cddma = 3;
-                       break;
-               case 0x08:
-                       printk("Secondary IDE");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               case 0x0A:
-                       printk("Primary IDE");
-                       dmatype = 0;
-                       if(cddma == -1) cddma = 5;
-                       break;
-               default:
-                       printk("\n");
-                       printk(KERN_ERR "Invalid CDROM type\n");
-                       return -EINVAL;
-       }
-
-       /*
-        *    Build the config words
-        */
-
-       mad16_conf = (joystick ^ 1) | cdtype;
-       mad16_cdsel = 0;
-       if (opl4)
-               mad16_cdsel |= 0x20;
-
-       if(cdtype){
-               if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
-               {
-                       printk("\n");
-                       printk(KERN_ERR "Invalid CDROM DMA\n");
-                       return -EINVAL;
-               }
-               if (cddma)
-                       printk(", DMA %d", cddma);
-               else
-                       printk(", no DMA");
-
-               if (!cdirq)
-                       printk(", no IRQ");
-               else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
-               {
-                       printk(", invalid IRQ (disabling)");
-                       cdirq = 0;
-               }
-               else printk(", IRQ %d", cdirq);
-
-               mad16_cdsel |= dma_map[dmatype][cddma];
-
-               if (cdtype < 0x08)
-               {
-                       switch (cdport)
-                       {
-                               case 0x340:
-                                       mad16_cdsel |= 0x00;
-                                       break;
-                               case 0x330:
-                                       mad16_cdsel |= 0x40;
-                                       break;
-                               case 0x360:
-                                       mad16_cdsel |= 0x80;
-                                       break;
-                               case 0x320:
-                                       mad16_cdsel |= 0xC0;
-                                       break;
-                               default:
-                                       printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
-                                       return -EINVAL;
-                       }
-               }
-               mad16_cdsel |= irq_map[cdirq];
-       }
-
-       printk(".\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma16;
-
-       if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
-               printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
-               return -EINVAL;
-       }
-
-       if (!request_region(MC0_PORT, 12, "mad16"))
-               return -EBUSY;
-
-       if (!probe_mad16(&cfg)) {
-               release_region(MC0_PORT, 12);
-               return -ENODEV;
-       }
-
-       cfg_mpu.io_base = mpu_io;
-       cfg_mpu.irq = mpu_irq;
-
-       found_mpu = probe_mad16_mpu(&cfg_mpu);
-
-       if (joystick)
-               mad16_register_gameport(0x201);
-
-       return 0;
-}
-
-static void __exit cleanup_mad16(void)
-{
-       if (found_mpu)
-               unload_mad16_mpu(&cfg_mpu);
-       mad16_unregister_gameport();
-       unload_mad16(&cfg);
-       release_region(MC0_PORT, 12);
-}
-
-module_init(init_mad16);
-module_exit(cleanup_mad16);
-
-#ifndef MODULE
-static int __init setup_mad16(char *str)
-{
-       /* io, irq */
-       int ints[8];
-
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-
-       io       = ints[1];
-       irq      = ints[2];
-       dma      = ints[3];
-       dma16    = ints[4];
-       mpu_io   = ints[5];
-       mpu_irq  = ints[6];
-       joystick = ints[7];
-
-       return 1;
-}
-
-__setup("mad16=", setup_mad16);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
deleted file mode 100644 (file)
index 1d98d10..0000000
+++ /dev/null
@@ -1,3686 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.[23].x
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *     (c) Copyright 1999       Alan Cox <alan.cox@linux.org>
- *
- *     Based heavily on SonicVibes.c:
- *      Copyright (C) 1998-1999  Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *     Heavily modified by Zach Brown <zab@zabbo.net> based on lunch
- *     with ESS engineers.  Many thanks to Howard Kim for providing 
- *     contacts and hardware.  Honorable mention goes to Eric 
- *     Brombaugh for all sorts of things.  Best regards to the 
- *     proprietors of Hack Central for fine lodging.
- *
- *  Supported devices:
- *  /dev/dsp0-3    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *
- *  Hardware Description
- *
- *     A working Maestro setup contains the Maestro chip wired to a 
- *     codec or 2.  In the Maestro we have the APUs, the ASSP, and the
- *     Wavecache.  The APUs can be though of as virtual audio routing
- *     channels.  They can take data from a number of sources and perform
- *     basic encodings of the data.  The wavecache is a storehouse for
- *     PCM data.  Typically it deals with PCI and interracts with the
- *     APUs.  The ASSP is a wacky DSP like device that ESS is loth
- *     to release docs on.  Thankfully it isn't required on the Maestro
- *     until you start doing insane things like FM emulation and surround
- *     encoding.  The codecs are almost always AC-97 compliant codecs, 
- *     but it appears that early Maestros may have had PT101 (an ESS
- *     part?) wired to them.  The only real difference in the Maestro
- *     families is external goop like docking capability, memory for
- *     the ASSP, and initialization differences.
- *
- *  Driver Operation
- *
- *     We only drive the APU/Wavecache as typical DACs and drive the
- *     mixers in the codecs.  There are 64 APUs.  We assign 6 to each
- *     /dev/dsp? device.  2 channels for output, and 4 channels for
- *     input.
- *
- *     Each APU can do a number of things, but we only really use
- *     3 basic functions.  For playback we use them to convert PCM
- *     data fetched over PCI by the wavecahche into analog data that
- *     is handed to the codec.  One APU for mono, and a pair for stereo.
- *     When in stereo, the combination of smarts in the APU and Wavecache
- *     decide which wavecache gets the left or right channel.
- *
- *     For record we still use the old overly mono system.  For each in
- *     coming channel the data comes in from the codec, through a 'input'
- *     APU, through another rate converter APU, and then into memory via
- *     the wavecache and PCI.  If its stereo, we mash it back into LRLR in
- *     software.  The pass between the 2 APUs is supposedly what requires us
- *     to have a 512 byte buffer sitting around in wavecache/memory.
- *
- *     The wavecache makes our life even more fun.  First off, it can
- *     only address the first 28 bits of PCI address space, making it
- *     useless on quite a few architectures.  Secondly, its insane.
- *     It claims to fetch from 4 regions of PCI space, each 4 meg in length.
- *     But that doesn't really work.  You can only use 1 region.  So all our
- *     allocations have to be in 4meg of each other.  Booo.  Hiss.
- *     So we have a module parameter, dsps_order, that is the order of
- *     the number of dsps to provide.  All their buffer space is allocated
- *     on open time.  The sonicvibes OSS routines we inherited really want
- *     power of 2 buffers, so we have all those next to each other, then
- *     512 byte regions for the recording wavecaches.  This ends up
- *     wasting quite a bit of memory.  The only fixes I can see would be 
- *     getting a kernel allocator that could work in zones, or figuring out
- *     just how to coerce the WP into doing what we want.
- *
- *     The indirection of the various registers means we have to spinlock
- *     nearly all register accesses.  We have the main register indirection
- *     like the wave cache, maestro registers, etc.  Then we have beasts
- *     like the APU interface that is indirect registers gotten at through
- *     the main maestro indirection.  Ouch.  We spinlock around the actual
- *     ports on a per card basis.  This means spinlock activity at each IO
- *     operation, but the only IO operation clusters are in non critical 
- *     paths and it makes the code far easier to follow.  Interrupts are
- *     blocked while holding the locks because the int handler has to
- *     get at some of them :(.  The mixer interface doesn't, however.
- *     We also have an OSS state lock that is thrown around in a few
- *     places.
- *
- *     This driver has brute force APM suspend support.  We catch suspend
- *     notifications and stop all work being done on the chip.  Any people
- *     that try between this shutdown and the real suspend operation will
- *     be put to sleep.  When we resume we restore our software state on
- *     the chip and wake up the people that were using it.  The code thats
- *     being used now is quite dirty and assumes we're on a uni-processor
- *     machine.  Much of it will need to be cleaned up for SMP ACPI or 
- *     similar.
- *
- *     We also pay attention to PCI power management now.  The driver
- *     will power down units of the chip that it knows aren't needed.
- *     The WaveProcessor and company are only powered on when people
- *     have /dev/dsp*s open.  On removal the driver will
- *     power down the maestro entirely.  There could still be
- *     trouble with BIOSen that magically change power states 
- *     themselves, but we'll see.  
- *     
- * History
- *  v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de>
- *      Ported to Linux 2.4 PCI API. Some clean ups, global devs list
- *      removed (now using pci device driver data).
- *      PM needs to be polished still. Bumped version.
- *  (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu>
- *      Add support for 978 docking and basic hardware volume control
- *  (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com>
- *     Add clocking= for people with seriously warped hardware
- *  (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *     add __init to maestro_ac97_init() and maestro_install()
- *  (still based on v0.14) Mar 29 2000 - Zach Brown <zab@redhat.com>
- *     move to 2.3 power management interface, which
- *             required hacking some suspend/resume/check paths 
- *     make static compilation work
- *  v0.14 - Jan 28 2000 - Zach Brown <zab@redhat.com>
- *     add PCI power management through ACPI regs.
- *     we now shut down on machine reboot/halt
- *     leave scary PCI config items alone (isa stuff, mostly)
- *     enable 1921s, it seems only mine was broke.
- *     fix swapped left/right pcm dac.  har har.
- *     up bob freq, increase buffers, fix pointers at underflow
- *     silly compilation problems
- *  v0.13 - Nov 18 1999 - Zach Brown <zab@redhat.com>
- *     fix nec Versas?  man would that be cool.
- *  v0.12 - Nov 12 1999 - Zach Brown <zab@redhat.com>
- *     brown bag volume max fix..
- *  v0.11 - Nov 11 1999 - Zach Brown <zab@redhat.com>
- *     use proper stereo apu decoding, mmap/write should work.
- *     make volume sliders more useful, tweak rate calculation.
- *     fix lame 8bit format reporting bug.  duh. apm apu saving buglet also
- *     fix maestro 1 clock freq "bug", remove pt101 support
- *  v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com>
- *     aha, so, sometimes the WP writes a status word to offset 0
- *       from one of the PCMBARs.  rearrange allocation accordingly..
- *       cheers again to Eric for being a good hacker in investigating this.
- *     Jeroen Hoogervorst submits 7500 fix out of nowhere.  yay.  :)
- *  v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com>
- *     added APM support.
- *     re-order something such that some 2Es now work.  Magic!
- *     new codec reset routine.  made some codecs come to life.
- *     fix clear_advance, sync some control with ESS.
- *     now write to all base regs to be paranoid.
- *  v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com>
- *     Fix initial buflen bug.  I am so smart.  also smp compiling..
- *     I owe Eric yet another beer: fixed recmask, igain, 
- *       muting, and adc sync consistency.  Go Team.
- *  v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com>
- *     tweak adc/dac, formating, and stuff to allow full duplex
- *     allocate dsps memory at open() so we can fit in the wavecache window
- *     fix wavecache braindamage.  again.  no more scribbling?
- *     fix ess 1921 codec bug on some laptops.
- *     fix dumb pci scanning bug
- *     started 2.3 cleanup, redid spinlocks, little cleanups
- *  v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com>
- *     fix wavecache thinkos.  limit to 1 /dev/dsp.
- *     eric is wearing his thinking toque this week.
- *             spotted apu mode bugs and gain ramping problem
- *     don't touch weird mixer regs, make recmask optional
- *     fixed igain inversion, defaults for mixers, clean up rec_start
- *     make mono recording work.
- *     report subsystem stuff, please send reports.
- *     littles: parallel out, amp now
- *  v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com>
- *     merged and fixed up Eric's initial recording code
- *     munged format handling to catch misuse, needs rewrite.
- *     revert ring bus init, fixup shared int, add pci busmaster setting
- *     fix mixer oss interface, fix mic mute and recmask
- *     mask off unsupported mixers, reset with all 1s, modularize defaults
- *     make sure bob is running while we need it
- *     got rid of device limit, initial minimal apm hooks
- *     pull out dead code/includes, only allow multimedia/audio maestros
- *  v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com>
- *     copied memory leak fix from sonicvibes driver
- *     different ac97 reset, play with 2.0 ac97, simplify ring bus setup
- *     bob freq code, region sanity, jitter sync fix; all from Eric 
- *
- * TODO
- *     fix bob frequency
- *     endianness
- *     do smart things with ac97 2.0 bits.
- *     dual codecs
- *     leave 54->61 open
- *
- *     it also would be fun to have a mode that would not use pci dma at all
- *     but would copy into the wavecache on board memory and use that 
- *     on architectures that don't like the maestro's pci dma ickiness.
- */
-
-/*****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/current.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "maestro.h"
-
-static struct pci_driver maestro_pci_driver;
-
-/* --------------------------------------------------------------------- */
-
-#define M_DEBUG 1
-
-#ifdef M_DEBUG
-static int debug;
-#define M_printk(args...) {if (debug) printk(args);}
-#else
-#define M_printk(x)
-#endif
-
-/* we try to setup 2^(dsps_order) /dev/dsp devices */
-static int dsps_order;
-/* whether or not we mess around with power management */
-static int use_pm=2; /* set to 1 for force */
-/* clocking for broken hardware - a few laptops seem to use a 50Khz clock
-       ie insmod with clocking=50000 or so */
-       
-static int clocking=48000;
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>");
-MODULE_DESCRIPTION("ESS Maestro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, bool, 0644);
-#endif
-module_param(dsps_order, int, 0);
-module_param(use_pm, int, 0);
-module_param(clocking, int, 0);
-
-/* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.15"
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS                 0x125D
-#define PCI_DEVICE_ID_ESS_ESS1968      0x1968          /* Maestro 2    */
-#define PCI_DEVICE_ID_ESS_ESS1978              0x1978          /* Maestro 2E   */
-
-#define PCI_VENDOR_ESS_OLD             0x1285          /* Platform Tech, 
-                                               the people the maestro 
-                                               was bought from */
-#define PCI_DEVICE_ID_ESS_ESS0100      0x0100          /* maestro 1 */
-#endif /* PCI_VENDOR_ESS */
-
-#define ESS_CHAN_HARD          0x100
-
-/* NEC Versas ? */
-#define NEC_VERSA_SUBID1       0x80581033
-#define NEC_VERSA_SUBID2       0x803c1033
-
-
-/* changed so that I could actually find all the
-       references and fix them up.  it's a little more readable now. */
-#define ESS_FMT_STEREO 0x01
-#define ESS_FMT_16BIT  0x02
-#define ESS_FMT_MASK   0x03
-#define ESS_DAC_SHIFT  0   
-#define ESS_ADC_SHIFT  4
-
-#define ESS_STATE_MAGIC                0x125D1968
-#define ESS_CARD_MAGIC         0x19283746
-
-#define DAC_RUNNING            1
-#define ADC_RUNNING            2
-
-#define MAX_DSP_ORDER  2
-#define MAX_DSPS       (1<<MAX_DSP_ORDER)
-#define NR_DSPS                (1<<dsps_order)
-#define NR_IDRS                32
-
-#define NR_APUS                64
-#define NR_APU_REGS    16
-
-/* acpi states */
-enum {
-       ACPI_D0=0,
-       ACPI_D1,
-       ACPI_D2,
-       ACPI_D3
-};
-
-/* bits in the acpi masks */
-#define ACPI_12MHZ     ( 1 << 15)
-#define ACPI_24MHZ     ( 1 << 14)
-#define ACPI_978       ( 1 << 13)
-#define ACPI_SPDIF     ( 1 << 12)
-#define ACPI_GLUE      ( 1 << 11)
-#define ACPI__10       ( 1 << 10) /* reserved */
-#define ACPI_PCIINT    ( 1 << 9)
-#define ACPI_HV                ( 1 << 8) /* hardware volume */
-#define ACPI_GPIO      ( 1 << 7)
-#define ACPI_ASSP      ( 1 << 6)
-#define ACPI_SB                ( 1 << 5) /* sb emul */
-#define ACPI_FM                ( 1 << 4) /* fm emul */
-#define ACPI_RB                ( 1 << 3) /* ringbus / aclink */
-#define ACPI_MIDI      ( 1 << 2) 
-#define ACPI_GP                ( 1 << 1) /* game port */
-#define ACPI_WP                ( 1 << 0) /* wave processor */
-
-#define ACPI_ALL       (0xffff)
-#define ACPI_SLEEP     (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \
-                       ACPI_MIDI|ACPI_GP|ACPI_WP))
-#define ACPI_NONE      (ACPI__10)
-
-/* these masks indicate which units we care about at
-       which states */
-static u16 acpi_state_mask[] = {
-       [ACPI_D0] = ACPI_ALL,
-       [ACPI_D1] = ACPI_SLEEP,
-       [ACPI_D2] = ACPI_SLEEP,
-       [ACPI_D3] = ACPI_NONE
-};
-
-static char version[] __devinitdata =
-KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n";
-
-
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum card_types_t {
-       TYPE_MAESTRO,
-       TYPE_MAESTRO2,
-       TYPE_MAESTRO2E
-};
-
-static const char *card_names[]={
-       [TYPE_MAESTRO] = "ESS Maestro",
-       [TYPE_MAESTRO2] = "ESS Maestro 2",
-       [TYPE_MAESTRO2E] = "ESS Maestro 2E"
-};
-
-static int clock_freq[]={
-       [TYPE_MAESTRO] = (49152000L / 1024L),
-       [TYPE_MAESTRO2] = (50000000L / 1024L),
-       [TYPE_MAESTRO2E] = (50000000L / 1024L)
-};
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-
-static struct notifier_block maestro_nb = {maestro_notifier, NULL, 0};
-
-/* --------------------------------------------------------------------- */
-
-struct ess_state {
-       unsigned int magic;
-       /* FIXME: we probably want submixers in here, but only one record pair */
-       u8 apu[6];              /* l/r output, l/r intput converters, l/r input apus */
-       u8 apu_mode[6];         /* Running mode for this APU */
-       u8 apu_pan[6];          /* Panning setup for this APU */
-       u32 apu_base[6];        /* base address for this apu */
-       struct ess_card *card;  /* Card info */
-       /* wave stuff */
-       unsigned int rateadc, ratedac;
-       unsigned char fmt, enable;
-
-       int index;
-
-       /* this locks around the oss state in the driver */
-       spinlock_t lock;
-       /* only let 1 be opening at a time */
-       struct mutex open_mutex;
-       wait_queue_head_t open_wait;
-       mode_t open_mode;
-
-       /* soundcore stuff */
-       int dev_audio;
-
-       struct dmabuf {
-               void *rawbuf;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               /* XXX zab - swptr only in here so that it can be referenced by
-                       clear_advance, as far as I can tell :( */
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;       /* our oss buffers are ready to go */
-               unsigned endcleared:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-               u16 base;               /* Offset for ptr */
-       } dma_dac, dma_adc;
-
-       /* pointer to each dsp?s piece of the apu->src buffer page */
-       void *mixbuf;
-
-};
-       
-struct ess_card {
-       unsigned int magic;
-
-       /* We keep maestro cards in a linked list */
-       struct ess_card *next;
-
-       int dev_mixer;
-
-       int card_type;
-
-       /* as most of this is static,
-               perhaps it should be a pointer to a global struct */
-       struct mixer_goo {
-               int modcnt;
-               int supported_mixers;
-               int stereo_mixers;
-               int record_sources;
-               /* the caller must guarantee arg sanity before calling these */
-/*             int (*read_mixer)(struct ess_card *card, int index);*/
-               void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right);
-               int (*recmask_io)(struct ess_card *card,int rw,int mask);
-               unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
-       } mix;
-       
-       int power_regs;
-               
-       int in_suspend;
-       wait_queue_head_t suspend_queue;
-
-       struct ess_state channels[MAX_DSPS];
-       u16 maestro_map[NR_IDRS];       /* Register map */
-       /* we have to store this junk so that we can come back from a
-               suspend */
-       u16 apu_map[NR_APUS][NR_APU_REGS];      /* contents of apu regs */
-
-       /* this locks around the physical registers on the card */
-       spinlock_t lock;
-
-       /* memory for this card.. wavecache limited :(*/
-       void *dmapages;
-       int dmaorder;
-
-       /* hardware resources */
-       struct pci_dev *pcidev;
-       u32 iobase;
-       u32 irq;
-
-       int bob_freq;
-       char dsps_open;
-
-       int dock_mute_vol;
-};
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val );
-
-static unsigned 
-ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static void check_suspend(struct ess_card *card);
-
-/* --------------------------------------------------------------------- */
-
-
-/*
- *     ESS Maestro AC97 codec programming interface.
- */
-        
-static void maestro_ac97_set(struct ess_card *card, u8 cmd, u16 val)
-{
-       int io = card->iobase;
-       int i;
-       /*
-        *      Wait for the codec bus to be free 
-        */
-
-       check_suspend(card);
-        
-       for(i=0;i<10000;i++)
-       {
-               if(!(inb(io+ESS_AC97_INDEX)&1)) 
-                       break;
-       }
-       /*
-        *      Write the bus
-        */ 
-       outw(val, io+ESS_AC97_DATA);
-       mdelay(1);
-       outb(cmd, io+ESS_AC97_INDEX);
-       mdelay(1);
-}
-
-static u16 maestro_ac97_get(struct ess_card *card, u8 cmd)
-{
-       int io = card->iobase;
-       int sanity=10000;
-       u16 data;
-       int i;
-       
-       check_suspend(card);
-       /*
-        *      Wait for the codec bus to be free 
-        */
-        
-       for(i=0;i<10000;i++)
-       {
-               if(!(inb(io+ESS_AC97_INDEX)&1))
-                       break;
-       }
-
-       outb(cmd|0x80, io+ESS_AC97_INDEX);
-       mdelay(1);
-       
-       while(inb(io+ESS_AC97_INDEX)&1)
-       {
-               sanity--;
-               if(!sanity)
-               {
-                       printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd);
-                       return 0;
-               }
-       }
-       data=inw(io+ESS_AC97_DATA);
-       mdelay(1);
-       return data;
-}
-
-/* OSS interface to the ac97s.. */
-
-#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\
-       SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\
-       SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN)
-
-#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
-       SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\
-       SOUND_MASK_SPEAKER)
-
-#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
-       SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\
-       SOUND_MASK_PHONEIN)
-
-#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) )
-
-/* this table has default mixer values for all OSS mixers.
-       be sure to fill it in if you add oss mixers
-       to anyone's supported mixer defines */
-
-static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_VOLUME] =          0x3232,
-       [SOUND_MIXER_BASS] =            0x3232,
-       [SOUND_MIXER_TREBLE] =          0x3232,
-       [SOUND_MIXER_SPEAKER] =         0x3232,
-       [SOUND_MIXER_MIC] =     0x8000, /* annoying */
-       [SOUND_MIXER_LINE] =    0x3232,
-       [SOUND_MIXER_CD] =      0x3232,
-       [SOUND_MIXER_VIDEO] =   0x3232,
-       [SOUND_MIXER_LINE1] =   0x3232,
-       [SOUND_MIXER_PCM] =             0x3232,
-       [SOUND_MIXER_IGAIN] =           0x3232
-};
-       
-static struct ac97_mixer_hw {
-       unsigned char offset;
-       int scale;
-} ac97_hw[SOUND_MIXER_NRDEVICES]= {
-       [SOUND_MIXER_VOLUME]    =       {0x02,63},
-       [SOUND_MIXER_BASS]      =       {0x08,15},
-       [SOUND_MIXER_TREBLE]    =       {0x08,15},
-       [SOUND_MIXER_SPEAKER]   =       {0x0a,15},
-       [SOUND_MIXER_MIC]       =       {0x0e,31},
-       [SOUND_MIXER_LINE]      =       {0x10,31},
-       [SOUND_MIXER_CD]        =       {0x12,31},
-       [SOUND_MIXER_VIDEO]     =       {0x14,31},
-       [SOUND_MIXER_LINE1]     =       {0x16,31},
-       [SOUND_MIXER_PCM]       =       {0x18,31},
-       [SOUND_MIXER_IGAIN]     =       {0x1c,15}
-};
-
-#if 0 /* *shrug* removed simply because we never used it.
-               feel free to implement again if needed */
-
-/* reads the given OSS mixer from the ac97
-       the caller must have insured that the ac97 knows
-       about that given mixer, and should be holding a
-       spinlock for the card */
-static int ac97_read_mixer(struct ess_card *card, int mixer) 
-{
-       u16 val;
-       int ret=0;
-       struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-       val = maestro_ac97_get(card, mh->offset);
-
-       if(AC97_STEREO_MASK & (1<<mixer)) {
-               /* nice stereo mixers .. */
-               int left,right;
-
-               left = (val >> 8)  & 0x7f;
-               right = val  & 0x7f;
-
-               if (mixer == SOUND_MIXER_IGAIN) {
-                       right = (right * 100) / mh->scale;
-                       left = (left * 100) / mh->scale;
-               } else {
-                       right = 100 - ((right * 100) / mh->scale);
-                       left = 100 - ((left * 100) / mh->scale);
-               }
-
-               ret = left | (right << 8);
-       } else if (mixer == SOUND_MIXER_SPEAKER) {
-               ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
-       } else if (mixer == SOUND_MIXER_MIC) {
-               ret = 100 - (((val & 0x1f) * 100) / mh->scale);
-       /*  the low bit is optional in the tone sliders and masking
-               it lets is avoid the 0xf 'bypass'.. */
-       } else if (mixer == SOUND_MIXER_BASS) {
-               ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
-       } else if (mixer == SOUND_MIXER_TREBLE) {
-               ret = 100 - (((val & 0xe) * 100) / mh->scale);
-       }
-
-       M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret);
-
-       return ret;
-}
-#endif
-
-/* write the OSS encoded volume to the given OSS encoded mixer,
-       again caller's job to make sure all is well in arg land,
-       call with spinlock held */
-       
-/* linear scale -> log */
-static unsigned char lin2log[101] = 
-{
-0, 0 , 15 , 23 , 30 , 34 , 38 , 42 , 45 , 47 ,
-50 , 52 , 53 , 55 , 57 , 58 , 60 , 61 , 62 ,
-63 , 65 , 66 , 67 , 68 , 69 , 69 , 70 , 71 ,
-72 , 73 , 73 , 74 , 75 , 75 , 76 , 77 , 77 ,
-78 , 78 , 79 , 80 , 80 , 81 , 81 , 82 , 82 ,
-83 , 83 , 84 , 84 , 84 , 85 , 85 , 86 , 86 ,
-87 , 87 , 87 , 88 , 88 , 88 , 89 , 89 , 89 ,
-90 , 90 , 90 , 91 , 91 , 91 , 92 , 92 , 92 ,
-93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 ,
-95 , 95 , 96 , 96 , 96 , 96 , 97 , 97 , 97 ,
-97 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 
-};
-
-static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right)
-{
-       u16 val=0;
-       struct ac97_mixer_hw *mh = &ac97_hw[mixer];
-
-       M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right);
-
-       if(AC97_STEREO_MASK & (1<<mixer)) {
-               /* stereo mixers, mute them if we can */
-
-               if (mixer == SOUND_MIXER_IGAIN) {
-                       /* igain's slider is reversed.. */
-                       right = (right * mh->scale) / 100;
-                       left = (left * mh->scale) / 100;
-                       if ((left == 0) && (right == 0))
-                               val |= 0x8000;
-               } else if (mixer == SOUND_MIXER_PCM || mixer == SOUND_MIXER_CD) {
-                       /* log conversion seems bad for them */
-                       if ((left == 0) && (right == 0))
-                               val = 0x8000;
-                       right = ((100 - right) * mh->scale) / 100;
-                       left = ((100 - left) * mh->scale) / 100;
-               } else {
-                       /* log conversion for the stereo controls */
-                       if((left == 0) && (right == 0))
-                               val = 0x8000;
-                       right = ((100 - lin2log[right]) * mh->scale) / 100;
-                       left = ((100 - lin2log[left]) * mh->scale) / 100;
-               }
-
-               val |= (left << 8) | right;
-
-       } else if (mixer == SOUND_MIXER_SPEAKER) {
-               val = (((100 - left) * mh->scale) / 100) << 1;
-       } else if (mixer == SOUND_MIXER_MIC) {
-               val = maestro_ac97_get(card, mh->offset) & ~0x801f;
-               val |= (((100 - left) * mh->scale) / 100);
-       /*  the low bit is optional in the tone sliders and masking
-               it lets is avoid the 0xf 'bypass'.. */
-       } else if (mixer == SOUND_MIXER_BASS) {
-               val = maestro_ac97_get(card , mh->offset) & ~0x0f00;
-               val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
-       } else if (mixer == SOUND_MIXER_TREBLE)  {
-               val = maestro_ac97_get(card , mh->offset) & ~0x000f;
-               val |= (((100 - left) * mh->scale) / 100) & 0x000e;
-       }
-
-       maestro_ac97_set(card , mh->offset, val);
-       
-       M_printk(" -> %x\n",val);
-}
-
-/* the following tables allow us to go from 
-       OSS <-> ac97 quickly. */
-
-enum ac97_recsettings {
-       AC97_REC_MIC=0,
-       AC97_REC_CD,
-       AC97_REC_VIDEO,
-       AC97_REC_AUX,
-       AC97_REC_LINE,
-       AC97_REC_STEREO, /* combination of all enabled outputs..  */
-       AC97_REC_MONO,        /*.. or the mono equivalent */
-       AC97_REC_PHONE        
-};
-
-static unsigned int ac97_oss_mask[] = {
-       [AC97_REC_MIC] = SOUND_MASK_MIC, 
-       [AC97_REC_CD] = SOUND_MASK_CD, 
-       [AC97_REC_VIDEO] = SOUND_MASK_VIDEO, 
-       [AC97_REC_AUX] = SOUND_MASK_LINE1, 
-       [AC97_REC_LINE] = SOUND_MASK_LINE, 
-       [AC97_REC_PHONE] = SOUND_MASK_PHONEIN
-};
-
-/* indexed by bit position */
-static unsigned int ac97_oss_rm[] = {
-       [SOUND_MIXER_MIC] = AC97_REC_MIC,
-       [SOUND_MIXER_CD] = AC97_REC_CD,
-       [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
-       [SOUND_MIXER_LINE1] = AC97_REC_AUX,
-       [SOUND_MIXER_LINE] = AC97_REC_LINE,
-       [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
-};
-       
-/* read or write the recmask 
-       the ac97 can really have left and right recording
-       inputs independently set, but OSS doesn't seem to 
-       want us to express that to the user. 
-       the caller guarantees that we have a supported bit set,
-       and they must be holding the card's spinlock */
-static int 
-ac97_recmask_io(struct ess_card *card, int read, int mask) 
-{
-       unsigned int val = ac97_oss_mask[ maestro_ac97_get(card, 0x1a) & 0x7 ];
-
-       if (read) return val;
-
-       /* oss can have many inputs, maestro can't.  try
-               to pick the 'new' one */
-
-       if (mask != val) mask &= ~val;
-
-       val = ffs(mask) - 1; 
-       val = ac97_oss_rm[val];
-       val |= val << 8;  /* set both channels */
-
-       M_printk("maestro: setting ac97 recmask to 0x%x\n",val);
-
-       maestro_ac97_set(card,0x1a,val);
-
-       return 0;
-};
-
-/*
- *     The Maestro can be wired to a standard AC97 compliant codec
- *     (see www.intel.com for the pdf's on this), or to a PT101 codec
- *     which appears to be the ES1918 (data sheet on the esstech.com.tw site)
- *
- *     The PT101 setup is untested.
- */
-static u16 __init maestro_ac97_init(struct ess_card *card)
-{
-       u16 vend1, vend2, caps;
-
-       card->mix.supported_mixers = AC97_SUPPORTED_MASK;
-       card->mix.stereo_mixers = AC97_STEREO_MASK;
-       card->mix.record_sources = AC97_RECORD_MASK;
-/*     card->mix.read_mixer = ac97_read_mixer;*/
-       card->mix.write_mixer = ac97_write_mixer;
-       card->mix.recmask_io = ac97_recmask_io;
-
-       vend1 = maestro_ac97_get(card, 0x7c);
-       vend2 = maestro_ac97_get(card, 0x7e);
-
-       caps = maestro_ac97_get(card, 0x00);
-
-       printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n",
-               vend1,vend2,caps,maestro_ac97_get(card,0x26) & 0xf);
-
-       if (! (caps & 0x4) ) {
-               /* no bass/treble nobs */
-               card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE);
-       }
-
-       /* XXX endianness, dork head. */
-       /* vendor specifc bits.. */
-       switch ((long)(vend1 << 16) | vend2) {
-       case 0x545200ff:        /* TriTech */
-               /* no idea what this does */
-               maestro_ac97_set(card,0x2a,0x0001);
-               maestro_ac97_set(card,0x2c,0x0000);
-               maestro_ac97_set(card,0x2c,0xffff);
-               break;
-#if 0  /* i thought the problems I was seeing were with
-       the 1921, but apparently they were with the pci board
-       it was on, so this code is commented out.
-        lets see if this holds true. */
-       case 0x83847609:        /* ESS 1921 */
-               /* writing to 0xe (mic) or 0x1a (recmask) seems
-                       to hang this codec */
-               card->mix.supported_mixers &= ~(SOUND_MASK_MIC);
-               card->mix.record_sources = 0;
-               card->mix.recmask_io = NULL;
-#if 0  /* don't ask.  I have yet to see what these actually do. */
-               maestro_ac97_set(card,0x76,0xABBA); /* o/~ Take a chance on me o/~ */
-               udelay(20);
-               maestro_ac97_set(card,0x78,0x3002);
-               udelay(20);
-               maestro_ac97_set(card,0x78,0x3802);
-               udelay(20);
-#endif
-               break;
-#endif
-       default: break;
-       }
-
-       maestro_ac97_set(card, 0x1E, 0x0404);
-       /* null misc stuff */
-       maestro_ac97_set(card, 0x20, 0x0000);
-
-       return 0;
-}
-
-#if 0  /* there has been 1 person on the planet with a pt101 that we
-       know of.  If they care, they can put this back in :) */
-static u16 maestro_pt101_init(struct ess_card *card,int iobase)
-{
-       printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n");
-       /* who knows.. */
-       maestro_ac97_set(iobase, 0x2A, 0x0001);
-       maestro_ac97_set(iobase, 0x2C, 0x0000);
-       maestro_ac97_set(iobase, 0x2C, 0xFFFF);
-       maestro_ac97_set(iobase, 0x10, 0x9F1F);
-       maestro_ac97_set(iobase, 0x12, 0x0808);
-       maestro_ac97_set(iobase, 0x14, 0x9F1F);
-       maestro_ac97_set(iobase, 0x16, 0x9F1F);
-       maestro_ac97_set(iobase, 0x18, 0x0404);
-       maestro_ac97_set(iobase, 0x1A, 0x0000);
-       maestro_ac97_set(iobase, 0x1C, 0x0000);
-       maestro_ac97_set(iobase, 0x02, 0x0404);
-       maestro_ac97_set(iobase, 0x04, 0x0808);
-       maestro_ac97_set(iobase, 0x0C, 0x801F);
-       maestro_ac97_set(iobase, 0x0E, 0x801F);
-       return 0;
-}
-#endif
-
-/* this is very magic, and very slow.. */
-static void 
-maestro_ac97_reset(int ioaddr, struct pci_dev *pcidev)
-{
-       u16 save_68;
-       u16 w;
-       u32 vend;
-
-       outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-       outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-       outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-       /* reset the first codec */
-       outw(0x0000,  ioaddr+0x36);
-       save_68 = inw(ioaddr+0x68);
-       pci_read_config_word(pcidev, 0x58, &w); /* something magical with gpio and bus arb. */
-       pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &vend);
-       if( w & 0x1)
-               save_68 |= 0x10;
-       outw(0xfffe, ioaddr + 0x64);    /* tickly gpio 0.. */
-       outw(0x0001, ioaddr + 0x68);
-       outw(0x0000, ioaddr + 0x60);
-       udelay(20);
-       outw(0x0001, ioaddr + 0x60);
-       mdelay(20);
-
-       outw(save_68 | 0x1, ioaddr + 0x68);     /* now restore .. */
-       outw( (inw(ioaddr + 0x38) & 0xfffc)|0x1, ioaddr + 0x38);
-       outw( (inw(ioaddr + 0x3a) & 0xfffc)|0x1, ioaddr + 0x3a);
-       outw( (inw(ioaddr + 0x3c) & 0xfffc)|0x1, ioaddr + 0x3c);
-
-       /* now the second codec */
-       outw(0x0000,  ioaddr+0x36);
-       outw(0xfff7, ioaddr + 0x64);
-       save_68 = inw(ioaddr+0x68);
-       outw(0x0009, ioaddr + 0x68);
-       outw(0x0001, ioaddr + 0x60);
-       udelay(20);
-       outw(0x0009, ioaddr + 0x60);
-       mdelay(500);    /* .. ouch.. */
-       outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
-       outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
-       outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
-
-#if 0 /* the loop here needs to be much better if we want it.. */
-       M_printk("trying software reset\n");
-       /* try and do a software reset */
-       outb(0x80|0x7c, ioaddr + 0x30);
-       for (w=0; ; w++) {
-               if ((inw(ioaddr+ 0x30) & 1) == 0) {
-                       if(inb(ioaddr + 0x32) !=0) break;
-
-                       outb(0x80|0x7d, ioaddr + 0x30);
-                       if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-                       outb(0x80|0x7f, ioaddr + 0x30);
-                       if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
-               }
-
-               if( w > 10000) {
-                       outb( inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);  /* do a software reset */
-                       mdelay(500); /* oh my.. */
-                       outb( inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37);  
-                       udelay(1);
-                       outw( 0x80, ioaddr+0x30);
-                       for(w = 0 ; w < 10000; w++) {
-                               if((inw(ioaddr + 0x30) & 1) ==0) break;
-                       }
-               }
-       }
-#endif
-       if ( vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) {
-               /* turn on external amp? */
-               outw(0xf9ff, ioaddr + 0x64);
-               outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68);
-               outw(0x0209, ioaddr + 0x60);
-       }
-
-       /* Turn on the 978 docking chip.
-          First frob the "master output enable" bit,
-          then set most of the playback volume control registers to max. */
-       outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0);
-       outb(0xff, ioaddr+0xc3);
-       outb(0xff, ioaddr+0xc4);
-       outb(0xff, ioaddr+0xc6);
-       outb(0xff, ioaddr+0xc8);
-       outb(0x3f, ioaddr+0xcf);
-       outb(0x3f, ioaddr+0xd0);
-}
-/*
- *     Indirect register access. Not all registers are readable so we
- *     need to keep register state ourselves
- */
-#define WRITEABLE_MAP  0xEFFFFF
-#define READABLE_MAP   0x64003F
-
-/*
- *     The Maestro engineers were a little indirection happy. These indirected
- *     registers themselves include indirect registers at another layer
- */
-
-static void __maestro_write(struct ess_card *card, u16 reg, u16 data)
-{
-       long ioaddr = card->iobase;
-
-       outw(reg, ioaddr+0x02);
-       outw(data, ioaddr+0x00);
-       if( reg >= NR_IDRS) printk("maestro: IDR %d out of bounds!\n",reg);
-       else card->maestro_map[reg]=data;
-
-}
-static void maestro_write(struct ess_state *s, u16 reg, u16 data)
-{
-       unsigned long flags;
-
-       check_suspend(s->card);
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       __maestro_write(s->card,reg,data);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 __maestro_read(struct ess_card *card, u16 reg)
-{
-       long ioaddr = card->iobase;
-
-       outw(reg, ioaddr+0x02);
-       return card->maestro_map[reg]=inw(ioaddr+0x00);
-}
-
-static u16 maestro_read(struct ess_state *s, u16 reg)
-{
-       if(READABLE_MAP & (1<<reg))
-       {
-               unsigned long flags;
-               check_suspend(s->card);
-               spin_lock_irqsave(&s->card->lock,flags);
-
-               __maestro_read(s->card,reg);
-
-               spin_unlock_irqrestore(&s->card->lock,flags);
-       }
-       return s->card->maestro_map[reg];
-}
-
-/*
- *     These routines handle accessing the second level indirections to the
- *     wave ram.
- */
-
-/*
- *     The register names are the ones ESS uses (see 104T31.ZIP)
- */
-#define IDR0_DATA_PORT         0x00
-#define IDR1_CRAM_POINTER      0x01
-#define IDR2_CRAM_DATA         0x02
-#define IDR3_WAVE_DATA         0x03
-#define IDR4_WAVE_PTR_LOW      0x04
-#define IDR5_WAVE_PTR_HI       0x05
-#define IDR6_TIMER_CTRL                0x06
-#define IDR7_WAVE_ROMRAM       0x07
-
-static void apu_index_set(struct ess_card *card, u16 index)
-{
-       int i;
-       __maestro_write(card, IDR1_CRAM_POINTER, index);
-       for(i=0;i<1000;i++)
-               if(__maestro_read(card, IDR1_CRAM_POINTER)==index)
-                       return;
-       printk(KERN_WARNING "maestro: APU register select failed.\n");
-}
-
-static void apu_data_set(struct ess_card *card, u16 data)
-{
-       int i;
-       for(i=0;i<1000;i++)
-       {
-               if(__maestro_read(card, IDR0_DATA_PORT)==data)
-                       return;
-               __maestro_write(card, IDR0_DATA_PORT, data);
-       }
-}
-
-/*
- *     This is the public interface for APU manipulation. It handles the
- *     interlock to avoid two APU writes in parallel etc. Don't diddle
- *     directly with the stuff above.
- */
-
-static void apu_set_register(struct ess_state *s, u16 channel, u8 reg, u16 data)
-{
-       unsigned long flags;
-       
-       check_suspend(s->card);
-
-       if(channel&ESS_CHAN_HARD)
-               channel&=~ESS_CHAN_HARD;
-       else
-       {
-               if(channel>5)
-                       printk("BAD CHANNEL %d.\n",channel);
-               else
-                       channel = s->apu[channel];
-               /* store based on real hardware apu/reg */
-               s->card->apu_map[channel][reg]=data;
-       }
-       reg|=(channel<<4);
-       
-       /* hooray for double indirection!! */
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       apu_index_set(s->card, reg);
-       apu_data_set(s->card, data);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 apu_get_register(struct ess_state *s, u16 channel, u8 reg)
-{
-       unsigned long flags;
-       u16 v;
-       
-       check_suspend(s->card);
-
-       if(channel&ESS_CHAN_HARD)
-               channel&=~ESS_CHAN_HARD;
-       else
-               channel = s->apu[channel];
-
-       reg|=(channel<<4);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       apu_index_set(s->card, reg);
-       v=__maestro_read(s->card, IDR0_DATA_PORT);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-       return v;
-}
-
-
-/*
- *     The wavecache buffers between the APUs and
- *     pci bus mastering
- */
-static void wave_set_register(struct ess_state *s, u16 reg, u16 value)
-{
-       long ioaddr = s->card->iobase;
-       unsigned long flags;
-       check_suspend(s->card);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-
-       outw(reg, ioaddr+0x10);
-       outw(value, ioaddr+0x12);
-
-       spin_unlock_irqrestore(&s->card->lock,flags);
-}
-
-static u16 wave_get_register(struct ess_state *s, u16 reg)
-{
-       long ioaddr = s->card->iobase;
-       unsigned long flags;
-       u16 value;
-       check_suspend(s->card);
-       
-       spin_lock_irqsave(&s->card->lock,flags);
-       outw(reg, ioaddr+0x10);
-       value=inw(ioaddr+0x12);
-       spin_unlock_irqrestore(&s->card->lock,flags);
-       
-       return value;
-}
-
-static void sound_reset(int ioaddr)
-{
-       outw(0x2000, 0x18+ioaddr);
-       udelay(1);
-       outw(0x0000, 0x18+ioaddr);
-       udelay(1);
-}
-
-/* sets the play formats of these apus, should be passed the already shifted format */
-static void set_apu_fmt(struct ess_state *s, int apu, int mode)
-{
-       int apu_fmt = 0x10;
-
-       if(!(mode&ESS_FMT_16BIT)) apu_fmt+=0x20; 
-       if((mode&ESS_FMT_STEREO)) apu_fmt+=0x10; 
-       s->apu_mode[apu]   = apu_fmt;
-       s->apu_mode[apu+1] = apu_fmt;
-}
-
-/* this only fixes the output apu mode to be later set by start_dac and
-       company.  output apu modes are set in ess_rec_setup */
-static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data)
-{
-       s->fmt = (s->fmt & mask) | data;
-       set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK);
-}
-
-/* this is off by a little bit.. */
-static u32 compute_rate(struct ess_state *s, u32 freq)
-{
-       u32 clock = clock_freq[s->card->card_type];     
-
-       freq = (freq * clocking)/48000;
-       
-       if (freq == 48000) 
-               return 0x10000;
-
-       return ((freq / clock) <<16 )+  
-               (((freq % clock) << 16) / clock);
-}
-
-static void set_dac_rate(struct ess_state *s, unsigned int rate)
-{
-       u32 freq;
-       int fmt = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-
-       s->ratedac = rate;
-
-       if(! (fmt & ESS_FMT_16BIT) && !(fmt & ESS_FMT_STEREO))
-               rate >>= 1;
-
-/*     M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/
-
-       freq = compute_rate(s, rate);
-       
-       /* Load the frequency, turn on 6dB */
-       apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 0, 3, freq>>8);
-       apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 1, 3, freq>>8);
-}
-
-static void set_adc_rate(struct ess_state *s, unsigned rate)
-{
-       u32 freq;
-
-       /* Sample Rate conversion APUs don't like 0x10000 for their rate */
-       if (rate > 47999)
-               rate = 47999;
-       if (rate < 4000)
-               rate = 4000;
-
-       s->rateadc = rate;
-
-       freq = compute_rate(s, rate);
-       
-       /* Load the frequency, turn on 6dB */
-       apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 2, 3, freq>>8);
-       apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 3, 3, freq>>8);
-
-       /* fix mixer rate at 48khz.  and its _must_ be 0x10000. */
-       freq = 0x10000;
-
-       apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 4, 3, freq>>8);
-       apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)|
-               ( ((freq&0xFF)<<8)|0x10 ));
-       apu_set_register(s, 5, 3, freq>>8);
-}
-
-/* Stop our host of recording apus */
-static inline void stop_adc(struct ess_state *s)
-{
-       /* XXX lets hope we don't have to lock around this */
-       if (! (s->enable & ADC_RUNNING)) return;
-
-       s->enable &= ~ADC_RUNNING;
-       apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F);
-       apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F);
-       apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F);
-       apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F);
-}      
-
-/* stop output apus */
-static void stop_dac(struct ess_state *s)
-{
-       /* XXX have to lock around this? */
-       if (! (s->enable & DAC_RUNNING)) return;
-
-       s->enable &= ~DAC_RUNNING;
-       apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F);
-       apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F);
-}      
-
-static void start_dac(struct ess_state *s)
-{
-       /* XXX locks? */
-       if (    (s->dma_dac.mapped || s->dma_dac.count > 0) && 
-               s->dma_dac.ready &&
-               (! (s->enable & DAC_RUNNING)) ) {
-
-               s->enable |= DAC_RUNNING;
-
-               apu_set_register(s, 0, 0, 
-                       (apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]);
-
-               if((s->fmt >> ESS_DAC_SHIFT)  & ESS_FMT_STEREO) 
-                       apu_set_register(s, 1, 0, 
-                               (apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]);
-       }
-}      
-
-static void start_adc(struct ess_state *s)
-{
-       /* XXX locks? */
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-           && s->dma_adc.ready && (! (s->enable & ADC_RUNNING)) ) {
-
-               s->enable |= ADC_RUNNING;
-               apu_set_register(s, 2, 0, 
-                       (apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]);
-               apu_set_register(s, 4, 0, 
-                       (apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]);
-
-               if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       apu_set_register(s, 3, 0, 
-                               (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]);
-                       apu_set_register(s, 5, 0, 
-                               (apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]);
-               }
-                       
-       }
-}      
-
-
-/*
- *     Native play back driver 
- */
-
-/* the mode passed should be already shifted and masked */
-static void 
-ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-       u32 pa;
-       u32 tmpval;
-       int high_apu = 0;
-       int channel;
-
-       M_printk("mode=%d rate=%d buf=%p len=%d.\n",
-               mode, rate, buffer, size);
-               
-       /* all maestro sizes are in 16bit words */
-       size >>=1;
-
-       if(mode&ESS_FMT_STEREO) {
-               high_apu++;
-               /* only 16/stereo gets size divided */
-               if(mode&ESS_FMT_16BIT)
-                       size>>=1;
-       }
-       
-       for(channel=0; channel <= high_apu; channel++)
-       {
-               pa = virt_to_bus(buffer);
-
-               /* set the wavecache control reg */
-               tmpval = (pa - 0x10) & 0xFFF8;
-               if(!(mode & ESS_FMT_16BIT)) tmpval |= 4;
-               if(mode & ESS_FMT_STEREO) tmpval |= 2;
-               ess->apu_base[channel]=tmpval;
-               wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-               
-               pa -= virt_to_bus(ess->card->dmapages);
-               pa>>=1; /* words */
-               
-               /* base offset of dma calcs when reading the pointer
-                       on the left one */
-               if(!channel) ess->dma_dac.base = pa&0xFFFF;
-               
-               pa|=0x00400000;                 /* System RAM */
-
-               /* XXX the 16bit here might not be needed.. */
-               if((mode & ESS_FMT_STEREO) && (mode & ESS_FMT_16BIT)) {
-                       if(channel) 
-                               pa|=0x00800000;                 /* Stereo */
-                       pa>>=1;
-               }
-                       
-/* XXX think about endianess when writing these registers */
-               M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa);
-               /* start of sample */
-               apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-               apu_set_register(ess, channel, 5, pa&0xFFFF);
-               /* sample end */
-               apu_set_register(ess, channel, 6, (pa+size)&0xFFFF);
-               /* setting loop len == sample len */
-               apu_set_register(ess, channel, 7, size);
-               
-               /* clear effects/env.. */
-               apu_set_register(ess, channel, 8, 0x0000);
-               /* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
-               apu_set_register(ess, channel, 9, 0xD000);
-
-               /* clear routing stuff */
-               apu_set_register(ess, channel, 11, 0x0000);
-               /* dma on, no envelopes, filter to all 1s) */
-               apu_set_register(ess, channel, 0, 0x400F);
-               
-               if(mode&ESS_FMT_16BIT)
-                       ess->apu_mode[channel]=0x10;
-               else
-                       ess->apu_mode[channel]=0x30;
-
-               if(mode&ESS_FMT_STEREO) {
-                       /* set panning: left or right */
-                       apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0 : 0x10));
-                       ess->apu_mode[channel] += 0x10;
-               } else
-                       apu_set_register(ess, channel, 10, 0x8F08);
-       }
-       
-       /* clear WP interrupts */
-       outw(1, ess->card->iobase+0x04);
-       /* enable WP ints */
-       outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-       /* go team! */
-       set_dac_rate(ess,rate);
-       start_dac(ess);
-}
-
-/*
- *     Native record driver 
- */
-
-/* again, passed mode is alrady shifted/masked */
-static void 
-ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
-{
-       int apu_step = 2;
-       int channel;
-
-       M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n",
-               mode, rate, buffer, size);
-               
-       /* all maestro sizes are in 16bit words */
-       size >>=1;
-
-       /* we're given the full size of the buffer, but
-       in stereo each channel will only use its half */
-       if(mode&ESS_FMT_STEREO) {
-               size >>=1; 
-               apu_step = 1;
-       }
-       
-       /* APU assignments: 2 = mono/left SRC
-                           3 = right SRC
-                           4 = mono/left Input Mixer
-                           5 = right Input Mixer */
-       for(channel=2;channel<6;channel+=apu_step)
-       {
-               int i;
-               int bsize, route;
-               u32 pa;
-               u32 tmpval;
-
-               /* data seems to flow from the codec, through an apu into
-                       the 'mixbuf' bit of page, then through the SRC apu
-                       and out to the real 'buffer'.  ok.  sure.  */
-               
-               if(channel & 0x04) {
-                       /* ok, we're an input mixer going from adc
-                               through the mixbuf to the other apus */
-
-                       if(!(channel & 0x01)) { 
-                               pa = virt_to_bus(ess->mixbuf);
-                       } else {
-                               pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4));
-                       }
-
-                       /* we source from a 'magic' apu */
-                       bsize = PAGE_SIZE >> 5; /* half of this channels alloc, in words */
-                       route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */
-                       ess->apu_mode[channel] = 0x90;  /* Input Mixer */
-
-               } else {  
-                       /* we're a rate converter taking
-                               input from the input apus and outputing it to
-                               system memory */
-                       if(!(channel & 0x01))  {
-                               pa = virt_to_bus(buffer);
-                       } else {
-                               /* right channel records its split half.
-                               *2 accommodates for rampant shifting earlier */
-                               pa = virt_to_bus(buffer + size*2);
-                       }
-
-                       ess->apu_mode[channel] = 0xB0;  /* Sample Rate Converter */
-
-                       bsize = size; 
-                       /* get input from inputing apu */
-                       route = channel + 2;
-               }
-
-               M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel);
-               
-               /* set the wavecache control reg */
-               tmpval = (pa - 0x10) & 0xFFF8;
-               ess->apu_base[channel]=tmpval;
-               wave_set_register(ess, ess->apu[channel]<<3, tmpval);
-               
-               pa -= virt_to_bus(ess->card->dmapages);
-               pa>>=1; /* words */
-               
-               /* base offset of dma calcs when reading the pointer
-                       on this left one */
-               if(channel==2) ess->dma_adc.base = pa&0xFFFF;
-
-               pa|=0x00400000;                 /* bit 22 -> System RAM */
-
-               M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", 
-                       ess->apu[channel], pa, bsize, route);
-               
-               /* Begin loading the APU */             
-               for(i=0;i<15;i++)               /* clear all PBRs */
-                       apu_set_register(ess, channel, i, 0x0000);
-                       
-               apu_set_register(ess, channel, 0, 0x400F);
-
-               /* need to enable subgroups.. and we should probably
-                       have different groups for different /dev/dsps..  */
-               apu_set_register(ess, channel, 2, 0x8);
-                               
-               /* Load the buffer into the wave engine */
-               apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8);
-               /* XXX reg is little endian.. */
-               apu_set_register(ess, channel, 5, pa&0xFFFF);
-               apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF);
-               apu_set_register(ess, channel, 7, bsize);
-                               
-               /* clear effects/env.. */
-               apu_set_register(ess, channel, 8, 0x00F0);
-               
-               /* amplitude now?  sure.  why not.  */
-               apu_set_register(ess, channel, 9, 0x0000);
-
-               /* set filter tune, radius, polar pan */
-               apu_set_register(ess, channel, 10, 0x8F08);
-
-               /* route input */
-               apu_set_register(ess, channel, 11, route);
-       }
-       
-       /* clear WP interrupts */
-       outw(1, ess->card->iobase+0x04);
-       /* enable WP ints */
-       outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18);
-
-       /* let 'er rip */
-       set_adc_rate(ess,rate);
-       start_adc(ess);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-       M_printk("set_dmaa??\n");
-}
-
-static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count)
-{
-       M_printk("set_dmac??\n");
-}
-
-/* Playback pointer */
-static inline unsigned get_dmaa(struct ess_state *s)
-{
-       int offset;
-
-       offset = apu_get_register(s,0,5);
-
-/*     M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */
-       
-       offset-=s->dma_dac.base;
-
-       return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/* Record pointer */
-static inline unsigned get_dmac(struct ess_state *s)
-{
-       int offset;
-
-       offset = apu_get_register(s,2,5);
-
-/*     M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */
-       
-       /* The offset is an address not a position relative to base */
-       offset-=s->dma_adc.base;
-       
-       return (offset&0xFFFE)<<1; /* hardware is in words */
-}
-
-/*
- *     Meet Bob, the timer...
- */
-
-static irqreturn_t ess_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static void stop_bob(struct ess_state *s)
-{
-       /* Mask IDR 11,17 */
-       maestro_write(s,  0x11, maestro_read(s, 0x11)&~1);
-       maestro_write(s,  0x17, maestro_read(s, 0x17)&~1);
-}
-
-/* eventually we could be clever and limit bob ints
-       to the frequency at which our smallest duration
-       chunks may expire */
-#define ESS_SYSCLK     50000000
-static void start_bob(struct ess_state *s)
-{
-       int prescale;
-       int divide;
-       
-       /* XXX make freq selector much smarter, see calc_bob_rate */
-       int freq = 200; 
-       
-       /* compute ideal interrupt frequency for buffer size & play rate */
-       /* first, find best prescaler value to match freq */
-       for(prescale=5;prescale<12;prescale++)
-               if(freq > (ESS_SYSCLK>>(prescale+9)))
-                       break;
-                       
-       /* next, back off prescaler whilst getting divider into optimum range */
-       divide=1;
-       while((prescale > 5) && (divide<32))
-       {
-               prescale--;
-               divide <<=1;
-       }
-       divide>>=1;
-       
-       /* now fine-tune the divider for best match */
-       for(;divide<31;divide++)
-               if(freq >= ((ESS_SYSCLK>>(prescale+9))/(divide+1)))
-                       break;
-       
-       /* divide = 0 is illegal, but don't let prescale = 4! */
-       if(divide == 0)
-       {
-               divide++;
-               if(prescale>5)
-                       prescale--;
-       }
-
-       maestro_write(s, 6, 0x9000 | (prescale<<5) | divide); /* set reg */
-       
-       /* Now set IDR 11/17 */
-       maestro_write(s, 0x11, maestro_read(s, 0x11)|1);
-       maestro_write(s, 0x17, maestro_read(s, 0x17)|1);
-}
-/* --------------------------------------------------------------------- */
-
-/* this quickly calculates the frequency needed for bob
-       and sets it if its different than what bob is
-       currently running at.  its called often so 
-       needs to be fairly quick. */
-#define BOB_MIN 50
-#define BOB_MAX 400
-static void calc_bob_rate(struct ess_state *s) {
-#if 0 /* this thing tries to set the frequency of bob such that
-       there are 2 interrupts / buffer walked by the dac/adc.  That
-       is probably very wrong for people who actually care about 
-       mid buffer positioning.  it should be calculated as bytes/interrupt
-       and that needs to be decided :)  so for now just use the static 150
-       in start_bob.*/
-
-       unsigned int dac_rate=2,adc_rate=1,newrate;
-       static int israte=-1;
-
-       if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN;
-       else  {
-               dac_rate =      (2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-                               (s->dma_dac.fragsize) ;
-       }
-               
-       if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN;
-       else {
-               adc_rate =      (2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) /
-                               (s->dma_adc.fragsize) ;
-       }
-
-       if(dac_rate > adc_rate) newrate = adc_rate;
-       else newrate=dac_rate;
-
-       if(newrate > BOB_MAX) newrate = BOB_MAX;
-       else {
-               if(newrate < BOB_MIN) 
-                       newrate = BOB_MIN;
-       }
-
-       if( israte != newrate) {
-               printk("dac: %d  adc: %d rate: %d\n",dac_rate,adc_rate,israte);
-               israte=newrate;
-       }
-#endif
-
-}
-
-static int 
-prog_dmabuf(struct ess_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       unsigned bytepersec;
-       unsigned bufs;
-       unsigned char fmt;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       fmt = s->fmt;
-       if (rec) {
-               stop_adc(s);
-               fmt >>= ESS_ADC_SHIFT;
-       } else {
-               stop_dac(s);
-               fmt >>= ESS_DAC_SHIFT;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       fmt &= ESS_FMT_MASK;
-
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-       /* this algorithm is a little nuts.. where did /1000 come from? */
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3; 
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-
-       M_printk("maestro: setup oss: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-       memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) 
-               ess_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-       else 
-               ess_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->ready = 1;
-
-       return 0;
-}
-
-static __inline__ void 
-clear_advance(struct ess_state *s)
-{
-       unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-       
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-       
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               /* account for wrapping? */
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void 
-ess_update_ptr(struct ess_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-               /* oh boy should this all be re-written.  everything in the current code paths think
-               that the various counters/pointers are expressed in bytes to the user but we have
-               two apus doing stereo stuff so we fix it up here.. it propagates to all the various
-               counters from here.  */
-               if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize;
-               } else {
-                       hwptr = get_dmac(s) % s->dma_adc.dmasize;
-               }
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               /* FILL ME 
-                               wrindir(s, SV_CIENABLE, s->enable); */
-                               stop_adc(s); 
-                               /* brute force everyone back in sync, sigh */
-                               s->dma_adc.count = 0;
-                               s->dma_adc.swptr = 0;
-                               s->dma_adc.hwptr = 0;
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-               /* the apu only reports the length it has seen, not the
-                       length of the memory that has been used (the WP
-                       knows that) */
-               if ( ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK) == (ESS_FMT_STEREO|ESS_FMT_16BIT))
-                       hwptr<<=1;
-
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-/*             M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-                               wake_up(&s->dma_dac.wait);
-                       }
-               } else {
-                       s->dma_dac.count -= diff;
-/*                     M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */
-                       if (s->dma_dac.count <= 0) {
-                               M_printk("underflow! diff: %d count: %d hw: %d sw: %d\n", diff, s->dma_dac.count, 
-                                       hwptr, s->dma_dac.swptr);
-                               /* FILL ME 
-                               wrindir(s, SV_CIENABLE, s->enable); */
-                               /* XXX how on earth can calling this with the lock held work.. */
-                               stop_dac(s);
-                               /* brute force everyone back in sync, sigh */
-                               s->dma_dac.count = 0; 
-                               s->dma_dac.swptr = hwptr; 
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-                               wake_up(&s->dma_dac.wait);
-/*                             printk("waking up DAC count: %d sw: %d hw: %d\n",s->dma_dac.count, s->dma_dac.swptr, 
-                                       hwptr);*/
-                       }
-               }
-       }
-}
-
-static irqreturn_t
-ess_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct ess_state *s;
-        struct ess_card *c = (struct ess_card *)dev_id;
-       int i;
-       u32 event;
-
-       if ( ! (event = inb(c->iobase+0x1A)) )
-               return IRQ_NONE;
-
-       outw(inw(c->iobase+4)&1, c->iobase+4);
-
-/*     M_printk("maestro int: %x\n",event);*/
-       if(event&(1<<6))
-       {
-               int x;
-               enum {UP_EVT, DOWN_EVT, MUTE_EVT} vol_evt;
-               int volume;
-
-               /* Figure out which volume control button was pushed,
-                  based on differences from the default register
-                  values. */
-               x = inb(c->iobase+0x1c);
-               if (x&1) vol_evt = MUTE_EVT;
-               else if (((x>>1)&7) > 4) vol_evt = UP_EVT;
-               else vol_evt = DOWN_EVT;
-
-               /* Reset the volume control registers. */
-               outb(0x88, c->iobase+0x1c);
-               outb(0x88, c->iobase+0x1d);
-               outb(0x88, c->iobase+0x1e);
-               outb(0x88, c->iobase+0x1f);
-
-               /* Deal with the button press in a hammer-handed
-                  manner by adjusting the master mixer volume. */
-               volume = c->mix.mixer_state[0] & 0xff;
-               if (vol_evt == UP_EVT) {
-                       volume += 5;
-                       if (volume > 100)
-                               volume = 100;
-               }
-               else if (vol_evt == DOWN_EVT) {
-                       volume -= 5;
-                       if (volume < 0)
-                               volume = 0;
-               } else {
-                       /* vol_evt == MUTE_EVT */
-                       if (volume == 0)
-                               volume = c->dock_mute_vol;
-                       else {
-                               c->dock_mute_vol = volume;
-                               volume = 0;
-                       }
-               }
-               set_mixer (c, 0, (volume << 8) | volume);
-       }
-
-       /* Ack all the interrupts. */
-       outb(0xFF, c->iobase+0x1A);
-               
-       /*
-        *      Update the pointers for all APU's we are running.
-        */
-       for(i=0;i<NR_DSPS;i++)
-       {
-               s=&c->channels[i];
-               if(s->dev_audio == -1)
-                       break;
-               spin_lock(&s->lock);
-               ess_update_ptr(s);
-               spin_unlock(&s->lock);
-       }
-       return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-       if (!(FOO) || (FOO)->magic != MAG) { \
-               printk(invalid_magic,__FUNCTION__);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC)
-
-static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) 
-{
-       unsigned int left,right;
-       /* cleanse input a little */
-       right = ((val >> 8)  & 0xff) ;
-       left = (val  & 0xff) ;
-
-       if(right > 100) right = 100;
-       if(left > 100) left = 100;
-
-       card->mix.mixer_state[mixer]=(right << 8) | left;
-       card->mix.write_mixer(card,mixer,left,right);
-}
-
-static void
-mixer_push_state(struct ess_card *card)
-{
-       int i;
-       for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) {
-               if( ! supported_mixer(card,i)) continue;
-
-               set_mixer(card,i,card->mix.mixer_state[i]);
-       }
-}
-
-static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
-{
-       int i, val=0;
-       unsigned long flags;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_CARD(card);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-               strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-               info.modify_counter = card->mix.modcnt;
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, card_names[card->card_type], sizeof(info.id));
-               strlcpy(info.name, card_names[card->card_type], sizeof(info.name));
-               if (copy_to_user(argp, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-
-       if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-
-        if (_IOC_DIR(cmd) == _IOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* give them the current record source */
-
-                       if(!card->mix.recmask_io) {
-                               val = 0;
-                       } else {
-                               spin_lock_irqsave(&card->lock, flags);
-                               val = card->mix.recmask_io(card,1,0);
-                               spin_unlock_irqrestore(&card->lock, flags);
-                       }
-                       break;
-                       
-                case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
-                       val = card->mix.supported_mixers;
-                       break;
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       val = card->mix.record_sources;
-                       break;
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       val = card->mix.stereo_mixers;
-                       break;
-                       
-                case SOUND_MIXER_CAPS:
-                       val = SOUND_CAP_EXCL_INPUT;
-                       break;
-
-               default: /* read a specific mixer */
-                       i = _IOC_NR(cmd);
-
-                       if ( ! supported_mixer(card,i)) 
-                               return -EINVAL;
-
-                       /* do we ever want to touch the hardware? */
-/*                     spin_lock_irqsave(&card->lock, flags);
-                       val = card->mix.read_mixer(card,i);
-                       spin_unlock_irqrestore(&card->lock, flags);*/
-
-                       val = card->mix.mixer_state[i];
-/*                     M_printk("returned 0x%x for mixer %d\n",val,i);*/
-
-                       break;
-               }
-               return put_user(val, p);
-       }
-       
-        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
-               return -EINVAL;
-       
-       card->mix.modcnt++;
-
-       if (get_user(val, p))
-               return -EFAULT;
-
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-
-               if (!card->mix.recmask_io) return -EINVAL;
-               if(!val) return 0;
-               if(! (val &= card->mix.record_sources)) return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-               card->mix.recmask_io(card,0,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-
-               if ( ! supported_mixer(card,i)) 
-                       return -EINVAL;
-
-               spin_lock_irqsave(&card->lock, flags);
-               set_mixer(card,i,val);
-               spin_unlock_irqrestore(&card->lock, flags);
-
-               return 0;
-       }
-}
-
-/* --------------------------------------------------------------------- */
-static int ess_open_mixdev(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct ess_card *card = NULL;
-       struct pci_dev *pdev = NULL;
-       struct pci_driver *drvr;
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               drvr = pci_dev_driver (pdev);
-               if (drvr == &maestro_pci_driver) {
-                       card = (struct ess_card*)pci_get_drvdata (pdev);
-                       if (!card)
-                               continue;
-                       if (card->dev_mixer == minor)
-                               break;
-               }
-       }
-       if (!card)
-               return -ENODEV;
-       file->private_data = card;
-       return nonseekable_open(inode, file);
-}
-
-static int ess_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct ess_card *card = (struct ess_card *)file->private_data;
-
-       VALIDATE_CARD(card);
-       
-       return 0;
-}
-
-static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ess_card *card = (struct ess_card *)file->private_data;
-
-       VALIDATE_CARD(card);
-
-       return mixer_ioctl(card, cmd, arg);
-}
-
-static /*const*/ struct file_operations ess_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = ess_ioctl_mixdev,
-       .open           = ess_open_mixdev,
-       .release        = ess_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct ess_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait,current);
-       unsigned long flags;
-       int count;
-       signed long tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-       current->state = TASK_INTERRUPTIBLE;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               /* XXX uhm.. questionable locking*/
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                       current->state = TASK_RUNNING;
-                        return -EBUSY;
-                }
-               tmo = (count * HZ) / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-               /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-                       or something.  who cares. - zach */
-               if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-                       M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies);
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       current->state = TASK_RUNNING;
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-/* Zach sez: "god this is gross.." */
-static int 
-comb_stereo(unsigned char *real_buffer,unsigned char  *tmp_buffer, int offset, 
-       int count, int bufsize)
-{  
-       /* No such thing as stereo recording, so we
-       use dual input mixers.  which means we have to 
-       combine mono to stereo buffer.  yuck. 
-
-       but we don't have to be able to work a byte at a time..*/
-
-       unsigned char *so,*left,*right;
-       int i;
-
-       so = tmp_buffer;
-       left = real_buffer + offset;
-       right = real_buffer + bufsize/2 + offset;
-
-/*     M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/
-
-       for(i=count/4; i ; i--) {
-               (*(so+2)) = *(right++);
-               (*(so+3)) = *(right++);
-               (*so) = *(left++);
-               (*(so+1)) = *(left++);
-               so+=4;
-       }
-
-       return 0;
-}
-
-/* in this loop, dma_adc.count signifies the amount of data thats waiting
-       to be copied to the user's buffer.  it is filled by the interrupt
-       handler and drained by this loop. */
-static ssize_t 
-ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       unsigned char *combbuf = NULL;
-       
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if(!(combbuf = kmalloc(count,GFP_KERNEL)))
-               return -ENOMEM;
-       ret = 0;
-
-       calc_bob_rate(s);
-
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               /* remember, all these things are expressed in bytes to be
-                       sent to the user.. hence the evil / 2 down below */
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-
-               if ( cnt > 0 ) cnt &= ~3;
-
-               if (cnt <= 0) {
-                       start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) 
-                       {
-                               ret = ret ? ret : -EAGAIN;
-                               goto rec_return_free;
-                       }
-                       if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-                               if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               stop_adc(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                               /* program enhanced mode registers */
-                               /* FILL ME */
-/*                             wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) 
-                       {
-                               ret = ret ? ret : -ERESTARTSYS;
-                               goto rec_return_free;
-                       }
-                       continue;
-               }
-       
-               if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {
-                       /* swptr/2 so that we know the real offset in each apu's buffer */
-                       comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize);
-                       if (copy_to_user(buffer, combbuf, cnt)) {
-                               ret = ret ? ret : -EFAULT;
-                               goto rec_return_free;
-                       }
-               } else  {
-                       if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                               ret = ret ? ret : -EFAULT;
-                               goto rec_return_free;
-                       }
-               }
-
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_adc(s);
-       }
-
-rec_return_free:
-       kfree(combbuf);
-       return ret;
-}
-
-static ssize_t 
-ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-       
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-
-       calc_bob_rate(s);
-
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-
-               cnt = s->dma_dac.dmasize-swptr;
-
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-               spin_unlock_irqrestore(&s->lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt <= 0) {
-                       start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if(!ret) ret = -EAGAIN;
-                               goto return_free;
-                       }
-                       if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-                               if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               stop_dac(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                               /* program enhanced mode registers */
-/*                             wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); */
-                               /* FILL ME */
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               goto return_free;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       goto return_free;
-               }
-/*             printk("wrote %d bytes at sw: %d cnt: %d while hw: %d\n",cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);*/
-
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               start_dac(s);
-       }
-return_free:
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-
-/* In 0.14 prog_dmabuf always returns success anyway ... */
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 0)) 
-                       return 0;
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 1))
-                       return 0;
-       }
-
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->dma_dac.wait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->dma_adc.wait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       ess_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int ess_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else 
-#if 0
-       /* if we can have the wp/wc do the combining
-               we can turn this back on.  */
-             if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else  
-#endif
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-/*     printk("maestro: ess_ioctl: cmd %d\n", cmd);*/
-       
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, file->f_flags & O_NONBLOCK);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               /* XXX fix */
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->card->pcidev->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->card->pcidev->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-               
-        case SNDCTL_DSP_STEREO:
-               if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                       else
-                               fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                       else
-                               fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_U8|AFMT_S16_LE, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-       /* fixed at 16bit for now */
-                               fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-#if 0
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-#endif
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-                               else
-                                       fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-                       (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-                               AFMT_S16_LE : 
-                               AFMT_U8, 
-                       p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-                       val |= PCM_ENABLE_INPUT;
-               if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               start_dac(s);
-                       } else
-                               stop_dac(s);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-                abinfo.bytes = s->dma_adc.count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                val = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               return put_user(val, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                       return ret;
-               spin_lock_irqsave(&s->lock, flags);
-               ess_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               M_printk("maestro: SETFRAGMENT: %0x\n",val);
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                                          : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return -EINVAL;
-}
-
-static void
-set_base_registers(struct ess_state *s,void *vaddr)
-{
-       unsigned long packed_phys = virt_to_bus(vaddr)>>12;
-       wave_set_register(s, 0x01FC , packed_phys);
-       wave_set_register(s, 0x01FD , packed_phys);
-       wave_set_register(s, 0x01FE , packed_phys);
-       wave_set_register(s, 0x01FF , packed_phys);
-}
-
-/* 
- * this guy makes sure we're in the right power
- * state for what we want to be doing 
- */
-static void maestro_power(struct ess_card *card, int tostate)
-{
-       u16 active_mask = acpi_state_mask[tostate];
-       u8 state;
-
-       if(!use_pm) return;
-
-       pci_read_config_byte(card->pcidev, card->power_regs+0x4, &state);
-       state&=3;
-
-       /* make sure we're in the right state */
-       if(state != tostate) {
-               M_printk(KERN_WARNING "maestro: dev %02x:%02x.%x switching from D%d to D%d\n",
-                       card->pcidev->bus->number, 
-                       PCI_SLOT(card->pcidev->devfn),
-                       PCI_FUNC(card->pcidev->devfn),
-                       state,tostate);
-               pci_write_config_byte(card->pcidev, card->power_regs+0x4, tostate);
-       }
-
-       /* and make sure the units we care about are on 
-               XXX we might want to do this before state flipping? */
-       pci_write_config_word(card->pcidev, 0x54, ~ active_mask);
-       pci_write_config_word(card->pcidev, 0x56, ~ active_mask);
-}
-
-/* we allocate a large power of two for all our memory.
-       this is cut up into (not to scale :):
-       |silly fifo word        | 512byte mixbuf per adc        | dac/adc * channels |
-*/
-static int
-allocate_buffers(struct ess_state *s)
-{
-       void *rawbuf=NULL;
-       int order,i;
-       struct page *page, *pend;
-
-       /* alloc as big a chunk as we can */
-       for (order = (dsps_order + (16-PAGE_SHIFT) + 1); order >= (dsps_order + 2 + 1); order--)
-               if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
-                       break;
-
-       if (!rawbuf)
-               return 1;
-
-       M_printk("maestro: allocated %ld (%d) bytes at %p\n",PAGE_SIZE<<order,order, rawbuf);
-
-       if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1))  {
-               printk(KERN_ERR "maestro: DMA buffer beyond 256MB! busaddr 0x%lx  size %ld\n",
-                       virt_to_bus(rawbuf), PAGE_SIZE << order);
-               kfree(rawbuf);
-               return 1;
-       }
-
-       s->card->dmapages = rawbuf;
-       s->card->dmaorder = order;
-
-       for(i=0;i<NR_DSPS;i++) {
-               struct ess_state *ess = &s->card->channels[i];
-
-               if(ess->dev_audio == -1)
-                       continue;
-
-               ess->dma_dac.ready = s->dma_dac.mapped = 0;
-               ess->dma_adc.ready = s->dma_adc.mapped = 0;
-               ess->dma_adc.buforder = ess->dma_dac.buforder = order - 1 - dsps_order - 1;
-
-               /* offset dac and adc buffers starting half way through and then at each [da][ad]c's
-                       order's intervals.. */
-               ess->dma_dac.rawbuf = rawbuf + (PAGE_SIZE<<(order-1)) + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 )));
-               ess->dma_adc.rawbuf = ess->dma_dac.rawbuf + ( PAGE_SIZE << ess->dma_dac.buforder);
-               /* offset mixbuf by a mixbuf so that the lame status fifo can
-                       happily scribble away.. */ 
-               ess->mixbuf = rawbuf + (512 * (i+1));
-
-               M_printk("maestro: setup apu %d: dac: %p adc: %p mix: %p\n",i,ess->dma_dac.rawbuf,
-                       ess->dma_adc.rawbuf, ess->mixbuf);
-
-       }
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (page = virt_to_page(rawbuf); page <= pend; page++)
-               SetPageReserved(page);
-
-       return 0;
-} 
-static void
-free_buffers(struct ess_state *s)
-{
-       struct page *page, *pend;
-
-       s->dma_dac.rawbuf = s->dma_adc.rawbuf = NULL;
-       s->dma_dac.mapped = s->dma_adc.mapped = 0;
-       s->dma_dac.ready = s->dma_adc.ready = 0;
-
-       M_printk("maestro: freeing %p\n",s->card->dmapages);
-       /* undo marking the pages as reserved */
-
-       pend = virt_to_page(s->card->dmapages + (PAGE_SIZE << s->card->dmaorder) - 1);
-       for (page = virt_to_page(s->card->dmapages); page <= pend; page++)
-               ClearPageReserved(page);
-
-       free_pages((unsigned long)s->card->dmapages,s->card->dmaorder);
-       s->card->dmapages = NULL;
-}
-
-static int 
-ess_open(struct inode *inode, struct file *file)
-{
-       unsigned int minor = iminor(inode);
-       struct ess_state *s = NULL;
-       unsigned char fmtm = ~0, fmts = 0;
-       struct pci_dev *pdev = NULL;
-       /*
-        *      Scan the cards and find the channel. We only
-        *      do this at open time so it is ok
-        */
-
-       while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-               struct ess_card *c;
-               struct pci_driver *drvr;
-
-               drvr = pci_dev_driver (pdev);
-               if (drvr == &maestro_pci_driver) {
-                       int i;
-                       struct ess_state *sp;
-
-                       c = (struct ess_card*)pci_get_drvdata (pdev);
-                       if (!c)
-                               continue;
-                       for(i=0;i<NR_DSPS;i++)
-                       {
-                               sp=&c->channels[i];
-                               if(sp->dev_audio < 0)
-                                       continue;
-                               if((sp->dev_audio ^ minor) & ~0xf)
-                                       continue;
-                               s=sp;
-                       }
-               }
-       }
-       if (!s)
-               return -ENODEV;
-
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EWOULDBLOCK;
-               }
-               mutex_unlock(&s->open_mutex);
-               interruptible_sleep_on(&s->open_wait);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-
-       /* under semaphore.. */
-       if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
-               mutex_unlock(&s->open_mutex);
-               return -ENOMEM;
-       }
-
-       /* we're covered by the open_mutex */
-       if( ! s->card->dsps_open )  {
-               maestro_power(s->card,ACPI_D0);
-               start_bob(s);
-       }
-       s->card->dsps_open++;
-       M_printk("maestro: open, %d bobs now\n",s->card->dsps_open);
-
-       /* ok, lets write WC base regs now that we've 
-               powered up the chip */
-       M_printk("maestro: writing 0x%lx (bus 0x%lx) to the wp\n",virt_to_bus(s->card->dmapages),
-               ((virt_to_bus(s->card->dmapages))&0xFFE00000)>>12);
-       set_base_registers(s,s->card->dmapages);
-
-       if (file->f_mode & FMODE_READ) {
-/*
-               fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */
-
-               fmtm &= ~((ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-               fmts = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT;
-
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               set_adc_rate(s, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               set_dac_rate(s, 8000);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int 
-ess_release(struct inode *inode, struct file *file)
-{
-       struct ess_state *s = (struct ess_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-       }
-               
-       s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-       /* we're covered by the open_mutex */
-       M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
-       if( --s->card->dsps_open <= 0) {
-               s->card->dsps_open = 0;
-               stop_bob(s);
-               free_buffers(s);
-               maestro_power(s->card,ACPI_D2);
-       }
-       mutex_unlock(&s->open_mutex);
-       wake_up(&s->open_wait);
-       unlock_kernel();
-       return 0;
-}
-
-static struct file_operations ess_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = ess_read,
-       .write          = ess_write,
-       .poll           = ess_poll,
-       .ioctl          = ess_ioctl,
-       .mmap           = ess_mmap,
-       .open           = ess_open,
-       .release        = ess_release,
-};
-
-static int
-maestro_config(struct ess_card *card) 
-{
-       struct pci_dev *pcidev = card->pcidev;
-       struct ess_state *ess = &card->channels[0];
-       int apu,iobase  = card->iobase;
-       u16 w;
-       u32 n;
-
-       /* We used to muck around with pci config space that
-        * we had no business messing with.  We don't know enough
-        * about the machine to know which DMA mode is appropriate, 
-        * etc.  We were guessing wrong on some machines and making
-        * them unhappy.  We now trust in the BIOS to do things right,
-        * which almost certainly means a new host of problems will
-        * arise with broken BIOS implementations.  screw 'em. 
-        * We're already intolerant of machines that don't assign
-        * IRQs.
-        */
-       
-       /* do config work at full power */
-       maestro_power(card,ACPI_D0);
-        
-       pci_read_config_word(pcidev, 0x50, &w);
-
-       w&=~(1<<5);                     /* Don't swap left/right (undoc)*/
-       
-       pci_write_config_word(pcidev, 0x50, w);
-       
-       pci_read_config_word(pcidev, 0x52, &w);
-       w&=~(1<<15);            /* Turn off internal clock multiplier */
-       /* XXX how do we know which to use? */
-       w&=~(1<<14);            /* External clock */
-       
-       w|= (1<<7);             /* Hardware volume control on */
-       w|= (1<<6);             /* Debounce off: easier to push the HWV buttons. */
-       w&=~(1<<5);             /* GPIO 4:5 */
-       w|= (1<<4);             /* Disconnect from the CHI.  Enabling this made a dell 7500 work. */
-       w&=~(1<<2);             /* MIDI fix off (undoc) */
-       w&=~(1<<1);             /* reserved, always write 0 */
-       pci_write_config_word(pcidev, 0x52, w);
-       
-       /*
-        *      Legacy mode
-        */
-
-       pci_read_config_word(pcidev, 0x40, &w);
-       w|=(1<<15);     /* legacy decode off */
-       w&=~(1<<14);    /* Disable SIRQ */
-       w&=~(0x1f);     /* disable mpu irq/io, game port, fm, SB */
-        
-       pci_write_config_word(pcidev, 0x40, w);
-
-       /* Set up 978 docking control chip. */
-       pci_read_config_word(pcidev, 0x58, &w);
-       w|=1<<2;        /* Enable 978. */
-       w|=1<<3;        /* Turn on 978 hardware volume control. */
-       w&=~(1<<11);    /* Turn on 978 mixer volume control. */
-       pci_write_config_word(pcidev, 0x58, w);
-       
-       sound_reset(iobase);
-
-       /*
-        *      Ring Bus Setup
-        */
-
-       /* setup usual 0x34 stuff.. 0x36 may be chip specific */
-        outw(0xC090, iobase+0x34); /* direct sound, stereo */
-        udelay(20);
-        outw(0x3000, iobase+0x36); /* direct sound, stereo */
-        udelay(20);
-
-
-       /*
-        *      Reset the CODEC
-        */
-        
-       maestro_ac97_reset(iobase,pcidev);
-       
-       /*
-        *      Ring Bus Setup
-        */
-                
-       n=inl(iobase+0x34);
-       n&=~0xF000;
-       n|=12<<12;              /* Direct Sound, Stereo */
-       outl(n, iobase+0x34);
-
-       n=inl(iobase+0x34);
-       n&=~0x0F00;             /* Modem off */
-       outl(n, iobase+0x34);
-
-       n=inl(iobase+0x34);
-       n&=~0x00F0;
-       n|=9<<4;                /* DAC, Stereo */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x000F;             /* ASSP off */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n|=(1<<29);             /* Enable ring bus */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n|=(1<<28);             /* Enable serial bus */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x00F00000;         /* MIC off */
-       outl(n, iobase+0x34);
-       
-       n=inl(iobase+0x34);
-       n&=~0x000F0000;         /* I2S off */
-       outl(n, iobase+0x34);
-       
-
-       w=inw(iobase+0x18);
-       w&=~(1<<7);             /* ClkRun off */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w&=~(1<<6);             /* Hardware volume control interrupt off... for now. */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w&=~(1<<4);             /* ASSP irq off */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w&=~(1<<3);             /* ISDN irq off */
-       outw(w, iobase+0x18);
-       
-       w=inw(iobase+0x18);
-       w|=(1<<2);              /* Direct Sound IRQ on */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w&=~(1<<1);             /* MPU401 IRQ off */
-       outw(w, iobase+0x18);
-
-       w=inw(iobase+0x18);
-       w|=(1<<0);              /* SB IRQ on */
-       outw(w, iobase+0x18);
-
-       /* Set hardware volume control registers to midpoints.
-          We can tell which button was pushed based on how they change. */
-       outb(0x88, iobase+0x1c);
-       outb(0x88, iobase+0x1d);
-       outb(0x88, iobase+0x1e);
-       outb(0x88, iobase+0x1f);
-
-       /* it appears some maestros (dell 7500) only work if these are set,
-               regardless of whether we use the assp or not. */
-
-       outb(0, iobase+0xA4); 
-       outb(3, iobase+0xA2); 
-       outb(0, iobase+0xA6);
-       
-       for(apu=0;apu<16;apu++)
-       {
-               /* Write 0 into the buffer area 0x1E0->1EF */
-               outw(0x01E0+apu, 0x10+iobase);
-               outw(0x0000, 0x12+iobase);
-       
-               /*
-                * The 1.10 test program seem to write 0 into the buffer area
-                * 0x1D0-0x1DF too.
-                */
-               outw(0x01D0+apu, 0x10+iobase);
-               outw(0x0000, 0x12+iobase);
-       }
-
-#if 1
-       wave_set_register(ess, IDR7_WAVE_ROMRAM, 
-               (wave_get_register(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)|0x100);
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)&~0x200);
-       wave_set_register(ess, IDR7_WAVE_ROMRAM,
-               wave_get_register(ess, IDR7_WAVE_ROMRAM)|~0x400);
-#else          
-       maestro_write(ess, IDR7_WAVE_ROMRAM, 
-               (maestro_read(ess, IDR7_WAVE_ROMRAM)&0xFF00));
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)|0x100);
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)&~0x200);
-       maestro_write(ess, IDR7_WAVE_ROMRAM,
-               maestro_read(ess, IDR7_WAVE_ROMRAM)|0x400);
-#endif
-       
-       maestro_write(ess, IDR2_CRAM_DATA, 0x0000);
-       maestro_write(ess, 0x08, 0xB004);
-       /* Now back to the DirectSound stuff */
-       maestro_write(ess, 0x09, 0x001B);
-       maestro_write(ess, 0x0A, 0x8000);
-       maestro_write(ess, 0x0B, 0x3F37);
-       maestro_write(ess, 0x0C, 0x0098);
-       
-       /* parallel out ?? */
-       maestro_write(ess, 0x0C, 
-               (maestro_read(ess, 0x0C)&~0xF000)|0x8000); 
-       /* parallel in, has something to do with recording :) */
-       maestro_write(ess, 0x0C, 
-               (maestro_read(ess, 0x0C)&~0x0F00)|0x0500);
-
-       maestro_write(ess, 0x0D, 0x7632);
-                       
-       /* Wave cache control on - test off, sg off, 
-               enable, enable extra chans 1Mb */
-
-       outw(inw(0x14+iobase)|(1<<8),0x14+iobase);
-       outw(inw(0x14+iobase)&0xFE03,0x14+iobase);
-       outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase);
-       outw(inw(0x14+iobase)|(1<<7),0x14+iobase);
-
-       outw(0xA1A0, 0x14+iobase);      /* 0300 ? */
-
-       /* Now clear the APU control ram */     
-       for(apu=0;apu<NR_APUS;apu++)
-       {
-               for(w=0;w<NR_APU_REGS;w++)
-                       apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0);
-               
-       }
-
-       return 0;
-       
-}
-
-/* this guy tries to find the pci power management
- * register bank.  this should really be in core
- * code somewhere.  1 on success. */
-static int
-parse_power(struct ess_card *card, struct pci_dev *pcidev)
-{
-       u32 n;
-       u16 w;
-       u8 next;
-       int max = 64;  /* an a 8bit guy pointing to 32bit guys
-                               can only express so much. */
-
-       card->power_regs = 0;
-
-       /* check to see if we have a capabilities list in
-               the config register */
-       pci_read_config_word(pcidev, PCI_STATUS, &w);
-       if(!(w & PCI_STATUS_CAP_LIST)) return 0;
-
-       /* walk the list, starting at the head. */
-       pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next);
-
-       while(next && max--) {
-               pci_read_config_dword(pcidev, next & ~3, &n);
-               if((n & 0xff) == PCI_CAP_ID_PM) {
-                       card->power_regs = next;
-                       break;
-               }
-               next = ((n>>8) & 0xff);
-       }
-
-       return card->power_regs ? 1 : 0;
-}
-
-static int __init
-maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
-{
-       int card_type = pdid->driver_data;
-       u32 n;
-       int iobase;
-       int i, ret;
-       struct ess_card *card;
-       struct ess_state *ess;
-       int num = 0;
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-       static int printed_version;
-       if (!printed_version++)
-               printk(version);
-#endif
-
-       /* don't pick up weird modem maestros */
-       if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-               return -ENODEV;
-
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-                       
-       iobase = pci_resource_start(pcidev,0);
-       if (!iobase || !(pci_resource_flags(pcidev, 0 ) & IORESOURCE_IO))
-               return -ENODEV;
-
-       if(pcidev->irq == 0)
-               return -ENODEV;
-
-       /* stake our claim on the iospace */
-       if( request_region(iobase, 256, card_names[card_type]) == NULL )
-       {
-               printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
-               return -EBUSY;
-       }
-
-       /* just to be sure */
-       pci_set_master(pcidev);
-
-       card = kmalloc(sizeof(struct ess_card), GFP_KERNEL);
-       if(card == NULL)
-       {
-               printk(KERN_WARNING "maestro: out of memory\n");
-               release_region(iobase, 256);
-               return -ENOMEM;
-       }
-       
-       memset(card, 0, sizeof(*card));
-       card->pcidev = pcidev;
-
-       card->iobase = iobase;
-       card->card_type = card_type;
-       card->irq = pcidev->irq;
-       card->magic = ESS_CARD_MAGIC;
-       spin_lock_init(&card->lock);
-       init_waitqueue_head(&card->suspend_queue);
-
-       card->dock_mute_vol = 50;
-       
-       /* init our groups of 6 apus */
-       for(i=0;i<NR_DSPS;i++)
-       {
-               struct ess_state *s=&card->channels[i];
-
-               s->index = i;
-
-               s->card = card;
-               init_waitqueue_head(&s->dma_adc.wait);
-               init_waitqueue_head(&s->dma_dac.wait);
-               init_waitqueue_head(&s->open_wait);
-               spin_lock_init(&s->lock);
-               mutex_init(&s->open_mutex);
-               s->magic = ESS_STATE_MAGIC;
-               
-               s->apu[0] = 6*i;
-               s->apu[1] = (6*i)+1;
-               s->apu[2] = (6*i)+2;
-               s->apu[3] = (6*i)+3;
-               s->apu[4] = (6*i)+4;
-               s->apu[5] = (6*i)+5;
-               
-               if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-                       printk("maestro: BOTCH!\n");
-               /* register devices */
-               if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0)
-                       break;
-       }
-       
-       num = i;
-       
-       /* clear the rest if we ran out of slots to register */
-       for(;i<NR_DSPS;i++)
-       {
-               struct ess_state *s=&card->channels[i];
-               s->dev_audio = -1;
-       }
-       
-       ess = &card->channels[0];
-
-       /*
-        *      Ok card ready. Begin setup proper
-        */
-
-       printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", 
-               card_names[card_type],iobase,card->irq);
-       pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-       printk(KERN_INFO "maestro:  subvendor id: 0x%08x\n",n); 
-
-       /* turn off power management unless:
-        *      - the user explicitly asks for it
-        *              or
-        *              - we're not a 2e, lesser chipps seem to have problems.
-        *              - we're not on our _very_ small whitelist.  some implemenetations
-        *                      really don't like the pm code, others require it.
-        *                      feel free to expand this as required.
-        */
-#define SUBSYSTEM_VENDOR(x) (x&0xffff)
-       if(     (use_pm != 1) && 
-               ((card_type != TYPE_MAESTRO2E)  || (SUBSYSTEM_VENDOR(n) != 0x1028)))
-                       use_pm = 0;
-
-       if(!use_pm) 
-               printk(KERN_INFO "maestro: not attempting power management.\n");
-       else {
-               if(!parse_power(card,pcidev)) 
-                       printk(KERN_INFO "maestro: no PCI power management interface found.\n");
-               else {
-                       pci_read_config_dword(pcidev, card->power_regs, &n);
-                       printk(KERN_INFO "maestro: PCI power management capability: 0x%x\n",n>>16);
-               }       
-       }
-
-       maestro_config(card);
-
-       if(maestro_ac97_get(card, 0x00)==0x0080) {
-               printk(KERN_ERR "maestro: my goodness!  you seem to have a pt101 codec, which is quite rare.\n"
-                               "\tyou should tell someone about this.\n");
-       } else {
-               maestro_ac97_init(card);
-       }
-
-       if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) {
-               printk("maestro: couldn't register mixer!\n");
-       } else {
-               memcpy(card->mix.mixer_state,mixer_defaults,sizeof(card->mix.mixer_state));
-               mixer_push_state(card);
-       }
-       
-       if((ret=request_irq(card->irq, ess_interrupt, IRQF_SHARED, card_names[card_type], card)))
-       {
-               printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq);
-               unregister_sound_mixer(card->dev_mixer);
-               for(i=0;i<NR_DSPS;i++)
-               {
-                       struct ess_state *s = &card->channels[i];
-                       if(s->dev_audio != -1)
-                               unregister_sound_dsp(s->dev_audio);
-               }
-               release_region(card->iobase, 256);              
-               unregister_reboot_notifier(&maestro_nb);
-               kfree(card);
-               return ret;
-       }
-
-       /* Turn on hardware volume control interrupt.
-          This has to come after we grab the IRQ above,
-          or a crash will result on installation if a button has been pressed,
-          because in that case we'll get an immediate interrupt. */
-       n = inw(iobase+0x18);
-       n|=(1<<6);
-       outw(n, iobase+0x18);
-
-       pci_set_drvdata(pcidev,card);
-       /* now go to sleep 'till something interesting happens */
-       maestro_power(card,ACPI_D2);
-
-       printk(KERN_INFO "maestro: %d channels configured.\n", num);
-       return 0;
-}
-
-static void maestro_remove(struct pci_dev *pcidev) {
-       struct ess_card *card = pci_get_drvdata(pcidev);
-       int i;
-       u32 n;
-       
-       /* XXX maybe should force stop bob, but should be all 
-               stopped by _release by now */
-
-       /* Turn off hardware volume control interrupt.
-          This has to come before we leave the IRQ below,
-          or a crash results if a button is pressed ! */
-       n = inw(card->iobase+0x18);
-       n&=~(1<<6);
-       outw(n, card->iobase+0x18);
-
-       free_irq(card->irq, card);
-       unregister_sound_mixer(card->dev_mixer);
-       for(i=0;i<NR_DSPS;i++)
-       {
-               struct ess_state *ess = &card->channels[i];
-               if(ess->dev_audio != -1)
-                       unregister_sound_dsp(ess->dev_audio);
-       }
-       /* Goodbye, Mr. Bond. */
-       maestro_power(card,ACPI_D3);
-       release_region(card->iobase, 256);
-       kfree(card);
-       pci_set_drvdata(pcidev,NULL);
-}
-
-static struct pci_device_id maestro_pci_tbl[] = {
-       {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2},
-       {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2E},
-       {PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO},
-       {0,}
-};
-MODULE_DEVICE_TABLE(pci, maestro_pci_tbl);
-
-static struct pci_driver maestro_pci_driver = {
-       .name     = "maestro",
-       .id_table = maestro_pci_tbl,
-       .probe    = maestro_probe,
-       .remove   = maestro_remove,
-};
-
-static int __init init_maestro(void)
-{
-       int rc;
-
-       rc = pci_register_driver(&maestro_pci_driver);
-       if (rc < 0)
-               return rc;
-
-       if (register_reboot_notifier(&maestro_nb))
-               printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n");
-#ifdef MODULE
-       printk(version);
-#endif
-       if (dsps_order < 0)   {
-               dsps_order = 1;
-               printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-       }
-       else if (dsps_order > MAX_DSP_ORDER)  {
-               dsps_order = MAX_DSP_ORDER;
-               printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
-       }
-       return 0;
-}
-
-static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-       /* this notifier is called when the kernel is really shut down. */
-       M_printk("maestro: shutting down\n");
-       /* this will remove all card instances too */
-       pci_unregister_driver(&maestro_pci_driver);
-       /* XXX dunno about power management */
-       return NOTIFY_OK;
-}
-
-/* --------------------------------------------------------------------- */
-
-
-static void cleanup_maestro(void) {
-       M_printk("maestro: unloading\n");
-       pci_unregister_driver(&maestro_pci_driver);
-       unregister_reboot_notifier(&maestro_nb);
-}
-
-/* --------------------------------------------------------------------- */
-
-void
-check_suspend(struct ess_card *card)
-{
-       DECLARE_WAITQUEUE(wait, current);
-
-       if(!card->in_suspend) return;
-
-       card->in_suspend++;
-       add_wait_queue(&(card->suspend_queue), &wait);
-       current->state = TASK_UNINTERRUPTIBLE;
-       schedule();
-       remove_wait_queue(&(card->suspend_queue), &wait);
-       current->state = TASK_RUNNING;
-}
-
-module_init(init_maestro);
-module_exit(cleanup_maestro);
diff --git a/sound/oss/maestro.h b/sound/oss/maestro.h
deleted file mode 100644 (file)
index 023ec7f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *     Registers for the ESS PCI cards
- */
-/*
- *     Memory access
- */
-#define ESS_MEM_DATA           0x00
-#define        ESS_MEM_INDEX           0x02
-
-/*
- *     AC-97 Codec port. Delay 1uS after each write. This is used to
- *     talk AC-97 (see intel.com). Write data then register.
- */
-#define ESS_AC97_INDEX         0x30            /* byte wide */
-#define ESS_AC97_DATA          0x32
-
-/* 
- *     Reading is a bit different. You write register|0x80 to ubdex
- *     delay 1uS poll the low bit of index, when it clears read the
- *     data value.
- */
-
-/*
- *     Control port. Not yet fully understood
- *     The value 0xC090 gets loaded to it then 0x0000 and 0x2800
- *     to the data port. Then after 4uS the value 0x300 is written
- */
-#define RING_BUS_CTRL_L                0x34
-#define RING_BUS_CTRL_H                0x36
-
-/*
- *     This is also used during setup. The value 0x17 is written to it
- */
-#define ESS_SETUP_18           0x18
-
-/*
- *     And this one gets 0x000b
- */
-#define ESS_SETUP_A2           0xA2
-
-/*
- *     And this 0x0000
- */
-#define ESS_SETUP_A4           0xA4
-#define ESS_SETUP_A6           0xA6
-
-/*
- *     Stuff to do with Harpo - the wave stuff
- */
-#define ESS_WAVETABLE_SIZE     0x14
-#define        ESS_WAVETABLE_2M        0xA180
-
diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c
deleted file mode 100644 (file)
index 5548e3c..0000000
+++ /dev/null
@@ -1,2969 +0,0 @@
-/*****************************************************************************
- *
- *      ESS Maestro3/Allegro driver for Linux 2.4.x
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *    (c) Copyright 2000 Zach Brown <zab@zabbo.net>
- *
- * I need to thank many people for helping make this driver happen.  
- * As always, Eric Brombaugh was a hacking machine and killed many bugs
- * that I was too dumb to notice.  Howard Kim at ESS provided reference boards 
- * and as much docs as he could.  Todd and Mick at Dell tested snapshots on 
- * an army of laptops.  msw and deviant at Red Hat also humoured me by hanging
- * their laptops every few hours in the name of science.
- * 
- * Shouts go out to Mike "DJ XPCom" Ang.
- *
- * History
- *  v1.23 - Jun 5 2002 - Michael Olson <olson@cs.odu.edu>
- *   added a module option to allow selection of GPIO pin number 
- *   for external amp 
- *  v1.22 - Feb 28 2001 - Zach Brown <zab@zabbo.net>
- *   allocate mem at insmod/setup, rather than open
- *   limit pci dma addresses to 28bit, thanks guys.
- *  v1.21 - Feb 04 2001 - Zach Brown <zab@zabbo.net>
- *   fix up really dumb notifier -> suspend oops
- *  v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net>
- *   get rid of pm callback and use pci_dev suspend/resume instead
- *   m3_probe cleanups, including pm oops think-o
- *  v1.10 - Jan 6 2001 - Zach Brown <zab@zabbo.net>
- *   revert to lame remap_page_range mmap() just to make it work
- *   record mmap fixed.
- *   fix up incredibly broken open/release resource management
- *   duh.  fix record format setting.
- *   add SMP locking and cleanup formatting here and there
- *  v1.00 - Dec 16 2000 - Zach Brown <zab@zabbo.net>
- *   port to sexy 2.4 interfaces
- *   properly align instance allocations so recording works
- *   clean up function namespace a little :/
- *   update PCI IDs based on mail from ESS
- *   arbitrarily bump version number to show its 2.4 now, 
- *      2.2 will stay 0., oss_audio port gets 2.
- *  v0.03 - Nov 05 2000 - Zach Brown <zab@zabbo.net>
- *   disable recording but allow dsp to be opened read 
- *   pull out most silly compat defines
- *  v0.02 - Nov 04 2000 - Zach Brown <zab@zabbo.net>
- *   changed clocking setup for m3, slowdown fixed.
- *   codec reset is hopefully reliable now
- *   rudimentary apm/power management makes suspend/resume work
- *  v0.01 - Oct 31 2000 - Zach Brown <zab@zabbo.net>
- *   first release
- *  v0.00 - Sep 09 2000 - Zach Brown <zab@zabbo.net>
- *   first pass derivation from maestro.c
- *
- * TODO
- *  in/out allocated contiguously so fullduplex mmap will work?
- *  no beep on init (mute)
- *  resetup msrc data memory if freq changes?
- *
- *  --
- *
- *  Allow me to ramble a bit about the m3 architecture.  The core of the
- *  chip is the 'assp', the custom ESS dsp that runs the show.  It has
- *  a small amount of code and data ram.  ESS drops binary dsp code images
- *  on our heads, but we don't get to see specs on the dsp.  
- *
- *  The constant piece of code on the dsp is the 'kernel'.  It also has a 
- *  chunk of the dsp memory that is statically set aside for its control
- *  info.  This is the KDATA defines in maestro3.h.  Part of its core
- *  data is a list of code addresses that point to the pieces of DSP code
- *  that it should walk through in its loop.  These other pieces of code
- *  do the real work.  The kernel presumably jumps into each of them in turn.
- *  These code images tend to have their own data area, and one can have
- *  multiple data areas representing different states for each of the 'client
- *  instance' code portions.  There is generally a list in the kernel data
- *  that points to the data instances for a given piece of code.
- *
- *  We've only been given the binary image for the 'minisrc', mini sample 
- *  rate converter.  This is rather annoying because it limits the work
- *  we can do on the dsp, but it also greatly simplifies the job of managing
- *  dsp data memory for the code and data for our playing streams :).  We
- *  statically allocate the minisrc code into a region we 'know' to be free
- *  based on the map of the binary kernel image we're loading.  We also 
- *  statically allocate the data areas for the maximum number of pcm streams
- *  we can be dealing with.  This max is set by the length of the static list
- *  in the kernel data that records the number of minisrc data regions we
- *  can have.  Thats right, all software dsp mixing with static code list
- *  limits.  Rock.
- *
- *  How sound goes in and out is still a relative mystery.  It appears
- *  that the dsp has the ability to get input and output through various
- *  'connections'.  To do IO from or to a connection, you put the address
- *  of the minisrc client area in the static kernel data lists for that 
- *  input or output.  so for pcm -> dsp -> mixer, we put the minisrc data
- *  instance in the DMA list and also in the list for the mixer.  I guess
- *  it Just Knows which is in/out, and we give some dma control info that
- *  helps.  There are all sorts of cool inputs/outputs that it seems we can't
- *  use without dsp code images that know how to use them.
- *
- *  So at init time we preload all the memory allocation stuff and set some
- *  system wide parameters.  When we really get a sound to play we build
- *  up its minisrc header (stream parameters, buffer addresses, input/output
- *  settings).  Then we throw its header on the various lists.  We also
- *  tickle some KDATA settings that ask the assp to raise clock interrupts
- *  and do some amount of software mixing before handing data to the ac97.
- *
- *  Sorry for the vague details.  Feel free to ask Eric or myself if you
- *  happen to be trying to use this driver elsewhere.  Please accept my
- *  apologies for the quality of the OSS support code, its passed through
- *  too many hands now and desperately wants to be rethought.
- */
-
-/*****************************************************************************/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/vmalloc.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/reboot.h>
-#include <linux/spinlock.h>
-#include <linux/ac97_codec.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#include "maestro3.h"
-
-#define M_DEBUG 1
-
-#define DRIVER_VERSION      "1.23"
-#define M3_MODULE_NAME      "maestro3"
-#define PFX                 M3_MODULE_NAME ": "
-
-#define M3_STATE_MAGIC      0x734d724d
-#define M3_CARD_MAGIC       0x646e6f50
-
-#define ESS_FMT_STEREO      0x01
-#define ESS_FMT_16BIT       0x02
-#define ESS_FMT_MASK        0x03
-#define ESS_DAC_SHIFT       0   
-#define ESS_ADC_SHIFT       4
-
-#define DAC_RUNNING         1
-#define ADC_RUNNING         2
-
-#define SND_DEV_DSP16       5 
-   
-#ifdef M_DEBUG
-static int debug;
-#define DPMOD   1   /* per module load */
-#define DPSTR   2   /* per 'stream' */
-#define DPSYS   3   /* per syscall */
-#define DPCRAP  4   /* stuff the user shouldn't see unless they're really debuggin */
-#define DPINT   5   /* per interrupt, LOTS */
-#define DPRINTK(DP, args...) {if (debug >= (DP)) printk(KERN_DEBUG PFX args);}
-#else
-#define DPRINTK(x)
-#endif
-
-struct m3_list {
-    int curlen;
-    u16 mem_addr;
-    int max;
-};
-
-static int external_amp = 1;
-static int gpio_pin = -1;
-
-struct m3_state {
-    unsigned int magic;
-    struct m3_card *card;
-    unsigned char fmt, enable;
-
-    int index;
-
-    /* this locks around the oss state in the driver */
-       /* no, this lock is removed - only use card->lock */
-       /* otherwise: against what are you protecting on SMP 
-               when irqhandler uses s->lock
-               and m3_assp_read uses card->lock ?
-               */
-    struct mutex open_mutex;
-    wait_queue_head_t open_wait;
-    mode_t open_mode;
-
-    int dev_audio;
-
-    struct assp_instance {
-        u16 code, data;
-    } dac_inst, adc_inst;
-
-    /* should be in dmabuf */
-    unsigned int rateadc, ratedac;
-
-    struct dmabuf {
-        void *rawbuf;
-        unsigned buforder;
-        unsigned numfrag;
-        unsigned fragshift;
-        unsigned hwptr, swptr;
-        unsigned total_bytes;
-        int count;
-        unsigned error; /* over/underrun */
-        wait_queue_head_t wait;
-        /* redundant, but makes calculations easier */
-        unsigned fragsize;
-        unsigned dmasize;
-        unsigned fragsamples;
-        /* OSS stuff */
-        unsigned mapped:1;
-        unsigned ready:1;    
-        unsigned endcleared:1;
-        unsigned ossfragshift;
-        int ossmaxfrags;
-        unsigned subdivision;
-        /* new in m3 */
-        int mixer_index, dma_index, msrc_index, adc1_index;
-        int in_lists;
-        /* 2.4.. */
-        dma_addr_t handle;
-
-    } dma_dac, dma_adc;
-};
-    
-struct m3_card {
-    unsigned int magic;
-
-    struct m3_card *next;
-
-    struct ac97_codec *ac97;
-    spinlock_t ac97_lock;
-
-    int card_type;
-
-#define NR_DSPS 1
-#define MAX_DSPS NR_DSPS
-    struct m3_state channels[MAX_DSPS];
-
-    /* this locks around the physical registers on the card */
-    spinlock_t lock;
-
-    /* hardware resources */
-    struct pci_dev *pcidev;
-    u32 iobase;
-    u32 irq;
-
-    int dacs_active;
-
-    int timer_users;
-
-    struct m3_list  msrc_list,
-                    mixer_list,
-                    adc1_list,
-                    dma_list;
-
-    /* for storing reset state..*/
-    u8 reset_state;
-
-    u16 *suspend_mem;
-    int in_suspend;
-    wait_queue_head_t suspend_queue;
-};
-
-/*
- * an arbitrary volume we set the internal
- * volume settings to so that the ac97 volume
- * range is a little less insane.  0x7fff is 
- * max.
- */
-#define ARB_VOLUME ( 0x6800 )
-
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-enum {
-    ESS_ALLEGRO,
-    ESS_MAESTRO3,
-    /*
-     * a maestro3 with 'hardware strapping', only
-     * found inside ESS?
-     */
-    ESS_MAESTRO3HW,
-};
-
-static char *card_names[] = {
-    [ESS_ALLEGRO] = "Allegro",
-    [ESS_MAESTRO3] = "Maestro3(i)",
-    [ESS_MAESTRO3HW] = "Maestro3(i)hw"
-};
-
-#ifndef PCI_VENDOR_ESS
-#define PCI_VENDOR_ESS      0x125D
-#endif
-
-#define M3_DEVICE(DEV, TYPE)                   \
-{                                              \
-.vendor             = PCI_VENDOR_ESS,                  \
-.device             = DEV,                             \
-.subvendor   = PCI_ANY_ID,                     \
-.subdevice   = PCI_ANY_ID,                     \
-.class      = PCI_CLASS_MULTIMEDIA_AUDIO << 8, \
-.class_mask  = 0xffff << 8,                    \
-.driver_data = TYPE,                           \
-}
-
-static struct pci_device_id m3_id_table[] = {
-    M3_DEVICE(0x1988, ESS_ALLEGRO),
-    M3_DEVICE(0x1998, ESS_MAESTRO3),
-    M3_DEVICE(0x199a, ESS_MAESTRO3HW),
-    {0,}
-};
-
-MODULE_DEVICE_TABLE (pci, m3_id_table);
-
-/*
- * reports seem to indicate that the m3 is limited
- * to 28bit bus addresses.  aaaargggh...
- */
-#define M3_PCI_DMA_MASK 0x0fffffff
-
-static unsigned 
-ld2(unsigned int x)
-{
-    unsigned r = 0;
-    
-    if (x >= 0x10000) {
-        x >>= 16;
-        r += 16;
-    }
-    if (x >= 0x100) {
-        x >>= 8;
-        r += 8;
-    }
-    if (x >= 0x10) {
-        x >>= 4;
-        r += 4;
-    }
-    if (x >= 4) {
-        x >>= 2;
-        r += 2;
-    }
-    if (x >= 2)
-        r++;
-    return r;
-}
-
-static struct m3_card *devs;
-
-/*
- * I'm not very good at laying out functions in a file :)
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf);
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static void check_suspend(struct m3_card *card);
-
-static struct notifier_block m3_reboot_nb = {
-       .notifier_call = m3_notifier,
-};
-
-static void m3_outw(struct m3_card *card,
-        u16 value, unsigned long reg)
-{
-    check_suspend(card);
-    outw(value, card->iobase + reg);
-}
-
-static u16 m3_inw(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inw(card->iobase + reg);
-}
-static void m3_outb(struct m3_card *card, 
-        u8 value, unsigned long reg)
-{
-    check_suspend(card);
-    outb(value, card->iobase + reg);
-}
-static u8 m3_inb(struct m3_card *card, unsigned long reg)
-{
-    check_suspend(card);
-    return inb(card->iobase + reg);
-}
-
-/*
- * access 16bit words to the code or data regions of the dsp's memory.
- * index addresses 16bit words.
- */
-static u16 __m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    return m3_inw(card, DSP_PORT_MEMORY_DATA);
-}
-static u16 m3_assp_read(struct m3_card *card, u16 region, u16 index)
-{
-    unsigned long flags;
-    u16 ret;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    ret = __m3_assp_read(card, region, index);
-    spin_unlock_irqrestore(&(card->lock), flags);
-
-    return ret;
-}
-
-static void __m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
-    m3_outw(card, index, DSP_PORT_MEMORY_INDEX);
-    m3_outw(card, data, DSP_PORT_MEMORY_DATA);
-}
-static void m3_assp_write(struct m3_card *card, 
-        u16 region, u16 index, u16 data)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&(card->lock), flags);
-    __m3_assp_write(card, region, index, data);
-    spin_unlock_irqrestore(&(card->lock), flags);
-}
-
-static void m3_assp_halt(struct m3_card *card)
-{
-    card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
-    mdelay(10);
-    m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-static void m3_assp_continue(struct m3_card *card)
-{
-    m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
-}
-
-/*
- * This makes me sad. the maestro3 has lists
- * internally that must be packed.. 0 terminates,
- * apparently, or maybe all unused entries have
- * to be 0, the lists have static lengths set
- * by the binary code images.
- */
-
-static int m3_add_list(struct m3_card *card,
-        struct m3_list *list, u16 val)
-{
-    DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n",
-            val, list, list->curlen);
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + list->curlen,
-            val);
-
-    return list->curlen++;
-
-}
-
-static void m3_remove_list(struct m3_card *card,
-        struct m3_list *list, int index)
-{
-    u16  val;
-    int lastindex = list->curlen - 1;
-
-    DPRINTK(DPSTR, "removing ind %d from list 0x%p\n",
-            index, list);
-
-    if(index != lastindex) {
-        val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + lastindex);
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                list->mem_addr + index,
-                val);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            list->mem_addr + lastindex,
-            0);
-
-    list->curlen--;
-}
-
-static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data)
-{
-    int tmp;
-
-    s->fmt = (s->fmt & mask) | data;
-
-    tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-
-    tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK;
-
-    /* write to 'mono' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1, 
-            (tmp & ESS_FMT_STEREO) ? 0 : 1);
-    /* write to '8bit' word */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2, 
-            (tmp & ESS_FMT_16BIT) ? 0 : 1);
-}
-
-static void set_dac_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->ratedac = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void set_adc_rate(struct m3_state *s, unsigned int rate)
-{
-    u32 freq;
-
-    if (rate > 48000)
-        rate = 48000;
-    if (rate < 8000)
-        rate = 8000;
-
-    s->rateadc = rate;
-
-    freq = ((rate << 15) + 24000 ) / 48000;
-    if(freq) 
-        freq--;
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_FREQUENCY,
-            freq);
-}
-
-static void inc_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-    
-    card->timer_users++;
-    DPRINTK(DPSYS, "inc timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users != 1) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         240 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         240 ) ;
-
-    m3_outw(card,  
-            m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static void dec_timer_users(struct m3_card *card)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&card->lock, flags);
-
-    card->timer_users--;
-    DPRINTK(DPSYS, "dec timer users now %d\n",
-            card->timer_users);
-    if(card->timer_users > 0 ) 
-        goto out;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_RELOAD,
-         0 ) ;
-
-    __m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_TIMER_COUNT_CURRENT,
-         0 ) ;
-
-    m3_outw(card,  m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE,
-            HOST_INT_CTRL);
-out:
-    spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/*
- * {start,stop}_{adc,dac} should be called
- * while holding the 'state' lock and they
- * will try to grab the 'card' lock..
- */
-static void stop_adc(struct m3_state *s)
-{
-    if (! (s->enable & ADC_RUNNING)) 
-        return;
-
-    s->enable &= ~ADC_RUNNING;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 0);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 0);
-}    
-
-static void stop_dac(struct m3_state *s)
-{
-    if (! (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "stop_dac()\n");
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 0);
-
-    s->enable &= ~DAC_RUNNING;
-    s->card->dacs_active--;
-    dec_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_dac(struct m3_state *s)
-{
-    if( (!s->dma_dac.mapped && s->dma_dac.count < 1) ||
-            !s->dma_dac.ready ||
-            (s->enable & DAC_RUNNING)) 
-        return;
-
-    DPRINTK(DPSYS, "start_dac()\n");
-
-    s->enable |= DAC_RUNNING;
-    s->card->dacs_active++;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + CDATA_INSTANCE_READY, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER, 
-            s->card->dacs_active ) ;
-}    
-
-static void start_adc(struct m3_state *s)
-{
-    if ((! s->dma_adc.mapped &&
-                s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-        || !s->dma_adc.ready 
-        || (s->enable & ADC_RUNNING) ) 
-            return;
-
-    DPRINTK(DPSYS, "start_adc()\n");
-
-    s->enable |= ADC_RUNNING;
-    inc_timer_users(s->card);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            KDATA_ADC1_REQUEST, 1);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + CDATA_INSTANCE_READY, 1);
-}    
-
-static struct play_vals {
-    u16 addr, val;
-} pv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 0} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */
-};
-
-
-/* the mode passed should be already shifted and masked */
-static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
-    int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_dac;
-    int i;
-
-    DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->dac_inst.data + 40 + 8);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19,
-        s->dac_inst.code + MINISRC_COEF_LOC);
-
-    /* enable or disable low pass filter? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22,
-        s->ratedac > 45000 ? 0xff : 0 );
-    
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->dac_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->dac_inst.data + pv[i].addr, pv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->mixer_index = m3_add_list(s->card, &s->card->mixer_list, 
-                s->dac_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_dac_rate(s,rate);
-    start_dac(s);
-}
-
-/*
- *    Native record driver 
- */
-static struct rec_vals {
-    u16 addr, val;
-} rv[] = {
-    {CDATA_LEFT_VOLUME, ARB_VOLUME},
-    {CDATA_RIGHT_VOLUME, ARB_VOLUME},
-    {SRC3_DIRECTION_OFFSET, 1} ,
-    /* +1, +2 are stereo/16 bit */
-    {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */
-    {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */
-    {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */
-    {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */
-    {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */
-    {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */
-    {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */
-    {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */
-    {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */
-    {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */
-    {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */
-    {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */
-    {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */
-    {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */
-    {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */
-    {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */
-    {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */
-    {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */
-    {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */
-};
-
-/* again, passed mode is alrady shifted/masked */
-static void m3_rec_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size)
-{
-    int dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2);
-    int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
-    int dsp_in_buffer = s->adc_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2);
-    int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1;
-    struct dmabuf *db = &s->dma_adc;
-    int i;
-
-    DPRINTK(DPSTR, "rec_setup mode=%d rate=%d buf=%p len=%d.\n",
-        mode, rate, buffer, size);
-
-#define LO(x) ((x) & 0xffff)
-#define HI(x) LO((x) >> 16)
-
-    /* host dma buffer pointers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_ADDRH,
-        HI(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1L,
-        LO(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1H,
-        HI(virt_to_bus(buffer) + size));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTL,
-        LO(virt_to_bus(buffer)));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_HOST_SRC_CURRENTH,
-        HI(virt_to_bus(buffer)));
-#undef LO
-#undef HI
-
-    /* dsp buffers */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_BEGIN,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_END_PLUS_1,
-        dsp_in_buffer + (dsp_in_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_HEAD,
-        dsp_in_buffer);
-    
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_IN_BUF_TAIL,
-        dsp_in_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_BEGIN,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_END_PLUS_1,
-        dsp_out_buffer + (dsp_out_size / 2));
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_HEAD,
-        dsp_out_buffer);
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_OUT_BUF_TAIL,
-        dsp_out_buffer);
-
-    /*
-     * some per client initializers
-     */
-
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + SRC3_DIRECTION_OFFSET + 12,
-        s->adc_inst.data + 40 + 8);
-
-    /* tell it which way dma is going? */
-    m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-        s->adc_inst.data + CDATA_DMA_CONTROL,
-        DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT + 
-        DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
-
-    /*
-     * set an armload of static initializers
-     */
-    for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) 
-        m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA,
-            s->adc_inst.data + rv[i].addr, rv[i].val);
-
-    /* 
-     * put us in the lists if we're not already there
-     */
-
-    if(db->in_lists == 0) {
-
-        db->adc1_index = m3_add_list(s->card, &s->card->adc1_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->dma_index = m3_add_list(s->card, &s->card->dma_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, 
-                s->adc_inst.data >> DP_SHIFT_COUNT);
-
-        db->in_lists = 1;
-    }
-
-    set_adc_rate(s,rate);
-    start_adc(s);
-}
-/* --------------------------------------------------------------------- */
-
-static void set_dmaa(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmaa??\n");
-}
-
-static void set_dmac(struct m3_state *s, unsigned int addr, unsigned int count)
-{
-    DPRINTK(DPINT,"set_dmac??\n");
-}
-
-static u32 get_dma_pos(struct m3_card *card,
-                      int instance_addr)
-{
-    u16 hi = 0, lo = 0;
-    int retry = 10;
-
-    /*
-     * try and get a valid answer
-     */
-    while(retry--) {
-        hi =  m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH);
-
-        lo = m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTL);
-
-        if(hi == m3_assp_read(card, MEMTYPE_INTERNAL_DATA,
-                instance_addr + CDATA_HOST_SRC_CURRENTH))
-            break;
-    }
-    return lo | (hi<<16);
-}
-
-static u32 get_dmaa(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->dac_inst.data) - 
-        virt_to_bus(s->dma_dac.rawbuf);
-
-    DPRINTK(DPINT,"get_dmaa: 0x%08x\n",offset);
-
-    return offset;
-}
-
-static u32 get_dmac(struct m3_state *s)
-{
-    u32 offset;
-
-    offset = get_dma_pos(s->card, s->adc_inst.data) -
-        virt_to_bus(s->dma_adc.rawbuf);
-
-    DPRINTK(DPINT,"get_dmac: 0x%08x\n",offset);
-
-    return offset;
-
-}
-
-static int 
-prog_dmabuf(struct m3_state *s, unsigned rec)
-{
-    struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-    unsigned rate = rec ? s->rateadc : s->ratedac;
-    unsigned bytepersec;
-    unsigned bufs;
-    unsigned char fmt;
-    unsigned long flags;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    fmt = s->fmt;
-    if (rec) {
-        stop_adc(s);
-        fmt >>= ESS_ADC_SHIFT;
-    } else {
-        stop_dac(s);
-        fmt >>= ESS_DAC_SHIFT;
-    }
-    fmt &= ESS_FMT_MASK;
-
-    db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-
-    bytepersec = rate << sample_shift[fmt];
-    bufs = PAGE_SIZE << db->buforder;
-    if (db->ossfragshift) {
-        if ((1000 << db->ossfragshift) < bytepersec)
-            db->fragshift = ld2(bytepersec/1000);
-        else
-            db->fragshift = db->ossfragshift;
-    } else {
-        db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-        if (db->fragshift < 3)
-            db->fragshift = 3; 
-    }
-    db->numfrag = bufs >> db->fragshift;
-    while (db->numfrag < 4 && db->fragshift > 3) {
-        db->fragshift--;
-        db->numfrag = bufs >> db->fragshift;
-    }
-    db->fragsize = 1 << db->fragshift;
-    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-        db->numfrag = db->ossmaxfrags;
-    db->fragsamples = db->fragsize >> sample_shift[fmt];
-    db->dmasize = db->numfrag << db->fragshift;
-
-    DPRINTK(DPSTR,"prog_dmabuf: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize);
-
-    memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize);
-
-    if (rec) 
-        m3_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize);
-    else 
-        m3_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize);
-
-    db->ready = 1;
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-
-    return 0;
-}
-
-static void clear_advance(struct m3_state *s)
-{
-    unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
-    
-    unsigned char *buf = s->dma_dac.rawbuf;
-    unsigned bsize = s->dma_dac.dmasize;
-    unsigned bptr = s->dma_dac.swptr;
-    unsigned len = s->dma_dac.fragsize;
-    
-    if (bptr + len > bsize) {
-        unsigned x = bsize - bptr;
-        memset(buf + bptr, c, x);
-        /* account for wrapping? */
-        bptr = 0;
-        len -= x;
-    }
-    memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void m3_update_ptr(struct m3_state *s)
-{
-    unsigned hwptr;
-    int diff;
-
-    /* update ADC pointer */
-    if (s->dma_adc.ready) {
-        hwptr = get_dmac(s) % s->dma_adc.dmasize;
-        diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-        s->dma_adc.hwptr = hwptr;
-        s->dma_adc.total_bytes += diff;
-        s->dma_adc.count += diff;
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-            wake_up(&s->dma_adc.wait);
-        if (!s->dma_adc.mapped) {
-            if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                stop_adc(s); 
-                /* brute force everyone back in sync, sigh */
-                s->dma_adc.count = 0;
-                s->dma_adc.swptr = 0;
-                s->dma_adc.hwptr = 0;
-                s->dma_adc.error++;
-            }
-        }
-    }
-    /* update DAC pointer */
-    if (s->dma_dac.ready) {
-        hwptr = get_dmaa(s) % s->dma_dac.dmasize; 
-        diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-
-        DPRINTK(DPINT,"updating dac: hwptr: %6d diff: %6d count: %6d\n",
-                hwptr,diff,s->dma_dac.count);
-
-        s->dma_dac.hwptr = hwptr;
-        s->dma_dac.total_bytes += diff;
-
-        if (s->dma_dac.mapped) {
-            
-            s->dma_dac.count += diff;
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) {
-                wake_up(&s->dma_dac.wait);
-            }
-        } else {
-
-            s->dma_dac.count -= diff;
-            
-            if (s->dma_dac.count <= 0) {
-                DPRINTK(DPCRAP,"underflow! diff: %d (0x%x) count: %d (0x%x) hw: %d (0x%x) sw: %d (0x%x)\n", 
-                        diff, diff, 
-                        s->dma_dac.count, 
-                        s->dma_dac.count, 
-                    hwptr, hwptr,
-                    s->dma_dac.swptr,
-                    s->dma_dac.swptr);
-                stop_dac(s);
-                /* brute force everyone back in sync, sigh */
-                s->dma_dac.count = 0; 
-                s->dma_dac.swptr = hwptr; 
-                s->dma_dac.error++;
-            } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                clear_advance(s);
-                s->dma_dac.endcleared = 1;
-            }
-            if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) {
-                wake_up(&s->dma_dac.wait);
-                DPRINTK(DPINT,"waking up DAC count: %d sw: %d hw: %d\n",
-                        s->dma_dac.count, s->dma_dac.swptr, hwptr);
-            }
-        }
-    }
-}
-
-static irqreturn_t m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-    struct m3_card *c = (struct m3_card *)dev_id;
-    struct m3_state *s = &c->channels[0];
-    u8 status;
-
-    status = inb(c->iobase+0x1A);
-
-    if(status == 0xff)
-       return IRQ_NONE;
-   
-    /* presumably acking the ints? */
-    outw(status, c->iobase+0x1A); 
-
-    if(c->in_suspend)
-        return IRQ_HANDLED;
-
-    /*
-     * ack an assp int if its running
-     * and has an int pending
-     */
-    if( status & ASSP_INT_PENDING) {
-        u8 ctl = inb(c->iobase + ASSP_CONTROL_B);
-        if( !(ctl & STOP_ASSP_CLOCK)) {
-            ctl = inb(c->iobase + ASSP_HOST_INT_STATUS );
-            if(ctl & DSP2HOST_REQ_TIMER) {
-                outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS);
-                /* update adc/dac info if it was a timer int */
-                spin_lock(&c->lock);
-                m3_update_ptr(s);
-                spin_unlock(&c->lock);
-            }
-        }
-    }
-
-    /* XXX is this needed? */
-    if(status & 0x40) 
-        outb(0x40, c->iobase+0x1A);
-    return IRQ_HANDLED;
-}
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value in %s\n";
-
-#define VALIDATE_MAGIC(FOO,MAG)                         \
-({                                                \
-    if (!(FOO) || (FOO)->magic != MAG) { \
-        printk(invalid_magic,__FUNCTION__);            \
-        return -ENXIO;                    \
-    }                                         \
-})
-
-#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,M3_STATE_MAGIC)
-#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,M3_CARD_MAGIC)
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct m3_state *s, int nonblock)
-{
-    DECLARE_WAITQUEUE(wait,current);
-    unsigned long flags;
-    int count;
-    signed long tmo;
-
-    if (s->dma_dac.mapped || !s->dma_dac.ready)
-        return 0;
-    set_current_state(TASK_INTERRUPTIBLE);
-    add_wait_queue(&s->dma_dac.wait, &wait);
-    for (;;) {
-        spin_lock_irqsave(&s->card->lock, flags);
-        count = s->dma_dac.count;
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (count <= 0)
-            break;
-        if (signal_pending(current))
-            break;
-        if (nonblock) {
-            remove_wait_queue(&s->dma_dac.wait, &wait);
-            set_current_state(TASK_RUNNING);
-            return -EBUSY;
-        }
-        tmo = (count * HZ) / s->ratedac;
-        tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK];
-        /* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
-            or something.  who cares. - zach */
-        if (!schedule_timeout(tmo ? tmo : 1) && tmo)
-            DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies);
-    }
-    remove_wait_queue(&s->dma_dac.wait, &wait);
-    set_current_state(TASK_RUNNING);
-    if (signal_pending(current))
-            return -ERESTARTSYS;
-    return 0;
-}
-
-static ssize_t m3_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_adc.mapped)
-        return -ENXIO;
-    if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-        return ret;
-    if (!access_ok(VERIFY_WRITE, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        swptr = s->dma_adc.swptr;
-        cnt = s->dma_adc.dmasize-swptr;
-        if (s->dma_adc.count < cnt)
-            cnt = s->dma_adc.count;
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_adc(s);
-            if (file->f_flags & O_NONBLOCK) 
-            {
-                ret = ret ? ret : -EAGAIN;
-                goto out;
-            }
-
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-
-            if(timed_out) {
-                printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                       s->dma_adc.hwptr, s->dma_adc.swptr);
-                stop_adc(s);
-                set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-            }
-            if (signal_pending(current)) 
-            {
-                ret = ret ? ret : -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-    
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-            ret = ret ? ret : -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        swptr = (swptr + cnt) % s->dma_adc.dmasize;
-        s->dma_adc.swptr = swptr;
-        s->dma_adc.count -= cnt;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_adc(s);
-    }
-
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static ssize_t m3_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    ssize_t ret;
-    unsigned long flags;
-    unsigned swptr;
-    int cnt;
-    
-    VALIDATE_STATE(s);
-    if (s->dma_dac.mapped)
-        return -ENXIO;
-    if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-        return ret;
-    if (!access_ok(VERIFY_READ, buffer, count))
-        return -EFAULT;
-    ret = 0;
-
-    spin_lock_irqsave(&s->card->lock, flags);
-
-    while (count > 0) {
-        int timed_out;
-
-        if (s->dma_dac.count < 0) {
-            s->dma_dac.count = 0;
-            s->dma_dac.swptr = s->dma_dac.hwptr;
-        }
-        swptr = s->dma_dac.swptr;
-
-        cnt = s->dma_dac.dmasize-swptr;
-
-        if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-            cnt = s->dma_dac.dmasize - s->dma_dac.count;
-
-
-        if (cnt > count)
-            cnt = count;
-
-        if (cnt <= 0) {
-            start_dac(s);
-            if (file->f_flags & O_NONBLOCK) {
-                if(!ret) ret = -EAGAIN;
-                goto out;
-            }
-            spin_unlock_irqrestore(&s->card->lock, flags);
-            timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0;
-            spin_lock_irqsave(&s->card->lock, flags);
-            if(timed_out) {
-                DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n",
-                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                       s->dma_dac.hwptr, s->dma_dac.swptr);
-                stop_dac(s);
-                set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-            }
-            if (signal_pending(current)) {
-                if (!ret) ret = -ERESTARTSYS;
-                goto out;
-            }
-            continue;
-        }
-        spin_unlock_irqrestore(&s->card->lock, flags);
-        if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-            if (!ret) ret = -EFAULT;
-            return ret;
-        }
-        spin_lock_irqsave(&s->card->lock, flags);
-
-        DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n",
-                cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);
-        
-        swptr = (swptr + cnt) % s->dma_dac.dmasize;
-
-        s->dma_dac.swptr = swptr;
-        s->dma_dac.count += cnt;
-        s->dma_dac.endcleared = 0;
-        count -= cnt;
-        buffer += cnt;
-        ret += cnt;
-        start_dac(s);
-    }
-out:
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return ret;
-}
-
-static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long flags;
-    unsigned int mask = 0;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        poll_wait(file, &s->dma_dac.wait, wait);
-    if (file->f_mode & FMODE_READ)
-        poll_wait(file, &s->dma_adc.wait, wait);
-
-    spin_lock_irqsave(&s->card->lock, flags);
-    m3_update_ptr(s);
-
-    if (file->f_mode & FMODE_READ) {
-        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-            mask |= POLLIN | POLLRDNORM;
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        if (s->dma_dac.mapped) {
-            if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                mask |= POLLOUT | POLLWRNORM;
-        } else {
-            if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                mask |= POLLOUT | POLLWRNORM;
-        }
-    }
-
-    spin_unlock_irqrestore(&s->card->lock, flags);
-    return mask;
-}
-
-static int m3_mmap(struct file *file, struct vm_area_struct *vma)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-    unsigned long max_size, size, start, offset;
-    struct dmabuf *db;
-    int ret = -EINVAL;
-
-    VALIDATE_STATE(s);
-    if (vma->vm_flags & VM_WRITE) {
-        if ((ret = prog_dmabuf(s, 0)) != 0)
-            return ret;
-        db = &s->dma_dac;
-    } else 
-    if (vma->vm_flags & VM_READ) {
-        if ((ret = prog_dmabuf(s, 1)) != 0)
-            return ret;
-        db = &s->dma_adc;
-    } else  
-        return -EINVAL;
-
-    max_size = db->dmasize;
-
-    start = vma->vm_start;
-    offset = (vma->vm_pgoff << PAGE_SHIFT);
-    size = vma->vm_end - vma->vm_start;
-
-    if(size > max_size)
-        goto out;
-    if(offset > max_size - size)
-        goto out;
-
-    /*
-     * this will be ->nopage() once I can 
-     * ask Jeff what the hell I'm doing wrong.
-     */
-    ret = -EAGAIN;
-    if (remap_pfn_range(vma, vma->vm_start,
-                       virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                       size, vma->vm_page_prot))
-        goto out;
-
-    db->mapped = 1;
-    ret = 0;
-
-out:
-    return ret;
-}
-
-/*
- * this function is a disaster..
- */
-#define get_user_ret(x, ptr,  ret) ({ if(get_user(x, ptr)) return ret; })
-static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-       struct m3_card *card=s->card;
-    unsigned long flags;
-    audio_buf_info abinfo;
-    count_info cinfo;
-    int val, mapped, ret;
-    unsigned char fmtm, fmtd;
-    void __user *argp = (void __user *)arg;
-    int __user *p = argp;
-
-    VALIDATE_STATE(s);
-
-    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-        ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-
-    DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd);
-
-    switch (cmd) {
-    case OSS_GETVERSION:
-        return put_user(SOUND_VERSION, p);
-
-    case SNDCTL_DSP_SYNC:
-        if (file->f_mode & FMODE_WRITE)
-            return drain_dac(s, file->f_flags & O_NONBLOCK);
-        return 0;
-        
-    case SNDCTL_DSP_SETDUPLEX:
-        /* XXX fix */
-        return 0;
-
-    case SNDCTL_DSP_GETCAPS:
-        return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-        
-    case SNDCTL_DSP_RESET:
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-        }
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            synchronize_irq(s->card->pcidev->irq);
-            s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SPEED:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val >= 0) {
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                set_adc_rate(s, val);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                set_dac_rate(s, val);
-            }
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-        
-    case SNDCTL_DSP_STEREO:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        fmtd = 0;
-        fmtm = ~0;
-        if (file->f_mode & FMODE_READ) {
-            stop_adc(s);
-            s->dma_adc.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            stop_dac(s);
-            s->dma_dac.ready = 0;
-            if (val)
-                fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-            else
-                fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-        }
-        set_fmt(s, fmtm, fmtd);
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_CHANNELS:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != 0) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val >= 2)
-                    fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-        
-    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-        return put_user(AFMT_U8|AFMT_S16_LE, p);
-        
-    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (val != AFMT_QUERY) {
-            fmtd = 0;
-            fmtm = ~0;
-            if (file->f_mode & FMODE_READ) {
-                stop_adc(s);
-                s->dma_adc.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT);
-            }
-            if (file->f_mode & FMODE_WRITE) {
-                stop_dac(s);
-                s->dma_dac.ready = 0;
-                if (val == AFMT_S16_LE)
-                    fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-                else
-                    fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT);
-            }
-            set_fmt(s, fmtm, fmtd);
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
-            (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-            : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 
-                AFMT_S16_LE : 
-                AFMT_U8, 
-            p);
-        
-    case SNDCTL_DSP_POST:
-        return 0;
-
-    case SNDCTL_DSP_GETTRIGGER:
-        val = 0;
-        if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING))
-            val |= PCM_ENABLE_INPUT;
-        if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) 
-            val |= PCM_ENABLE_OUTPUT;
-        return put_user(val, p);
-        
-    case SNDCTL_DSP_SETTRIGGER:
-        get_user_ret(val, p, -EFAULT);
-        if (file->f_mode & FMODE_READ) {
-            if (val & PCM_ENABLE_INPUT) {
-                if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                    return ret;
-                start_adc(s);
-            } else
-                stop_adc(s);
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            if (val & PCM_ENABLE_OUTPUT) {
-                if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                    return ret;
-                start_dac(s);
-            } else
-                stop_dac(s);
-        }
-        return 0;
-
-    case SNDCTL_DSP_GETOSPACE:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_dac.fragsize;
-        abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
-        abinfo.fragstotal = s->dma_dac.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-    case SNDCTL_DSP_GETISPACE:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0)
-            return val;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        abinfo.fragsize = s->dma_adc.fragsize;
-        abinfo.bytes = s->dma_adc.count;
-        abinfo.fragstotal = s->dma_adc.numfrag;
-        abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-        spin_unlock_irqrestore(&card->lock, flags);
-        return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-        
-    case SNDCTL_DSP_NONBLOCK:
-        file->f_flags |= O_NONBLOCK;
-        return 0;
-
-    case SNDCTL_DSP_GETODELAY:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        val = s->dma_dac.count;
-        spin_unlock_irqrestore(&card->lock, flags);
-        return put_user(val, p);
-
-    case SNDCTL_DSP_GETIPTR:
-        if (!(file->f_mode & FMODE_READ))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_adc.total_bytes;
-        cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
-        cinfo.ptr = s->dma_adc.hwptr;
-        if (s->dma_adc.mapped)
-            s->dma_adc.count &= s->dma_adc.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-               return -EFAULT;
-       return 0;
-
-    case SNDCTL_DSP_GETOPTR:
-        if (!(file->f_mode & FMODE_WRITE))
-            return -EINVAL;
-        spin_lock_irqsave(&card->lock, flags);
-        m3_update_ptr(s);
-        cinfo.bytes = s->dma_dac.total_bytes;
-        cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
-        cinfo.ptr = s->dma_dac.hwptr;
-        if (s->dma_dac.mapped)
-            s->dma_dac.count &= s->dma_dac.fragsize-1;
-        spin_unlock_irqrestore(&card->lock, flags);
-       if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-               return -EFAULT;
-       return 0;
-
-    case SNDCTL_DSP_GETBLKSIZE:
-        if (file->f_mode & FMODE_WRITE) {
-            if ((val = prog_dmabuf(s, 0)))
-                return val;
-            return put_user(s->dma_dac.fragsize, p);
-        }
-        if ((val = prog_dmabuf(s, 1)))
-            return val;
-        return put_user(s->dma_adc.fragsize, p);
-
-    case SNDCTL_DSP_SETFRAGMENT:
-        get_user_ret(val, p, -EFAULT);
-        spin_lock_irqsave(&card->lock, flags);
-        if (file->f_mode & FMODE_READ) {
-            s->dma_adc.ossfragshift = val & 0xffff;
-            s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_adc.ossfragshift < 4)
-                s->dma_adc.ossfragshift = 4;
-            if (s->dma_adc.ossfragshift > 15)
-                s->dma_adc.ossfragshift = 15;
-            if (s->dma_adc.ossmaxfrags < 4)
-                s->dma_adc.ossmaxfrags = 4;
-        }
-        if (file->f_mode & FMODE_WRITE) {
-            s->dma_dac.ossfragshift = val & 0xffff;
-            s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-            if (s->dma_dac.ossfragshift < 4)
-                s->dma_dac.ossfragshift = 4;
-            if (s->dma_dac.ossfragshift > 15)
-                s->dma_dac.ossfragshift = 15;
-            if (s->dma_dac.ossmaxfrags < 4)
-                s->dma_dac.ossmaxfrags = 4;
-        }
-        spin_unlock_irqrestore(&card->lock, flags);
-        return 0;
-
-    case SNDCTL_DSP_SUBDIVIDE:
-        if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-            (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-            return -EINVAL;
-                get_user_ret(val, p, -EFAULT);
-        if (val != 1 && val != 2 && val != 4)
-            return -EINVAL;
-        if (file->f_mode & FMODE_READ)
-            s->dma_adc.subdivision = val;
-        if (file->f_mode & FMODE_WRITE)
-            s->dma_dac.subdivision = val;
-        return 0;
-
-    case SOUND_PCM_READ_RATE:
-        return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-    case SOUND_PCM_READ_CHANNELS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p);
-
-    case SOUND_PCM_READ_BITS:
-        return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) 
-                       : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p);
-
-    case SOUND_PCM_WRITE_FILTER:
-    case SNDCTL_DSP_SETSYNCRO:
-    case SOUND_PCM_READ_FILTER:
-        return -EINVAL;
-        
-    }
-    return -EINVAL;
-}
-
-static int
-allocate_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    int order;
-
-    DPRINTK(DPSTR,"allocating for dmabuf %p\n", db);
-
-    /* 
-     * alloc as big a chunk as we can, start with 
-     * 64k 'cause we're insane.  based on order cause
-     * the amazingly complicated prog_dmabuf wants it.
-     *
-     * pci_alloc_sonsistent guarantees that it won't cross a natural
-     * boundary; the m3 hardware can't have dma cross a 64k bus
-     * address boundary.
-     */
-    for (order = 16-PAGE_SHIFT; order >= 1; order--) {
-        db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order,
-                        &(db->handle));
-        if(db->rawbuf)
-            break;
-    }
-
-    if (!db->rawbuf)
-        return 1;
-
-    DPRINTK(DPSTR,"allocated %ld (%d) bytes at %p\n",
-            PAGE_SIZE<<order, order, db->rawbuf);
-
-    {
-        struct page *page, *pend;
-
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << order) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            SetPageReserved(page);
-    }
-
-
-    db->buforder = order;
-    db->ready = 0;
-    db->mapped = 0;
-
-    return 0;
-}
-
-static void
-nuke_lists(struct m3_card *card, struct dmabuf *db)
-{
-    m3_remove_list(card, &(card->dma_list), db->dma_index);
-    m3_remove_list(card, &(card->msrc_list), db->msrc_index);
-    db->in_lists = 0;
-}
-
-static void
-free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db)
-{
-    if(db->rawbuf == NULL)
-        return;
-
-    DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db);
-
-    {
-        struct page *page, *pend;
-        pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-        for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-            ClearPageReserved(page);
-    }
-
-
-    pci_free_consistent(pci_dev, PAGE_SIZE << db->buforder,
-            db->rawbuf, db->handle);
-
-    db->rawbuf = NULL;
-    db->buforder = 0;
-    db->mapped = 0;
-    db->ready = 0;
-}
-
-static int m3_open(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *c;
-    struct m3_state *s = NULL;
-    int i;
-    unsigned char fmtm = ~0, fmts = 0;
-    unsigned long flags;
-
-    /*
-     *    Scan the cards and find the channel. We only
-     *    do this at open time so it is ok
-     */
-    for(c = devs ; c != NULL ; c = c->next) {
-
-        for(i=0;i<NR_DSPS;i++) {
-
-            if(c->channels[i].dev_audio < 0)
-                continue;
-            if((c->channels[i].dev_audio ^ minor) & ~0xf)
-                continue;
-
-            s = &c->channels[i];
-            break;
-        }
-    }
-        
-    if (!s)
-        return -ENODEV;
-        
-    VALIDATE_STATE(s);
-
-    file->private_data = s;
-
-    /* wait for device to become free */
-    mutex_lock(&s->open_mutex);
-    while (s->open_mode & file->f_mode) {
-        if (file->f_flags & O_NONBLOCK) {
-            mutex_unlock(&s->open_mutex);
-            return -EWOULDBLOCK;
-        }
-        mutex_unlock(&s->open_mutex);
-        interruptible_sleep_on(&s->open_wait);
-        if (signal_pending(current))
-            return -ERESTARTSYS;
-        mutex_lock(&s->open_mutex);
-    }
-    
-    spin_lock_irqsave(&c->lock, flags);
-
-    if (file->f_mode & FMODE_READ) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; 
-
-        s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-        set_adc_rate(s, 8000);
-    }
-    if (file->f_mode & FMODE_WRITE) {
-        fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT);
-        if ((minor & 0xf) == SND_DEV_DSP16)
-            fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT;
-
-        s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-        set_dac_rate(s, 8000);
-    }
-    set_fmt(s, fmtm, fmts);
-    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-
-    mutex_unlock(&s->open_mutex);
-    spin_unlock_irqrestore(&c->lock, flags);
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release(struct inode *inode, struct file *file)
-{
-    struct m3_state *s = (struct m3_state *)file->private_data;
-       struct m3_card *card=s->card;
-    unsigned long flags;
-
-    VALIDATE_STATE(s);
-    if (file->f_mode & FMODE_WRITE)
-        drain_dac(s, file->f_flags & O_NONBLOCK);
-
-    mutex_lock(&s->open_mutex);
-    spin_lock_irqsave(&card->lock, flags);
-
-    if (file->f_mode & FMODE_WRITE) {
-        stop_dac(s);
-        if(s->dma_dac.in_lists) {
-            m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index);
-            nuke_lists(s->card, &(s->dma_dac));
-        }
-    }
-    if (file->f_mode & FMODE_READ) {
-        stop_adc(s);
-        if(s->dma_adc.in_lists) {
-            m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index);
-            nuke_lists(s->card, &(s->dma_adc));
-        }
-    }
-        
-    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-    spin_unlock_irqrestore(&card->lock, flags);
-    mutex_unlock(&s->open_mutex);
-    wake_up(&s->open_wait);
-
-    return 0;
-}
-
-/*
- * Wait for the ac97 serial bus to be free.
- * return nonzero if the bus is still busy.
- */
-static int m3_ac97_wait(struct m3_card *card)
-{
-    int i = 10000;
-
-    while( (m3_inb(card, 0x30) & 1) && i--) ;
-
-    return i == 0;
-}
-
-static u16 m3_ac97_read(struct ac97_codec *codec, u8 reg)
-{
-    u16 ret = 0;
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy reading reg 0x%x\n",reg);
-        goto out;
-    }
-
-    m3_outb(card, 0x80 | (reg & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy finishing read reg 0x%x\n",reg);
-        goto out;
-    }
-
-    ret =  m3_inw(card, 0x32);
-    DPRINTK(DPCRAP,"reading 0x%04x from 0x%02x\n",ret, reg);
-
-out:
-    spin_unlock(&card->ac97_lock);
-    return ret;
-}
-
-static void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
-{
-    struct m3_card *card = codec->private_data;
-
-    spin_lock(&card->ac97_lock);
-
-    if(m3_ac97_wait(card)) {
-        printk(KERN_ERR PFX "serial bus busy writing 0x%x to 0x%x\n",val, reg);
-        goto out;
-    }
-    DPRINTK(DPCRAP,"writing 0x%04x  to  0x%02x\n", val, reg);
-
-    m3_outw(card, val, 0x32);
-    m3_outb(card, reg & 0x7f, 0x30);
-out:
-    spin_unlock(&card->ac97_lock);
-}
-/* OSS /dev/mixer file operation methods */
-static int m3_open_mixdev(struct inode *inode, struct file *file)
-{
-    unsigned int minor = iminor(inode);
-    struct m3_card *card = devs;
-
-    for (card = devs; card != NULL; card = card->next) {
-        if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor))
-                break;
-    }
-
-    if (!card) {
-        return -ENODEV;
-    }
-
-    file->private_data = card->ac97;
-
-    return nonseekable_open(inode, file);
-}
-
-static int m3_release_mixdev(struct inode *inode, struct file *file)
-{
-    return 0;
-}
-
-static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
-                                    unsigned long arg)
-{
-    struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-    return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static struct file_operations m3_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .ioctl   = m3_ioctl_mixdev,
-       .open    = m3_open_mixdev,
-       .release = m3_release_mixdev,
-};
-
-static void remote_codec_config(int io, int isremote)
-{
-    isremote = isremote ? 1 : 0;
-
-    outw(  (inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote,
-            io + RING_BUS_CTRL_B);
-    outw(  (inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote,
-            io + SDO_OUT_DEST_CTRL);
-    outw(  (inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote,
-            io + SDO_IN_DEST_CTRL);
-}
-
-/* 
- * hack, returns non zero on err 
- */
-static int try_read_vendor(struct m3_card *card)
-{
-    u16 ret;
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    m3_outb(card, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30);
-
-    if(m3_ac97_wait(card)) 
-        return 1;
-
-    ret =  m3_inw(card, 0x32);
-
-    return (ret == 0) || (ret == 0xffff);
-}
-
-static void m3_codec_reset(struct m3_card *card, int busywait)
-{
-    u16 dir;
-    int delay1 = 0, delay2 = 0, i;
-    int io = card->iobase;
-
-    switch (card->card_type) {
-        /*
-         * the onboard codec on the allegro seems 
-         * to want to wait a very long time before
-         * coming back to life 
-         */
-        case ESS_ALLEGRO:
-            delay1 = 50;
-            delay2 = 800;
-        break;
-        case ESS_MAESTRO3:
-        case ESS_MAESTRO3HW:
-            delay1 = 20;
-            delay2 = 500;
-        break;
-    }
-
-    for(i = 0; i < 5; i ++) {
-        dir = inw(io + GPIO_DIRECTION);
-        dir |= 0x10; /* assuming pci bus master? */
-
-        remote_codec_config(io, 0);
-
-        outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A);
-        udelay(20);
-
-        outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION);
-        outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK);
-        outw(0, io + GPIO_DATA);
-        outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
-
-        if(busywait)  {
-            mdelay(delay1);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay1 * HZ) / 1000);
-        }
-
-        outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
-        udelay(5);
-        /* ok, bring back the ac-link */
-        outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
-        outw(~0, io + GPIO_MASK);
-
-        if(busywait) {
-            mdelay(delay2);
-        } else {
-            set_current_state(TASK_UNINTERRUPTIBLE);
-            schedule_timeout((delay2 * HZ) / 1000);
-        }
-        if(! try_read_vendor(card))
-            break;
-
-        delay1 += 10;
-        delay2 += 100;
-
-        DPRINTK(DPMOD, "retrying codec reset with delays of %d and %d ms\n",
-                delay1, delay2);
-    }
-
-#if 0
-    /* more gung-ho reset that doesn't
-     * seem to work anywhere :)
-     */
-    tmp = inw(io + RING_BUS_CTRL_A);
-    outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
-    mdelay(20);
-    outw(tmp, io + RING_BUS_CTRL_A);
-    mdelay(50);
-#endif
-}
-
-static int __devinit m3_codec_install(struct m3_card *card)
-{
-    struct ac97_codec *codec;
-
-    if ((codec = ac97_alloc_codec()) == NULL)
-        return -ENOMEM;
-
-    codec->private_data = card;
-    codec->codec_read = m3_ac97_read;
-    codec->codec_write = m3_ac97_write;
-    /* someday we should support secondary codecs.. */
-    codec->id = 0;
-
-    if (ac97_probe_codec(codec) == 0) {
-        printk(KERN_ERR PFX "codec probe failed\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) {
-        printk(KERN_ERR PFX "couldn't register mixer!\n");
-        ac97_release_codec(codec);
-        return -1;
-    }
-
-    card->ac97 = codec;
-
-    return 0;
-}
-
-
-#define MINISRC_LPF_LEN 10
-static u16 minisrc_lpf[MINISRC_LPF_LEN] = {
-    0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
-    0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
-};
-static void m3_assp_init(struct m3_card *card)
-{
-    int i;
-
-    /* zero kernel data */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR + i, 0);
-
-    /* zero mixer data? */
-    for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-                KDATA_BASE_ADDR2 + i, 0);
-
-    /* init dma pointer */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_CURRENT_DMA, 
-            KDATA_DMA_XFER0);
-
-    /* write kernel into code memory.. */
-    for(i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                REV_B_CODE_MEMORY_BEGIN + i, 
-                assp_kernel_image[i]);
-    }
-
-    /*
-     * We only have this one client and we know that 0x400
-     * is free in our kernel's mem map, so lets just
-     * drop it there.  It seems that the minisrc doesn't
-     * need vectors, so we won't bother with them..
-     */
-    for(i = 0 ; i < sizeof(assp_minisrc_image) / 2; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, 
-                0x400 + i, 
-                assp_minisrc_image[i]);
-    }
-
-    /*
-     * write the coefficients for the low pass filter?
-     */
-    for(i = 0; i < MINISRC_LPF_LEN ; i++) {
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-            0x400 + MINISRC_COEF_LOC + i,
-            minisrc_lpf[i]);
-    }
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_CODE,
-        0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN,
-        0x8000);
-
-    /*
-     * the minisrc is the only thing on
-     * our task list..
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-            KDATA_TASK0, 
-            0x400);
-
-    /*
-     * init the mixer number..
-     */
-
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-            KDATA_MIXER_TASK_NUMBER,0);
-
-    /*
-     * EXTREME KERNEL MASTER VOLUME
-     */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-        KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
-
-    card->mixer_list.mem_addr = KDATA_MIXER_XFER0;
-    card->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS;
-    card->adc1_list.mem_addr = KDATA_ADC1_XFER0;
-    card->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS;
-    card->dma_list.mem_addr = KDATA_DMA_XFER0;
-    card->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS;
-    card->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC;
-    card->msrc_list.max = MAX_INSTANCE_MINISRC;
-}
-
-static int setup_msrc(struct m3_card *card,
-        struct assp_instance *inst, int index)
-{
-    int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
-            MINISRC_IN_BUFFER_SIZE / 2 +
-            1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 );
-    int address, i;
-
-    /*
-     * the revb memory map has 0x1100 through 0x1c00
-     * free.  
-     */
-
-    /*
-     * align instance address to 256 bytes so that it's
-     * shifted list address is aligned.  
-     * list address = (mem address >> 1) >> 7;
-     */
-    data_bytes = (data_bytes + 255) & ~255;
-    address = 0x1100 + ((data_bytes/2) * index);
-
-    if((address + (data_bytes/2)) >= 0x1c00) {
-        printk(KERN_ERR PFX "no memory for %d bytes at ind %d (addr 0x%x)\n",
-                data_bytes, index, address);
-        return -1;
-    }
-
-    for(i = 0; i < data_bytes/2 ; i++) 
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA,
-                address + i, 0);
-
-    inst->code = 0x400;
-    inst->data = address;
-
-    return 0;
-}
-
-static int m3_assp_client_init(struct m3_state *s)
-{
-    setup_msrc(s->card, &(s->dac_inst), s->index * 2);
-    setup_msrc(s->card, &(s->adc_inst), (s->index * 2) + 1);
-
-    return 0;
-}
-
-static void m3_amp_enable(struct m3_card *card, int enable)
-{
-    /* 
-     * this works for the reference board, have to find
-     * out about others
-     *
-     * this needs more magic for 4 speaker, but..
-     */
-    int io = card->iobase;
-    u16 gpo, polarity_port, polarity;
-
-    if(!external_amp)
-        return;
-
-    if (gpio_pin >= 0  && gpio_pin <= 15) {
-        polarity_port = 0x1000 + (0x100 * gpio_pin);
-    } else {
-        switch (card->card_type) {
-            case ESS_ALLEGRO:
-                polarity_port = 0x1800;
-                break;
-            default:
-                polarity_port = 0x1100;
-                /* Panasonic toughbook CF72 has to be different... */
-                if(card->pcidev->subsystem_vendor == 0x10F7 && card->pcidev->subsystem_device == 0x833D)
-                       polarity_port = 0x1D00;
-                break;
-        }
-    }
-
-    gpo = (polarity_port >> 8) & 0x0F;
-    polarity = polarity_port >> 12;
-    if ( enable )
-        polarity = !polarity;
-    polarity = polarity << gpo;
-    gpo = 1 << gpo;
-
-    outw(~gpo , io + GPIO_MASK);
-
-    outw( inw(io + GPIO_DIRECTION) | gpo ,
-            io + GPIO_DIRECTION);
-
-    outw( (GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity) ,
-            io + GPIO_DATA);
-
-    outw(0xffff , io + GPIO_MASK);
-}
-
-static int
-maestro_config(struct m3_card *card) 
-{
-    struct pci_dev *pcidev = card->pcidev;
-    u32 n;
-    u8  t; /* makes as much sense as 'n', no? */
-
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= REDUCED_DEBOUNCE;
-    n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    outb(RESET_ASSP, card->iobase + ASSP_CONTROL_B);
-    pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-    n &= ~INT_CLK_SELECT;
-    if(card->card_type >= ESS_MAESTRO3)  {
-        n &= ~INT_CLK_MULT_ENABLE; 
-        n |= INT_CLK_SRC_NOT_PCI;
-    }
-    n &=  ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 );
-    pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
-
-    if(card->card_type <= ESS_ALLEGRO) {
-        pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n);
-        n |= IN_CLK_12MHZ_SELECT;
-        pci_write_config_dword(pcidev, PCI_USER_CONFIG, n);
-    }
-
-    t = inb(card->iobase + ASSP_CONTROL_A);
-    t &= ~( DSP_CLK_36MHZ_SELECT  | ASSP_CLK_49MHZ_SELECT);
-    t |= ASSP_CLK_49MHZ_SELECT;
-    t |= ASSP_0_WS_ENABLE; 
-    outb(t, card->iobase + ASSP_CONTROL_A);
-
-    outb(RUN_ASSP, card->iobase + ASSP_CONTROL_B); 
-
-    return 0;
-} 
-
-static void m3_enable_ints(struct m3_card *card)
-{
-    unsigned long io = card->iobase;
-
-    outw(ASSP_INT_ENABLE, io + HOST_INT_CTRL);
-    outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
-            io + ASSP_CONTROL_C);
-}
-
-static struct file_operations m3_audio_fops = {
-       .owner   = THIS_MODULE,
-       .llseek  = no_llseek,
-       .read    = m3_read,
-       .write   = m3_write,
-       .poll    = m3_poll,
-       .ioctl   = m3_ioctl,
-       .mmap    = m3_mmap,
-       .open    = m3_open,
-       .release = m3_release,
-};
-
-#ifdef CONFIG_PM
-static int alloc_dsp_suspendmem(struct m3_card *card)
-{
-    int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-
-    if( (card->suspend_mem = vmalloc(len)) == NULL)
-        return 1;
-
-    return 0;
-}
-
-#else
-#define alloc_dsp_suspendmem(args...) 0
-#endif
-
-/*
- * great day!  this function is ugly as hell.
- */
-static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
-{
-    u32 n;
-    int i;
-    struct m3_card *card = NULL;
-    int ret = 0;
-    int card_type = pci_id->driver_data;
-
-    DPRINTK(DPMOD, "in maestro_install\n");
-
-    if (pci_enable_device(pci_dev))
-        return -EIO;
-
-    if (pci_set_dma_mask(pci_dev, M3_PCI_DMA_MASK)) {
-        printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n");
-        return -ENODEV;
-    }
-        
-    pci_set_master(pci_dev);
-
-    if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) {
-        printk(KERN_WARNING PFX "out of memory\n");
-        return -ENOMEM;
-    }
-    memset(card, 0, sizeof(struct m3_card));
-    card->pcidev = pci_dev;
-    init_waitqueue_head(&card->suspend_queue);
-
-    if ( ! request_region(pci_resource_start(pci_dev, 0),
-                pci_resource_len (pci_dev, 0), M3_MODULE_NAME)) {
-
-        printk(KERN_WARNING PFX "unable to reserve I/O space.\n");
-        ret = -EBUSY;
-        goto out;
-    }
-
-    card->iobase = pci_resource_start(pci_dev, 0);
-
-    if(alloc_dsp_suspendmem(card)) {
-        printk(KERN_WARNING PFX "couldn't alloc %d bytes for saving dsp state on suspend\n",
-                REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH);
-        ret = -ENOMEM;
-        goto out;
-    }
-
-    card->card_type = card_type;
-    card->irq = pci_dev->irq;
-    card->next = devs;
-    card->magic = M3_CARD_MAGIC;
-    spin_lock_init(&card->lock);
-    spin_lock_init(&card->ac97_lock);
-    devs = card;
-    for(i = 0; i<NR_DSPS; i++) {
-        struct m3_state *s = &(card->channels[i]);
-        s->dev_audio = -1;
-    }
-
-    printk(KERN_INFO PFX "Configuring ESS %s found at IO 0x%04X IRQ %d\n", 
-        card_names[card->card_type], card->iobase, card->irq);
-
-    pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-    printk(KERN_INFO PFX " subvendor id: 0x%08x\n",n); 
-
-    maestro_config(card);
-    m3_assp_halt(card);
-
-    m3_codec_reset(card, 0);
-
-    if(m3_codec_install(card))  {
-        ret = -EIO; 
-        goto out;
-    }
-
-    m3_assp_init(card);
-    m3_amp_enable(card, 1);
-    
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s=&card->channels[i];
-
-        s->index = i;
-
-        s->card = card;
-        init_waitqueue_head(&s->dma_adc.wait);
-        init_waitqueue_head(&s->dma_dac.wait);
-        init_waitqueue_head(&s->open_wait);
-        mutex_init(&(s->open_mutex));
-        s->magic = M3_STATE_MAGIC;
-
-        m3_assp_client_init(s);
-        
-        if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-            printk(KERN_WARNING PFX "initing a dsp device that is already in use?\n");
-        /* register devices */
-        if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) {
-            break;
-        }
-
-        if( allocate_dmabuf(card->pcidev, &(s->dma_adc)) ||
-                allocate_dmabuf(card->pcidev, &(s->dma_dac)))  { 
-            ret = -ENOMEM;
-            goto out;
-        }
-    }
-    
-    if(request_irq(card->irq, m3_interrupt, IRQF_SHARED, card_names[card->card_type], card)) {
-
-        printk(KERN_ERR PFX "unable to allocate irq %d,\n", card->irq);
-
-        ret = -EIO;
-        goto out;
-    }
-
-    pci_set_drvdata(pci_dev, card);
-    
-    m3_enable_ints(card);
-    m3_assp_continue(card);
-
-out:
-    if(ret) {
-        if(card->iobase)
-            release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
-        vfree(card->suspend_mem);
-        if(card->ac97) {
-            unregister_sound_mixer(card->ac97->dev_mixer);
-            kfree(card->ac97);
-        }
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio != -1)
-                unregister_sound_dsp(s->dev_audio);
-        }
-        kfree(card);
-    }
-
-    return ret; 
-}
-
-static void m3_remove(struct pci_dev *pci_dev)
-{
-    struct m3_card *card;
-
-    unregister_reboot_notifier(&m3_reboot_nb);
-
-    while ((card = devs)) {
-        int i;
-        devs = devs->next;
-    
-        free_irq(card->irq, card);
-        unregister_sound_mixer(card->ac97->dev_mixer);
-        kfree(card->ac97);
-
-        for(i=0;i<NR_DSPS;i++)
-        {
-            struct m3_state *s = &card->channels[i];
-            if(s->dev_audio < 0)
-                continue;
-
-            unregister_sound_dsp(s->dev_audio);
-            free_dmabuf(card->pcidev, &s->dma_adc);
-            free_dmabuf(card->pcidev, &s->dma_dac);
-        }
-
-        release_region(card->iobase, 256);
-        vfree(card->suspend_mem);
-        kfree(card);
-    }
-    devs = NULL;
-}
-
-/*
- * some bioses like the sound chip to be powered down
- * at shutdown.  We're just calling _suspend to
- * achieve that..
- */
-static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf)
-{
-    struct m3_card *card;
-
-    DPRINTK(DPMOD, "notifier suspending all cards\n");
-
-    for(card = devs; card != NULL; card = card->next) {
-        if(!card->in_suspend)
-            m3_suspend(card->pcidev, PMSG_SUSPEND); /* XXX legal? */
-    }
-    return 0;
-}
-
-static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
-    unsigned long flags;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-    /* must be a better way.. */
-       spin_lock_irqsave(&card->lock, flags);
-
-    DPRINTK(DPMOD, "pm in dev %p\n",card);
-
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-
-        if(s->dev_audio == -1)
-            continue;
-
-        DPRINTK(DPMOD, "stop_adc/dac() device %d\n",i);
-        stop_dac(s);
-        stop_adc(s);
-    }
-
-    mdelay(10); /* give the assp a chance to idle.. */
-
-    m3_assp_halt(card);
-
-    if(card->suspend_mem) {
-        int index = 0;
-
-        DPRINTK(DPMOD, "saving code\n");
-        for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_CODE, i);
-        DPRINTK(DPMOD, "saving data\n");
-        for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-            card->suspend_mem[index++] = 
-                m3_assp_read(card, MEMTYPE_INTERNAL_DATA, i);
-    }
-
-    DPRINTK(DPMOD, "powering down apci regs\n");
-    m3_outw(card, 0xffff, 0x54);
-    m3_outw(card, 0xffff, 0x56);
-
-    card->in_suspend = 1;
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    return 0;
-}
-
-static int m3_resume(struct pci_dev *pci_dev)
-{
-    unsigned long flags;
-    int index;
-    int i;
-    struct m3_card *card = pci_get_drvdata(pci_dev);
-
-       spin_lock_irqsave(&card->lock, flags);
-    card->in_suspend = 0;
-
-    DPRINTK(DPMOD, "resuming\n");
-
-    /* first lets just bring everything back. .*/
-
-    DPRINTK(DPMOD, "bringing power back on card 0x%p\n",card);
-    m3_outw(card, 0, 0x54);
-    m3_outw(card, 0, 0x56);
-
-    DPRINTK(DPMOD, "restoring pci configs and reseting codec\n");
-    maestro_config(card);
-    m3_assp_halt(card);
-    m3_codec_reset(card, 1);
-
-    DPRINTK(DPMOD, "restoring dsp code card\n");
-    index = 0;
-    for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_CODE, i, 
-            card->suspend_mem[index++]);
-    for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++)
-        m3_assp_write(card, MEMTYPE_INTERNAL_DATA, i, 
-            card->suspend_mem[index++]);
-
-     /* tell the dma engine to restart itself */
-    m3_assp_write(card, MEMTYPE_INTERNAL_DATA, 
-        KDATA_DMA_ACTIVE, 0);
-
-    DPRINTK(DPMOD, "resuming dsp\n");
-    m3_assp_continue(card);
-
-    DPRINTK(DPMOD, "enabling ints\n");
-    m3_enable_ints(card);
-
-    /* bring back the old school flavor */
-    for(i = 0; i < SOUND_MIXER_NRDEVICES ; i++) {
-        int state = card->ac97->mixer_state[i];
-        if (!supported_mixer(card->ac97, i)) 
-                continue;
-
-        card->ac97->write_mixer(card->ac97, i, 
-                state & 0xff, (state >> 8) & 0xff);
-    }
-
-    m3_amp_enable(card, 1);
-
-    /* 
-     * now we flip on the music 
-     */
-    for(i=0;i<NR_DSPS;i++) {
-        struct m3_state *s = &card->channels[i];
-        if(s->dev_audio == -1)
-            continue;
-        /*
-         * db->ready makes it so these guys can be
-         * called unconditionally..
-         */
-        DPRINTK(DPMOD, "turning on dacs ind %d\n",i);
-        start_dac(s);    
-        start_adc(s);    
-    }
-
-    spin_unlock_irqrestore(&card->lock, flags);
-
-    /* 
-     * all right, we think things are ready, 
-     * wake up people who were using the device 
-     * when we suspended
-     */
-    wake_up(&card->suspend_queue);
-
-    return 0;
-}
-
-MODULE_AUTHOR("Zach Brown <zab@zabbo.net>");
-MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver");
-MODULE_LICENSE("GPL");
-
-#ifdef M_DEBUG
-module_param(debug, int, 0);
-#endif
-module_param(external_amp, int, 0);
-module_param(gpio_pin, int, 0);
-
-static struct pci_driver m3_pci_driver = {
-       .name     = "ess_m3_audio",
-       .id_table = m3_id_table,
-       .probe    = m3_probe,
-       .remove   = m3_remove,
-       .suspend  = m3_suspend,
-       .resume   = m3_resume,
-};
-
-static int __init m3_init_module(void)
-{
-    printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n");
-
-    if (register_reboot_notifier(&m3_reboot_nb)) {
-        printk(KERN_WARNING PFX "reboot notifier registration failed\n");
-        return -ENODEV; /* ? */
-    }
-
-    if (pci_register_driver(&m3_pci_driver)) {
-        unregister_reboot_notifier(&m3_reboot_nb);
-        return -ENODEV;
-    }
-    return 0;
-}
-
-static void __exit m3_cleanup_module(void)
-{
-    pci_unregister_driver(&m3_pci_driver);
-}
-
-module_init(m3_init_module);
-module_exit(m3_cleanup_module);
-
-void check_suspend(struct m3_card *card)
-{
-    DECLARE_WAITQUEUE(wait, current);
-
-    if(!card->in_suspend) 
-        return;
-
-    card->in_suspend++;
-    add_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    schedule();
-    remove_wait_queue(&card->suspend_queue, &wait);
-    set_current_state(TASK_RUNNING);
-}
diff --git a/sound/oss/maestro3.h b/sound/oss/maestro3.h
deleted file mode 100644 (file)
index dde2986..0000000
+++ /dev/null
@@ -1,821 +0,0 @@
-/*
- *      ESS Technology allegro audio driver.
- *
- *      Copyright (C) 1992-2000  Don Kim (don.kim@esstech.com)
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU General Public License for more details.
- *
- *      You should have received a copy of the GNU General Public License
- *      along with this program; if not, write to the Free Software
- *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *      Hacked for the maestro3 driver by zab
- */
-
-// Allegro PCI configuration registers
-#define PCI_LEGACY_AUDIO_CTRL   0x40
-#define SOUND_BLASTER_ENABLE    0x00000001
-#define FM_SYNTHESIS_ENABLE     0x00000002
-#define GAME_PORT_ENABLE        0x00000004
-#define MPU401_IO_ENABLE        0x00000008
-#define MPU401_IRQ_ENABLE       0x00000010
-#define ALIAS_10BIT_IO          0x00000020
-#define SB_DMA_MASK             0x000000C0
-#define SB_DMA_0                0x00000040
-#define SB_DMA_1                0x00000040
-#define SB_DMA_R                0x00000080
-#define SB_DMA_3                0x000000C0
-#define SB_IRQ_MASK             0x00000700
-#define SB_IRQ_5                0x00000000
-#define SB_IRQ_7                0x00000100
-#define SB_IRQ_9                0x00000200
-#define SB_IRQ_10               0x00000300
-#define MIDI_IRQ_MASK           0x00003800
-#define SERIAL_IRQ_ENABLE       0x00004000
-#define DISABLE_LEGACY          0x00008000
-
-#define PCI_ALLEGRO_CONFIG      0x50
-#define SB_ADDR_240             0x00000004
-#define MPU_ADDR_MASK           0x00000018
-#define MPU_ADDR_330            0x00000000
-#define MPU_ADDR_300            0x00000008
-#define MPU_ADDR_320            0x00000010
-#define MPU_ADDR_340            0x00000018
-#define USE_PCI_TIMING          0x00000040
-#define POSTED_WRITE_ENABLE     0x00000080
-#define DMA_POLICY_MASK         0x00000700
-#define DMA_DDMA                0x00000000
-#define DMA_TDMA                0x00000100
-#define DMA_PCPCI               0x00000200
-#define DMA_WBDMA16             0x00000400
-#define DMA_WBDMA4              0x00000500
-#define DMA_WBDMA2              0x00000600
-#define DMA_WBDMA1              0x00000700
-#define DMA_SAFE_GUARD          0x00000800
-#define HI_PERF_GP_ENABLE       0x00001000
-#define PIC_SNOOP_MODE_0        0x00002000
-#define PIC_SNOOP_MODE_1        0x00004000
-#define SOUNDBLASTER_IRQ_MASK   0x00008000
-#define RING_IN_ENABLE          0x00010000
-#define SPDIF_TEST_MODE         0x00020000
-#define CLK_MULT_MODE_SELECT_2  0x00040000
-#define EEPROM_WRITE_ENABLE     0x00080000
-#define CODEC_DIR_IN            0x00100000
-#define HV_BUTTON_FROM_GD       0x00200000
-#define REDUCED_DEBOUNCE        0x00400000
-#define HV_CTRL_ENABLE          0x00800000
-#define SPDIF_ENABLE            0x01000000
-#define CLK_DIV_SELECT          0x06000000
-#define CLK_DIV_BY_48           0x00000000
-#define CLK_DIV_BY_49           0x02000000
-#define CLK_DIV_BY_50           0x04000000
-#define CLK_DIV_RESERVED        0x06000000
-#define PM_CTRL_ENABLE          0x08000000
-#define CLK_MULT_MODE_SELECT    0x30000000
-#define CLK_MULT_MODE_SHIFT     28
-#define CLK_MULT_MODE_0         0x00000000
-#define CLK_MULT_MODE_1         0x10000000
-#define CLK_MULT_MODE_2         0x20000000
-#define CLK_MULT_MODE_3         0x30000000
-#define INT_CLK_SELECT          0x40000000
-#define INT_CLK_MULT_RESET      0x80000000
-
-// M3
-#define INT_CLK_SRC_NOT_PCI     0x00100000
-#define INT_CLK_MULT_ENABLE     0x80000000
-
-#define PCI_ACPI_CONTROL        0x54
-#define PCI_ACPI_D0             0x00000000
-#define PCI_ACPI_D1             0xB4F70000
-#define PCI_ACPI_D2             0xB4F7B4F7
-
-#define PCI_USER_CONFIG         0x58
-#define EXT_PCI_MASTER_ENABLE   0x00000001
-#define SPDIF_OUT_SELECT        0x00000002
-#define TEST_PIN_DIR_CTRL       0x00000004
-#define AC97_CODEC_TEST         0x00000020
-#define TRI_STATE_BUFFER        0x00000080
-#define IN_CLK_12MHZ_SELECT     0x00000100
-#define MULTI_FUNC_DISABLE      0x00000200
-#define EXT_MASTER_PAIR_SEL     0x00000400
-#define PCI_MASTER_SUPPORT      0x00000800
-#define STOP_CLOCK_ENABLE       0x00001000
-#define EAPD_DRIVE_ENABLE       0x00002000
-#define REQ_TRI_STATE_ENABLE    0x00004000
-#define REQ_LOW_ENABLE          0x00008000
-#define MIDI_1_ENABLE           0x00010000
-#define MIDI_2_ENABLE           0x00020000
-#define SB_AUDIO_SYNC           0x00040000
-#define HV_CTRL_TEST            0x00100000
-#define SOUNDBLASTER_TEST       0x00400000
-
-#define PCI_USER_CONFIG_C       0x5C
-
-#define PCI_DDMA_CTRL           0x60
-#define DDMA_ENABLE             0x00000001
-
-
-// Allegro registers
-#define HOST_INT_CTRL           0x18
-#define SB_INT_ENABLE           0x0001
-#define MPU401_INT_ENABLE       0x0002
-#define ASSP_INT_ENABLE         0x0010
-#define RING_INT_ENABLE         0x0020
-#define HV_INT_ENABLE           0x0040
-#define CLKRUN_GEN_ENABLE       0x0100
-#define HV_CTRL_TO_PME          0x0400
-#define SOFTWARE_RESET_ENABLE   0x8000
-
-/*
- * should be using the above defines, probably.
- */
-#define REGB_ENABLE_RESET               0x01
-#define REGB_STOP_CLOCK                 0x10
-
-#define HOST_INT_STATUS         0x1A
-#define SB_INT_PENDING          0x01
-#define MPU401_INT_PENDING      0x02
-#define ASSP_INT_PENDING        0x10
-#define RING_INT_PENDING        0x20
-#define HV_INT_PENDING          0x40
-
-#define HARDWARE_VOL_CTRL       0x1B
-#define SHADOW_MIX_REG_VOICE    0x1C
-#define HW_VOL_COUNTER_VOICE    0x1D
-#define SHADOW_MIX_REG_MASTER   0x1E
-#define HW_VOL_COUNTER_MASTER   0x1F
-
-#define CODEC_COMMAND           0x30
-#define CODEC_READ_B            0x80
-
-#define CODEC_STATUS            0x30
-#define CODEC_BUSY_B            0x01
-
-#define CODEC_DATA              0x32
-
-#define RING_BUS_CTRL_A         0x36
-#define RAC_PME_ENABLE          0x0100
-#define RAC_SDFS_ENABLE         0x0200
-#define LAC_PME_ENABLE          0x0400
-#define LAC_SDFS_ENABLE         0x0800
-#define SERIAL_AC_LINK_ENABLE   0x1000
-#define IO_SRAM_ENABLE          0x2000
-#define IIS_INPUT_ENABLE        0x8000
-
-#define RING_BUS_CTRL_B         0x38
-#define SECOND_CODEC_ID_MASK    0x0003
-#define SPDIF_FUNC_ENABLE       0x0010
-#define SECOND_AC_ENABLE        0x0020
-#define SB_MODULE_INTF_ENABLE   0x0040
-#define SSPE_ENABLE             0x0040
-#define M3I_DOCK_ENABLE         0x0080
-
-#define SDO_OUT_DEST_CTRL       0x3A
-#define COMMAND_ADDR_OUT        0x0003
-#define PCM_LR_OUT_LOCAL        0x0000
-#define PCM_LR_OUT_REMOTE       0x0004
-#define PCM_LR_OUT_MUTE         0x0008
-#define PCM_LR_OUT_BOTH         0x000C
-#define LINE1_DAC_OUT_LOCAL     0x0000
-#define LINE1_DAC_OUT_REMOTE    0x0010
-#define LINE1_DAC_OUT_MUTE      0x0020
-#define LINE1_DAC_OUT_BOTH      0x0030
-#define PCM_CLS_OUT_LOCAL       0x0000
-#define PCM_CLS_OUT_REMOTE      0x0040
-#define PCM_CLS_OUT_MUTE        0x0080
-#define PCM_CLS_OUT_BOTH        0x00C0
-#define PCM_RLF_OUT_LOCAL       0x0000
-#define PCM_RLF_OUT_REMOTE      0x0100
-#define PCM_RLF_OUT_MUTE        0x0200
-#define PCM_RLF_OUT_BOTH        0x0300
-#define LINE2_DAC_OUT_LOCAL     0x0000
-#define LINE2_DAC_OUT_REMOTE    0x0400
-#define LINE2_DAC_OUT_MUTE      0x0800
-#define LINE2_DAC_OUT_BOTH      0x0C00
-#define HANDSET_OUT_LOCAL       0x0000
-#define HANDSET_OUT_REMOTE      0x1000
-#define HANDSET_OUT_MUTE        0x2000
-#define HANDSET_OUT_BOTH        0x3000
-#define IO_CTRL_OUT_LOCAL       0x0000
-#define IO_CTRL_OUT_REMOTE      0x4000
-#define IO_CTRL_OUT_MUTE        0x8000
-#define IO_CTRL_OUT_BOTH        0xC000
-
-#define SDO_IN_DEST_CTRL        0x3C
-#define STATUS_ADDR_IN          0x0003
-#define PCM_LR_IN_LOCAL         0x0000
-#define PCM_LR_IN_REMOTE        0x0004
-#define PCM_LR_RESERVED         0x0008
-#define PCM_LR_IN_BOTH          0x000C
-#define LINE1_ADC_IN_LOCAL      0x0000
-#define LINE1_ADC_IN_REMOTE     0x0010
-#define LINE1_ADC_IN_MUTE       0x0020
-#define MIC_ADC_IN_LOCAL        0x0000
-#define MIC_ADC_IN_REMOTE       0x0040
-#define MIC_ADC_IN_MUTE         0x0080
-#define LINE2_DAC_IN_LOCAL      0x0000
-#define LINE2_DAC_IN_REMOTE     0x0400
-#define LINE2_DAC_IN_MUTE       0x0800
-#define HANDSET_IN_LOCAL        0x0000
-#define HANDSET_IN_REMOTE       0x1000
-#define HANDSET_IN_MUTE         0x2000
-#define IO_STATUS_IN_LOCAL      0x0000
-#define IO_STATUS_IN_REMOTE     0x4000
-
-#define SPDIF_IN_CTRL           0x3E
-#define SPDIF_IN_ENABLE         0x0001
-
-#define GPIO_DATA               0x60
-#define GPIO_DATA_MASK          0x0FFF
-#define GPIO_HV_STATUS          0x3000
-#define GPIO_PME_STATUS         0x4000
-
-#define GPIO_MASK               0x64
-#define GPIO_DIRECTION          0x68
-#define GPO_PRIMARY_AC97        0x0001
-#define GPI_LINEOUT_SENSE       0x0004
-#define GPO_SECONDARY_AC97      0x0008
-#define GPI_VOL_DOWN            0x0010
-#define GPI_VOL_UP              0x0020
-#define GPI_IIS_CLK             0x0040
-#define GPI_IIS_LRCLK           0x0080
-#define GPI_IIS_DATA            0x0100
-#define GPI_DOCKING_STATUS      0x0100
-#define GPI_HEADPHONE_SENSE     0x0200
-#define GPO_EXT_AMP_SHUTDOWN    0x1000
-
-// M3
-#define GPO_M3_EXT_AMP_SHUTDN   0x0002
-
-#define ASSP_INDEX_PORT         0x80
-#define ASSP_MEMORY_PORT        0x82
-#define ASSP_DATA_PORT          0x84
-
-#define MPU401_DATA_PORT        0x98
-#define MPU401_STATUS_PORT      0x99
-
-#define CLK_MULT_DATA_PORT      0x9C
-
-#define ASSP_CONTROL_A          0xA2
-#define ASSP_0_WS_ENABLE        0x01
-#define ASSP_CTRL_A_RESERVED1   0x02
-#define ASSP_CTRL_A_RESERVED2   0x04
-#define ASSP_CLK_49MHZ_SELECT   0x08
-#define FAST_PLU_ENABLE         0x10
-#define ASSP_CTRL_A_RESERVED3   0x20
-#define DSP_CLK_36MHZ_SELECT    0x40
-
-#define ASSP_CONTROL_B          0xA4
-#define RESET_ASSP              0x00
-#define RUN_ASSP                0x01
-#define ENABLE_ASSP_CLOCK       0x00
-#define STOP_ASSP_CLOCK         0x10
-#define RESET_TOGGLE            0x40
-
-#define ASSP_CONTROL_C          0xA6
-#define ASSP_HOST_INT_ENABLE    0x01
-#define FM_ADDR_REMAP_DISABLE   0x02
-#define HOST_WRITE_PORT_ENABLE  0x08
-
-#define ASSP_HOST_INT_STATUS    0xAC
-#define DSP2HOST_REQ_PIORECORD  0x01
-#define DSP2HOST_REQ_I2SRATE    0x02
-#define DSP2HOST_REQ_TIMER      0x04
-
-// AC97 registers
-// XXX fix this crap up
-/*#define AC97_RESET              0x00*/
-
-#define AC97_VOL_MUTE_B         0x8000
-#define AC97_VOL_M              0x1F
-#define AC97_LEFT_VOL_S         8
-
-#define AC97_MASTER_VOL         0x02
-#define AC97_LINE_LEVEL_VOL     0x04
-#define AC97_MASTER_MONO_VOL    0x06
-#define AC97_PC_BEEP_VOL        0x0A
-#define AC97_PC_BEEP_VOL_M      0x0F
-#define AC97_SROUND_MASTER_VOL  0x38
-#define AC97_PC_BEEP_VOL_S      1
-
-/*#define AC97_PHONE_VOL          0x0C
-#define AC97_MIC_VOL            0x0E*/
-#define AC97_MIC_20DB_ENABLE    0x40
-
-/*#define AC97_LINEIN_VOL         0x10
-#define AC97_CD_VOL             0x12
-#define AC97_VIDEO_VOL          0x14
-#define AC97_AUX_VOL            0x16*/
-#define AC97_PCM_OUT_VOL        0x18
-/*#define AC97_RECORD_SELECT      0x1A*/
-#define AC97_RECORD_MIC         0x00
-#define AC97_RECORD_CD          0x01
-#define AC97_RECORD_VIDEO       0x02
-#define AC97_RECORD_AUX         0x03
-#define AC97_RECORD_MONO_MUX    0x02
-#define AC97_RECORD_DIGITAL     0x03
-#define AC97_RECORD_LINE        0x04
-#define AC97_RECORD_STEREO      0x05
-#define AC97_RECORD_MONO        0x06
-#define AC97_RECORD_PHONE       0x07
-
-/*#define AC97_RECORD_GAIN        0x1C*/
-#define AC97_RECORD_VOL_M       0x0F
-
-/*#define AC97_GENERAL_PURPOSE    0x20*/
-#define AC97_POWER_DOWN_CTRL    0x26
-#define AC97_ADC_READY          0x0001
-#define AC97_DAC_READY          0x0002
-#define AC97_ANALOG_READY       0x0004
-#define AC97_VREF_ON            0x0008
-#define AC97_PR0                0x0100
-#define AC97_PR1                0x0200
-#define AC97_PR2                0x0400
-#define AC97_PR3                0x0800
-#define AC97_PR4                0x1000
-
-#define AC97_RESERVED1          0x28
-
-#define AC97_VENDOR_TEST        0x5A
-
-#define AC97_CLOCK_DELAY        0x5C
-#define AC97_LINEOUT_MUX_SEL    0x0001
-#define AC97_MONO_MUX_SEL       0x0002
-#define AC97_CLOCK_DELAY_SEL    0x1F
-#define AC97_DAC_CDS_SHIFT      6
-#define AC97_ADC_CDS_SHIFT      11
-
-#define AC97_MULTI_CHANNEL_SEL  0x74
-
-/*#define AC97_VENDOR_ID1         0x7C
-#define AC97_VENDOR_ID2         0x7E*/
-
-/*
- * ASSP control regs
- */
-#define DSP_PORT_TIMER_COUNT    0x06
-
-#define DSP_PORT_MEMORY_INDEX   0x80
-
-#define DSP_PORT_MEMORY_TYPE    0x82
-#define MEMTYPE_INTERNAL_CODE   0x0002
-#define MEMTYPE_INTERNAL_DATA   0x0003
-#define MEMTYPE_MASK            0x0003
-
-#define DSP_PORT_MEMORY_DATA    0x84
-
-#define DSP_PORT_CONTROL_REG_A  0xA2
-#define DSP_PORT_CONTROL_REG_B  0xA4
-#define DSP_PORT_CONTROL_REG_C  0xA6
-
-#define REV_A_CODE_MEMORY_BEGIN         0x0000
-#define REV_A_CODE_MEMORY_END           0x0FFF
-#define REV_A_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_A_CODE_MEMORY_LENGTH        (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1)
-
-#define REV_B_CODE_MEMORY_BEGIN         0x0000
-#define REV_B_CODE_MEMORY_END           0x0BFF
-#define REV_B_CODE_MEMORY_UNIT_LENGTH   0x0040
-#define REV_B_CODE_MEMORY_LENGTH        (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1)
-
-#define REV_A_DATA_MEMORY_BEGIN         0x1000
-#define REV_A_DATA_MEMORY_END           0x2FFF
-#define REV_A_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_A_DATA_MEMORY_LENGTH        (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1)
-
-#define REV_B_DATA_MEMORY_BEGIN         0x1000
-#define REV_B_DATA_MEMORY_END           0x2BFF
-#define REV_B_DATA_MEMORY_UNIT_LENGTH   0x0080
-#define REV_B_DATA_MEMORY_LENGTH        (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1)
-
-
-#define NUM_UNITS_KERNEL_CODE          16
-#define NUM_UNITS_KERNEL_DATA           2
-
-#define NUM_UNITS_KERNEL_CODE_WITH_HSP 16
-#define NUM_UNITS_KERNEL_DATA_WITH_HSP  5
-
-/*
- * Kernel data layout
- */
-
-#define DP_SHIFT_COUNT                  7
-
-#define KDATA_BASE_ADDR                 0x1000
-#define KDATA_BASE_ADDR2                0x1080
-
-#define KDATA_TASK0                     (KDATA_BASE_ADDR + 0x0000)
-#define KDATA_TASK1                     (KDATA_BASE_ADDR + 0x0001)
-#define KDATA_TASK2                     (KDATA_BASE_ADDR + 0x0002)
-#define KDATA_TASK3                     (KDATA_BASE_ADDR + 0x0003)
-#define KDATA_TASK4                     (KDATA_BASE_ADDR + 0x0004)
-#define KDATA_TASK5                     (KDATA_BASE_ADDR + 0x0005)
-#define KDATA_TASK6                     (KDATA_BASE_ADDR + 0x0006)
-#define KDATA_TASK7                     (KDATA_BASE_ADDR + 0x0007)
-#define KDATA_TASK_ENDMARK              (KDATA_BASE_ADDR + 0x0008)
-
-#define KDATA_CURRENT_TASK              (KDATA_BASE_ADDR + 0x0009)
-#define KDATA_TASK_SWITCH               (KDATA_BASE_ADDR + 0x000A)
-
-#define KDATA_INSTANCE0_POS3D           (KDATA_BASE_ADDR + 0x000B)
-#define KDATA_INSTANCE1_POS3D           (KDATA_BASE_ADDR + 0x000C)
-#define KDATA_INSTANCE2_POS3D           (KDATA_BASE_ADDR + 0x000D)
-#define KDATA_INSTANCE3_POS3D           (KDATA_BASE_ADDR + 0x000E)
-#define KDATA_INSTANCE4_POS3D           (KDATA_BASE_ADDR + 0x000F)
-#define KDATA_INSTANCE5_POS3D           (KDATA_BASE_ADDR + 0x0010)
-#define KDATA_INSTANCE6_POS3D           (KDATA_BASE_ADDR + 0x0011)
-#define KDATA_INSTANCE7_POS3D           (KDATA_BASE_ADDR + 0x0012)
-#define KDATA_INSTANCE8_POS3D           (KDATA_BASE_ADDR + 0x0013)
-#define KDATA_INSTANCE_POS3D_ENDMARK    (KDATA_BASE_ADDR + 0x0014)
-
-#define KDATA_INSTANCE0_SPKVIRT         (KDATA_BASE_ADDR + 0x0015)
-#define KDATA_INSTANCE_SPKVIRT_ENDMARK  (KDATA_BASE_ADDR + 0x0016)
-
-#define KDATA_INSTANCE0_SPDIF           (KDATA_BASE_ADDR + 0x0017)
-#define KDATA_INSTANCE_SPDIF_ENDMARK    (KDATA_BASE_ADDR + 0x0018)
-
-#define KDATA_INSTANCE0_MODEM           (KDATA_BASE_ADDR + 0x0019)
-#define KDATA_INSTANCE_MODEM_ENDMARK    (KDATA_BASE_ADDR + 0x001A)
-
-#define KDATA_INSTANCE0_SRC             (KDATA_BASE_ADDR + 0x001B)
-#define KDATA_INSTANCE1_SRC             (KDATA_BASE_ADDR + 0x001C)
-#define KDATA_INSTANCE_SRC_ENDMARK      (KDATA_BASE_ADDR + 0x001D)
-
-#define KDATA_INSTANCE0_MINISRC         (KDATA_BASE_ADDR + 0x001E)
-#define KDATA_INSTANCE1_MINISRC         (KDATA_BASE_ADDR + 0x001F)
-#define KDATA_INSTANCE2_MINISRC         (KDATA_BASE_ADDR + 0x0020)
-#define KDATA_INSTANCE3_MINISRC         (KDATA_BASE_ADDR + 0x0021)
-#define KDATA_INSTANCE_MINISRC_ENDMARK  (KDATA_BASE_ADDR + 0x0022)
-
-#define KDATA_INSTANCE0_CPYTHRU         (KDATA_BASE_ADDR + 0x0023)
-#define KDATA_INSTANCE1_CPYTHRU         (KDATA_BASE_ADDR + 0x0024)
-#define KDATA_INSTANCE_CPYTHRU_ENDMARK  (KDATA_BASE_ADDR + 0x0025)
-
-#define KDATA_CURRENT_DMA               (KDATA_BASE_ADDR + 0x0026)
-#define KDATA_DMA_SWITCH                (KDATA_BASE_ADDR + 0x0027)
-#define KDATA_DMA_ACTIVE                (KDATA_BASE_ADDR + 0x0028)
-
-#define KDATA_DMA_XFER0                 (KDATA_BASE_ADDR + 0x0029)
-#define KDATA_DMA_XFER1                 (KDATA_BASE_ADDR + 0x002A)
-#define KDATA_DMA_XFER2                 (KDATA_BASE_ADDR + 0x002B)
-#define KDATA_DMA_XFER3                 (KDATA_BASE_ADDR + 0x002C)
-#define KDATA_DMA_XFER4                 (KDATA_BASE_ADDR + 0x002D)
-#define KDATA_DMA_XFER5                 (KDATA_BASE_ADDR + 0x002E)
-#define KDATA_DMA_XFER6                 (KDATA_BASE_ADDR + 0x002F)
-#define KDATA_DMA_XFER7                 (KDATA_BASE_ADDR + 0x0030)
-#define KDATA_DMA_XFER8                 (KDATA_BASE_ADDR + 0x0031)
-#define KDATA_DMA_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0032)
-
-#define KDATA_I2S_SAMPLE_COUNT          (KDATA_BASE_ADDR + 0x0033)
-#define KDATA_I2S_INT_METER             (KDATA_BASE_ADDR + 0x0034)
-#define KDATA_I2S_ACTIVE                (KDATA_BASE_ADDR + 0x0035)
-
-#define KDATA_TIMER_COUNT_RELOAD        (KDATA_BASE_ADDR + 0x0036)
-#define KDATA_TIMER_COUNT_CURRENT       (KDATA_BASE_ADDR + 0x0037)
-
-#define KDATA_HALT_SYNCH_CLIENT         (KDATA_BASE_ADDR + 0x0038)
-#define KDATA_HALT_SYNCH_DMA            (KDATA_BASE_ADDR + 0x0039)
-#define KDATA_HALT_ACKNOWLEDGE          (KDATA_BASE_ADDR + 0x003A)
-
-#define KDATA_ADC1_XFER0                (KDATA_BASE_ADDR + 0x003B)
-#define KDATA_ADC1_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x003C)
-#define KDATA_ADC1_LEFT_VOLUME                 (KDATA_BASE_ADDR + 0x003D)
-#define KDATA_ADC1_RIGHT_VOLUME                (KDATA_BASE_ADDR + 0x003E)
-#define KDATA_ADC1_LEFT_SUR_VOL                        (KDATA_BASE_ADDR + 0x003F)
-#define KDATA_ADC1_RIGHT_SUR_VOL               (KDATA_BASE_ADDR + 0x0040)
-
-#define KDATA_ADC2_XFER0                (KDATA_BASE_ADDR + 0x0041)
-#define KDATA_ADC2_XFER_ENDMARK         (KDATA_BASE_ADDR + 0x0042)
-#define KDATA_ADC2_LEFT_VOLUME                 (KDATA_BASE_ADDR + 0x0043)
-#define KDATA_ADC2_RIGHT_VOLUME                        (KDATA_BASE_ADDR + 0x0044)
-#define KDATA_ADC2_LEFT_SUR_VOL                        (KDATA_BASE_ADDR + 0x0045)
-#define KDATA_ADC2_RIGHT_SUR_VOL               (KDATA_BASE_ADDR + 0x0046)
-
-#define KDATA_CD_XFER0                                 (KDATA_BASE_ADDR + 0x0047)                                      
-#define KDATA_CD_XFER_ENDMARK                  (KDATA_BASE_ADDR + 0x0048)
-#define KDATA_CD_LEFT_VOLUME                   (KDATA_BASE_ADDR + 0x0049)
-#define KDATA_CD_RIGHT_VOLUME                  (KDATA_BASE_ADDR + 0x004A)
-#define KDATA_CD_LEFT_SUR_VOL                  (KDATA_BASE_ADDR + 0x004B)
-#define KDATA_CD_RIGHT_SUR_VOL                 (KDATA_BASE_ADDR + 0x004C)
-
-#define KDATA_MIC_XFER0                                        (KDATA_BASE_ADDR + 0x004D)
-#define KDATA_MIC_XFER_ENDMARK                 (KDATA_BASE_ADDR + 0x004E)
-#define KDATA_MIC_VOLUME                               (KDATA_BASE_ADDR + 0x004F)
-#define KDATA_MIC_SUR_VOL                              (KDATA_BASE_ADDR + 0x0050)
-
-#define KDATA_I2S_XFER0                 (KDATA_BASE_ADDR + 0x0051)
-#define KDATA_I2S_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0052)
-
-#define KDATA_CHI_XFER0                 (KDATA_BASE_ADDR + 0x0053)
-#define KDATA_CHI_XFER_ENDMARK          (KDATA_BASE_ADDR + 0x0054)
-
-#define KDATA_SPDIF_XFER                (KDATA_BASE_ADDR + 0x0055)
-#define KDATA_SPDIF_CURRENT_FRAME       (KDATA_BASE_ADDR + 0x0056)
-#define KDATA_SPDIF_FRAME0              (KDATA_BASE_ADDR + 0x0057)
-#define KDATA_SPDIF_FRAME1              (KDATA_BASE_ADDR + 0x0058)
-#define KDATA_SPDIF_FRAME2              (KDATA_BASE_ADDR + 0x0059)
-
-#define KDATA_SPDIF_REQUEST             (KDATA_BASE_ADDR + 0x005A)
-#define KDATA_SPDIF_TEMP                (KDATA_BASE_ADDR + 0x005B)
-
-#define KDATA_SPDIFIN_XFER0             (KDATA_BASE_ADDR + 0x005C)
-#define KDATA_SPDIFIN_XFER_ENDMARK      (KDATA_BASE_ADDR + 0x005D)
-#define KDATA_SPDIFIN_INT_METER         (KDATA_BASE_ADDR + 0x005E)
-
-#define KDATA_DSP_RESET_COUNT           (KDATA_BASE_ADDR + 0x005F)
-#define KDATA_DEBUG_OUTPUT              (KDATA_BASE_ADDR + 0x0060)
-
-#define KDATA_KERNEL_ISR_LIST           (KDATA_BASE_ADDR + 0x0061)
-
-#define KDATA_KERNEL_ISR_CBSR1          (KDATA_BASE_ADDR + 0x0062)
-#define KDATA_KERNEL_ISR_CBER1          (KDATA_BASE_ADDR + 0x0063)
-#define KDATA_KERNEL_ISR_CBCR           (KDATA_BASE_ADDR + 0x0064)
-#define KDATA_KERNEL_ISR_AR0            (KDATA_BASE_ADDR + 0x0065)
-#define KDATA_KERNEL_ISR_AR1            (KDATA_BASE_ADDR + 0x0066)
-#define KDATA_KERNEL_ISR_AR2            (KDATA_BASE_ADDR + 0x0067)
-#define KDATA_KERNEL_ISR_AR3            (KDATA_BASE_ADDR + 0x0068)
-#define KDATA_KERNEL_ISR_AR4            (KDATA_BASE_ADDR + 0x0069)
-#define KDATA_KERNEL_ISR_AR5            (KDATA_BASE_ADDR + 0x006A)
-#define KDATA_KERNEL_ISR_BRCR           (KDATA_BASE_ADDR + 0x006B)
-#define KDATA_KERNEL_ISR_PASR           (KDATA_BASE_ADDR + 0x006C)
-#define KDATA_KERNEL_ISR_PAER           (KDATA_BASE_ADDR + 0x006D)
-
-#define KDATA_CLIENT_SCRATCH0           (KDATA_BASE_ADDR + 0x006E)
-#define KDATA_CLIENT_SCRATCH1           (KDATA_BASE_ADDR + 0x006F)
-#define KDATA_KERNEL_SCRATCH            (KDATA_BASE_ADDR + 0x0070)
-#define KDATA_KERNEL_ISR_SCRATCH        (KDATA_BASE_ADDR + 0x0071)
-
-#define KDATA_OUEUE_LEFT                (KDATA_BASE_ADDR + 0x0072)
-#define KDATA_QUEUE_RIGHT               (KDATA_BASE_ADDR + 0x0073)
-
-#define KDATA_ADC1_REQUEST              (KDATA_BASE_ADDR + 0x0074)
-#define KDATA_ADC2_REQUEST              (KDATA_BASE_ADDR + 0x0075)
-#define KDATA_CD_REQUEST                               (KDATA_BASE_ADDR + 0x0076)
-#define KDATA_MIC_REQUEST                              (KDATA_BASE_ADDR + 0x0077)
-
-#define KDATA_ADC1_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0078)
-#define KDATA_ADC2_MIXER_REQUEST        (KDATA_BASE_ADDR + 0x0079)
-#define KDATA_CD_MIXER_REQUEST                 (KDATA_BASE_ADDR + 0x007A)
-#define KDATA_MIC_MIXER_REQUEST                        (KDATA_BASE_ADDR + 0x007B)
-#define KDATA_MIC_SYNC_COUNTER                 (KDATA_BASE_ADDR + 0x007C)
-
-/*
- * second 'segment' (?) reserved for mixer
- * buffers..
- */
-
-#define KDATA_MIXER_WORD0               (KDATA_BASE_ADDR2 + 0x0000)
-#define KDATA_MIXER_WORD1               (KDATA_BASE_ADDR2 + 0x0001)
-#define KDATA_MIXER_WORD2               (KDATA_BASE_ADDR2 + 0x0002)
-#define KDATA_MIXER_WORD3               (KDATA_BASE_ADDR2 + 0x0003)
-#define KDATA_MIXER_WORD4               (KDATA_BASE_ADDR2 + 0x0004)
-#define KDATA_MIXER_WORD5               (KDATA_BASE_ADDR2 + 0x0005)
-#define KDATA_MIXER_WORD6               (KDATA_BASE_ADDR2 + 0x0006)
-#define KDATA_MIXER_WORD7               (KDATA_BASE_ADDR2 + 0x0007)
-#define KDATA_MIXER_WORD8               (KDATA_BASE_ADDR2 + 0x0008)
-#define KDATA_MIXER_WORD9               (KDATA_BASE_ADDR2 + 0x0009)
-#define KDATA_MIXER_WORDA               (KDATA_BASE_ADDR2 + 0x000A)
-#define KDATA_MIXER_WORDB               (KDATA_BASE_ADDR2 + 0x000B)
-#define KDATA_MIXER_WORDC               (KDATA_BASE_ADDR2 + 0x000C)
-#define KDATA_MIXER_WORDD               (KDATA_BASE_ADDR2 + 0x000D)
-#define KDATA_MIXER_WORDE               (KDATA_BASE_ADDR2 + 0x000E)
-#define KDATA_MIXER_WORDF               (KDATA_BASE_ADDR2 + 0x000F)
-
-#define KDATA_MIXER_XFER0               (KDATA_BASE_ADDR2 + 0x0010)
-#define KDATA_MIXER_XFER1               (KDATA_BASE_ADDR2 + 0x0011)
-#define KDATA_MIXER_XFER2               (KDATA_BASE_ADDR2 + 0x0012)
-#define KDATA_MIXER_XFER3               (KDATA_BASE_ADDR2 + 0x0013)
-#define KDATA_MIXER_XFER4               (KDATA_BASE_ADDR2 + 0x0014)
-#define KDATA_MIXER_XFER5               (KDATA_BASE_ADDR2 + 0x0015)
-#define KDATA_MIXER_XFER6               (KDATA_BASE_ADDR2 + 0x0016)
-#define KDATA_MIXER_XFER7               (KDATA_BASE_ADDR2 + 0x0017)
-#define KDATA_MIXER_XFER8               (KDATA_BASE_ADDR2 + 0x0018)
-#define KDATA_MIXER_XFER9               (KDATA_BASE_ADDR2 + 0x0019)
-#define KDATA_MIXER_XFER_ENDMARK        (KDATA_BASE_ADDR2 + 0x001A)
-
-#define KDATA_MIXER_TASK_NUMBER         (KDATA_BASE_ADDR2 + 0x001B)
-#define KDATA_CURRENT_MIXER             (KDATA_BASE_ADDR2 + 0x001C)
-#define KDATA_MIXER_ACTIVE              (KDATA_BASE_ADDR2 + 0x001D)
-#define KDATA_MIXER_BANK_STATUS         (KDATA_BASE_ADDR2 + 0x001E)
-#define KDATA_DAC_LEFT_VOLUME          (KDATA_BASE_ADDR2 + 0x001F)
-#define KDATA_DAC_RIGHT_VOLUME          (KDATA_BASE_ADDR2 + 0x0020)
-
-#define MAX_INSTANCE_MINISRC            (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC)
-#define MAX_VIRTUAL_DMA_CHANNELS        (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0)
-#define MAX_VIRTUAL_MIXER_CHANNELS      (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0)
-#define MAX_VIRTUAL_ADC1_CHANNELS       (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0)
-
-/*
- * client data area offsets
- */
-#define CDATA_INSTANCE_READY            0x00
-
-#define CDATA_HOST_SRC_ADDRL            0x01
-#define CDATA_HOST_SRC_ADDRH            0x02
-#define CDATA_HOST_SRC_END_PLUS_1L      0x03
-#define CDATA_HOST_SRC_END_PLUS_1H      0x04
-#define CDATA_HOST_SRC_CURRENTL         0x05
-#define CDATA_HOST_SRC_CURRENTH         0x06
-
-#define CDATA_IN_BUF_CONNECT            0x07
-#define CDATA_OUT_BUF_CONNECT           0x08
-
-#define CDATA_IN_BUF_BEGIN              0x09
-#define CDATA_IN_BUF_END_PLUS_1         0x0A
-#define CDATA_IN_BUF_HEAD               0x0B
-#define CDATA_IN_BUF_TAIL               0x0C
-#define CDATA_OUT_BUF_BEGIN             0x0D
-#define CDATA_OUT_BUF_END_PLUS_1        0x0E
-#define CDATA_OUT_BUF_HEAD              0x0F
-#define CDATA_OUT_BUF_TAIL              0x10
-
-#define CDATA_DMA_CONTROL               0x11
-#define CDATA_RESERVED                  0x12
-
-#define CDATA_FREQUENCY                 0x13
-#define CDATA_LEFT_VOLUME               0x14
-#define CDATA_RIGHT_VOLUME              0x15
-#define CDATA_LEFT_SUR_VOL              0x16
-#define CDATA_RIGHT_SUR_VOL             0x17
-
-#define CDATA_HEADER_LEN                0x18
-
-#define SRC3_DIRECTION_OFFSET           CDATA_HEADER_LEN
-#define SRC3_MODE_OFFSET                (CDATA_HEADER_LEN + 1)
-#define SRC3_WORD_LENGTH_OFFSET         (CDATA_HEADER_LEN + 2)
-#define SRC3_PARAMETER_OFFSET           (CDATA_HEADER_LEN + 3)
-#define SRC3_COEFF_ADDR_OFFSET          (CDATA_HEADER_LEN + 8)
-#define SRC3_FILTAP_ADDR_OFFSET         (CDATA_HEADER_LEN + 10)
-#define SRC3_TEMP_INBUF_ADDR_OFFSET     (CDATA_HEADER_LEN + 16)
-#define SRC3_TEMP_OUTBUF_ADDR_OFFSET    (CDATA_HEADER_LEN + 17)
-
-#define MINISRC_IN_BUFFER_SIZE   ( 0x50 * 2 )
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_OUT_BUFFER_SIZE  ( 0x50 * 2 * 2)
-#define MINISRC_TMP_BUFFER_SIZE  ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 )
-#define MINISRC_BIQUAD_STAGE    2
-#define MINISRC_COEF_LOC          0X175
-
-#define DMACONTROL_BLOCK_MASK           0x000F
-#define  DMAC_BLOCK0_SELECTOR           0x0000
-#define  DMAC_BLOCK1_SELECTOR           0x0001
-#define  DMAC_BLOCK2_SELECTOR           0x0002
-#define  DMAC_BLOCK3_SELECTOR           0x0003
-#define  DMAC_BLOCK4_SELECTOR           0x0004
-#define  DMAC_BLOCK5_SELECTOR           0x0005
-#define  DMAC_BLOCK6_SELECTOR           0x0006
-#define  DMAC_BLOCK7_SELECTOR           0x0007
-#define  DMAC_BLOCK8_SELECTOR           0x0008
-#define  DMAC_BLOCK9_SELECTOR           0x0009
-#define  DMAC_BLOCKA_SELECTOR           0x000A
-#define  DMAC_BLOCKB_SELECTOR           0x000B
-#define  DMAC_BLOCKC_SELECTOR           0x000C
-#define  DMAC_BLOCKD_SELECTOR           0x000D
-#define  DMAC_BLOCKE_SELECTOR           0x000E
-#define  DMAC_BLOCKF_SELECTOR           0x000F
-#define DMACONTROL_PAGE_MASK            0x00F0
-#define  DMAC_PAGE0_SELECTOR            0x0030
-#define  DMAC_PAGE1_SELECTOR            0x0020
-#define  DMAC_PAGE2_SELECTOR            0x0010
-#define  DMAC_PAGE3_SELECTOR            0x0000
-#define DMACONTROL_AUTOREPEAT           0x1000
-#define DMACONTROL_STOPPED              0x2000
-#define DMACONTROL_DIRECTION            0x0100
-
-
-/*
- * DSP Code images
- */
-
-static u16 assp_kernel_image[] = {
-    0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 
-    0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, 
-    0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, 
-    0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, 
-    0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, 
-    0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, 
-    0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, 
-    0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, 
-    0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, 
-    0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, 
-    0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, 
-    0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, 
-    0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, 
-    0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, 
-    0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, 
-    0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, 
-    0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, 
-    0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, 
-    0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, 
-    0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, 
-    0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, 
-    0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, 
-    0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, 
-    0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, 
-    0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, 
-    0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, 
-    0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, 
-    0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, 
-    0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, 
-    0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, 
-    0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, 
-    0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 
-    0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, 
-    0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, 
-    0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, 
-    0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, 
-    0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 
-    0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, 
-    0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, 
-    0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, 
-    0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, 
-    0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, 
-    0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 
-    0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, 
-    0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, 
-    0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, 
-    0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 
-    0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, 
-    0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, 
-    0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, 
-    0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, 
-    0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, 
-    0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, 
-    0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, 
-    0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, 
-    0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 
-    0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, 
-    0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 
-    0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, 
-    0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, 
-    0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, 
-    0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, 
-    0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, 
-    0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, 
-    0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, 
-    0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, 
-    0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, 
-    0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, 
-    0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, 
-    0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, 
-    0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, 
-    0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, 
-    0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, 
-    0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, 
-    0xBE3A, 
-};
-
-/*
- * Mini sample rate converter code image
- * that is to be loaded at 0x400 on the DSP.
- */
-static u16 assp_minisrc_image[] = {
-
-    0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 
-    0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 
-    0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, 
-    0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, 
-    0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, 
-    0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, 
-    0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, 
-    0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, 
-    0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, 
-    0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, 
-    0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, 
-    0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, 
-    0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, 
-    0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, 
-    0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, 
-    0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, 
-    0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, 
-    0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, 
-    0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, 
-    0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, 
-    0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, 
-    0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, 
-    0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, 
-    0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, 
-    0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, 
-    0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, 
-    0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, 
-    0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, 
-    0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, 
-    0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, 
-    0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, 
-    0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
-};
-
diff --git a/sound/oss/maui.c b/sound/oss/maui.c
deleted file mode 100644 (file)
index 317f225..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * sound/oss/maui.c
- *
- * The low level driver for Turtle Beach Maui and Tropez.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *     Changes:
- *             Alan Cox                General clean up, use kernel IRQ 
- *                                     system
- *             Christoph Hellwig       Adapted to module_init/module_exit
- *             Bartlomiej Zolnierkiewicz
- *                                     Added __init to download_code()
- *
- *     Status:
- *             Andrew J. Kroll         Tested 06/01/1999 with:
- *                                     * OSWF.MOT File Version: 1.15
- *                                     * OSWF.MOT File Dated: 09/12/94
- *                                     * Older versions will cause problems.
- */
-
-#include <linux/interrupt.h>
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include "sound_config.h"
-#include "sound_firmware.h"
-
-#include "mpu401.h"
-
-static int      maui_base = 0x330;
-
-static volatile int irq_ok;
-static int     *maui_osp;
-
-#define HOST_DATA_PORT (maui_base + 2)
-#define HOST_STAT_PORT (maui_base + 3)
-#define HOST_CTRL_PORT (maui_base + 3)
-
-#define STAT_TX_INTR   0x40
-#define STAT_TX_AVAIL  0x20
-#define STAT_TX_IENA   0x10
-#define STAT_RX_INTR   0x04
-#define STAT_RX_AVAIL  0x02
-#define STAT_RX_IENA   0x01
-
-static int      (*orig_load_patch)(int dev, int format, const char __user *addr,
-                             int offs, int count, int pmgr_flag) = NULL;
-
-#include "maui_boot.h"
-
-static int maui_wait(int mask)
-{
-       int i;
-
-       /*
-        * Perform a short initial wait without sleeping
-        */
-
-       for (i = 0; i < 100; i++)
-               if (inb(HOST_STAT_PORT) & mask)
-                       return 1;
-
-       /*
-        * Wait up to 15 seconds with sleeping
-        */
-
-       for (i = 0; i < 150; i++) {
-               if (inb(HOST_STAT_PORT) & mask)
-                       return 1;
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(HZ / 10);
-               if (signal_pending(current))
-                       return 0;
-       }
-       return 0;
-}
-
-static int maui_read(void)
-{
-       if (maui_wait(STAT_RX_AVAIL))
-               return inb(HOST_DATA_PORT);
-       return -1;
-}
-
-static int maui_write(unsigned char data)
-{
-       if (maui_wait(STAT_TX_AVAIL)) {
-               outb((data), HOST_DATA_PORT);
-               return 1;
-       }
-       printk(KERN_WARNING "Maui: Write timeout\n");
-       return 0;
-}
-
-static irqreturn_t mauiintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       irq_ok = 1;
-       return IRQ_HANDLED;
-}
-
-static int __init download_code(void)
-{
-       int i, lines = 0;
-       int eol_seen = 0, done = 0;
-       int skip = 1;
-
-       printk(KERN_INFO "Code download (%d bytes): ", maui_osLen);
-
-       for (i = 0; i < maui_osLen; i++) {
-               if (maui_os[i] != '\r') {
-                       if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n'))) {
-                               skip = 0;
-
-                               if (maui_os[i] == '\n')
-                                       eol_seen = skip = 1;
-                               else if (maui_os[i] == 'S') {
-                                       if (maui_os[i + 1] == '8')
-                                               done = 1;
-                                       if (!maui_write(0xF1))
-                                               goto failure;
-                                       if (!maui_write('S'))
-                                               goto failure;
-                               } else {
-                                       if (!maui_write(maui_os[i]))
-                                               goto failure;
-                               }
-
-                               if (eol_seen) {
-                                       int c = 0;
-                                       int n;
-
-                                       eol_seen = 0;
-
-                                       for (n = 0; n < 2; n++) {
-                                               if (maui_wait(STAT_RX_AVAIL)) {
-                                                       c = inb(HOST_DATA_PORT);
-                                                       break;
-                                               }
-                                       }
-                                       if (c != 0x80) {
-                                               printk("Download not acknowledged\n");
-                                               return 0;
-                                       }
-                                       else if (!(lines++ % 10))
-                                               printk(".");
-
-                                       if (done) {
-                                               printk("\n");
-                                               printk(KERN_INFO "Download complete\n");
-                                               return 1;
-                                       }
-                               }
-                       }
-               }
-       }
-
-failure:
-       printk("\n");
-       printk(KERN_ERR "Download failed!!!\n");
-       return 0;
-}
-
-static int __init maui_init(int irq)
-{
-       unsigned char bits;
-
-       switch (irq) {
-               case 9:
-                       bits = 0x00;
-                       break;
-               case 5:
-                       bits = 0x08;
-                       break;
-               case 12:
-                       bits = 0x10;
-                       break;
-               case 15:
-                       bits = 0x18;
-                       break;
-
-               default:
-                       printk(KERN_ERR "Maui: Invalid IRQ %d\n", irq);
-                       return 0;
-       }
-       outb((0x00), HOST_CTRL_PORT);   /* Reset */
-       outb((bits), HOST_DATA_PORT);   /* Set the IRQ bits */
-       outb((bits | 0x80), HOST_DATA_PORT);    /* Set the IRQ bits again? */
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-       outb((0xD0), HOST_CTRL_PORT);   /* Cause interrupt */
-
-#ifdef CONFIG_SMP
-       {
-               int i;
-               for (i = 0; i < 1000000 && !irq_ok; i++)
-                       ;
-               if (!irq_ok)
-                       return 0;
-       }
-#endif
-       outb((0x80), HOST_CTRL_PORT);   /* Leave reset */
-
-       printk(KERN_INFO "Turtle Beach Maui initialization\n");
-
-       if (!download_code())
-               return 0;
-
-       outb((0xE0), HOST_CTRL_PORT);   /* Normal operation */
-
-       /* Select mpu401 mode */
-
-       maui_write(0xf0);
-       maui_write(1);
-       if (maui_read() != 0x80) {
-               maui_write(0xf0);
-               maui_write(1);
-               if (maui_read() != 0x80)
-                       printk(KERN_ERR "Maui didn't acknowledge set HW mode command\n");
-       }
-       printk(KERN_INFO "Maui initialized OK\n");
-       return 1;
-}
-
-static int maui_short_wait(int mask) {
-       int i;
-
-       for (i = 0; i < 1000; i++) {
-               if (inb(HOST_STAT_PORT) & mask) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static int maui_load_patch(int dev, int format, const char __user *addr,
-               int offs, int count, int pmgr_flag)
-{
-
-       struct sysex_info header;
-       unsigned long left, src_offs;
-       int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
-       int i;
-
-       if (format == SYSEX_PATCH)      /* Handled by midi_synth.c */
-               return orig_load_patch(dev, format, addr, offs, count, pmgr_flag);
-
-       if (format != MAUI_PATCH)
-       {
-                 printk(KERN_WARNING "Maui: Unknown patch format\n");
-       }
-       if (count < hdr_size) {
-/*               printk("Maui error: Patch header too short\n");*/
-                 return -EINVAL;
-       }
-       count -= hdr_size;
-
-       /*
-        * Copy the header from user space but ignore the first bytes which have
-        * been transferred already.
-        */
-
-       if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs))
-               return -EFAULT;
-
-       if (count < header.len) {
-                 printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len);
-                 header.len = count;
-       }
-       left = header.len;
-       src_offs = 0;
-
-       for (i = 0; i < left; i++) {
-               unsigned char   data;
-
-               if(get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i])))
-                       return -EFAULT;
-               if (i == 0 && !(data & 0x80))
-                       return -EINVAL;
-
-               if (maui_write(data) == -1)
-                       return -EIO;
-       }
-
-       if ((i = maui_read()) != 0x80) {
-               if (i != -1)
-                       printk("Maui: Error status %02x\n", i);
-               return -EIO;
-       }
-       return 0;
-}
-
-static int __init probe_maui(struct address_info *hw_config)
-{
-       struct resource *ports;
-       int this_dev;
-       int i;
-       int tmp1, tmp2, ret;
-
-       ports = request_region(hw_config->io_base, 2, "mpu401");
-       if (!ports)
-               return 0;
-
-       if (!request_region(hw_config->io_base + 2, 6, "Maui"))
-               goto out;
-
-       maui_base = hw_config->io_base;
-       maui_osp = hw_config->osp;
-
-       if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0)
-               goto out2;
-
-       /*
-        * Initialize the processor if necessary
-        */
-
-       if (maui_osLen > 0) {
-               if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) ||
-                       !maui_write(0x9F) ||    /* Report firmware version */
-                       !maui_short_wait(STAT_RX_AVAIL) ||
-                       maui_read() == -1 || maui_read() == -1)
-                       if (!maui_init(hw_config->irq))
-                               goto out3;
-       }
-       if (!maui_write(0xCF))  /* Report hardware version */ {
-               printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-               goto out3;
-       }
-       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) {
-               printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n");
-               goto out3;
-       }
-       if (tmp1 == 0xff || tmp2 == 0xff)
-               goto out3;
-       printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2);
-
-       if (!maui_write(0x9F))  /* Report firmware version */
-               goto out3;
-       if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1)
-               goto out3;
-
-       printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2);
-
-       if (!maui_write(0x85))  /* Report free DRAM */
-               goto out3;
-       tmp1 = 0;
-       for (i = 0; i < 4; i++) {
-               tmp1 |= maui_read() << (7 * i);
-       }
-       printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024);
-
-       for (i = 0; i < 1000; i++)
-               if (probe_mpu401(hw_config, ports))
-                       break;
-
-       ret = probe_mpu401(hw_config, ports);
-       if (!ret)
-               goto out3;
-
-       conf_printf("Maui", hw_config);
-
-       hw_config->irq *= -1;
-       hw_config->name = "Maui";
-       attach_mpu401(hw_config, THIS_MODULE);
-
-       if (hw_config->slots[1] != -1)  /* The MPU401 driver installed itself */ {
-               struct synth_operations *synth;
-
-               this_dev = hw_config->slots[1];
-
-               /*
-                * Intercept patch loading calls so that they can be handled
-                * by the Maui driver.
-                */
-
-               synth = midi_devs[this_dev]->converter;
-               if (synth != NULL) {
-                       synth->id = "MAUI";
-                       orig_load_patch = synth->load_patch;
-                       synth->load_patch = &maui_load_patch;
-               } else
-                       printk(KERN_ERR "Maui: Can't install patch loader\n");
-       }
-       return 1;
-
-out3:
-       free_irq(hw_config->irq, NULL);
-out2:
-       release_region(hw_config->io_base + 2, 6);
-out:
-       release_region(hw_config->io_base, 2);
-       return 0;
-}
-
-static void __exit unload_maui(struct address_info *hw_config)
-{
-       int irq = hw_config->irq;
-       release_region(hw_config->io_base + 2, 6);
-       unload_mpu401(hw_config);
-
-       if (irq < 0)
-               irq = -irq;
-       if (irq > 0)
-               free_irq(irq, NULL);
-}
-
-static int fw_load;
-
-static struct address_info cfg;
-
-static int __initdata io = -1;
-static int __initdata irq = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-
-/*
- *     Install a Maui card. Needs mpu401 loaded already.
- */
-
-static int __init init_maui(void)
-{
-       printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n");
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-
-       if (cfg.io_base == -1 || cfg.irq == -1) {
-               printk(KERN_INFO "maui: irq and io must be set.\n");
-               return -EINVAL;
-       }
-
-       if (maui_os == NULL) {
-               fw_load = 1;
-               maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os);
-       }
-       if (probe_maui(&cfg) == 0)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit cleanup_maui(void)
-{
-       if (fw_load && maui_os)
-               vfree(maui_os);
-       unload_maui(&cfg);
-}
-
-module_init(init_maui);
-module_exit(cleanup_maui);
-
-#ifndef MODULE
-static int __init setup_maui(char *str)
-{
-        /* io, irq */
-       int ints[3];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io = ints[1];
-       irq = ints[2];
-
-       return 1;
-}
-
-__setup("maui=", setup_maui);
-#endif
-MODULE_LICENSE("GPL");
index 321f4c4b5a7bc6cdb9858f0bd0e90bc54fd9f4f2..162d07cc489f6fba5411c8ccb8b884868d0ef11c 100644 (file)
@@ -432,16 +432,7 @@ static void mpu401_input_loop(struct mpu_config *devc)
        devc->m_busy = 0;
 }
 
-int intchk_mpu401(void *dev_id)
-{
-       struct mpu_config *devc;
-       int dev = (int) dev_id;
-
-       devc = &dev_conf[dev];
-       return input_avail(devc);
-}
-
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
+static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
 {
        struct mpu_config *devc;
        int dev = (int) dev_id;
@@ -1761,8 +1752,6 @@ static int mpu_timer_init(int midi_dev)
 EXPORT_SYMBOL(probe_mpu401);
 EXPORT_SYMBOL(attach_mpu401);
 EXPORT_SYMBOL(unload_mpu401);
-EXPORT_SYMBOL(intchk_mpu401);
-EXPORT_SYMBOL(mpuintr);
 
 static struct address_info cfg;
 
index bdc5bde641e6b7fc56dfbb1b2e40df9bda0cf9bd..84c0e9522ef7e674cc75e86606e5585b3aae410c 100644 (file)
@@ -10,5 +10,3 @@ int probe_mpu401(struct address_info *hw_config, struct resource *ports);
 int attach_mpu401(struct address_info * hw_config, struct module *owner);
 void unload_mpu401(struct address_info *hw_info);
 
-int intchk_mpu401(void *dev_id);
-irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
diff --git a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c
deleted file mode 100644 (file)
index 2535ed0..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * sound/oss/opl3sa.c
- *
- * Low level driver for Yamaha YMF701B aka OPL3-SA chip
- * 
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- *     Alan Cox                Modularisation
- *     Christoph Hellwig       Adapted to module_init/module_exit
- *     Arnaldo C. de Melo      got rid of attach_uart401
- *
- * FIXME:
- *     Check for install of mpu etc is wrong, should check result of the mss stuff
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-
-#undef  SB_OK
-
-#include "sound_config.h"
-
-#include "ad1848.h"
-#include "mpu401.h"
-
-#ifdef SB_OK
-#include "sb.h"
-static int sb_initialized;
-#endif
-
-static DEFINE_SPINLOCK(lock);
-
-static unsigned char opl3sa_read(int addr)
-{
-       unsigned long flags;
-       unsigned char tmp;
-
-       spin_lock_irqsave(&lock,flags);
-       outb((0x1d), 0xf86);    /* password */
-       outb(((unsigned char) addr), 0xf86);    /* address */
-       tmp = inb(0xf87);       /* data */
-       spin_unlock_irqrestore(&lock,flags);
-
-       return tmp;
-}
-
-static void opl3sa_write(int addr, int data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&lock,flags);
-       outb((0x1d), 0xf86);    /* password */
-       outb(((unsigned char) addr), 0xf86);    /* address */
-       outb(((unsigned char) data), 0xf87);    /* data */
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init opl3sa_detect(void)
-{
-       int tmp;
-
-       if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04)
-       {
-               DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01)));
-               /* return 0; */
-       }
-
-       /*
-        * Check that the password feature has any effect
-        */
-       
-       if (inb(0xf87) == tmp)
-       {
-               DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87)));
-               return 0;
-       }
-       tmp = (opl3sa_read(0x04) & 0xe0) >> 5;
-
-       if (tmp != 0 && tmp != 1)
-       {
-               DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp));
-               return 0;
-       }
-       DDB(printk("OPL3-SA mode %x detected\n", tmp));
-
-       opl3sa_write(0x01, 0x00);       /* Disable MSS */
-       opl3sa_write(0x02, 0x00);       /* Disable SB */
-       opl3sa_write(0x03, 0x00);       /* Disable MPU */
-
-       return 1;
-}
-
-/*
- *    Probe and attach routines for the Windows Sound System mode of
- *     OPL3-SA
- */
-
-static int __init probe_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-       unsigned char tmp = 0x24;       /* WSS enable */
-
-       /*
-        * Check if the IO port returns valid signature. The original MS Sound
-        * system returns 0x04 while some cards (OPL3-SA for example)
-        * return 0x00.
-        */
-
-       if (!opl3sa_detect())
-       {
-               printk(KERN_ERR "OSS: OPL3-SA chip not found\n");
-               return 0;
-       }
-       
-       switch (hw_config->io_base)
-       {
-               case 0x530:
-                       tmp |= 0x00;
-                       break;
-               case 0xe80:
-                       tmp |= 0x08;
-                       break;
-               case 0xf40:
-                       tmp |= 0x10;
-                       break;
-               case 0x604:
-                       tmp |= 0x18;
-                       break;
-               default:
-                       printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base);
-                 return 0;
-       }
-
-       opl3sa_write(0x01, tmp);        /* WSS setup register */
-
-       return probe_ms_sound(hw_config, ports);
-}
-
-static void __init attach_opl3sa_wss(struct address_info *hw_config, struct resource *ports)
-{
-       int nm = num_mixers;
-
-       /* FIXME */
-       attach_ms_sound(hw_config, ports, THIS_MODULE);
-       if (num_mixers > nm)    /* A mixer was installed */
-       {
-               AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);
-               AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);
-               AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);
-       }
-}
-
-
-static int __init probe_opl3sa_mpu(struct address_info *hw_config)
-{
-       unsigned char conf;
-       static signed char irq_bits[] = {
-               -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4
-       };
-
-       if (hw_config->irq > 10)
-       {
-               printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-       if (irq_bits[hw_config->irq] == -1)
-       {
-               printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
-               return 0;
-       }
-       switch (hw_config->io_base)
-       {
-               case 0x330:
-                       conf = 0x00;
-                       break;
-               case 0x332:
-                       conf = 0x20;
-                       break;
-               case 0x334:
-                       conf = 0x40;
-                       break;
-               case 0x300:
-                       conf = 0x60;
-                       break;
-               default:
-                       return 0;       /* Invalid port */
-       }
-
-       conf |= 0x83;           /* MPU & OPL3 (synth) & game port enable */
-       conf |= irq_bits[hw_config->irq] << 2;
-
-       opl3sa_write(0x03, conf);
-
-       hw_config->name = "OPL3-SA (MPU401)";
-
-       return probe_uart401(hw_config, THIS_MODULE);
-}
-
-static void __exit unload_opl3sa_wss(struct address_info *hw_config)
-{
-       int dma2 = hw_config->dma2;
-
-       if (dma2 == -1)
-               dma2 = hw_config->dma;
-
-       release_region(0xf86, 2);
-       release_region(hw_config->io_base, 4);
-
-       ad1848_unload(hw_config->io_base + 4,
-                     hw_config->irq,
-                     hw_config->dma,
-                     dma2,
-                     0);
-       sound_unload_audiodev(hw_config->slots[0]);
-}
-
-static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config)
-{
-       unload_uart401(hw_config);
-}
-
-#ifdef SB_OK
-static inline void __exit unload_opl3sa_sb(struct address_info *hw_config)
-{
-       sb_dsp_unload(hw_config);
-}
-#endif
-
-static int found_mpu;
-
-static struct address_info cfg;
-static struct address_info cfg_mpu;
-
-static int __initdata io       = -1;
-static int __initdata irq      = -1;
-static int __initdata dma      = -1;
-static int __initdata dma2     = -1;
-static int __initdata mpu_io   = -1;
-static int __initdata mpu_irq  = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(mpu_io, int, 0);
-module_param(mpu_irq, int, 0);
-
-static int __init init_opl3sa(void)
-{
-       struct resource *ports;
-       if (io == -1 || irq == -1 || dma == -1) {
-               printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n");
-               return -EINVAL;
-       }
-
-       cfg.io_base = io;
-       cfg.irq = irq;
-       cfg.dma = dma;
-       cfg.dma2 = dma2;
-       
-       cfg_mpu.io_base = mpu_io;
-       cfg_mpu.irq = mpu_irq;
-
-       ports = request_region(io + 4, 4, "ad1848");
-       if (!ports)
-               return -EBUSY;
-
-       if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ {
-               release_region(io + 4, 4);
-               return 0;
-       }
-
-       if (!request_region(io, 4, "WSS config")) {
-               release_region(0x86, 2);
-               release_region(io + 4, 4);
-               return 0;
-       }
-
-       if (probe_opl3sa_wss(&cfg, ports) == 0) {
-               release_region(0xf86, 2);
-               release_region(io, 4);
-               release_region(io + 4, 4);
-               return -ENODEV;
-       }
-
-       found_mpu=probe_opl3sa_mpu(&cfg_mpu);
-
-       attach_opl3sa_wss(&cfg, ports);
-       return 0;
-}
-
-static void __exit cleanup_opl3sa(void)
-{
-       if(found_mpu)
-               unload_opl3sa_mpu(&cfg_mpu);
-       unload_opl3sa_wss(&cfg);
-}
-
-module_init(init_opl3sa);
-module_exit(cleanup_opl3sa);
-
-#ifndef MODULE
-static int __init setup_opl3sa(char *str)
-{
-       /* io, irq, dma, dma2, mpu_io, mpu_irq */
-       int ints[7];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma2    = ints[4];
-       mpu_io  = ints[5];
-       mpu_irq = ints[6];
-
-       return 1;
-}
-
-__setup("opl3sa=", setup_opl3sa);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
deleted file mode 100644 (file)
index f17d25b..0000000
+++ /dev/null
@@ -1,1857 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-   based on es1370.c
-
-
-
-   *  10 Jan 2001: 0.1 initial version
-   *  19 Jan 2001: 0.2 fixed bug in select()
-   *  27 Apr 2001: 0.3 more than one card usable
-   *  11 May 2001: 0.4 fixed for SMP, included into kernel source tree
-   *  17 May 2001: 0.5 draining code didn't work on new cards
-   *  18 May 2001: 0.6 remove synchronize_irq() call 
-   *  17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards
-   *   2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!)
-                       Marcus Meissner <Marcus.Meissner@caldera.de>
-
-                      Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-                      HP20020108 fixed handling of "large" read()
-                      HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-                      HP20020118 made mixer ioctl and handling of devices>1 more safe
-                      HP20020201 fixed handling of "large" read() properly
-                      added REV 1.5 S/P-DIF receiver support
-                      SNDCTL_DSP_SPEED now returns the actual speed
-   *  10 Aug 2002: added synchronize_irq() again
-
-TODO:
-   - test more than one card --- done
-   - check for pci IOREGION (see es1370) in rme96xx_probe ??
-   - error detection
-   - mmap interface
-   - mixer mmap interface
-   - mixer ioctl
-   - get rid of noise upon first open (why ??)
-   - allow multiple open (at least for read)
-   - allow multiple open for non overlapping regions
-   - recheck the multiple devices part (offsets of different devices, etc)
-   - do decent draining in _release --- done
-   - SMP support
-   - what about using fragstotal>2 for small fragsize? (HP20020118)
-   - add support for AFMT_S32_LE
-*/
-
-#ifndef RMEVERSION
-#define RMEVERSION "0.8"
-#endif
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/sound.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/mutex.h>
-
-#include <asm/dma.h>
-#include <asm/page.h>
-
-#include "rme96xx.h"
-
-#define NR_DEVICE 2
-
-static int devices = 1;
-module_param(devices, int, 0);
-MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver");
-
-
-MODULE_AUTHOR("Guenter Geiger, geiger@debian.org");
-MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver");
-MODULE_LICENSE("GPL");
-
-
-#ifdef DEBUG
-#define DBG(x) printk("RME_DEBUG:");x
-#define COMM(x) printk("RME_COMM: " x "\n");
-#else
-#define DBG(x) while (0) {}
-#define COMM(x)
-#endif
-
-/*-------------------------------------------------------------------------- 
-                        Preporcessor Macros and Definitions
- --------------------------------------------------------------------------*/
-
-#define RME96xx_MAGIC 0x6473
-
-/* Registers-Space in offsets from base address with 16MByte size */
-
-#define RME96xx_IO_EXTENT     16l*1024l*1024l
-#define RME96xx_CHANNELS_PER_CARD 26
-
-/*                  Write - Register */
-
-/* 0,4,8,12,16,20,24,28 ... hardware init (erasing fifo-pointer intern) */
-#define RME96xx_num_of_init_regs   8
-
-#define RME96xx_init_buffer       (0/4)
-#define RME96xx_play_buffer       (32/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_rec_buffer        (36/4)  /* pointer to 26x64kBit RAM from mainboard */
-#define RME96xx_control_register  (64/4)  /* exact meaning see below */
-#define RME96xx_irq_clear         (96/4)  /* irq acknowledge */
-#define RME96xx_time_code         (100/4) /* if used with alesis adat */
-#define RME96xx_thru_base         (128/4) /* 132...228 Thru for 26 channels */
-#define RME96xx_thru_channels     RME96xx_CHANNELS_PER_CARD
-
-/*                     Read Register */
-
-#define RME96xx_status_register    0     /* meaning see below */
-
-
-
-/* Status Register: */
-/* ------------------------------------------------------------------------ */
-#define RME96xx_IRQ          0x0000001 /* IRQ is High if not reset by RMExx_irq_clear */
-#define RME96xx_lock_2       0x0000002 /* ADAT 3-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_1       0x0000004 /* ADAT 2-PLL: 1=locked, 0=unlocked */
-#define RME96xx_lock_0       0x0000008 /* ADAT 1-PLL: 1=locked, 0=unlocked */
-
-#define RME96xx_fs48         0x0000010 /* sample rate 0 ...44.1/88.2,  1 ... 48/96 Khz */
-#define RME96xx_wsel_rd      0x0000020 /* if Word-Clock is used and valid then 1 */
-#define RME96xx_buf_pos1     0x0000040 /* Bit 6..15 : Position of buffer-pointer in 64Bytes-blocks */
-#define RME96xx_buf_pos2     0x0000080 /* resolution +/- 1 64Byte/block (since 64Bytes bursts) */
-#define RME96xx_buf_pos3     0x0000100 /* 10 bits = 1024 values */
-#define RME96xx_buf_pos4     0x0000200 /* if we mask off the first 6 bits, we can take the status */
-#define RME96xx_buf_pos5     0x0000400 /* register as sample counter in the hardware buffer */
-#define RME96xx_buf_pos6     0x0000800 
-
-#define RME96xx_buf_pos7     0x0001000 
-#define RME96xx_buf_pos8     0x0002000 
-#define RME96xx_buf_pos9     0x0004000
-#define RME96xx_buf_pos10    0x0008000 
-
-#define RME96xx_sync_2       0x0010000 /* if ADAT-IN3 synced to system clock */
-#define RME96xx_sync_1       0x0020000 /* if ADAT-IN2 synced to system clock */
-#define RME96xx_sync_0       0x0040000 /* if ADAT-IN1 synced to system clock */
-#define RME96xx_DS_rd        0x0080000 /* 1=Double Speed, 0=Normal Speed */
-
-#define RME96xx_tc_busy      0x0100000 /* 1=time-code copy in progress (960ms) */
-#define RME96xx_tc_out       0x0200000 /* time-code out bit */
-#define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz  */
-#define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz, */
-
-#define RME96xx_F_2          0x1000000 /*  001=Rev 1.5+ external Crystal Chip */
-#define RME96xx_ERF          0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/
-#define RME96xx_buffer_id    0x4000000 /* toggles by each interrupt on rec/play */
-#define RME96xx_tc_valid     0x8000000 /* 1 = a signal is detected on time-code input */
-#define RME96xx_SPDIF_READ  0x10000000 /* byte available from Rev 1.5+ SPDIF interface */
-
-/* Status Register Fields */
-
-#define RME96xx_lock            (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2)
-#define RME96xx_sync            (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2)
-#define RME96xx_F               (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2)
-#define rme96xx_decode_spdif_rate(x) ((x)>>22)
-
-/* Bit 6..15 : h/w buffer pointer */
-#define RME96xx_buf_pos          0x000FFC0 
-/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
-   Rev G EEPROMS and Rev 1.5 cards or later.
-*/ 
-#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos))
-
-
-/* Control-Register: */                            
-/*--------------------------------------------------------------------------------*/
-
-#define RME96xx_start_bit      0x0001 /* start record/play */
-#define RME96xx_latency0       0x0002 /* Buffer size / latency */
-#define RME96xx_latency1       0x0004 /*   buffersize = 512Bytes * 2^n */
-#define RME96xx_latency2       0x0008 /*   0=64samples ... 7=8192samples */
-
-#define RME96xx_Master         0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */
-#define RME96xx_IE             0x0020 /* Interupt Enable */
-#define RME96xx_freq           0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
-#define RME96xx_freq1          0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */
-#define RME96xx_DS              0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME96xx_PRO            0x0200 /* SPDIF-OUT 0=consumer, 1=professional */
-#define RME96xx_EMP            0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */
-#define RME96xx_Dolby          0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */
-
-#define RME96xx_opt_out                0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */
-#define RME96xx_wsel            0x2000 /* use Wordclock as sync (overwrites master) */
-#define RME96xx_inp_0           0x4000 /* SPDIF-IN 00=optical (ADAT1), */
-#define RME96xx_inp_1           0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */
-
-#define RME96xx_SyncRef0       0x10000 /* preferred sync-source in autosync */
-#define RME96xx_SyncRef1       0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-
-#define RME96xx_SPDIF_RESET    (1<<18) /* Rev 1.5+: h/w SPDIF receiver */
-#define RME96xx_SPDIF_SELECT   (1<<19)
-#define RME96xx_SPDIF_CLOCK    (1<<20)
-#define RME96xx_SPDIF_WRITE    (1<<21)
-#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
-
-
-#define RME96xx_ctrl_init            (RME96xx_latency0 |\
-                                     RME96xx_Master |\
-                                     RME96xx_inp_1)
-                              
-
-
-/* Control register fields and shortcuts */
-
-#define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2)
-#define RME96xx_inp         (RME96xx_inp_0|RME96xx_inp_1)
-#define RME96xx_SyncRef    (RME96xx_SyncRef0|RME96xx_SyncRef1)
-#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL)
-
-/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1  (??? HP20020201) */
-
-#define RME96xx_SET_LATENCY(x)   (((x)&0x7)<<1)
-#define RME96xx_GET_LATENCY(x)   (((x)>>1)&0x7)
-#define RME96xx_SET_inp(x) (((x)&0x3)<<14)
-#define RME96xx_GET_inp(x)   (((x)>>14)&0x3)
-#define RME96xx_SET_SyncRef(x) (((x)&0x3)<<17)
-#define RME96xx_GET_SyncRef(x)   (((x)>>17)&0x3)
-
-
-/* buffer sizes */
-#define RME96xx_BYTES_PER_SAMPLE  4 /* sizeof(u32) */
-#define RME_16K 16*1024
-
-#define RME96xx_DMA_MAX_SAMPLES  (RME_16K)
-#define RME96xx_DMA_MAX_SIZE     (RME_16K * RME96xx_BYTES_PER_SAMPLE)
-#define RME96xx_DMA_MAX_SIZE_ALL (RME96xx_DMA_MAX_SIZE * RME96xx_CHANNELS_PER_CARD)
-
-#define RME96xx_NUM_OF_FRAGMENTS     2
-#define RME96xx_FRAGMENT_MAX_SIZE    (RME96xx_DMA_MAX_SIZE/2)
-#define RME96xx_FRAGMENT_MAX_SAMPLES (RME96xx_DMA_MAX_SAMPLES/2)
-#define RME96xx_MAX_LATENCY       7   /* 16k samples */
-
-
-#define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */
-#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */
-
-#define RME_MESS "rme96xx:"
-/*------------------------------------------------------------------------ 
-                  Types, struct and function declarations 
- ------------------------------------------------------------------------*/
-
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT RME_MESS" invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != RME96xx_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-
-static struct file_operations rme96xx_audio_fops;
-static struct file_operations rme96xx_mixer_fops;
-static int numcards;
-
-typedef int32_t raw_sample_t;
-
-typedef struct _rme96xx_info {
-
-       /* hardware settings */
-       int magic;
-       struct pci_dev * pcidev; /* pci_dev structure */
-       unsigned long __iomem *iobase;  
-       unsigned int irq;
-
-       /* list of rme96xx devices */
-       struct list_head devs;
-
-       spinlock_t lock;
-
-       u32 *recbuf;             /* memory for rec buffer */
-       u32 *playbuf;            /* memory for play buffer */
-
-       u32 control_register;
-
-       u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
-
-       int hw_rev;             /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
-       char *card_name;        /* hammerfall or hammerfall light names */
-
-       int open_count;         /* unused ???   HP20020201 */
-
-       int rate;
-       int latency;
-       unsigned int fragsize;
-       int started;
-
-       int hwptr; /* can be negativ because of pci burst offset  */
-       unsigned int hwbufid;  /* set by interrupt, buffer which is written/read now */
-       
-       struct dmabuf {
-
-               unsigned int format;
-               int formatshift;
-               int inchannels;       /* number of channels for device */
-               int outchannels;       /* number of channels for device */
-               int mono; /* if true, we play mono on 2 channels */
-               int inoffset; /* which channel is considered the first one */
-               int outoffset;
-               
-               /* state */
-               int opened;               /* open() made */
-               int started;              /* first write/read */
-               int mmapped;              /* mmap */
-               int open_mode;
-
-               struct _rme96xx_info *s;  
-
-               /* pointer to read/write position in buffer */
-               unsigned readptr;          
-               unsigned writeptr;          
-
-               unsigned error; /* over/underruns cleared on sync again */
-
-               /* waiting and locking */
-               wait_queue_head_t wait;
-               struct mutex  open_mutex;
-               wait_queue_head_t open_wait;
-
-       } dma[RME96xx_MAX_DEVS]; 
-
-       int dspnum[RME96xx_MAX_DEVS];  /* register with sound subsystem */ 
-       int mixer;  /* register with sound subsystem */ 
-} rme96xx_info;
-
-
-/* fiddling with the card (first level hardware control) */
-
-static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask)
-{
-
-       s->control_register|=mask;
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask)
-{
-
-       s->control_register&=(~mask);
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-
-}
-
-static inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
-{
-       int val;
-       u32 status;
-       status = readl(s->iobase + RME96xx_status_register);
-       val = (status & RME96xx_fs48) ? 48000 : 44100;
-       if (status & RME96xx_DS_rd)
-               val *= 2;
-       return val;
-}
-
-static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
-{
-       int val;
-       val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
-       if (s->control_register & RME96xx_DS)
-               val *= 2;
-       return val;
-}
-
-
-/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver   HP 20020201 */
-
-static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff)
-{
-       if (onoff) 
-               s->control_register |= mask;
-       else 
-               s->control_register &= ~mask;
-               
-       writel(s->control_register,s->iobase + RME96xx_control_register);
-}
-
-static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val)
-{
-       long mask;
-       long i;
-
-       for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
-               if (val & mask)
-                       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1);
-               else 
-                       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0);
-
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-       }
-}
-
-static int rme96xx_spdif_read_byte (rme96xx_info* s)
-{
-       long mask;
-       long val;
-       long i;
-
-       val = 0;
-
-       for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
-               if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ)
-                       val |= mask;
-               rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
-       }
-
-       return val;
-}
-
-static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data)
-{
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-       rme96xx_spdif_write_byte (s, 0x20);
-       rme96xx_spdif_write_byte (s, address);
-       rme96xx_spdif_write_byte (s, data);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-}
-
-
-static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address)
-{
-       int ret;
-
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-       rme96xx_spdif_write_byte (s, 0x20);
-       rme96xx_spdif_write_byte (s, address);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
-
-       rme96xx_spdif_write_byte (s, 0x21);
-       ret = rme96xx_spdif_read_byte (s);
-       rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
-
-       return ret;
-}
-
-static void rme96xx_initialize_spdif_receiver (rme96xx_info* s)
-{
-       /* XXX what unsets this ? */
-       /* no idea ???   HP 20020201 */
-
-       s->control_register |= RME96xx_SPDIF_RESET;
-
-       rme96xx_write_spdif_codec (s, 4, 0x40);
-       rme96xx_write_spdif_codec (s, 17, 0x13);
-       rme96xx_write_spdif_codec (s, 6, 0x02);
-}
-
-static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate)
-{
-       unsigned int rate_bits;
-
-       *spdifrate = 0x1;
-       if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) {
-               return -1;      /* error condition */
-       }
-       
-       if (s->hw_rev == 15) {
-
-               int x, y, ret;
-               
-               x = rme96xx_spdif_read_codec (s, 30);
-
-               if (x != 0) 
-                       y = 48000 * 64 / x;
-               else
-                       y = 0;
-
-               if      (y > 30400 && y < 33600)  {ret = 32000; *spdifrate = 0x7;}
-               else if (y > 41900 && y < 46000)  {ret = 44100; *spdifrate = 0x6;}
-               else if (y > 46000 && y < 50400)  {ret = 48000; *spdifrate = 0x5;}
-               else if (y > 60800 && y < 67200)  {ret = 64000; *spdifrate = 0x0;}
-               else if (y > 83700 && y < 92000)  {ret = 88200; *spdifrate = 0x4;}
-               else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;}
-               else                              {ret = 0; *spdifrate = 0x1;}
-               return ret;
-       }
-
-       rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F;
-
-       switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) {
-       case 0x7:
-               return 32000;
-               break;
-
-       case 0x6:
-               return 44100;
-               break;
-
-       case 0x5:
-               return 48000;
-               break;
-
-       case 0x4:
-               return 88200;
-               break;
-
-       case 0x3:
-               return 96000;
-               break;
-
-       case 0x0:
-               return 64000;
-               break;
-
-       default:
-               /* was an ALSA warning ...
-                 snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
-                 s->card_name, rate_bits);
-               */
-               return 0;
-               break;
-       }
-}
-
-/* end of code from ALSA card-rme9652.c */
-
-
-
-/* the hwbuf in the status register seems to have some jitter, to get rid of
-   it, we first only let the numbers grow, to be on the secure side we 
-   subtract a certain amount RME96xx_BURSTBYTES from the resulting number */
-
-/* the function returns the hardware pointer in bytes */
-#define RME96xx_BURSTBYTES -64  /* bytes by which hwptr could be off */
-
-static inline int rme96xx_gethwptr(rme96xx_info* s,int exact)
-{
-       unsigned long flags;
-       if (exact) {
-               unsigned int hwp;
-/* the hwptr seems to be rather unreliable :(, so we don't use it */
-               spin_lock_irqsave(&s->lock,flags);
-               
-               hwp  = readl(s->iobase + RME96xx_status_register) & 0xffc0;
-               s->hwptr = (hwp < s->hwptr) ? s->hwptr : hwp;
-//             s->hwptr = hwp;
-
-               spin_unlock_irqrestore(&s->lock,flags);
-               return (s->hwptr+RME96xx_BURSTBYTES) & ((s->fragsize<<1)-1);
-       }
-       return (s->hwbufid ? s->fragsize : 0);
-}
-
-static inline void rme96xx_setlatency(rme96xx_info* s,int l)
-{
-       s->latency = l;
-       s->fragsize = 1<<(8+l);
-       rme96xx_unset_ctrl(s,RME96xx_latency);
-       rme96xx_set_ctrl(s,RME96xx_SET_LATENCY(l));     
-}
-
-
-static void rme96xx_clearbufs(struct dmabuf* dma)
-{
-       int i,j;
-       unsigned long flags;
-
-       /* clear dmabufs */
-       for(i=0;i<devices;i++) {
-               for (j=0;j<dma->outchannels + dma->mono;j++)
-                       memset(&dma->s->playbuf[(dma->outoffset + j)*RME96xx_DMA_MAX_SAMPLES], 
-                              0, RME96xx_DMA_MAX_SIZE);
-       }
-       spin_lock_irqsave(&dma->s->lock,flags);
-       dma->writeptr = 0;
-       dma->readptr = 0;
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-}
-
-static int rme96xx_startcard(rme96xx_info *s,int stop)
-{
-       int i;
-       unsigned long flags;
-
-       COMM       ("startcard");
-       if(s->control_register & RME96xx_IE){
-               /* disable interrupt first */
-               
-               rme96xx_unset_ctrl( s,RME96xx_start_bit );
-               udelay(10);
-               rme96xx_unset_ctrl( s,RME96xx_IE);
-               spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-               s->started = 0;
-               spin_unlock_irqrestore(&s->lock,flags);
-               if (stop) {
-                    COMM("Sound card stopped");
-                    return 1;
-               }
-       }
-       COMM       ("interrupt disabled");
-       /* first initialize all pointers on card */
-       for(i=0;i<RME96xx_num_of_init_regs;i++){
-               writel(0,s->iobase + i);
-               udelay(10); /* ?? */
-       }
-       COMM       ("regs cleaned");
-
-       spin_lock_irqsave(&s->lock,flags); /* timing is critical */
-       udelay(10);
-       s->started = 1;
-       s->hwptr = 0;
-       spin_unlock_irqrestore(&s->lock,flags);
-
-       rme96xx_set_ctrl( s, RME96xx_IE | RME96xx_start_bit);
-
-
-       COMM("Sound card started");
-  
-       return 1;
-}
-
-
-static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp)
-{
-       int cnt;
-       int  swptr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dma->s->lock,flags); 
-       swptr = dma->writeptr;
-       cnt = (hwp - swptr);
-       
-       if (cnt < 0) {
-            cnt = ((dma->s->fragsize<<1) - swptr);
-       }
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-       return cnt;
-}
-
-static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp)
-{
-       int cnt;
-       int  swptr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dma->s->lock,flags); 
-       swptr = dma->readptr;
-       cnt = (hwp - swptr);
-        
-       if (cnt < 0) {
-               cnt = ((dma->s->fragsize<<1) - swptr);
-       }
-       spin_unlock_irqrestore(&dma->s->lock,flags);
-       return cnt;
-}
-
-
-static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop)
-{
-       int swptr = dma->writeptr;
-       switch (dma->format) {
-       case AFMT_S32_BLOCKED:
-       {
-            char __user * buf = (char __user *)buffer;
-            int cnt = count/dma->outchannels;
-            int i;
-            for (i=0;i < dma->outchannels;i++) {
-                 char* hwbuf =(char*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-                 hwbuf+=swptr;
-
-                 if (copy_from_user(hwbuf,buf, cnt))
-                      return -1;
-                 buf+=hop;
-            }
-            swptr+=cnt;
-            break;
-       }
-       case AFMT_S16_LE:
-       {
-            int i,j;
-            int cnt = count/dma->outchannels;
-            for (i=0;i < dma->outchannels + dma->mono;i++) {
-                    short __user * sbuf = (short __user *)buffer + i*(!dma->mono);
-                    short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES];          
-                    hwbuf+=(swptr>>1);
-                    for (j=0;j<(cnt>>1);j++) {
-                            hwbuf++; /* skip the low 16 bits */
-                            __get_user(*hwbuf++,sbuf++);
-                            sbuf+=(dma->outchannels-1);
-                    }
-            }
-            swptr += (cnt<<1);
-            break;
-       }
-       default:
-            printk(RME_MESS" unsupported format\n");
-            return -1;
-       } /* switch */
-
-       swptr&=((dma->s->fragsize<<1) -1);
-       dma->writeptr = swptr;
-
-       return 0;
-}
-
-/* The count argument is the number of bytes */
-static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop)
-{
-       int swptr = dma->readptr;
-       switch (dma->format) {
-       case AFMT_S32_BLOCKED:
-       {
-            char __user * buf = (char __user *)buffer;
-            int cnt = count/dma->inchannels;
-            int i;
-
-            for (i=0;i < dma->inchannels;i++) {
-                 char* hwbuf =(char*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];
-                 hwbuf+=swptr;
-
-                 if (copy_to_user(buf,hwbuf,cnt))
-                      return -1;
-                 buf+=hop;
-            }
-            swptr+=cnt;
-            break;
-       }
-       case AFMT_S16_LE:
-       {
-            int i,j;
-            int cnt = count/dma->inchannels;
-            for (i=0;i < dma->inchannels;i++) {
-                 short __user * sbuf = (short __user *)buffer + i;
-                 short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES];       
-                 hwbuf+=(swptr>>1);
-                 for (j=0;j<(cnt>>1);j++) {
-                      hwbuf++;
-                      __put_user(*hwbuf++,sbuf++);
-                      sbuf+=(dma->inchannels-1);
-                 }
-            }
-            swptr += (cnt<<1);
-            break;
-       }
-       default:
-            printk(RME_MESS" unsupported format\n");
-            return -1;
-       } /* switch */
-       
-       swptr&=((dma->s->fragsize<<1) -1);      
-       dma->readptr = swptr;
-       return 0;
-}
-
-
-static irqreturn_t rme96xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       int i;
-       rme96xx_info *s = (rme96xx_info *)dev_id;
-       struct dmabuf *db;
-       u32 status;
-       unsigned long flags;
-
-       status = readl(s->iobase + RME96xx_status_register);
-       if (!(status & RME96xx_IRQ)) {
-               return IRQ_NONE;
-       }
-
-       spin_lock_irqsave(&s->lock,flags);
-       writel(0,s->iobase + RME96xx_irq_clear);
-
-       s->hwbufid = (status & RME96xx_buffer_id)>>26;  
-       if ((status & 0xffc0) <= 256) s->hwptr = 0; 
-       for(i=0;i<devices;i++)
-       {
-               db = &(s->dma[i]);
-               if(db->started > 0)
-                       wake_up(&(db->wait));           
-       }  
-       spin_unlock_irqrestore(&s->lock,flags);
-       return IRQ_HANDLED;
-}
-
-
-
-/*---------------------------------------------------------------------------- 
- PCI detection and module initialization stuff 
- ----------------------------------------------------------------------------*/
-
-static void* busmaster_malloc(int size) {
-     int pg; /* 2 s exponent of memory size */
-        char *buf;
-
-        DBG(printk("kernel malloc pages ..\n"));
-        
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        buf = (char *) __get_free_pages(GFP_KERNEL | GFP_DMA, pg);
-
-        if (buf) {
-                struct page* page, *last_page;
-
-                page = virt_to_page(buf);
-                last_page = page + (1 << pg);
-                DBG(printk("setting reserved bit\n"));
-                while (page < last_page) {
-                       SetPageReserved(page);
-                        page++;
-                }
-               return buf;
-        }
-       DBG(printk("allocated %ld",(long)buf));
-       return NULL;
-}
-
-static void busmaster_free(void* ptr,int size) {
-        int pg;
-       struct page* page, *last_page;
-
-        if (ptr == NULL)
-                return;
-
-        for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++);
-
-        page = virt_to_page(ptr);
-        last_page = page + (1 << pg);
-        while (page < last_page) {
-               ClearPageReserved(page);
-               page++;
-       }
-       DBG(printk("freeing pages\n"));
-        free_pages((unsigned long) ptr, pg);
-       DBG(printk("done\n"));
-}
-
-/* initialize those parts of the info structure which are not pci detectable resources */
-
-static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) {
-
-       mutex_init(&dma->open_mutex);
-       init_waitqueue_head(&dma->open_wait);
-       init_waitqueue_head(&dma->wait);
-       dma->s = s; 
-       dma->error = 0;
-
-       dma->format = AFMT_S32_BLOCKED;
-       dma->formatshift = 0;
-       dma->inchannels = dma->outchannels = 1;
-       dma->inoffset = ioffset;
-       dma->outoffset = ooffset;
-
-       dma->opened=0;
-       dma->started=0;
-       dma->mmapped=0;
-       dma->open_mode=0;
-       dma->mono=0;
-
-       rme96xx_clearbufs(dma);
-       return 0;
-}
-
-
-static int rme96xx_init(rme96xx_info* s)
-{
-       int i;
-       int status;
-       unsigned short rev;
-
-       DBG(printk("%s\n", __FUNCTION__));
-       numcards++;
-
-       s->magic = RME96xx_MAGIC; 
-
-       spin_lock_init(&s->lock);
-
-       COMM            ("setup busmaster memory")
-       s->recbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-       s->playbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL);
-
-       if (!s->recbuf || !s->playbuf) {
-               printk(KERN_ERR RME_MESS" Unable to allocate busmaster memory\n");
-               return -ENODEV;
-       }
-
-       COMM            ("setting rec and playbuffers")
-
-       writel((u32) virt_to_bus(s->recbuf),s->iobase + RME96xx_rec_buffer);
-       writel((u32) virt_to_bus(s->playbuf),s->iobase + RME96xx_play_buffer);
-
-       COMM             ("initializing control register")
-       rme96xx_unset_ctrl(s,0xffffffff);
-       rme96xx_set_ctrl(s,RME96xx_ctrl_init);
-
-
-       COMM              ("setup devices")     
-       for (i=0;i < devices;i++) {
-               struct dmabuf * dma = &s->dma[i];
-               rme96xx_dmabuf_init(s,dma,2*i,2*i);
-       }
-
-       /* code from ALSA card-rme9652.c   HP 20020201 */
-        /* Determine the h/w rev level of the card. This seems like
-          a particularly kludgy way to encode it, but its what RME
-          chose to do, so we follow them ...
-       */
-
-       status = readl(s->iobase + RME96xx_status_register);
-       if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) {
-               s->hw_rev = 15;
-       } else {
-               s->hw_rev = 11;
-       }
-
-       /* Differentiate between the standard Hammerfall, and the
-          "Light", which does not have the expansion board. This
-          method comes from information received from Mathhias
-          Clausen at RME. Display the EEPROM and h/w revID where
-          relevant.  
-       */
-
-       pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev);
-       switch (rev & 0xff) {
-       case 8: /* original eprom */
-               if (s->hw_rev == 15) {
-                       s->card_name = "RME Digi9636 (Rev 1.5)";
-               } else {
-                       s->card_name = "RME Digi9636";
-               }
-               break;
-       case 9: /* W36_G EPROM */
-               s->card_name = "RME Digi9636 (Rev G)";
-               break;
-       case 4: /* W52_G EPROM */
-               s->card_name = "RME Digi9652 (Rev G)";
-               break;
-       default:
-       case 3: /* original eprom */
-               if (s->hw_rev == 15) {
-                       s->card_name = "RME Digi9652 (Rev 1.5)";
-               } else {
-                       s->card_name = "RME Digi9652";
-               }
-               break;
-       }
-
-       printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); 
-
-       if (s->hw_rev == 15)
-               rme96xx_initialize_spdif_receiver (s);
-
-       s->started = 0;
-       rme96xx_setlatency(s,7);
-
-       printk(KERN_INFO RME_MESS" card %d initialized\n",numcards); 
-       return 0;
-}
-
-
-/* open uses this to figure out which device was opened .. this seems to be 
-   unnecessary complex */
-
-static LIST_HEAD(devs);
-
-static int __devinit rme96xx_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       int i;
-       rme96xx_info *s;
-
-       DBG(printk("%s\n", __FUNCTION__));
-       
-       if (pcidev->irq == 0) 
-               return -1;
-       if (!pci_dma_supported(pcidev, 0xffffffff)) {
-               printk(KERN_WARNING RME_MESS" architecture does not support 32bit PCI busmaster DMA\n");
-               return -1;
-       }
-       if (!(s = kmalloc(sizeof(rme96xx_info), GFP_KERNEL))) {
-               printk(KERN_WARNING RME_MESS" out of memory\n");
-               return -1;
-       }
-       memset(s, 0, sizeof(rme96xx_info));
-
-       s->pcidev = pcidev;
-       s->iobase = ioremap(pci_resource_start(pcidev, 0),RME96xx_IO_EXTENT);
-       s->irq = pcidev->irq;
-
-        DBG(printk("remapped iobase: %lx irq %d\n",(long)s->iobase,s->irq));
-
-       if (pci_enable_device(pcidev))
-               goto err_irq;
-       if (request_irq(s->irq, rme96xx_interrupt, IRQF_SHARED, "rme96xx", s)) {
-               printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       
-       /* initialize the card */
-
-       i = 0;
-       if (rme96xx_init(s) < 0) {
-               printk(KERN_ERR RME_MESS" initialization failed\n");
-               goto err_devices;
-       }
-       for (i=0;i<devices;i++) {
-               if ((s->dspnum[i] = register_sound_dsp(&rme96xx_audio_fops, -1)) < 0)
-                       goto err_devices;
-       }
-
-       if ((s->mixer = register_sound_mixer(&rme96xx_mixer_fops, -1)) < 0)
-               goto err_devices;
-
-       pci_set_drvdata(pcidev, s);
-       pcidev->dma_mask = 0xffffffff; /* ????? */
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-
-       DBG(printk("initialization successful\n"));
-       return 0;
-
-       /* error handler */
- err_devices:
-       while (i--) 
-               unregister_sound_dsp(s->dspnum[i]);
-       free_irq(s->irq,s);
- err_irq:
-       kfree(s);
-       return -1;
-}
-
-
-static void __devexit rme96xx_remove(struct pci_dev *dev)
-{
-       int i;
-       rme96xx_info *s = pci_get_drvdata(dev);
-
-       if (!s) {
-               printk(KERN_ERR"device structure not valid\n");
-               return ;
-       }
-
-       if (s->started) rme96xx_startcard(s,0);
-
-       i = devices;
-       while (i) {
-               i--;
-               unregister_sound_dsp(s->dspnum[i]);
-       }
-       
-       unregister_sound_mixer(s->mixer);
-       synchronize_irq(s->irq);
-       free_irq(s->irq,s);
-       busmaster_free(s->recbuf,RME96xx_DMA_MAX_SIZE_ALL);
-       busmaster_free(s->playbuf,RME96xx_DMA_MAX_SIZE_ALL);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-
-#ifndef PCI_VENDOR_ID_RME 
-#define PCI_VENDOR_ID_RME 0x10ee
-#endif
-#ifndef PCI_DEVICE_ID_RME9652
-#define PCI_DEVICE_ID_RME9652 0x3fc4
-#endif
-#ifndef PCI_ANY_ID
-#define PCI_ANY_ID 0
-#endif
-
-static struct pci_device_id id_table[] = {
-       {
-               .vendor    = PCI_VENDOR_ID_RME,
-               .device    = PCI_DEVICE_ID_RME9652,
-               .subvendor = PCI_ANY_ID,
-               .subdevice = PCI_ANY_ID,
-       },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver rme96xx_driver = {
-       .name     =  "rme96xx",
-       .id_table = id_table,
-       .probe    = rme96xx_probe,
-       .remove   = __devexit_p(rme96xx_remove),
-};
-
-static int __init init_rme96xx(void)
-{
-       printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
-       devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
-       printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
-        numcards = 0;
-       return pci_register_driver(&rme96xx_driver);
-}
-
-static void __exit cleanup_rme96xx(void)
-{
-       printk(KERN_INFO RME_MESS" unloading\n");
-       pci_unregister_driver(&rme96xx_driver);
-}
-
-module_init(init_rme96xx);
-module_exit(cleanup_rme96xx);
-
-
-
-
-
-/*-------------------------------------------------------------------------- 
-   Implementation of file operations 
----------------------------------------------------------------------------*/
-
-#define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED)
-/* AFTM_U8 is not (yet?) supported ...  HP20020201 */
-
-static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct dmabuf * dma = (struct dmabuf *)file->private_data; 
-       rme96xx_info *s = dma->s;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val = 0;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-
-       DBG(printk("ioctl %ud\n",cmd));
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-#if 0
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/);
-#endif
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-//             rme96xx_clearbufs(dma);
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-/* generally it's not a problem if we change the speed 
-                       if (dma->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE))
-                               return -EINVAL;
-*/
-                       spin_lock_irqsave(&s->lock, flags);
-
-                       switch (val) {
-                       case 44100:
-                       case 88200:
-                               rme96xx_unset_ctrl(s,RME96xx_freq);
-                               break;
-                       case 48000: 
-                       case 96000: 
-                               rme96xx_set_ctrl(s,RME96xx_freq);
-                               break;
-                       /* just report current rate as default
-                          e.g. use 0 to "select" current digital input rate
-                       default:
-                               rme96xx_unset_ctrl(s,RME96xx_freq);
-                               val = 44100;
-                       */
-                       }
-                       if (val > 50000)
-                               rme96xx_set_ctrl(s,RME96xx_DS);
-                       else
-                               rme96xx_unset_ctrl(s,RME96xx_DS);
-                       /* set val to actual value  HP 20020201 */
-                       /* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */
-                       if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel))
-                               val = rme96xx_get_sample_rate_ctrl(s);
-                       else
-                               val = rme96xx_get_sample_rate_status(s);
-                       s->rate = val;
-                       spin_unlock_irqrestore(&s->lock, flags);
-               }
-               DBG(printk("speed set to %d\n",val));
-               return put_user(val, p);
-               
-        case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */
-                if (get_user(val, p))
-                       return -EFAULT;
-               
-               if (!val) {
-                       DBG(printk("setting to mono\n")); 
-                       dma->mono=1; 
-                       dma->inchannels = 1;
-                       dma->outchannels = 1;
-               }
-               else {
-                       DBG(printk("setting to stereo\n")); 
-                       dma->mono = 0;
-                       dma->inchannels = 2;
-                       dma->outchannels = 2;
-               }
-               return 0;
-        case SNDCTL_DSP_CHANNELS:
-               /* remember to check for resonable offset/channel pairs here */
-                if (get_user(val, p))
-                       return -EFAULT;
-
-               if (file->f_mode & FMODE_WRITE) {                       
-                       if (val > 0 && (dma->outoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-                               dma->outchannels = val;
-                       else
-                               dma->outchannels = val = 2;
-                       DBG(printk("setting to outchannels %d\n",val)); 
-               }
-               if (file->f_mode & FMODE_READ) {
-                       if (val > 0 && (dma->inoffset + val) <= RME96xx_CHANNELS_PER_CARD) 
-                               dma->inchannels = val;
-                       else
-                               dma->inchannels = val = 2;
-                       DBG(printk("setting to inchannels %d\n",val)); 
-               }
-
-               dma->mono=0;
-
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(RME96xx_FMT, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               DBG(printk("setting to format %x\n",val)); 
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       if (val & RME96xx_FMT)
-                               dma->format = val;
-                       switch (dma->format) {
-                       case AFMT_S16_LE:
-                               dma->formatshift=1;
-                               break;
-                       case AFMT_S32_BLOCKED:
-                               dma->formatshift=0;
-                               break;
-                       }
-               }
-               return put_user(dma->format, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-#if 0
-               if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) 
-                       val |= PCM_ENABLE_OUTPUT;
-#endif
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-#if 0
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
-                                       return ret;
-                               start_adc(s);
-                       } else
-                               stop_adc(s);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
-                                       return ret;
-                               start_dac2(s);
-                       } else
-                               stop_dac2(s);
-               }
-#endif
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-
-
-               count = rme96xx_getospace(dma,val);
-               if (!s->started) count = s->fragsize*2;
-               abinfo.fragsize =(s->fragsize*dma->outchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->outchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = (count > s->fragsize); 
-
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-
-               count = rme96xx_getispace(dma,val);
-
-               abinfo.fragsize = (s->fragsize*dma->inchannels)>>dma->formatshift;
-                abinfo.bytes = (count*dma->inchannels)>>dma->formatshift;
-                abinfo.fragstotal = 2;
-                abinfo.fragments = count > s->fragsize; 
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY: /* What should this exactly do ? ,
-                                     ATM it is just abinfo.bytes */
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-
-               val = rme96xx_gethwptr(dma->s,0);
-               count = val - dma->readptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-               return put_user(count, p);
-
-
-/* check out how to use mmaped mode (can only be blocked !!!) */
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               val = rme96xx_gethwptr(dma->s,0);
-               spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-               count = val - dma->readptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-               if (dma->mmapped)
-                       dma->readptr &= s->fragsize<<1;
-               spin_unlock_irqrestore(&s->lock,flags);
-
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               val = rme96xx_gethwptr(dma->s,0);
-               spin_lock_irqsave(&s->lock,flags);
-                cinfo.bytes = s->fragsize<<1;
-               count = val - dma->writeptr;
-               if (count < 0)
-                       count += s->fragsize<<1;
-
-                cinfo.blocks = (count > s->fragsize); 
-                cinfo.ptr = val;
-               if (dma->mmapped)
-                       dma->writeptr &= s->fragsize<<1;
-               spin_unlock_irqrestore(&s->lock,flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-        case SNDCTL_DSP_GETBLKSIZE:
-            return put_user(s->fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               val&=0xffff;
-               val -= 7;
-               if (val < 0) val = 0;
-               if (val > 7) val = 7;
-               rme96xx_setlatency(s,val);
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-#if 0
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac2.subdivision = val;
-#endif         
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               /* HP20020201 */
-               s->rate = rme96xx_get_sample_rate_status(s);
-               return put_user(s->rate, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user(dma->outchannels, p);
-
-        case SOUND_PCM_READ_BITS:
-               switch (dma->format) {
-                       case AFMT_S32_BLOCKED:
-                               val = 32;
-                               break;
-                       case AFMT_S16_LE:
-                               val = 16;
-                               break;
-               }
-               return put_user(val, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-
-
-       return -ENODEV;
-}
-
-
-
-static int rme96xx_open(struct inode *in, struct file *f)
-{
-       int minor = iminor(in);
-       struct list_head *list;
-       int devnum;
-       rme96xx_info *s;
-       struct dmabuf* dma;
-       DECLARE_WAITQUEUE(wait, current); 
-
-       DBG(printk("device num %d open\n",devnum));
-
-       nonseekable_open(in, f);
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, rme96xx_info, devs);
-               for (devnum=0; devnum<devices; devnum++)
-                       if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
-                               break;
-               if (devnum<devices)
-                       break;
-       }
-               VALIDATE_STATE(s);
-
-       dma = &s->dma[devnum];
-       f->private_data = dma;
-       /* wait for device to become free */
-       mutex_lock(&dma->open_mutex);
-       while (dma->open_mode & f->f_mode) {
-               if (f->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&dma->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&dma->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&dma->open_mutex);
-               schedule();
-               remove_wait_queue(&dma->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&dma->open_mutex);
-       }
-
-       COMM                ("hardware open")
-
-       if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
-
-       dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
-       dma->opened = 1;
-       mutex_unlock(&dma->open_mutex);
-
-       DBG(printk("device num %d open finished\n",devnum));
-       return 0;
-}
-
-static int rme96xx_release(struct inode *in, struct file *file)
-{
-       struct dmabuf * dma = (struct dmabuf*) file->private_data;
-       /* int hwp;  ... was unused   HP20020201 */
-       DBG(printk("%s\n", __FUNCTION__));
-
-       COMM          ("draining")
-       if (dma->open_mode & FMODE_WRITE) {
-#if 0 /* Why doesn't this work with some cards ?? */
-            hwp = rme96xx_gethwptr(dma->s,0);
-            while (rme96xx_getospace(dma,hwp)) {
-                 interruptible_sleep_on(&(dma->wait));
-                 hwp = rme96xx_gethwptr(dma->s,0);
-            }
-#endif
-            rme96xx_clearbufs(dma);
-       }
-
-       dma->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
-
-       if (!(dma->open_mode & (FMODE_READ|FMODE_WRITE))) {
-            dma->opened = 0;
-            if (dma->s->started) rme96xx_startcard(dma->s,1);
-       }
-
-       wake_up(&dma->open_wait);
-       mutex_unlock(&dma->open_mutex);
-
-       return 0;
-}
-
-
-static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       ssize_t ret = 0;
-       int cnt; /* number of bytes from "buffer" that will/can be used */
-       int hop = count/dma->outchannels;
-       int hwp;
-       int exact = (file->f_flags & O_NONBLOCK); 
-
-
-       if(dma == NULL || (dma->s) == NULL) 
-               return -ENXIO;
-
-       if (dma->mmapped || !dma->opened)
-               return -ENXIO;
-
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-
-       if (! (dma->open_mode  & FMODE_WRITE))
-                return -ENXIO;
-
-       if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-       if(!(dma->started)){             
-               COMM          ("first write")
-                       
-               dma->readptr = hwp;
-               dma->writeptr = hwp;
-               dma->started = 1;
-       }
-
-       while (count > 0) {
-               cnt = rme96xx_getospace(dma,hwp);               
-               cnt>>=dma->formatshift;
-               cnt*=dma->outchannels;
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt != 0) {
-                       if (rme96xx_copyfromuser(dma,buffer,cnt,hop))
-                               return ret ? ret : -EFAULT;
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-                       if (count == 0) return ret;
-               }
-               if (file->f_flags & O_NONBLOCK)
-                       return ret ? ret : -EAGAIN;
-               
-               if ((hwp - dma->writeptr) <= 0) {
-                       interruptible_sleep_on(&(dma->wait));
-                       
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-               }                       
-
-               hwp = rme96xx_gethwptr(dma->s,exact);
-
-       }; /* count > 0 */
-
-       return ret;
-}
-
-static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{ 
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       ssize_t ret = 0;
-       int cnt; /* number of bytes from "buffer" that will/can be used */
-       int hop = count/dma->inchannels;
-       int hwp;
-       int exact = (file->f_flags & O_NONBLOCK); 
-
-
-       if(dma == NULL || (dma->s) == NULL) 
-               return -ENXIO;
-
-       if (dma->mmapped || !dma->opened)
-               return -ENXIO;
-
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-
-       if (! (dma->open_mode  & FMODE_READ))
-                return -ENXIO;
-
-       if (!dma->s->started) rme96xx_startcard(dma->s,exact);
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-       if(!(dma->started)){             
-               COMM          ("first read")
-                    
-               dma->writeptr = hwp;
-               dma->readptr = hwp;
-               dma->started = 1;
-       }
-
-       while (count > 0) {
-               cnt = rme96xx_getispace(dma,hwp);               
-               cnt>>=dma->formatshift;
-               cnt*=dma->inchannels;
-
-               if (cnt > count)
-                       cnt = count;
-
-               if (cnt != 0) {
-                       
-                       if (rme96xx_copytouser(dma,buffer,cnt,hop))
-                               return ret ? ret : -EFAULT;
-                       
-                       count -= cnt;
-                       buffer += cnt;
-                       ret += cnt;
-                       if (count == 0) return ret;
-               }
-               if (file->f_flags & O_NONBLOCK)
-                       return ret ? ret : -EAGAIN;
-               
-               if ((hwp - dma->readptr) <= 0) {
-                       interruptible_sleep_on(&(dma->wait));
-                       
-                       if (signal_pending(current))
-                               return ret ? ret : -ERESTARTSYS;
-               }                       
-               hwp = rme96xx_gethwptr(dma->s,exact);
-
-       }; /* count > 0 */
-
-       return ret;
-}
-
-static int rm96xx_mmap(struct file *file, struct vm_area_struct *vma) {
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       rme96xx_info* s = dma->s;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-
-       if (vma->vm_pgoff != 0) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       size = vma->vm_end - vma->vm_start;
-       if (size > RME96xx_DMA_MAX_SIZE) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-
-
-       if (vma->vm_flags & VM_WRITE) {
-               if (!s->started) rme96xx_startcard(s,1);
-
-               if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-                       unlock_kernel();
-                       return -EAGAIN;
-               }
-       } 
-       else if (vma->vm_flags & VM_READ) {
-               if (!s->started) rme96xx_startcard(s,1);
-               if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) {
-                       unlock_kernel();
-                       return -EAGAIN;
-               }
-       } else  {
-               unlock_kernel();
-               return -EINVAL;
-       }
-
-
-/* this is the mapping */
-       vma->vm_flags &= ~VM_IO;
-       dma->mmapped = 1;
-       unlock_kernel();
-       return 0;
-}
-
-static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct dmabuf *dma = (struct dmabuf *)file->private_data;
-       rme96xx_info* s = dma->s;
-       unsigned int mask = 0;
-       unsigned int hwp,cnt;
-
-        DBG(printk("rme96xx poll_wait ...\n"));
-       VALIDATE_STATE(s);
-
-       if (!s->started) {
-                 mask |= POLLOUT | POLLWRNORM;
-       }
-       poll_wait(file, &dma->wait, wait);
-
-       hwp = rme96xx_gethwptr(dma->s,0);
-
-        DBG(printk("rme96xx poll: ..cnt %d > %d\n",cnt,s->fragsize));  
-
-       cnt = rme96xx_getispace(dma,hwp);
-
-       if (file->f_mode & FMODE_READ) 
-            if (cnt > 0)
-                 mask |= POLLIN | POLLRDNORM;
-
-
-
-       cnt = rme96xx_getospace(dma,hwp);
-
-       if (file->f_mode & FMODE_WRITE) 
-            if (cnt > 0)
-                 mask |= POLLOUT | POLLWRNORM;
-
-
-//        printk("rme96xx poll_wait ...%d > %d\n",rme96xx_getospace(dma,hwp),rme96xx_getispace(dma,hwp));
-
-       return mask;
-}
-
-
-static struct file_operations rme96xx_audio_fops = {
-       .owner   = THIS_MODULE,
-       .read    = rme96xx_read,
-       .write   = rme96xx_write,
-       .poll    = rme96xx_poll,
-       .ioctl   = rme96xx_ioctl,  
-       .mmap    = rm96xx_mmap,
-       .open    = rme96xx_open,  
-       .release = rme96xx_release 
-};
-
-static int rme96xx_mixer_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       rme96xx_info *s;
-
-       COMM  ("mixer open");
-
-       nonseekable_open(inode, file);
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, rme96xx_info, devs);
-               if (s->mixer== minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-
-       COMM                       ("mixer opened")
-       return 0;
-}
-
-static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       rme96xx_info *s = (rme96xx_info *)file->private_data;
-       u32 status;
-       int spdifrate;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       status = readl(s->iobase + RME96xx_status_register);
-       /* hack to convert rev 1.5 SPDIF rate to "crystalrate" format   HP 20020201 */
-       rme96xx_spdif_sample_rate(s,&spdifrate);
-       status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F);
-
-       VALIDATE_STATE(s);
-       if (cmd == SOUND_MIXER_PRIVATE1) {
-               rme_mixer mixer;
-               if (copy_from_user(&mixer,argp,sizeof(mixer)))
-                       return -EFAULT;
-               
-               mixer.devnr &= RME96xx_MASK_DEVS;
-               if (mixer.devnr >= devices)
-                       mixer.devnr = devices-1;
-               if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) {
-                       /* modify only if device not open */
-                       if (mixer.o_offset < 0)
-                               mixer.o_offset = 0;
-                       if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD)
-                               mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1;
-                       if (mixer.i_offset < 0)
-                               mixer.i_offset = 0;
-                       if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD)
-                               mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1;
-                       s->dma[mixer.devnr].outoffset = mixer.o_offset;
-                       s->dma[mixer.devnr].inoffset = mixer.i_offset;
-               }
-
-               mixer.o_offset = s->dma[mixer.devnr].outoffset;
-               mixer.i_offset = s->dma[mixer.devnr].inoffset;
-
-               return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0;
-       }
-       if (cmd == SOUND_MIXER_PRIVATE2) {
-               return put_user(status, p);
-       }
-       if (cmd == SOUND_MIXER_PRIVATE3) {
-               u32 control;
-               if (copy_from_user(&control,argp,sizeof(control)))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_WRITE) {
-                       s->control_register &= ~RME96xx_mixer_allowed;
-                       s->control_register |= control & RME96xx_mixer_allowed;
-                       writel(control,s->iobase + RME96xx_control_register);
-               }
-
-            return put_user(s->control_register, p);
-       }
-       return -1;
-}
-
-
-
-static int rme96xx_mixer_release(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static /*const*/ struct file_operations rme96xx_mixer_fops = {
-       .owner   = THIS_MODULE,
-       .ioctl   = rme96xx_mixer_ioctl,
-       .open    = rme96xx_mixer_open,
-       .release = rme96xx_mixer_release,
-};
diff --git a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h
deleted file mode 100644 (file)
index 7a3c188..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* (C) 2000 Guenter Geiger <geiger@debian.org>
-   with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
-
-Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
-   HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
-   HP20020201 completed?
-
-A text/graphic control panel (rmectrl/xrmectrl) is available from
-   http://gige.xdv.org/pages/soft/pages/rme
-*/
-
-
-#ifndef AFMT_S32_BLOCKED
-#define AFMT_S32_BLOCKED 0x0000400
-#endif
-
-/* AFMT_S16_BLOCKED not yet supported */
-#ifndef AFMT_S16_BLOCKED 
-#define AFMT_S16_BLOCKED 0x0000800
-#endif
-
-
-typedef struct rme_status {
-       unsigned int irq:1;
-       unsigned int lockmask:3;     /* ADAT input PLLs locked */
-                                    /*   100=ADAT1, 010=ADAT2, 001=ADAT3 */
-       unsigned int sr48:1;         /* sample rate: 0=44.1/88.2 1=48/96 kHz */
-       unsigned int wclock:1;       /* 1=wordclock used */
-       unsigned int bufpoint:10;
-       unsigned int syncmask:3;     /* ADAT input in sync with system clock */
-                                    /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */
-       unsigned int doublespeed:1;  /* sample rate: 0=44.1/48 1=88.2/96 kHz */
-       unsigned int tc_busy:1;
-       unsigned int tc_out:1;
-       unsigned int crystalrate:3;  /* spdif input sample rate: */
-                                    /*   000=64kHz, 100=88.2kHz, 011=96kHz */
-                                    /*   111=32kHz, 110=44.1kHz, 101=48kHz */
-       unsigned int spdif_error:1;  /* 1=no spdif lock */
-       unsigned int bufid:1;
-       unsigned int tc_valid:1;     /* 1=timecode input detected */
-       unsigned int spdif_read:1;
-} rme_status_t;
-
-
-/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */
-typedef struct rme_control {
-       unsigned int start:1;
-       unsigned int latency:3;      /* buffer size / latency [samples]: */
-                                    /*   0=64 ... 7=8192 */
-       unsigned int master:1;       /* W: clock mode: 1=master 0=slave/auto */
-       unsigned int ie:1;
-       unsigned int sr48:1;         /* samplerate 0=44.1/88.2, 1=48/96 kHz */
-       unsigned int spare:1;
-       unsigned int doublespeed:1;  /* double speed 0=44.1/48, 1=88.2/96 Khz */
-       unsigned int pro:1;          /* W: SPDIF-OUT 0=consumer, 1=professional */
-       unsigned int emphasis:1;     /* W: SPDIF-OUT emphasis 0=off, 1=on */
-       unsigned int dolby:1;        /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */
-       unsigned int opt_out:1;      /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */
-       unsigned int wordclock:1;    /* W: use Wordclock as sync (overwrites master) */
-        unsigned int spdif_in:2;     /* W: SPDIF-IN: */
-                                     /*    00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */
-       unsigned int sync_ref:2;     /* W: preferred sync-source in autosync */
-                                     /*    00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
-       unsigned int spdif_reset:1;
-       unsigned int spdif_select:1;
-       unsigned int spdif_clock:1;
-       unsigned int spdif_write:1;
-       unsigned int adat1_cd:1;     /* W: Rev 1.5+: if set, internal CD connector carries ADAT */
-} rme_ctrl_t;
-
-
-typedef struct _rme_mixer {
-       int i_offset;
-       int o_offset;
-       int devnr;
-       int spare[8];
-} rme_mixer;
-
index 0ce4e4ef6fe9b2fe90e45250d89ef32b64d0b965..23922377250d8ac213d043b8e10ac4a5c47610b7 100644 (file)
@@ -16,7 +16,6 @@
  */
 #include <linux/kmod.h>
 #include <linux/spinlock.h>
-#define SEQUENCER_C
 #include "sound_config.h"
 
 #include "midi_ctrl.h"
index 5d008798c31018bdc1a0af6976476acce59347a9..118525638bd396a48b044cf93d88198653a9f798 100644 (file)
@@ -20,10 +20,3 @@ EXPORT_SYMBOL(sound_timer_init);
 EXPORT_SYMBOL(sound_timer_interrupt);
 EXPORT_SYMBOL(sound_timer_syncinterval);
 
-/* Tuning */
-
-#define _SEQUENCER_C_
-#include "tuning.h"
-
-EXPORT_SYMBOL(cent_tuning);
-EXPORT_SYMBOL(semitone_tuning);
diff --git a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c
deleted file mode 100644 (file)
index 0bcff67..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * sound/oss/sgalaxy.c
- *
- * Low level driver for Aztech Sound Galaxy cards.
- * Copyright 1998 Artur Skawina <skawina@geocities.com>
- *
- * Supported cards:
- *    Aztech Sound Galaxy Waverider Pro 32 - 3D
- *    Aztech Sound Galaxy Washington 16
- *
- * Based on cs4232.c by Hannu Savolainen and Alan Cox.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added __init to sb_rst() and sb_cmd()
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "sound_config.h"
-#include "ad1848.h"
-
-static void sleep( unsigned howlong )
-{
-       current->state   = TASK_INTERRUPTIBLE;
-       schedule_timeout(howlong);
-}
-
-#define DPORT 0x80
-
-/* Sound Blaster regs */
-
-#define SBDSP_RESET      0x6
-#define SBDSP_READ       0xA
-#define SBDSP_COMMAND    0xC
-#define SBDSP_STATUS     SBDSP_COMMAND
-#define SBDSP_DATA_AVAIL 0xE
-
-static int __init sb_rst(int base)
-{
-       int   i;
-   
-       outb( 1, base+SBDSP_RESET );     /* reset the DSP */
-       outb( 0, base+SBDSP_RESET );
-    
-       for ( i=0; i<500; i++ )          /* delay */
-               inb(DPORT);
-      
-       for ( i=0; i<100000; i++ )
-       {
-               if ( inb( base+SBDSP_DATA_AVAIL )&0x80 )
-                       break;
-       }
-
-       if ( inb( base+SBDSP_READ )!=0xAA )
-               return 0;
-
-       return 1;
-}
-
-static int __init sb_cmd( int base, unsigned char val )
-{
-       int  i;
-
-       for ( i=100000; i; i-- )
-       {
-               if ( (inb( base+SBDSP_STATUS )&0x80)==0 )
-               {
-                       outb( val, base+SBDSP_COMMAND );
-                       break;
-               }
-       }
-       return i;      /* i>0 == success */
-}
-
-
-#define ai_sgbase    driver_use_1
-
-static int __init probe_sgalaxy( struct address_info *ai )
-{
-       struct resource *ports;
-       int n;
-
-       if (!request_region(ai->io_base, 4, "WSS config")) {
-               printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-               return 0;
-       }
-
-       ports = request_region(ai->io_base + 4, 4, "ad1848");
-       if (!ports) {
-               printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base);
-               release_region(ai->io_base, 4);
-               return 0;
-       }
-
-       if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) {
-               printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase);
-               release_region(ai->io_base + 4, 4);
-               release_region(ai->io_base, 4);
-               return 0;
-       }
-        
-       if (ad1848_detect(ports, NULL, ai->osp))
-               goto out;  /* The card is already active, check irq etc... */
-        
-       /* switch to MSS/WSS mode */
-   
-       sb_rst( ai->ai_sgbase );
-   
-       sb_cmd( ai->ai_sgbase, 9 );
-       sb_cmd( ai->ai_sgbase, 0 );
-
-       sleep( HZ/10 );
-
-out:
-       if (!probe_ms_sound(ai, ports)) {
-               release_region(ai->io_base + 4, 4);
-               release_region(ai->io_base, 4);
-               release_region(ai->ai_sgbase, 0x10);
-               return 0;
-       }
-
-       attach_ms_sound(ai, ports, THIS_MODULE);
-       n=ai->slots[0];
-       
-       if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) {
-               AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE );   /* Line-in */
-               AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH );  /* FM+Wavetable*/
-               AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD );     /* CD */
-       }
-       return 1;
-}
-
-static void __exit unload_sgalaxy( struct address_info *ai )
-{
-       unload_ms_sound( ai );
-       release_region( ai->ai_sgbase, 0x10 );
-}
-
-static struct address_info cfg;
-
-static int __initdata io       = -1;
-static int __initdata irq      = -1;
-static int __initdata dma      = -1;
-static int __initdata dma2     = -1;
-static int __initdata sgbase   = -1;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-module_param(dma, int, 0);
-module_param(dma2, int, 0);
-module_param(sgbase, int, 0);
-
-static int __init init_sgalaxy(void)
-{
-       cfg.io_base   = io;
-       cfg.irq       = irq;
-       cfg.dma       = dma;
-       cfg.dma2      = dma2;
-       cfg.ai_sgbase = sgbase;
-
-       if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) {
-               printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n");
-               return -EINVAL;
-       }
-
-       if ( probe_sgalaxy(&cfg) == 0 )
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit cleanup_sgalaxy(void)
-{
-       unload_sgalaxy(&cfg);
-}
-
-module_init(init_sgalaxy);
-module_exit(cleanup_sgalaxy);
-
-#ifndef MODULE
-static int __init setup_sgalaxy(char *str)
-{
-       /* io, irq, dma, dma2, sgbase */
-       int ints[6];
-       
-       str = get_options(str, ARRAY_SIZE(ints), ints);
-       io      = ints[1];
-       irq     = ints[2];
-       dma     = ints[3];
-       dma2    = ints[4];
-       sgbase  = ints[5];
-
-       return 1;
-}
-
-__setup("sgalaxy=", setup_sgalaxy);
-#endif
-MODULE_LICENSE("GPL");
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
deleted file mode 100644 (file)
index 8ea532d..0000000
+++ /dev/null
@@ -1,2792 +0,0 @@
-/*****************************************************************************/
-
-/*
- *      sonicvibes.c  --  S3 Sonic Vibes audio driver.
- *
- *      Copyright (C) 1998-2001, 2003  Thomas Sailer (t.sailer@alumni.ethz.ch)
- *
- *      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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Special thanks to David C. Niemi
- *
- *
- * Module command line parameters:
- *   none so far
- *
- *
- *  Supported devices:
- *  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
- *  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
- *  /dev/midi   simple MIDI UART interface, no ioctl
- *
- *  The card has both an FM and a Wavetable synth, but I have to figure
- *  out first how to drive them...
- *
- *  Revision history
- *    06.05.1998   0.1   Initial release
- *    10.05.1998   0.2   Fixed many bugs, esp. ADC rate calculation
- *                       First stab at a simple midi interface (no bells&whistles)
- *    13.05.1998   0.3   Fix stupid cut&paste error: set_adc_rate was called instead of
- *                       set_dac_rate in the FMODE_WRITE case in sv_open
- *                       Fix hwptr out of bounds (now mpg123 works)
- *    14.05.1998   0.4   Don't allow excessive interrupt rates
- *    08.06.1998   0.5   First release using Alan Cox' soundcore instead of miscdevice
- *    03.08.1998   0.6   Do not include modversions.h
- *                       Now mixer behaviour can basically be selected between
- *                       "OSS documented" and "OSS actual" behaviour
- *    31.08.1998   0.7   Fix realplayer problems - dac.count issues
- *    10.12.1998   0.8   Fix drain_dac trying to wait on not yet initialized DMA
- *    16.12.1998   0.9   Fix a few f_file & FMODE_ bugs
- *    06.01.1999   0.10  remove the silly SA_INTERRUPT flag.
- *                       hopefully killed the egcs section type conflict
- *    12.03.1999   0.11  cinfo.blocks should be reset after GETxPTR ioctl.
- *                       reported by Johan Maes <joma@telindus.be>
- *    22.03.1999   0.12  return EAGAIN instead of EBUSY when O_NONBLOCK
- *                       read/write cannot be executed
- *    05.04.1999   0.13  added code to sv_read and sv_write which should detect
- *                       lockups of the sound chip and revive it. This is basically
- *                       an ugly hack, but at least applications using this driver
- *                       won't hang forever. I don't know why these lockups happen,
- *                       it might well be the motherboard chipset (an early 486 PCI
- *                       board with ALI chipset), since every busmastering 100MB
- *                       ethernet card I've tried (Realtek 8139 and Macronix tulip clone)
- *                       exhibit similar behaviour (they work for a couple of packets
- *                       and then lock up and can be revived by ifconfig down/up).
- *    07.04.1999   0.14  implemented the following ioctl's: SOUND_PCM_READ_RATE, 
- *                       SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; 
- *                       Alpha fixes reported by Peter Jones <pjones@redhat.com>
- *                       Note: dmaio hack might still be wrong on archs other than i386
- *    15.06.1999   0.15  Fix bad allocation bug.
- *                       Thanks to Deti Fliegl <fliegl@in.tum.de>
- *    28.06.1999   0.16  Add pci_set_master
- *    03.08.1999   0.17  adapt to Linus' new __setup/__initcall
- *                       added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr"
- *    12.08.1999   0.18  module_init/__setup fixes
- *    24.08.1999   0.19  get rid of the dmaio kludge, replace with allocate_resource
- *    31.08.1999   0.20  add spin_lock_init
- *                       use new resource allocation to allocate DDMA IO space
- *                       replaced current->state = x with set_current_state(x)
- *    03.09.1999   0.21  change read semantics for MIDI to match
- *                       OSS more closely; remove possible wakeup race
- *    28.10.1999   0.22  More waitqueue races fixed
- *    01.12.1999   0.23  New argument to allocate_resource
- *    07.12.1999   0.24  More allocate_resource semantics change
- *    08.01.2000   0.25  Prevent some ioctl's from returning bad count values on underrun/overrun;
- *                       Tim Janik's BSE (Bedevilled Sound Engine) found this
- *                       use Martin Mares' pci_assign_resource
- *    07.02.2000   0.26  Use pci_alloc_consistent and pci_register_driver
- *    21.11.2000   0.27  Initialize dma buffers in poll, otherwise poll may return a bogus mask
- *    12.12.2000   0.28  More dma buffer initializations, patch from
- *                       Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com>
- *    31.01.2001   0.29  Register/Unregister gameport
- *                       Fix SETTRIGGER non OSS API conformity
- *    18.05.2001   0.30  PCI probing and error values cleaned up by Marcus
- *                       Meissner <mm@caldera.de>
- *    03.01.2003   0.31  open_mode fixes from Georg Acher <acher@in.tum.de>
- *
- */
-
-/*****************************************************************************/
-      
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/sound.h>
-#include <linux/slab.h>
-#include <linux/soundcard.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/gameport.h>
-#include <linux/dma-mapping.h>
-#include <linux/mutex.h>
-
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include "dm.h"
-
-#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
-#define SUPPORT_JOYSTICK 1
-#endif
-
-/* --------------------------------------------------------------------- */
-
-#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-/* --------------------------------------------------------------------- */
-
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3             0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SONICVIBES
-#define PCI_DEVICE_ID_S3_SONICVIBES  0xca00
-#endif
-
-#define SV_MAGIC  ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES)
-
-#define SV_EXTENT_SB      0x10
-#define SV_EXTENT_ENH     0x10
-#define SV_EXTENT_SYNTH   0x4
-#define SV_EXTENT_MIDI    0x4
-#define SV_EXTENT_GAME    0x8
-#define SV_EXTENT_DMA     0x10
-
-/*
- * we are not a bridge and thus use a resource for DDMA that is used for bridges but
- * left empty for normal devices
- */
-#define RESOURCE_SB       0
-#define RESOURCE_ENH      1
-#define RESOURCE_SYNTH    2
-#define RESOURCE_MIDI     3
-#define RESOURCE_GAME     4
-#define RESOURCE_DDMA     7
-
-#define SV_MIDI_DATA      0
-#define SV_MIDI_COMMAND   1
-#define SV_MIDI_STATUS    1
-
-#define SV_DMA_ADDR0      0
-#define SV_DMA_ADDR1      1
-#define SV_DMA_ADDR2      2
-#define SV_DMA_ADDR3      3
-#define SV_DMA_COUNT0     4
-#define SV_DMA_COUNT1     5
-#define SV_DMA_COUNT2     6
-#define SV_DMA_MODE       0xb
-#define SV_DMA_RESET      0xd
-#define SV_DMA_MASK       0xf
-
-/*
- * DONT reset the DMA controllers unless you understand
- * the reset semantics. Assuming reset semantics as in
- * the 8237 does not work.
- */
-
-#define DMA_MODE_AUTOINIT 0x10
-#define DMA_MODE_READ     0x44    /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE    0x48    /* memory to I/O, no autoinit, increment, single mode */
-
-#define SV_CODEC_CONTROL  0
-#define SV_CODEC_INTMASK  1
-#define SV_CODEC_STATUS   2
-#define SV_CODEC_IADDR    4
-#define SV_CODEC_IDATA    5
-
-#define SV_CCTRL_RESET      0x80
-#define SV_CCTRL_INTADRIVE  0x20
-#define SV_CCTRL_WAVETABLE  0x08
-#define SV_CCTRL_REVERB     0x04
-#define SV_CCTRL_ENHANCED   0x01
-
-#define SV_CINTMASK_DMAA    0x01
-#define SV_CINTMASK_DMAC    0x04
-#define SV_CINTMASK_SPECIAL 0x08
-#define SV_CINTMASK_UPDOWN  0x40
-#define SV_CINTMASK_MIDI    0x80
-
-#define SV_CSTAT_DMAA       0x01
-#define SV_CSTAT_DMAC      0x04
-#define SV_CSTAT_SPECIAL    0x08
-#define SV_CSTAT_UPDOWN            0x40
-#define SV_CSTAT_MIDI      0x80
-
-#define SV_CIADDR_TRD       0x80
-#define SV_CIADDR_MCE       0x40
-
-/* codec indirect registers */
-#define SV_CIMIX_ADCINL     0x00
-#define SV_CIMIX_ADCINR     0x01
-#define SV_CIMIX_AUX1INL    0x02
-#define SV_CIMIX_AUX1INR    0x03
-#define SV_CIMIX_CDINL      0x04
-#define SV_CIMIX_CDINR      0x05
-#define SV_CIMIX_LINEINL    0x06
-#define SV_CIMIX_LINEINR    0x07
-#define SV_CIMIX_MICIN      0x08
-#define SV_CIMIX_SYNTHINL   0x0A
-#define SV_CIMIX_SYNTHINR   0x0B
-#define SV_CIMIX_AUX2INL    0x0C
-#define SV_CIMIX_AUX2INR    0x0D
-#define SV_CIMIX_ANALOGINL  0x0E
-#define SV_CIMIX_ANALOGINR  0x0F
-#define SV_CIMIX_PCMINL     0x10
-#define SV_CIMIX_PCMINR     0x11
-
-#define SV_CIGAMECONTROL    0x09
-#define SV_CIDATAFMT        0x12
-#define SV_CIENABLE         0x13
-#define SV_CIUPDOWN         0x14
-#define SV_CIREVISION       0x15
-#define SV_CIADCOUTPUT      0x16
-#define SV_CIDMAABASECOUNT1 0x18
-#define SV_CIDMAABASECOUNT0 0x19
-#define SV_CIDMACBASECOUNT1 0x1c
-#define SV_CIDMACBASECOUNT0 0x1d
-#define SV_CIPCMSR0         0x1e
-#define SV_CIPCMSR1         0x1f
-#define SV_CISYNTHSR0       0x20
-#define SV_CISYNTHSR1       0x21
-#define SV_CIADCCLKSOURCE   0x22
-#define SV_CIADCALTSR       0x23
-#define SV_CIADCPLLM        0x24
-#define SV_CIADCPLLN        0x25
-#define SV_CISYNTHPLLM      0x26
-#define SV_CISYNTHPLLN      0x27
-#define SV_CIUARTCONTROL    0x2a
-#define SV_CIDRIVECONTROL   0x2b
-#define SV_CISRSSPACE       0x2c
-#define SV_CISRSCENTER      0x2d
-#define SV_CIWAVETABLESRC   0x2e
-#define SV_CIANALOGPWRDOWN  0x30
-#define SV_CIDIGITALPWRDOWN 0x31
-
-
-#define SV_CIMIX_ADCSRC_CD     0x20
-#define SV_CIMIX_ADCSRC_DAC    0x40
-#define SV_CIMIX_ADCSRC_AUX2   0x60
-#define SV_CIMIX_ADCSRC_LINE   0x80
-#define SV_CIMIX_ADCSRC_AUX1   0xa0
-#define SV_CIMIX_ADCSRC_MIC    0xc0
-#define SV_CIMIX_ADCSRC_MIXOUT 0xe0
-#define SV_CIMIX_ADCSRC_MASK   0xe0
-
-#define SV_CFMT_STEREO     0x01
-#define SV_CFMT_16BIT      0x02
-#define SV_CFMT_MASK       0x03
-#define SV_CFMT_ASHIFT     0   
-#define SV_CFMT_CSHIFT     4
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
-
-#define SV_CENABLE_PPE     0x4
-#define SV_CENABLE_RE      0x2
-#define SV_CENABLE_PE      0x1
-
-
-/* MIDI buffer sizes */
-
-#define MIDIINBUF  256
-#define MIDIOUTBUF 256
-
-#define FMODE_MIDI_SHIFT 2
-#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
-#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
-
-#define FMODE_DMFM 0x10
-
-/* --------------------------------------------------------------------- */
-
-struct sv_state {
-       /* magic */
-       unsigned int magic;
-
-       /* list of sonicvibes devices */
-       struct list_head devs;
-
-       /* the corresponding pci_dev structure */
-       struct pci_dev *dev;
-
-       /* soundcore stuff */
-       int dev_audio;
-       int dev_mixer;
-       int dev_midi;
-       int dev_dmfm;
-
-       /* hardware resources */
-       unsigned long iosb, ioenh, iosynth, iomidi;  /* long for SPARC */
-       unsigned int iodmaa, iodmac, irq;
-
-        /* mixer stuff */
-        struct {
-                unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
-               unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-        } mix;
-
-       /* wave stuff */
-       unsigned int rateadc, ratedac;
-       unsigned char fmt, enable;
-
-       spinlock_t lock;
-       struct mutex open_mutex;
-       mode_t open_mode;
-       wait_queue_head_t open_wait;
-
-       struct dmabuf {
-               void *rawbuf;
-               dma_addr_t dmaaddr;
-               unsigned buforder;
-               unsigned numfrag;
-               unsigned fragshift;
-               unsigned hwptr, swptr;
-               unsigned total_bytes;
-               int count;
-               unsigned error; /* over/underrun */
-               wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
-               unsigned dmasize;
-               unsigned fragsamples;
-               /* OSS stuff */
-               unsigned mapped:1;
-               unsigned ready:1;
-               unsigned endcleared:1;
-               unsigned enabled:1;
-               unsigned ossfragshift;
-               int ossmaxfrags;
-               unsigned subdivision;
-       } dma_dac, dma_adc;
-
-       /* midi stuff */
-       struct {
-               unsigned ird, iwr, icnt;
-               unsigned ord, owr, ocnt;
-               wait_queue_head_t iwait;
-               wait_queue_head_t owait;
-               struct timer_list timer;
-               unsigned char ibuf[MIDIINBUF];
-               unsigned char obuf[MIDIOUTBUF];
-       } midi;
-
-#if SUPPORT_JOYSTICK
-       struct gameport *gameport;
-#endif
-};
-
-/* --------------------------------------------------------------------- */
-
-static LIST_HEAD(devs);
-static unsigned long wavetable_mem;
-
-/* --------------------------------------------------------------------- */
-
-static inline unsigned ld2(unsigned int x)
-{
-       unsigned r = 0;
-       
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
-       }
-       if (x >= 2)
-               r++;
-       return r;
-}
-
-/* --------------------------------------------------------------------- */
-
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
-static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmaa, u;
-
-       count--;
-       for (u = 4; u > 0; u--, addr >>= 8, io++)
-               outb(addr & 0xff, io);
-       for (u = 3; u > 0; u--, count >>= 8, io++)
-               outb(count & 0xff, io);
-#else /* DMABYTEIO */
-       count--;
-       outl(addr, s->iodmaa + SV_DMA_ADDR0);
-       outl(count, s->iodmaa + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-       outb(0x18, s->iodmaa + SV_DMA_MODE);
-}
-
-static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmac, u;
-
-       count >>= 1;
-       count--;
-       for (u = 4; u > 0; u--, addr >>= 8, io++)
-               outb(addr & 0xff, io);
-       for (u = 3; u > 0; u--, count >>= 8, io++)
-               outb(count & 0xff, io);
-#else /* DMABYTEIO */
-       count >>= 1;
-       count--;
-       outl(addr, s->iodmac + SV_DMA_ADDR0);
-       outl(count, s->iodmac + SV_DMA_COUNT0);
-#endif /* DMABYTEIO */
-       outb(0x14, s->iodmac + SV_DMA_MODE);
-}
-
-static inline unsigned get_dmaa(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmaa+6, v = 0, u;
-
-       for (u = 3; u > 0; u--, io--) {
-               v <<= 8;
-               v |= inb(io);
-       }
-       return v + 1;
-#else /* DMABYTEIO */
-       return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1;
-#endif /* DMABYTEIO */
-}
-
-static inline unsigned get_dmac(struct sv_state *s)
-{
-#ifdef DMABYTEIO
-       unsigned io = s->iodmac+6, v = 0, u;
-
-       for (u = 3; u > 0; u--, io--) {
-               v <<= 8;
-               v |= inb(io);
-       }
-       return (v + 1) << 1;
-#else /* DMABYTEIO */
-       return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
-#endif /* DMABYTEIO */
-}
-
-static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data)
-{
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(data, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-}
-
-static unsigned char rdindir(struct sv_state *s, unsigned char idx)
-{
-       unsigned char v;
-
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       v = inb(s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       return v;
-}
-
-static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR);
-       if (mask) {
-               s->fmt = inb(s->ioenh + SV_CODEC_IDATA);
-               udelay(10);
-       }
-       s->fmt = (s->fmt & mask) | data;
-       outb(s->fmt, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(0, s->ioenh + SV_CODEC_IADDR);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-}
-
-static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data)
-{
-       outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-}
-
-#define REFFREQUENCY  24576000
-#define ADCMULT 512
-#define FULLRATE 48000
-
-static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate)
-{
-       unsigned long flags;
-       unsigned char r, m=0, n=0;
-       unsigned xm, xn, xr, xd, metric = ~0U;
-       /* the warnings about m and n used uninitialized are bogus and may safely be ignored */
-
-       if (rate < 625000/ADCMULT)
-               rate = 625000/ADCMULT;
-       if (rate > 150000000/ADCMULT)
-               rate = 150000000/ADCMULT;
-       /* slight violation of specs, needed for continuous sampling rates */
-       for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1);
-       for (xn = 3; xn < 35; xn++)
-               for (xm = 3; xm < 130; xm++) {
-                       xr = REFFREQUENCY/ADCMULT * xm / xn;
-                       xd = abs((signed)(xr - rate));
-                       if (xd < metric) {
-                               metric = xd;
-                               m = xm - 2;
-                               n = xn - 2;
-                       }
-               }
-       reg &= 0x3f;
-       spin_lock_irqsave(&s->lock, flags);
-       outb(reg, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(m, s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       outb(r | n, s->ioenh + SV_CODEC_IDATA);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-       return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7);
-}
-
-#if 0
-
-static unsigned getpll(struct sv_state *s, unsigned char reg)
-{
-       unsigned long flags;
-       unsigned char m, n;
-
-       reg &= 0x3f;
-       spin_lock_irqsave(&s->lock, flags);
-       outb(reg, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       m = inb(s->ioenh + SV_CODEC_IDATA);
-       udelay(10);
-       outb(reg+1, s->ioenh + SV_CODEC_IADDR);
-       udelay(10);
-       n = inb(s->ioenh + SV_CODEC_IDATA);
-       spin_unlock_irqrestore(&s->lock, flags);
-       udelay(10);
-       return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7);
-}
-
-#endif
-
-static void set_dac_rate(struct sv_state *s, unsigned rate)
-{
-       unsigned div;
-       unsigned long flags;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-       div = (rate * 65536 + FULLRATE/2) / FULLRATE;
-       if (div > 65535)
-               div = 65535;
-       spin_lock_irqsave(&s->lock, flags);
-       wrindir(s, SV_CIPCMSR1, div >> 8);
-       wrindir(s, SV_CIPCMSR0, div);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->ratedac = (div * FULLRATE + 32768) / 65536;
-}
-
-static void set_adc_rate(struct sv_state *s, unsigned rate)
-{
-       unsigned long flags;
-       unsigned rate1, rate2, div;
-
-       if (rate > 48000)
-               rate = 48000;
-       if (rate < 4000)
-               rate = 4000;
-       rate1 = setpll(s, SV_CIADCPLLM, rate);
-       div = (48000 + rate/2) / rate;
-       if (div > 8)
-               div = 8;
-       rate2 = (48000 + div/2) / div;
-       spin_lock_irqsave(&s->lock, flags);
-       wrindir(s, SV_CIADCALTSR, (div-1) << 4);
-       if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) {
-               wrindir(s, SV_CIADCCLKSOURCE, 0x10);
-               s->rateadc = rate2;
-       } else {
-               wrindir(s, SV_CIADCCLKSOURCE, 0x00);
-               s->rateadc = rate1;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}
-
-/* --------------------------------------------------------------------- */
-
-static inline void stop_adc(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->enable &= ~SV_CENABLE_RE;
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static inline void stop_dac(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE);
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_dac(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
-               s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE;
-               wrindir(s, SV_CIENABLE, s->enable);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-static void start_adc(struct sv_state *s)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
-           && s->dma_adc.ready) {
-               s->enable |= SV_CENABLE_RE;
-               wrindir(s, SV_CIENABLE, s->enable);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-}      
-
-/* --------------------------------------------------------------------- */
-
-#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-static void dealloc_dmabuf(struct sv_state *s, struct dmabuf *db)
-{
-       struct page *page, *pend;
-
-       if (db->rawbuf) {
-               /* undo marking the pages as reserved */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       ClearPageReserved(page);
-               pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
-       }
-       db->rawbuf = NULL;
-       db->mapped = db->ready = 0;
-}
-
-
-/* DMAA is used for playback, DMAC is used for recording */
-
-static int prog_dmabuf(struct sv_state *s, unsigned rec)
-{
-       struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
-       unsigned rate = rec ? s->rateadc : s->ratedac;
-       int order;
-       unsigned bytepersec;
-       unsigned bufs;
-       struct page *page, *pend;
-       unsigned char fmt;
-       unsigned long flags;
-
-       spin_lock_irqsave(&s->lock, flags);
-       fmt = s->fmt;
-       if (rec) {
-               s->enable &= ~SV_CENABLE_RE;
-               fmt >>= SV_CFMT_CSHIFT;
-       } else {
-               s->enable &= ~SV_CENABLE_PE;
-               fmt >>= SV_CFMT_ASHIFT;
-       }
-       wrindir(s, SV_CIENABLE, s->enable);
-       spin_unlock_irqrestore(&s->lock, flags);
-       fmt &= SV_CFMT_MASK;
-       db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
-       if (!db->rawbuf) {
-               db->ready = db->mapped = 0;
-               for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
-                       if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr)))
-                               break;
-               if (!db->rawbuf)
-                       return -ENOMEM;
-               db->buforder = order;
-               if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-                       printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
-                              virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-               if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-                       printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
-                              virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
-               /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-               pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
-               for (page = virt_to_page(db->rawbuf); page <= pend; page++)
-                       SetPageReserved(page);
-       }
-       bytepersec = rate << sample_shift[fmt];
-       bufs = PAGE_SIZE << db->buforder;
-       if (db->ossfragshift) {
-               if ((1000 << db->ossfragshift) < bytepersec)
-                       db->fragshift = ld2(bytepersec/1000);
-               else
-                       db->fragshift = db->ossfragshift;
-       } else {
-               db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-               if (db->fragshift < 3)
-                       db->fragshift = 3;
-       }
-       db->numfrag = bufs >> db->fragshift;
-       while (db->numfrag < 4 && db->fragshift > 3) {
-               db->fragshift--;
-               db->numfrag = bufs >> db->fragshift;
-       }
-       db->fragsize = 1 << db->fragshift;
-       if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
-               db->numfrag = db->ossmaxfrags;
-       db->fragsamples = db->fragsize >> sample_shift[fmt];
-       db->dmasize = db->numfrag << db->fragshift;
-       memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
-       spin_lock_irqsave(&s->lock, flags);
-       if (rec) {
-               set_dmac(s, db->dmaaddr, db->numfrag << db->fragshift);
-               /* program enhanced mode registers */
-               wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8);
-               wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1);
-       } else {
-               set_dmaa(s, db->dmaaddr, db->numfrag << db->fragshift);
-               /* program enhanced mode registers */
-               wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8);
-               wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1);
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       db->enabled = 1;
-       db->ready = 1;
-       return 0;
-}
-
-static inline void clear_advance(struct sv_state *s)
-{
-       unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80;
-       unsigned char *buf = s->dma_dac.rawbuf;
-       unsigned bsize = s->dma_dac.dmasize;
-       unsigned bptr = s->dma_dac.swptr;
-       unsigned len = s->dma_dac.fragsize;
-
-       if (bptr + len > bsize) {
-               unsigned x = bsize - bptr;
-               memset(buf + bptr, c, x);
-               bptr = 0;
-               len -= x;
-       }
-       memset(buf + bptr, c, len);
-}
-
-/* call with spinlock held! */
-static void sv_update_ptr(struct sv_state *s)
-{
-       unsigned hwptr;
-       int diff;
-
-       /* update ADC pointer */
-       if (s->dma_adc.ready) {
-               hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize;
-               diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
-               s->dma_adc.hwptr = hwptr;
-               s->dma_adc.total_bytes += diff;
-               s->dma_adc.count += diff;
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
-                       wake_up(&s->dma_adc.wait);
-               if (!s->dma_adc.mapped) {
-                       if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
-                               s->enable &= ~SV_CENABLE_RE;
-                               wrindir(s, SV_CIENABLE, s->enable);
-                               s->dma_adc.error++;
-                       }
-               }
-       }
-       /* update DAC pointer */
-       if (s->dma_dac.ready) {
-               hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize;
-               diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
-               s->dma_dac.hwptr = hwptr;
-               s->dma_dac.total_bytes += diff;
-               if (s->dma_dac.mapped) {
-                       s->dma_dac.count += diff;
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
-                               wake_up(&s->dma_dac.wait);
-               } else {
-                       s->dma_dac.count -= diff;
-                       if (s->dma_dac.count <= 0) {
-                               s->enable &= ~SV_CENABLE_PE;
-                               wrindir(s, SV_CIENABLE, s->enable);
-                               s->dma_dac.error++;
-                       } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) {
-                               clear_advance(s);
-                               s->dma_dac.endcleared = 1;
-                       }
-                       if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize)
-                               wake_up(&s->dma_dac.wait);
-               }
-       }
-}
-
-/* hold spinlock for the following! */
-static void sv_handle_midi(struct sv_state *s)
-{
-       unsigned char ch;
-       int wake;
-
-       wake = 0;
-       while (!(inb(s->iomidi+1) & 0x80)) {
-               ch = inb(s->iomidi);
-               if (s->midi.icnt < MIDIINBUF) {
-                       s->midi.ibuf[s->midi.iwr] = ch;
-                       s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
-                       s->midi.icnt++;
-               }
-               wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.iwait);
-       wake = 0;
-       while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) {
-               outb(s->midi.obuf[s->midi.ord], s->iomidi);
-               s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
-               s->midi.ocnt--;
-               if (s->midi.ocnt < MIDIOUTBUF-16)
-                       wake = 1;
-       }
-       if (wake)
-               wake_up(&s->midi.owait);
-}
-
-static irqreturn_t sv_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-        struct sv_state *s = (struct sv_state *)dev_id;
-       unsigned int intsrc;
-       
-       /* fastpath out, to ease interrupt sharing */
-       intsrc = inb(s->ioenh + SV_CODEC_STATUS);
-       if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI)))
-               return IRQ_NONE;
-       spin_lock(&s->lock);
-       sv_update_ptr(s);
-       sv_handle_midi(s);
-       spin_unlock(&s->lock);
-       return IRQ_HANDLED;
-}
-
-static void sv_midi_timer(unsigned long data)
-{
-       struct sv_state *s = (struct sv_state *)data;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&s->lock, flags);
-       sv_handle_midi(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->midi.timer.expires = jiffies+1;
-       add_timer(&s->midi.timer);
-}
-
-/* --------------------------------------------------------------------- */
-
-static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n";
-
-#define VALIDATE_STATE(s)                         \
-({                                                \
-       if (!(s) || (s)->magic != SV_MAGIC) { \
-               printk(invalid_magic);            \
-               return -ENXIO;                    \
-       }                                         \
-})
-
-/* --------------------------------------------------------------------- */
-
-#define MT_4          1
-#define MT_5MUTE      2
-#define MT_4MUTEMONO  3
-#define MT_6MUTE      4
-
-static const struct {
-       unsigned left:5;
-       unsigned right:5;
-       unsigned type:3;
-       unsigned rec:3;
-} mixtable[SOUND_MIXER_NRDEVICES] = {
-       [SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL,    SV_CIMIX_ADCINR,    MT_4,         0 },
-       [SOUND_MIXER_LINE1]  = { SV_CIMIX_AUX1INL,   SV_CIMIX_AUX1INR,   MT_5MUTE,     5 },
-       [SOUND_MIXER_CD]     = { SV_CIMIX_CDINL,     SV_CIMIX_CDINR,     MT_5MUTE,     1 },
-       [SOUND_MIXER_LINE]   = { SV_CIMIX_LINEINL,   SV_CIMIX_LINEINR,   MT_5MUTE,     4 },
-       [SOUND_MIXER_MIC]    = { SV_CIMIX_MICIN,     SV_CIMIX_ADCINL,    MT_4MUTEMONO, 6 },
-       [SOUND_MIXER_SYNTH]  = { SV_CIMIX_SYNTHINL,  SV_CIMIX_SYNTHINR,  MT_5MUTE,     2 },
-       [SOUND_MIXER_LINE2]  = { SV_CIMIX_AUX2INL,   SV_CIMIX_AUX2INR,   MT_5MUTE,     3 },
-       [SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE,     7 },
-       [SOUND_MIXER_PCM]    = { SV_CIMIX_PCMINL,    SV_CIMIX_PCMINR,    MT_6MUTE,     0 }
-};
-
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct sv_state *s, unsigned i, int *arg)
-{
-       unsigned long flags;
-       unsigned char l, r, rl, rr;
-
-       spin_lock_irqsave(&s->lock, flags);
-       l = rdindir(s, mixtable[i].left);
-       r = rdindir(s, mixtable[i].right);
-       spin_unlock_irqrestore(&s->lock, flags);
-       switch (mixtable[i].type) {
-       case MT_4:
-               r &= 0xf;
-               l &= 0xf;
-               rl = 10 + 6 * (l & 15);
-               rr = 10 + 6 * (r & 15);
-               break;
-
-       case MT_4MUTEMONO:
-               rl = 55 - 3 * (l & 15);
-               if (r & 0x10)
-                       rl += 45;
-               rr = rl;
-               r = l;
-               break;
-
-       case MT_5MUTE:
-       default:
-               rl = 100 - 3 * (l & 31);
-               rr = 100 - 3 * (r & 31);
-               break;
-                               
-       case MT_6MUTE:
-               rl = 100 - 3 * (l & 63) / 2;
-               rr = 100 - 3 * (r & 63) / 2;
-               break;
-       }
-       if (l & 0x80)
-               rl = 0;
-       if (r & 0x80)
-               rr = 0;
-       return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = 
-{
-       [SOUND_MIXER_RECLEV] = 1,
-       [SOUND_MIXER_LINE1]  = 2,
-       [SOUND_MIXER_CD]     = 3,
-       [SOUND_MIXER_LINE]   = 4,
-       [SOUND_MIXER_MIC]    = 5,
-       [SOUND_MIXER_SYNTH]  = 6,
-       [SOUND_MIXER_LINE2]  = 7,
-       [SOUND_MIXER_VOLUME] = 8,
-       [SOUND_MIXER_PCM]    = 9
-};
-
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
-static unsigned mixer_recmask(struct sv_state *s)
-{
-       unsigned long flags;
-       int i, j;
-
-       spin_lock_irqsave(&s->lock, flags);
-       j = rdindir(s, SV_CIMIX_ADCINL) >> 5;
-       spin_unlock_irqrestore(&s->lock, flags);
-       j &= 7;
-       for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++);
-       return 1 << i;
-}
-
-static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg)
-{
-       unsigned long flags;
-       int i, val;
-       unsigned char l, r, rl, rr;
-       int __user *p = (int __user *)arg;
-
-       VALIDATE_STATE(s);
-        if (cmd == SOUND_MIXER_INFO) {
-               mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "SonicVibes", sizeof(info.id));
-               strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-               info.modify_counter = s->mix.modcnt;
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == SOUND_OLD_MIXER_INFO) {
-               _old_mixer_info info;
-               memset(&info, 0, sizeof(info));
-               strlcpy(info.id, "SonicVibes", sizeof(info.id));
-               strlcpy(info.name, "S3 SonicVibes", sizeof(info.name));
-               if (copy_to_user((void __user *)arg, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       if (cmd == OSS_GETVERSION)
-               return put_user(SOUND_VERSION, p);
-       if (cmd == SOUND_MIXER_PRIVATE1) {  /* SRS settings */
-               if (get_user(val, p))
-                       return -EFAULT;
-               spin_lock_irqsave(&s->lock, flags);
-               if (val & 1) {
-                       if (val & 2) {
-                               l = 4 - ((val >> 2) & 7);
-                               if (l & ~3)
-                                       l = 4;
-                               r = 4 - ((val >> 5) & 7);
-                               if (r & ~3)
-                                       r = 4;
-                               wrindir(s, SV_CISRSSPACE, l);
-                               wrindir(s, SV_CISRSCENTER, r);
-                       } else
-                               wrindir(s, SV_CISRSSPACE, 0x80);
-               }
-               l = rdindir(s, SV_CISRSSPACE);
-               r = rdindir(s, SV_CISRSCENTER);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (l & 0x80)
-                       return put_user(0, p);
-               return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, p);
-       }
-       if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int))
-                return -EINVAL;
-        if (_SIOC_DIR(cmd) == _SIOC_READ) {
-                switch (_IOC_NR(cmd)) {
-                case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-                       return put_user(mixer_recmask(s), p);
-                       
-                case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-
-                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].rec)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
-                       for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
-                               if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO)
-                                       val |= 1 << i;
-                       return put_user(val, p);
-                       
-                case SOUND_MIXER_CAPS:
-                       return put_user(SOUND_CAP_EXCL_INPUT, p);
-
-               default:
-                       i = _IOC_NR(cmd);
-                        if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                                return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                       return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-                       if (!volidx[i])
-                               return -EINVAL;
-                       return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-               }
-       }
-        if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) 
-               return -EINVAL;
-       s->mix.modcnt++;
-       switch (_IOC_NR(cmd)) {
-       case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
-               if (get_user(val, p))
-                       return -EFAULT;
-               i = hweight32(val);
-               if (i == 0)
-                       return 0; /*val = mixer_recmask(s);*/
-               else if (i > 1) 
-                       val &= ~mixer_recmask(s);
-               for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
-                       if (!(val & (1 << i)))
-                               continue;
-                       if (mixtable[i].rec)
-                               break;
-               }
-               if (i == SOUND_MIXER_NRDEVICES)
-                       return 0;
-               spin_lock_irqsave(&s->lock, flags);
-               frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5);
-               frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5);
-               spin_unlock_irqrestore(&s->lock, flags);
-               return 0;
-
-       default:
-               i = _IOC_NR(cmd);
-               if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
-                       return -EINVAL;
-               if (get_user(val, p))
-                       return -EFAULT;
-               l = val & 0xff;
-               r = (val >> 8) & 0xff;
-               if (mixtable[i].type == MT_4MUTEMONO)
-                       l = (r + l) / 2;
-               if (l > 100)
-                       l = 100;
-               if (r > 100)
-                       r = 100;
-               spin_lock_irqsave(&s->lock, flags);
-               switch (mixtable[i].type) {
-               case MT_4:
-                       if (l >= 10)
-                               l -= 10;
-                       if (r >= 10)
-                               r -= 10;
-                       frobindir(s, mixtable[i].left, 0xf0, l / 6);
-                       frobindir(s, mixtable[i].right, 0xf0, l / 6);
-                       break;
-
-               case MT_4MUTEMONO:
-                       rr = 0;
-                       if (l < 10)
-                               rl = 0x80;
-                       else {
-                               if (l >= 55) {
-                                       rr = 0x10;
-                                       l -= 45;
-                               }
-                               rl = (55 - l) / 3;
-                       }
-                       wrindir(s, mixtable[i].left, rl);
-                       frobindir(s, mixtable[i].right, ~0x10, rr);
-                       break;
-                       
-               case MT_5MUTE:
-                       if (l < 7)
-                               rl = 0x80;
-                       else
-                               rl = (100 - l) / 3;
-                       if (r < 7)
-                               rr = 0x80;
-                       else
-                               rr = (100 - r) / 3;
-                       wrindir(s, mixtable[i].left, rl);
-                       wrindir(s, mixtable[i].right, rr);
-                       break;
-                               
-               case MT_6MUTE:
-                       if (l < 6)
-                               rl = 0x80;
-                       else
-                               rl = (100 - l) * 2 / 3;
-                       if (r < 6)
-                               rr = 0x80;
-                       else
-                               rr = (100 - r) * 2 / 3;
-                       wrindir(s, mixtable[i].left, rl);
-                       wrindir(s, mixtable[i].right, rr);
-                       break;
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, p);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-               if (!volidx[i])
-                       return -EINVAL;
-               s->mix.vol[volidx[i]-1] = val;
-               return put_user(s->mix.vol[volidx[i]-1], p);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-       }
-}
-
-/* --------------------------------------------------------------------- */
-
-static int sv_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_mixer == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       return nonseekable_open(inode, file);
-}
-
-static int sv_release_mixdev(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       
-       VALIDATE_STATE(s);
-       return 0;
-}
-
-static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg);
-}
-
-static /*const*/ struct file_operations sv_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = sv_ioctl_mixdev,
-       .open           = sv_open_mixdev,
-       .release        = sv_release_mixdev,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int drain_dac(struct sv_state *s, int nonblock)
-{
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       int count, tmo;
-
-       if (s->dma_dac.mapped || !s->dma_dac.ready)
-               return 0;
-        add_wait_queue(&s->dma_dac.wait, &wait);
-        for (;;) {
-               __set_current_state(TASK_INTERRUPTIBLE);
-                spin_lock_irqsave(&s->lock, flags);
-               count = s->dma_dac.count;
-                spin_unlock_irqrestore(&s->lock, flags);
-               if (count <= 0)
-                       break;
-               if (signal_pending(current))
-                        break;
-                if (nonblock) {
-                        remove_wait_queue(&s->dma_dac.wait, &wait);
-                        set_current_state(TASK_RUNNING);
-                        return -EBUSY;
-                }
-               tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
-               tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK];
-               if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "sv: dma timed out??\n");
-        }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-        set_current_state(TASK_RUNNING);
-        if (signal_pending(current))
-                return -ERESTARTSYS;
-        return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_adc.mapped)
-               return -ENXIO;
-       if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
-               return ret;
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       ret = 0;
-#if 0
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_adc.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               swptr = s->dma_adc.swptr;
-               cnt = s->dma_adc.dmasize-swptr;
-               if (s->dma_adc.count < cnt)
-                       cnt = s->dma_adc.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_adc.enabled)
-                               start_adc(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
-                                      s->dma_adc.hwptr, s->dma_adc.swptr);
-                               stop_adc(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
-                               /* program enhanced mode registers */
-                               wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1);
-                               s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_adc.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_adc.swptr = swptr;
-               s->dma_adc.count -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_adc.enabled)
-                       start_adc(s);
-       }
-        remove_wait_queue(&s->dma_adc.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-static ssize_t sv_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned swptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (s->dma_dac.mapped)
-               return -ENXIO;
-       if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-               return ret;
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       ret = 0;
-#if 0
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       spin_unlock_irqrestore(&s->lock, flags);
-#endif
-        add_wait_queue(&s->dma_dac.wait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               if (s->dma_dac.count < 0) {
-                       s->dma_dac.count = 0;
-                       s->dma_dac.swptr = s->dma_dac.hwptr;
-               }
-               swptr = s->dma_dac.swptr;
-               cnt = s->dma_dac.dmasize-swptr;
-               if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
-                       cnt = s->dma_dac.dmasize - s->dma_dac.count;
-               if (cnt <= 0)
-                       __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (s->dma_dac.enabled)
-                               start_dac(s);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       if (!schedule_timeout(HZ)) {
-                               printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                      s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, 
-                                      s->dma_dac.hwptr, s->dma_dac.swptr);
-                               stop_dac(s);
-                               spin_lock_irqsave(&s->lock, flags);
-                               set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
-                               /* program enhanced mode registers */
-                               wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
-                               wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1);
-                               s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
-                               spin_unlock_irqrestore(&s->lock, flags);
-                       }
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               swptr = (swptr + cnt) % s->dma_dac.dmasize;
-               spin_lock_irqsave(&s->lock, flags);
-               s->dma_dac.swptr = swptr;
-               s->dma_dac.count += cnt;
-               s->dma_dac.endcleared = 0;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               if (s->dma_dac.enabled)
-                       start_dac(s);
-       }
-        remove_wait_queue(&s->dma_dac.wait, &wait);
-       set_current_state(TASK_RUNNING);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE) {
-               if (!s->dma_dac.ready && prog_dmabuf(s, 1))
-                       return 0;
-               poll_wait(file, &s->dma_dac.wait, wait);
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!s->dma_adc.ready && prog_dmabuf(s, 0))
-                       return 0;
-               poll_wait(file, &s->dma_adc.wait, wait);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       sv_update_ptr(s);
-       if (file->f_mode & FMODE_READ) {
-               if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->dma_dac.mapped) {
-                       if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int sv_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       struct dmabuf *db;
-       int ret = -EINVAL;
-       unsigned long size;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(s, 1)) != 0)
-                       goto out;
-               db = &s->dma_dac;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(s, 0)) != 0)
-                       goto out;
-               db = &s->dma_adc;
-       } else 
-               goto out;
-       ret = -EINVAL;
-       if (vma->vm_pgoff != 0)
-               goto out;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << db->buforder))
-               goto out;
-       ret = -EAGAIN;
-       if (remap_pfn_range(vma, vma->vm_start,
-                               virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
-                               size, vma->vm_page_prot))
-               goto out;
-       db->mapped = 1;
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
-}
-
-static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-        audio_buf_info abinfo;
-        count_info cinfo;
-       int count;
-       int val, mapped, ret;
-       unsigned char fmtm, fmtd;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       VALIDATE_STATE(s);
-        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
-               ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
-       switch (cmd) {
-       case OSS_GETVERSION:
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_SYNC:
-               if (file->f_mode & FMODE_WRITE)
-                       return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
-               return 0;
-               
-       case SNDCTL_DSP_SETDUPLEX:
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p);
-               
-        case SNDCTL_DSP_RESET:
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       synchronize_irq(s->irq);
-                       s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
-               }
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       synchronize_irq(s->irq);
-                       s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SPEED:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val >= 0) {
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               set_adc_rate(s, val);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               set_dac_rate(s, val);
-                       }
-               }
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-               
-        case SNDCTL_DSP_STEREO:
-                if (get_user(val, p))
-                       return -EFAULT;
-               fmtd = 0;
-               fmtm = ~0;
-               if (file->f_mode & FMODE_READ) {
-                       stop_adc(s);
-                       s->dma_adc.ready = 0;
-                       if (val)
-                               fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-                       else
-                               fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       stop_dac(s);
-                       s->dma_dac.ready = 0;
-                       if (val)
-                               fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-                       else
-                               fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-               }
-               set_fmt(s, fmtm, fmtd);
-               return 0;
-
-        case SNDCTL_DSP_CHANNELS:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 0) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val >= 2)
-                                       fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-               
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
-                return put_user(AFMT_S16_LE|AFMT_U8, p);
-               
-       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (val != AFMT_QUERY) {
-                       fmtd = 0;
-                       fmtm = ~0;
-                       if (file->f_mode & FMODE_READ) {
-                               stop_adc(s);
-                               s->dma_adc.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT);
-                       }
-                       if (file->f_mode & FMODE_WRITE) {
-                               stop_dac(s);
-                               s->dma_dac.ready = 0;
-                               if (val == AFMT_S16_LE)
-                                       fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-                               else
-                                       fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT);
-                       }
-                       set_fmt(s, fmtm, fmtd);
-               }
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p);
-               
-       case SNDCTL_DSP_POST:
-                return 0;
-
-        case SNDCTL_DSP_GETTRIGGER:
-               val = 0;
-               if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE) 
-                       val |= PCM_ENABLE_INPUT;
-               if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) 
-                       val |= PCM_ENABLE_OUTPUT;
-               return put_user(val, p);
-               
-       case SNDCTL_DSP_SETTRIGGER:
-               if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       if (val & PCM_ENABLE_INPUT) {
-                               if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
-                                       return ret;
-                               s->dma_adc.enabled = 1;
-                               start_adc(s);
-                       } else {
-                               s->dma_adc.enabled = 0;
-                               stop_adc(s);
-                       }
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       if (val & PCM_ENABLE_OUTPUT) {
-                               if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
-                                       return ret;
-                               s->dma_dac.enabled = 1;
-                               start_dac(s);
-                       } else {
-                               s->dma_dac.enabled = 0;
-                               stop_dac(s);
-                       }
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-               abinfo.fragsize = s->dma_dac.fragsize;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = s->dma_dac.dmasize - count;
-                abinfo.fragstotal = s->dma_dac.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-               abinfo.fragsize = s->dma_adc.fragsize;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                abinfo.bytes = count;
-                abinfo.fragstotal = s->dma_adc.numfrag;
-                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
-               spin_unlock_irqrestore(&s->lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-               
-        case SNDCTL_DSP_NONBLOCK:
-                file->f_flags |= O_NONBLOCK;
-                return 0;
-
-        case SNDCTL_DSP_GETODELAY:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                count = s->dma_dac.count;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (count < 0)
-                       count = 0;
-               return put_user(count, p);
-
-        case SNDCTL_DSP_GETIPTR:
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                cinfo.bytes = s->dma_adc.total_bytes;
-               count = s->dma_adc.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_adc.fragshift;
-                cinfo.ptr = s->dma_adc.hwptr;
-               if (s->dma_adc.mapped)
-                       s->dma_adc.count &= s->dma_adc.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETOPTR:
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0)
-                       return val;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_update_ptr(s);
-                cinfo.bytes = s->dma_dac.total_bytes;
-               count = s->dma_dac.count;
-               if (count < 0)
-                       count = 0;
-                cinfo.blocks = count >> s->dma_dac.fragshift;
-                cinfo.ptr = s->dma_dac.hwptr;
-               if (s->dma_dac.mapped)
-                       s->dma_dac.count &= s->dma_dac.fragsize-1;
-               spin_unlock_irqrestore(&s->lock, flags);
-                if (copy_to_user(argp, &cinfo, sizeof(cinfo)))
-                       return -EFAULT;
-               return 0;
-
-        case SNDCTL_DSP_GETBLKSIZE:
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(s, 0)))
-                               return val;
-                       return put_user(s->dma_dac.fragsize, p);
-               }
-               if ((val = prog_dmabuf(s, 1)))
-                       return val;
-               return put_user(s->dma_adc.fragsize, p);
-
-        case SNDCTL_DSP_SETFRAGMENT:
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (file->f_mode & FMODE_READ) {
-                       s->dma_adc.ossfragshift = val & 0xffff;
-                       s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_adc.ossfragshift < 4)
-                               s->dma_adc.ossfragshift = 4;
-                       if (s->dma_adc.ossfragshift > 15)
-                               s->dma_adc.ossfragshift = 15;
-                       if (s->dma_adc.ossmaxfrags < 4)
-                               s->dma_adc.ossmaxfrags = 4;
-               }
-               if (file->f_mode & FMODE_WRITE) {
-                       s->dma_dac.ossfragshift = val & 0xffff;
-                       s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
-                       if (s->dma_dac.ossfragshift < 4)
-                               s->dma_dac.ossfragshift = 4;
-                       if (s->dma_dac.ossfragshift > 15)
-                               s->dma_dac.ossfragshift = 15;
-                       if (s->dma_dac.ossmaxfrags < 4)
-                               s->dma_dac.ossmaxfrags = 4;
-               }
-               return 0;
-
-        case SNDCTL_DSP_SUBDIVIDE:
-               if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
-                   (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
-                       return -EINVAL;
-                if (get_user(val, p))
-                       return -EFAULT;
-               if (val != 1 && val != 2 && val != 4)
-                       return -EINVAL;
-               if (file->f_mode & FMODE_READ)
-                       s->dma_adc.subdivision = val;
-               if (file->f_mode & FMODE_WRITE)
-                       s->dma_dac.subdivision = val;
-               return 0;
-
-        case SOUND_PCM_READ_RATE:
-               return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p);
-
-        case SOUND_PCM_READ_CHANNELS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p);
-
-        case SOUND_PCM_READ_BITS:
-               return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) 
-                                          : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p);
-
-        case SOUND_PCM_WRITE_FILTER:
-        case SNDCTL_DSP_SETSYNCRO:
-        case SOUND_PCM_READ_FILTER:
-                return -EINVAL;
-               
-       }
-       return mixer_ioctl(s, cmd, arg);
-}
-
-static int sv_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned char fmtm = ~0, fmts = 0;
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (!((s->dev_audio ^ minor) & ~0xf))
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & file->f_mode) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       if (file->f_mode & FMODE_READ) {
-               fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT;
-               s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
-               s->dma_adc.enabled = 1;
-               set_adc_rate(s, 8000);
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT);
-               if ((minor & 0xf) == SND_DEV_DSP16)
-                       fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT;
-               s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
-               s->dma_dac.enabled = 1;
-               set_dac_rate(s, 8000);
-       }
-       set_fmt(s, fmtm, fmts);
-       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE)
-               drain_dac(s, file->f_flags & O_NONBLOCK);
-       mutex_lock(&s->open_mutex);
-       if (file->f_mode & FMODE_WRITE) {
-               stop_dac(s);
-               dealloc_dmabuf(s, &s->dma_dac);
-       }
-       if (file->f_mode & FMODE_READ) {
-               stop_adc(s);
-               dealloc_dmabuf(s, &s->dma_adc);
-       }
-       s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_audio_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = sv_read,
-       .write          = sv_write,
-       .poll           = sv_poll,
-       .ioctl          = sv_ioctl,
-       .mmap           = sv_mmap,
-       .open           = sv_open,
-       .release        = sv_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static ssize_t sv_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_WRITE, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-       add_wait_queue(&s->midi.iwait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.ird;
-               cnt = MIDIINBUF - ptr;
-               if (s->midi.icnt < cnt)
-                       cnt = s->midi.icnt;
-               if (cnt <= 0)
-                      __set_current_state(TASK_INTERRUPTIBLE);
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                      if (file->f_flags & O_NONBLOCK) {
-                              if (!ret)
-                                      ret = -EAGAIN;
-                              break;
-                      }
-                      schedule();
-                      if (signal_pending(current)) {
-                              if (!ret)
-                                      ret = -ERESTARTSYS;
-                              break;
-                      }
-                       continue;
-               }
-               if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIINBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.ird = ptr;
-               s->midi.icnt -= cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               break;
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.iwait, &wait);
-       return ret;
-}
-
-static ssize_t sv_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned ptr;
-       int cnt;
-
-       VALIDATE_STATE(s);
-       if (!access_ok(VERIFY_READ, buffer, count))
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-       ret = 0;
-        add_wait_queue(&s->midi.owait, &wait);
-       while (count > 0) {
-               spin_lock_irqsave(&s->lock, flags);
-               ptr = s->midi.owr;
-               cnt = MIDIOUTBUF - ptr;
-               if (s->midi.ocnt + cnt > MIDIOUTBUF)
-                       cnt = MIDIOUTBUF - s->midi.ocnt;
-               if (cnt <= 0) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       sv_handle_midi(s);
-               }
-               spin_unlock_irqrestore(&s->lock, flags);
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret)
-                                       ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       if (signal_pending(current)) {
-                               if (!ret)
-                                       ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) {
-                       if (!ret)
-                               ret = -EFAULT;
-                       break;
-               }
-               ptr = (ptr + cnt) % MIDIOUTBUF;
-               spin_lock_irqsave(&s->lock, flags);
-               s->midi.owr = ptr;
-               s->midi.ocnt += cnt;
-               spin_unlock_irqrestore(&s->lock, flags);
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               spin_lock_irqsave(&s->lock, flags);
-               sv_handle_midi(s);
-               spin_unlock_irqrestore(&s->lock, flags);
-       }
-       __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&s->midi.owait, &wait);
-       return ret;
-}
-
-/* No kernel lock - we have our own spinlock */
-static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       VALIDATE_STATE(s);
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &s->midi.owait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &s->midi.iwait, wait);
-       spin_lock_irqsave(&s->lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               if (s->midi.icnt > 0)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               if (s->midi.ocnt < MIDIOUTBUF)
-                       mask |= POLLOUT | POLLWRNORM;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       return mask;
-}
-
-static int sv_midi_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_midi == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-               //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL);
-               outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-               wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */
-               wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */
-               outb(0xff, s->iomidi+1); /* reset command */
-               outb(0x3f, s->iomidi+1); /* uart command */
-               if (!(inb(s->iomidi+1) & 0x80))
-                       inb(s->iomidi);
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-               init_timer(&s->midi.timer);
-               s->midi.timer.expires = jiffies+1;
-               s->midi.timer.data = (unsigned long)s;
-               s->midi.timer.function = sv_midi_timer;
-               add_timer(&s->midi.timer);
-       }
-       if (file->f_mode & FMODE_READ) {
-               s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_midi_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       unsigned long flags;
-       unsigned count, tmo;
-
-       VALIDATE_STATE(s);
-
-       lock_kernel();
-       if (file->f_mode & FMODE_WRITE) {
-               add_wait_queue(&s->midi.owait, &wait);
-               for (;;) {
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       spin_lock_irqsave(&s->lock, flags);
-                       count = s->midi.ocnt;
-                       spin_unlock_irqrestore(&s->lock, flags);
-                       if (count <= 0)
-                               break;
-                       if (signal_pending(current))
-                               break;
-                       if (file->f_flags & O_NONBLOCK) {
-                               remove_wait_queue(&s->midi.owait, &wait);
-                               set_current_state(TASK_RUNNING);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       tmo = (count * HZ) / 3100;
-                       if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG "sv: midi timed out??\n");
-               }
-               remove_wait_queue(&s->midi.owait, &wait);
-               set_current_state(TASK_RUNNING);
-       }
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
-       spin_lock_irqsave(&s->lock, flags);
-       if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
-               outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK);
-               del_timer(&s->midi.timer);              
-       }
-       spin_unlock_irqrestore(&s->lock, flags);
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_midi_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = sv_midi_read,
-       .write          = sv_midi_write,
-       .poll           = sv_midi_poll,
-       .open           = sv_midi_open,
-       .release        = sv_midi_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       static const unsigned char op_offset[18] = {
-               0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
-               0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-               0x10, 0x11, 0x12, 0x13, 0x14, 0x15
-       };
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       struct dm_fm_voice v;
-       struct dm_fm_note n;
-       struct dm_fm_params p;
-       unsigned int io;
-       unsigned int regb;
-
-       switch (cmd) {          
-       case FM_IOCTL_RESET:
-               for (regb = 0xb0; regb < 0xb9; regb++) {
-                       outb(regb, s->iosynth);
-                       outb(0, s->iosynth+1);
-                       outb(regb, s->iosynth+2);
-                       outb(0, s->iosynth+3);
-               }
-               return 0;
-
-       case FM_IOCTL_PLAY_NOTE:
-               if (copy_from_user(&n, (void __user *)arg, sizeof(n)))
-                       return -EFAULT;
-               if (n.voice >= 18)
-                       return -EINVAL;
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->iosynth+2;
-               } else {
-                       regb = n.voice;
-                       io = s->iosynth;
-               }
-               outb(0xa0 + regb, io);
-               outb(n.fnum & 0xff, io+1);
-               outb(0xb0 + regb, io);
-               outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
-               return 0;
-
-       case FM_IOCTL_SET_VOICE:
-               if (copy_from_user(&v, (void __user *)arg, sizeof(v)))
-                       return -EFAULT;
-               if (v.voice >= 18)
-                       return -EINVAL;
-               regb = op_offset[v.voice];
-               io = s->iosynth + ((v.op & 1) << 1);
-               outb(0x20 + regb, io);
-               outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
-                    ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
-               outb(0x40 + regb, io);
-               outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
-               outb(0x60 + regb, io);
-               outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
-               outb(0x80 + regb, io);
-               outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
-               outb(0xe0 + regb, io);
-               outb(v.waveform & 0x7, io+1);
-               if (n.voice >= 9) {
-                       regb = n.voice - 9;
-                       io = s->iosynth+2;
-               } else {
-                       regb = n.voice;
-                       io = s->iosynth;
-               }
-               outb(0xc0 + regb, io);
-               outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
-                    (v.connection & 1), io+1);
-               return 0;
-               
-       case FM_IOCTL_SET_PARAMS:
-               if (copy_from_user(&p, (void *__user )arg, sizeof(p)))
-                       return -EFAULT;
-               outb(0x08, s->iosynth);
-               outb((p.kbd_split & 1) << 6, s->iosynth+1);
-               outb(0xbd, s->iosynth);
-               outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
-                    ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1);
-               return 0;
-
-       case FM_IOCTL_SET_OPL:
-               outb(4, s->iosynth+2);
-               outb(arg, s->iosynth+3);
-               return 0;
-
-       case FM_IOCTL_SET_MODE:
-               outb(5, s->iosynth+2);
-               outb(arg & 1, s->iosynth+3);
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-static int sv_dmfm_open(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       DECLARE_WAITQUEUE(wait, current);
-       struct list_head *list;
-       struct sv_state *s;
-
-       for (list = devs.next; ; list = list->next) {
-               if (list == &devs)
-                       return -ENODEV;
-               s = list_entry(list, struct sv_state, devs);
-               if (s->dev_dmfm == minor)
-                       break;
-       }
-               VALIDATE_STATE(s);
-       file->private_data = s;
-       /* wait for device to become free */
-       mutex_lock(&s->open_mutex);
-       while (s->open_mode & FMODE_DMFM) {
-               if (file->f_flags & O_NONBLOCK) {
-                       mutex_unlock(&s->open_mutex);
-                       return -EBUSY;
-               }
-               add_wait_queue(&s->open_wait, &wait);
-               __set_current_state(TASK_INTERRUPTIBLE);
-               mutex_unlock(&s->open_mutex);
-               schedule();
-               remove_wait_queue(&s->open_wait, &wait);
-               set_current_state(TASK_RUNNING);
-               if (signal_pending(current))
-                       return -ERESTARTSYS;
-               mutex_lock(&s->open_mutex);
-       }
-       /* init the stuff */
-       outb(1, s->iosynth);
-       outb(0x20, s->iosynth+1); /* enable waveforms */
-       outb(4, s->iosynth+2);
-       outb(0, s->iosynth+3);  /* no 4op enabled */
-       outb(5, s->iosynth+2);
-       outb(1, s->iosynth+3);  /* enable OPL3 */
-       s->open_mode |= FMODE_DMFM;
-       mutex_unlock(&s->open_mutex);
-       return nonseekable_open(inode, file);
-}
-
-static int sv_dmfm_release(struct inode *inode, struct file *file)
-{
-       struct sv_state *s = (struct sv_state *)file->private_data;
-       unsigned int regb;
-
-       VALIDATE_STATE(s);
-       lock_kernel();
-       mutex_lock(&s->open_mutex);
-       s->open_mode &= ~FMODE_DMFM;
-       for (regb = 0xb0; regb < 0xb9; regb++) {
-               outb(regb, s->iosynth);
-               outb(0, s->iosynth+1);
-               outb(regb, s->iosynth+2);
-               outb(0, s->iosynth+3);
-       }
-       wake_up(&s->open_wait);
-       mutex_unlock(&s->open_mutex);
-       unlock_kernel();
-       return 0;
-}
-
-static /*const*/ struct file_operations sv_dmfm_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = sv_dmfm_ioctl,
-       .open           = sv_dmfm_open,
-       .release        = sv_dmfm_release,
-};
-
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices; only used for command line params */
-#define NR_DEVICE 5
-
-static int reverb[NR_DEVICE];
-
-#if 0
-static int wavetable[NR_DEVICE];
-#endif
-
-static unsigned int devindex;
-
-module_param_array(reverb, bool, NULL, 0);
-MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM");
-#if 0
-MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i");
-MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled");
-#endif
-
-MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
-MODULE_DESCRIPTION("S3 SonicVibes Driver");
-MODULE_LICENSE("GPL");
-
-
-/* --------------------------------------------------------------------- */
-
-static struct initvol {
-       int mixch;
-       int vol;
-} initvol[] __devinitdata = {
-       { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE1, 0x4040 },
-       { SOUND_MIXER_WRITE_CD, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE, 0x4040 },
-       { SOUND_MIXER_WRITE_MIC, 0x4040 },
-       { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
-       { SOUND_MIXER_WRITE_LINE2, 0x4040 },
-       { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
-       { SOUND_MIXER_WRITE_PCM, 0x4040 }
-};
-
-#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
-                                (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
-
-#ifdef SUPPORT_JOYSTICK
-static int __devinit sv_register_gameport(struct sv_state *s, int io_port)
-{
-       struct gameport *gp;
-
-       if (!request_region(io_port, SV_EXTENT_GAME, "S3 SonicVibes Gameport")) {
-               printk(KERN_ERR "sv: gameport io ports are in use\n");
-               return -EBUSY;
-       }
-
-       s->gameport = gp = gameport_allocate_port();
-       if (!gp) {
-               printk(KERN_ERR "sv: can not allocate memory for gameport\n");
-               release_region(io_port, SV_EXTENT_GAME);
-               return -ENOMEM;
-       }
-
-       gameport_set_name(gp, "S3 SonicVibes Gameport");
-       gameport_set_phys(gp, "isa%04x/gameport0", io_port);
-       gp->dev.parent = &s->dev->dev;
-       gp->io = io_port;
-
-       gameport_register_port(gp);
-
-       return 0;
-}
-
-static inline void sv_unregister_gameport(struct sv_state *s)
-{
-       if (s->gameport) {
-               int gpio = s->gameport->io;
-               gameport_unregister_port(s->gameport);
-               release_region(gpio, SV_EXTENT_GAME);
-       }
-}
-#else
-static inline int sv_register_gameport(struct sv_state *s, int io_port) { return -ENOSYS; }
-static inline void sv_unregister_gameport(struct sv_state *s) { }
-#endif /* SUPPORT_JOYSTICK */
-
-static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
-{
-       static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
-               struct sv_state *s;
-       mm_segment_t fs;
-       int i, val, ret;
-       int gpio;
-       char *ddmaname;
-       unsigned ddmanamelen;
-
-       if ((ret=pci_enable_device(pcidev)))
-               return ret;
-
-       if (!RSRCISIOREGION(pcidev, RESOURCE_SB) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_ENH) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_MIDI) ||
-           !RSRCISIOREGION(pcidev, RESOURCE_GAME))
-               return -ENODEV;
-       if (pcidev->irq == 0)
-               return -ENODEV;
-       if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) {
-               printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n");
-               return -ENODEV;
-       }
-       /* try to allocate a DDMA resource if not already available */
-       if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) {
-               pcidev->resource[RESOURCE_DDMA].start = 0;
-               pcidev->resource[RESOURCE_DDMA].end = 2*SV_EXTENT_DMA-1;
-               pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO;
-               ddmanamelen = strlen(sv_ddma_name)+1;
-               if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL)))
-                       return -1;
-               memcpy(ddmaname, sv_ddma_name, ddmanamelen);
-               pcidev->resource[RESOURCE_DDMA].name = ddmaname;
-               if (pci_assign_resource(pcidev, RESOURCE_DDMA)) {
-                       pcidev->resource[RESOURCE_DDMA].name = NULL;
-                       kfree(ddmaname);
-                       printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
-                       return -EBUSY;
-               }
-       }
-       if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) {
-               printk(KERN_WARNING "sv: out of memory\n");
-               return -ENOMEM;
-       }
-       memset(s, 0, sizeof(struct sv_state));
-       init_waitqueue_head(&s->dma_adc.wait);
-       init_waitqueue_head(&s->dma_dac.wait);
-       init_waitqueue_head(&s->open_wait);
-       init_waitqueue_head(&s->midi.iwait);
-       init_waitqueue_head(&s->midi.owait);
-       mutex_init(&s->open_mutex);
-       spin_lock_init(&s->lock);
-       s->magic = SV_MAGIC;
-       s->dev = pcidev;
-       s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
-       s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
-       s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
-       s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
-       s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
-       s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
-       gpio = pci_resource_start(pcidev, RESOURCE_GAME);
-       pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9);  /* enable and use extended mode */
-       pci_write_config_dword(pcidev, 0x48, s->iodmac | 9);  /* enable */
-       printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n",
-              s->iosb, s->ioenh, s->iosynth, s->iomidi, gpio, s->iodmaa, s->iodmac);
-       s->irq = pcidev->irq;
-       
-       /* hack */
-       pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12);  /* wavetable base address */
-
-       ret = -EBUSY;
-       if (!request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
-               goto err_region5;
-       }
-       if (!request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA")) {
-               printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1);
-               goto err_region4;
-       }
-       if (!request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC")) {
-               printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1);
-               goto err_region3;
-       }
-       if (!request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
-               goto err_region2;
-       }
-       if (!request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth")) {
-               printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
-               goto err_region1;
-       }
-
-       /* initialize codec registers */
-       outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */
-       udelay(50);
-       outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */
-       udelay(50);
-       outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */
-            | (reverb[devindex] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL);
-       inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */
-       wrindir(s, SV_CIDRIVECONTROL, 0);  /* drive current 16mA */
-       wrindir(s, SV_CIENABLE, s->enable = 0);  /* disable DMAA and DMAC */
-       outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK);
-       /* outb(0xff, s->iodmaa + SV_DMA_RESET); */
-       /* outb(0xff, s->iodmac + SV_DMA_RESET); */
-       inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-       wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */
-       wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */
-       wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */
-       setpll(s, SV_CIADCPLLM, 8000);
-       wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */
-       wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff);
-       wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff);
-       wrindir(s, SV_CIADCOUTPUT, 0);
-       /* request irq */
-       if ((ret=request_irq(s->irq,sv_interrupt,IRQF_SHARED,"S3 SonicVibes",s))) {
-               printk(KERN_ERR "sv: irq %u in use\n", s->irq);
-               goto err_irq;
-       }
-       printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n",
-              s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));
-       /* register devices */
-       if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) {
-               ret = s->dev_audio;
-               goto err_dev1;
-       }
-       if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) {
-               ret = s->dev_mixer;
-               goto err_dev2;
-       }
-       if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) {
-               ret = s->dev_midi;
-               goto err_dev3;
-       }
-       if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) {
-               ret = s->dev_dmfm;
-               goto err_dev4;
-       }
-       pci_set_master(pcidev);  /* enable bus mastering */
-       /* initialize the chips */
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       val = SOUND_MASK_LINE|SOUND_MASK_SYNTH;
-       mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
-       for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
-               val = initvol[i].vol;
-               mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
-       }
-       set_fs(fs);
-       /* register gameport */
-       sv_register_gameport(s, gpio);
-       /* store it in the driver field */
-       pci_set_drvdata(pcidev, s);
-       /* put it into driver list */
-       list_add_tail(&s->devs, &devs);
-       /* increment devindex */
-       if (devindex < NR_DEVICE-1)
-               devindex++;
-       return 0;
-
- err_dev4:
-       unregister_sound_midi(s->dev_midi);
- err_dev3:
-       unregister_sound_mixer(s->dev_mixer);
- err_dev2:
-       unregister_sound_dsp(s->dev_audio);
- err_dev1:
-       printk(KERN_ERR "sv: cannot register misc device\n");
-       free_irq(s->irq, s);
- err_irq:
-       release_region(s->iosynth, SV_EXTENT_SYNTH);
- err_region1:
-       release_region(s->iomidi, SV_EXTENT_MIDI);
- err_region2:
-       release_region(s->iodmac, SV_EXTENT_DMA);
- err_region3:
-       release_region(s->iodmaa, SV_EXTENT_DMA);
- err_region4:
-       release_region(s->ioenh, SV_EXTENT_ENH);
- err_region5:
-       kfree(s);
-       return ret;
-}
-
-static void __devexit sv_remove(struct pci_dev *dev)
-{
-       struct sv_state *s = pci_get_drvdata(dev);
-
-       if (!s)
-               return;
-       list_del(&s->devs);
-       outb(~0, s->ioenh + SV_CODEC_INTMASK);  /* disable ints */
-       synchronize_irq(s->irq);
-       inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */
-       wrindir(s, SV_CIENABLE, 0);     /* disable DMAA and DMAC */
-       /*outb(0, s->iodmaa + SV_DMA_RESET);*/
-       /*outb(0, s->iodmac + SV_DMA_RESET);*/
-       free_irq(s->irq, s);
-       sv_unregister_gameport(s);
-       release_region(s->iodmac, SV_EXTENT_DMA);
-       release_region(s->iodmaa, SV_EXTENT_DMA);
-       release_region(s->ioenh, SV_EXTENT_ENH);
-       release_region(s->iomidi, SV_EXTENT_MIDI);
-       release_region(s->iosynth, SV_EXTENT_SYNTH);
-       unregister_sound_dsp(s->dev_audio);
-       unregister_sound_mixer(s->dev_mixer);
-       unregister_sound_midi(s->dev_midi);
-       unregister_sound_special(s->dev_dmfm);
-       kfree(s);
-       pci_set_drvdata(dev, NULL);
-}
-
-static struct pci_device_id id_table[] = {
-       { PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, id_table);
-
-static struct pci_driver sv_driver = {
-       .name           = "sonicvibes",
-       .id_table       = id_table,
-       .probe          = sv_probe,
-       .remove         = __devexit_p(sv_remove),
-};
-static int __init init_sonicvibes(void)
-{
-       printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n");
-#if 0
-       if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-               printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
-       return pci_register_driver(&sv_driver);
-}
-
-static void __exit cleanup_sonicvibes(void)
-{
-       printk(KERN_INFO "sv: unloading\n");
-       pci_unregister_driver(&sv_driver);
-       if (wavetable_mem)
-               free_pages(wavetable_mem, 20-PAGE_SHIFT);
-}
-
-module_init(init_sonicvibes);
-module_exit(cleanup_sonicvibes);
-
-/* --------------------------------------------------------------------- */
-
-#ifndef MODULE
-
-/* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */
-
-static int __init sonicvibes_setup(char *str)
-{
-       static unsigned __initdata nr_dev = 0;
-
-       if (nr_dev >= NR_DEVICE)
-               return 0;
-#if 0
-       if (get_option(&str, &reverb[nr_dev]) == 2)
-               (void)get_option(&str, &wavetable[nr_dev]);
-#else
-       (void)get_option(&str, &reverb[nr_dev]);
-#endif
-
-       nr_dev++;
-       return 1;
-}
-
-__setup("sonicvibes=", sonicvibes_setup);
-
-#endif /* MODULE */
index 1ae07509664fb149fb18501f75f3bc91e4c483ae..cd335ba8145066c6eef6840ed02618be14f2d03e 100644 (file)
@@ -13,8 +13,6 @@ int DMAbuf_move_wrpointer(int dev, int l);
 void DMAbuf_init(int dev, int dma1, int dma2);
 void DMAbuf_deinit(int dev);
 int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
-int DMAbuf_open_dma (int dev);
-void DMAbuf_close_dma (int dev);
 void DMAbuf_inputintr(int dev);
 void DMAbuf_outputintr(int dev, int underflow_flag);
 struct dma_buffparms;
index 858e1fe6c618ceda29d1e79ca23964735418bae8..a73e3dd39f9a558bee683e1de5316a3e1329d9ef 100644 (file)
@@ -1,13 +1,11 @@
-#ifdef SEQUENCER_C
-
-unsigned short semitone_tuning[24] = 
+static unsigned short semitone_tuning[24] =
 {
 /*   0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, 
 /*   8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, 
 /*  16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
 };
 
-unsigned short cent_tuning[100] =
+static unsigned short cent_tuning[100] =
 {
 /*   0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, 
 /*   8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, 
@@ -23,7 +21,3 @@ unsigned short cent_tuning[100] =
 /*  88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, 
 /*  96 */ 10570, 10576, 10582, 10589
 };
-#else
-extern unsigned short semitone_tuning[24];
-extern unsigned short cent_tuning[100];
-#endif
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
deleted file mode 100644 (file)
index 1dec395..0000000
+++ /dev/null
@@ -1,3554 +0,0 @@
-/*  -*- linux-c -*-
- *
- * sound/wavfront.c
- *
- * A Linux driver for Turtle Beach WaveFront Series (Maui, Tropez, Tropez Plus)
- *
- * This driver supports the onboard wavetable synthesizer (an ICS2115),
- * including patch, sample and program loading and unloading, conversion
- * of GUS patches during loading, and full user-level access to all
- * WaveFront commands. It tries to provide semi-intelligent patch and
- * sample management as well.
- *
- * It also provides support for the ICS emulation of an MPU-401.  Full
- * support for the ICS emulation's "virtual MIDI mode" is provided in
- * wf_midi.c.
- *
- * Support is also provided for the Tropez Plus' onboard FX processor,
- * a Yamaha YSS225. Currently, code exists to configure the YSS225,
- * and there is an interface allowing tweaking of any of its memory
- * addresses. However, I have been unable to decipher the logical
- * positioning of the configuration info for various effects, so for
- * now, you just get the YSS225 in the same state as Turtle Beach's
- * "SETUPSND.EXE" utility leaves it.
- *
- * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co],
- * This chip also controls the configuration of the card: the wavefront
- * synth is logical unit 4.
- *
- *
- * Supported devices:
- *
- *   /dev/dsp                      - using cs4232+ad1848 modules, OSS compatible
- *   /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible
- *   /dev/synth00                  - raw synth interface
- * 
- **********************************************************************
- *
- * Copyright (C) by Paul Barton-Davis 1998
- *
- * Some portions of this file are taken from work that is
- * copyright (C) by Hannu Savolainen 1993-1996
- *
- * Although the relevant code here is all new, the handling of
- * sample/alias/multi- samples is entirely based on a driver by Matt
- * Martin and Rutger Nijlunsing which demonstrated how to get things
- * to work correctly. The GUS patch loading code has been almost
- * unaltered by me, except to fit formatting and function names in the
- * rest of the file. Many thanks to them.
- *
- * Appreciation and thanks to Hannu Savolainen for his early work on the Maui
- * driver, and answering a few questions while this one was developed.
- *
- * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their
- * complete lack of help in developing this driver, and in particular
- * for their utter silence in response to questions about undocumented
- * aspects of configuring a WaveFront soundcard, particularly the
- * effects processor.
- *
- * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $
- *
- * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- * Changes:
- * 11-10-2000  Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
- *             Added some __init and __initdata to entries in yss225.c
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/syscalls.h>
-#include <linux/ioport.h>    
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/config.h>
-
-#include <linux/delay.h>
-
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME        "WaveFront MIDI"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-/* Compile-time control of the extent to which OSS is supported.
-
-   I consider /dev/sequencer to be an anachronism, but given its
-   widespread usage by various Linux MIDI software, it seems worth
-   offering support to it if it's not too painful. Instead of using
-   /dev/sequencer, I recommend:
-
-     for synth programming and patch loading: /dev/synthNN
-     for kernel-synchronized MIDI sequencing: the ALSA sequencer
-     for direct MIDI control: /dev/midiNN
-
-   I have never tried static compilation into the kernel. The #if's
-   for this are really just notes to myself about what the code is
-   for.
-*/
-
-#define OSS_SUPPORT_SEQ            0x1  /* use of /dev/sequencer */
-#define OSS_SUPPORT_STATIC_INSTALL 0x2  /* static compilation into kernel */
-
-#define OSS_SUPPORT_LEVEL          0x1  /* just /dev/sequencer for now */
-
-#if    OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-static int (*midi_load_patch) (int devno, int format, const char __user *addr,
-                              int offs, int count, int pmgr_flag) = NULL;
-#endif /* OSS_SUPPORT_SEQ */
-
-/* if WF_DEBUG not defined, no run-time debugging messages will
-   be available via the debug flag setting. Given the current
-   beta state of the driver, this will remain set until a future 
-   version.
-*/
-
-#define WF_DEBUG 1
-
-#ifdef WF_DEBUG
-
-/* Thank goodness for gcc's preprocessor ... */
-
-#define DPRINT(cond, format, args...) \
-       if ((dev.debug & (cond)) == (cond)) { \
-            printk (KERN_DEBUG LOGNAME format, ## args); \
-       }
-#else
-#define DPRINT(cond, format, args...)
-#endif
-
-#define LOGNAME "WaveFront: "
-
-/* bitmasks for WaveFront status port value */
-
-#define STAT_RINTR_ENABLED     0x01
-#define STAT_CAN_READ          0x02
-#define STAT_INTR_READ         0x04
-#define STAT_WINTR_ENABLED     0x10
-#define STAT_CAN_WRITE         0x20
-#define STAT_INTR_WRITE                0x40
-
-/*** Module-accessible parameters ***************************************/
-
-static int wf_raw;     /* we normally check for "raw state" to firmware
-                          loading. if set, then during driver loading, the
-                          state of the board is ignored, and we reset the
-                          board and load the firmware anyway.
-                       */
-                  
-static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
-                         whatever state it is when the driver is loaded.
-                         The default is to download the microprogram and
-                         associated coefficients to set it up for "default"
-                         operation, whatever that means.
-                      */
-
-static int debug_default;  /* you can set this to control debugging
-                             during driver loading. it takes any combination
-                             of the WF_DEBUG_* flags defined in
-                             wavefront.h
-                          */
-
-/* XXX this needs to be made firmware and hardware version dependent */
-
-static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed
-                                                   version of the WaveFront OS
-                                                 */
-
-static int wait_polls = 2000; /* This is a number of tries we poll the
-                                status register before resorting to sleeping.
-                                WaveFront being an ISA card each poll takes
-                                about 1.2us. So before going to
-                                sleep we wait up to 2.4ms in a loop.
-                            */
-
-static int sleep_length = HZ/100; /* This says how long we're going to
-                                    sleep between polls.
-                                    10ms sounds reasonable for fast response.
-                                 */
-
-static int sleep_tries = 50;       /* Wait for status 0.5 seconds total. */
-
-static int reset_time = 2; /* hundreths of a second we wait after a HW reset for
-                             the expected interrupt.
-                          */
-
-static int ramcheck_time = 20;    /* time in seconds to wait while ROM code
-                                    checks on-board RAM.
-                                 */
-
-static int osrun_time = 10;  /* time in seconds we wait for the OS to
-                               start running.
-                            */
-
-module_param(wf_raw, int, 0);
-module_param(fx_raw, int, 0);
-module_param(debug_default, int, 0);
-module_param(wait_polls, int, 0);
-module_param(sleep_length, int, 0);
-module_param(sleep_tries, int, 0);
-module_param(ospath, charp, 0);
-module_param(reset_time, int, 0);
-module_param(ramcheck_time, int, 0);
-module_param(osrun_time, int, 0);
-
-/***************************************************************************/
-
-/* Note: because this module doesn't export any symbols, this really isn't
-   a global variable, even if it looks like one. I was quite confused by
-   this when I started writing this as a (newer) module -- pbd.
-*/
-
-struct wf_config {
-       int devno;            /* device number from kernel */
-       int irq;              /* "you were one, one of the few ..." */
-       int base;             /* low i/o port address */
-
-#define mpu_data_port    base 
-#define mpu_command_port base + 1 /* write semantics */
-#define mpu_status_port  base + 1 /* read semantics */
-#define data_port        base + 2 
-#define status_port      base + 3 /* read semantics */
-#define control_port     base + 3 /* write semantics  */
-#define block_port       base + 4 /* 16 bit, writeonly */
-#define last_block_port  base + 6 /* 16 bit, writeonly */
-
-       /* FX ports. These are mapped through the ICS2115 to the YS225.
-          The ICS2115 takes care of flipping the relevant pins on the
-          YS225 so that access to each of these ports does the right
-          thing. Note: these are NOT documented by Turtle Beach.
-       */
-
-#define fx_status       base + 8 
-#define fx_op           base + 8 
-#define fx_lcr          base + 9 
-#define fx_dsp_addr     base + 0xa
-#define fx_dsp_page     base + 0xb 
-#define fx_dsp_lsb      base + 0xc 
-#define fx_dsp_msb      base + 0xd 
-#define fx_mod_addr     base + 0xe
-#define fx_mod_data     base + 0xf 
-
-       volatile int irq_ok;               /* set by interrupt handler */
-        volatile int irq_cnt;              /* ditto */
-       int opened;                        /* flag, holds open(2) mode */
-       char debug;                        /* debugging flags */
-       int freemem;                       /* installed RAM, in bytes */ 
-
-       int synth_dev;                     /* devno for "raw" synth */
-       int mididev;                       /* devno for internal MIDI */
-       int ext_mididev;                   /* devno for external MIDI */ 
-        int fx_mididev;                    /* devno for FX MIDI interface */
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       int oss_dev;                      /* devno for OSS sequencer synth */
-#endif /* OSS_SUPPORT_SEQ */
-
-       char fw_version[2];                /* major = [0], minor = [1] */
-       char hw_version[2];                /* major = [0], minor = [1] */
-       char israw;                        /* needs Motorola microcode */
-       char has_fx;                       /* has FX processor (Tropez+) */
-       char prog_status[WF_MAX_PROGRAM];  /* WF_SLOT_* */
-       char patch_status[WF_MAX_PATCH];   /* WF_SLOT_* */
-       char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */
-       int samples_used;                  /* how many */
-       char interrupts_on;                /* h/w MPU interrupts enabled ? */
-       char rom_samples_rdonly;           /* can we write on ROM samples */
-       wait_queue_head_t interrupt_sleeper; 
-} dev;
-
-static DEFINE_SPINLOCK(lock);
-static int  detect_wffx(void);
-static int  wffx_ioctl (wavefront_fx_info *);
-static int  wffx_init (void);
-
-static int wavefront_delete_sample (int sampnum);
-static int wavefront_find_free_sample (void);
-
-/* From wf_midi.c */
-
-extern int  virtual_midi_enable  (void);
-extern int  virtual_midi_disable (void);
-extern int  detect_wf_mpu (int, int);
-extern int  install_wf_mpu (void);
-extern int  uninstall_wf_mpu (void);
-
-typedef struct {
-       int cmd;
-       char *action;
-       unsigned int read_cnt;
-       unsigned int write_cnt;
-       int need_ack;
-} wavefront_command;
-
-static struct {
-       int errno;
-       const char *errstr;
-} wavefront_errors[] = {
-       { 0x01, "Bad sample number" },
-       { 0x02, "Out of sample memory" },
-       { 0x03, "Bad patch number" },
-       { 0x04, "Error in number of voices" },
-       { 0x06, "Sample load already in progress" },
-       { 0x0B, "No sample load request pending" },
-       { 0x0E, "Bad MIDI channel number" },
-       { 0x10, "Download Record Error" },
-       { 0x80, "Success" },
-       { 0 }
-};
-
-#define NEEDS_ACK 1
-
-static wavefront_command wavefront_commands[] = {
-       { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK },
-       { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0},
-       { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK },
-       { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 },
-       { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK },
-       { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 },
-       { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK },
-       { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK },
-       { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 },
-       { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK },
-       { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK },
-       { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK },
-       { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK },
-       { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 },
-       { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 },
-       { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 },
-       { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 },
-       { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 },
-       { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 },
-       { WFC_DOWNLOAD_SAMPLE, "download sample",
-         0, WF_SAMPLE_BYTES, NEEDS_ACK },
-       { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK},
-       { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header",
-         0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK },
-       { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 },
-
-       /* This command requires a variable number of bytes to be written.
-          There is a hack in wavefront_cmd() to support this. The actual
-          count is passed in as the read buffer ptr, cast appropriately.
-          Ugh.
-       */
-
-       { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK },
-
-       /* This one is a hack as well. We just read the first byte of the
-          response, don't fetch an ACK, and leave the rest to the 
-          calling function. Ugly, ugly, ugly.
-       */
-
-       { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 },
-       { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias",
-         0, WF_ALIAS_BYTES, NEEDS_ACK },
-       { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0},
-       { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK },
-       { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 },
-       { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" },
-       { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 },
-       { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK },
-       { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 },
-       { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK },
-       { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 },
-       { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9,
-         NEEDS_ACK},
-       { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0},
-       { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel",
-         0, 1, NEEDS_ACK },
-       { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK },
-       { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers",
-         32, 0, 0 },
-       { WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK },
-       { 0x00 }
-};
-
-static const char *
-wavefront_errorstr (int errnum)
-
-{
-       int i;
-
-       for (i = 0; wavefront_errors[i].errstr; i++) {
-               if (wavefront_errors[i].errno == errnum) {
-                       return wavefront_errors[i].errstr;
-               }
-       }
-
-       return "Unknown WaveFront error";
-}
-
-static wavefront_command *
-wavefront_get_command (int cmd) 
-
-{
-       int i;
-
-       for (i = 0; wavefront_commands[i].cmd != 0; i++) {
-               if (cmd == wavefront_commands[i].cmd) {
-                       return &wavefront_commands[i];
-               }
-       }
-
-       return (wavefront_command *) 0;
-}
-
-static inline int
-wavefront_status (void) 
-
-{
-       return inb (dev.status_port);
-}
-
-static int
-wavefront_wait (int mask)
-
-{
-       int i;
-
-       for (i = 0; i < wait_polls; i++)
-               if (wavefront_status() & mask)
-                       return 1;
-
-       for (i = 0; i < sleep_tries; i++) {
-
-               if (wavefront_status() & mask) {
-                       set_current_state(TASK_RUNNING);
-                       return 1;
-               }
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(sleep_length);
-               if (signal_pending(current))
-                       break;
-       }
-
-       set_current_state(TASK_RUNNING);
-       return 0;
-}
-
-static int
-wavefront_read (void)
-
-{
-       if (wavefront_wait (STAT_CAN_READ))
-               return inb (dev.data_port);
-
-       DPRINT (WF_DEBUG_DATA, "read timeout.\n");
-
-       return -1;
-}
-
-static int
-wavefront_write (unsigned char data)
-
-{
-       if (wavefront_wait (STAT_CAN_WRITE)) {
-               outb (data, dev.data_port);
-               return 0;
-       }
-
-       DPRINT (WF_DEBUG_DATA, "write timeout.\n");
-
-       return -1;
-}
-
-static int
-wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf)
-
-{
-       int ack;
-       int i;
-       int c;
-       wavefront_command *wfcmd;
-
-       if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
-               printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n",
-                       cmd);
-               return 1;
-       }
-
-       /* Hack to handle the one variable-size write command. See
-          wavefront_send_multisample() for the other half of this
-          gross and ugly strategy.
-       */
-
-       if (cmd == WFC_DOWNLOAD_MULTISAMPLE) {
-               wfcmd->write_cnt = (unsigned int) rbuf;
-               rbuf = NULL;
-       }
-
-       DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n",
-                              cmd, wfcmd->action, wfcmd->read_cnt,
-                              wfcmd->write_cnt, wfcmd->need_ack);
-    
-       if (wavefront_write (cmd)) { 
-               DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request "
-                                                    "0x%x [%s].\n",
-                                                    cmd, wfcmd->action);
-               return 1;
-       } 
-
-       if (wfcmd->write_cnt > 0) {
-               DPRINT (WF_DEBUG_DATA, "writing %d bytes "
-                                       "for 0x%x\n",
-                                       wfcmd->write_cnt, cmd);
-
-               for (i = 0; i < wfcmd->write_cnt; i++) {
-                       if (wavefront_write (wbuf[i])) {
-                               DPRINT (WF_DEBUG_IO, "bad write for byte "
-                                                     "%d of 0x%x [%s].\n",
-                                                     i, cmd, wfcmd->action);
-                               return 1;
-                       }
-
-                       DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n",
-                                               i, wbuf[i]);
-               }
-       }
-
-       if (wfcmd->read_cnt > 0) {
-               DPRINT (WF_DEBUG_DATA, "reading %d ints "
-                                       "for 0x%x\n",
-                                       wfcmd->read_cnt, cmd);
-
-               for (i = 0; i < wfcmd->read_cnt; i++) {
-
-                       if ((c = wavefront_read()) == -1) {
-                               DPRINT (WF_DEBUG_IO, "bad read for byte "
-                                                     "%d of 0x%x [%s].\n",
-                                                     i, cmd, wfcmd->action);
-                               return 1;
-                       }
-
-                       /* Now handle errors. Lots of special cases here */
-           
-                       if (c == 0xff) { 
-                               if ((c = wavefront_read ()) == -1) {
-                                       DPRINT (WF_DEBUG_IO, "bad read for "
-                                                             "error byte at "
-                                                             "read byte %d "
-                                                             "of 0x%x [%s].\n",
-                                                             i, cmd,
-                                                             wfcmd->action);
-                                       return 1;
-                               }
-
-                               /* Can you believe this madness ? */
-
-                               if (c == 1 &&
-                                   wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) {
-                                       rbuf[0] = WF_ST_EMPTY;
-                                       return (0);
-
-                               } else if (c == 3 &&
-                                          wfcmd->cmd == WFC_UPLOAD_PATCH) {
-
-                                       return 3;
-
-                               } else if (c == 1 &&
-                                          wfcmd->cmd == WFC_UPLOAD_PROGRAM) {
-
-                                       return 1;
-
-                               } else {
-
-                                       DPRINT (WF_DEBUG_IO, "error %d (%s) "
-                                                             "during "
-                                                             "read for byte "
-                                                             "%d of 0x%x "
-                                                             "[%s].\n",
-                                                             c,
-                                                             wavefront_errorstr (c),
-                                                             i, cmd,
-                                                             wfcmd->action);
-                                       return 1;
-
-                               }
-               
-               } else {
-                               rbuf[i] = c;
-                       }
-                       
-                       DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]);
-               }
-       }
-       
-       if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) {
-
-               DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd);
-
-               /* Some commands need an ACK, but return zero instead
-                  of the standard value.
-               */
-           
-               if ((ack = wavefront_read()) == 0) {
-                       ack = WF_ACK;
-               }
-       
-               if (ack != WF_ACK) {
-                       if (ack == -1) {
-                               DPRINT (WF_DEBUG_IO, "cannot read ack for "
-                                                     "0x%x [%s].\n",
-                                                     cmd, wfcmd->action);
-                               return 1;
-               
-                       } else {
-                               int err = -1; /* something unknown */
-
-                               if (ack == 0xff) { /* explicit error */
-                   
-                                       if ((err = wavefront_read ()) == -1) {
-                                               DPRINT (WF_DEBUG_DATA,
-                                                       "cannot read err "
-                                                       "for 0x%x [%s].\n",
-                                                       cmd, wfcmd->action);
-                                       }
-                               }
-                               
-                               DPRINT (WF_DEBUG_IO, "0x%x [%s] "
-                                       "failed (0x%x, 0x%x, %s)\n",
-                                       cmd, wfcmd->action, ack, err,
-                                       wavefront_errorstr (err));
-                               
-                               return -err;
-                       }
-               }
-               
-               DPRINT (WF_DEBUG_DATA, "ack received "
-                                       "for 0x%x [%s]\n",
-                                       cmd, wfcmd->action);
-       } else {
-
-               DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need "
-                                      "ACK (%d,%d,%d)\n",
-                                      cmd, wfcmd->action, wfcmd->read_cnt,
-                                      wfcmd->write_cnt, wfcmd->need_ack);
-       }
-
-       return 0;
-       
-}
-\f
-/***********************************************************************
-WaveFront: data munging   
-
-Things here are weird. All data written to the board cannot 
-have its most significant bit set. Any data item with values 
-potentially > 0x7F (127) must be split across multiple bytes.
-
-Sometimes, we need to munge numeric values that are represented on
-the x86 side as 8-32 bit values. Sometimes, we need to munge data
-that is represented on the x86 side as an array of bytes. The most
-efficient approach to handling both cases seems to be to use 2
-different functions for munging and 2 for de-munging. This avoids
-weird casting and worrying about bit-level offsets.
-
-**********************************************************************/
-
-static 
-unsigned char *
-munge_int32 (unsigned int src,
-            unsigned char *dst,
-            unsigned int dst_size)
-{
-       int i;
-
-       for (i = 0;i < dst_size; i++) {
-               *dst = src & 0x7F;  /* Mask high bit of LSB */
-               src = src >> 7;     /* Rotate Right 7 bits  */
-                                   /* Note: we leave the upper bits in place */ 
-
-               dst++;
-       };
-       return dst;
-};
-
-static int 
-demunge_int32 (unsigned char* src, int src_size)
-
-{
-       int i;
-       int outval = 0;
-       
-       for (i = src_size - 1; i >= 0; i--) {
-               outval=(outval<<7)+src[i];
-       }
-
-       return outval;
-};
-
-static 
-unsigned char *
-munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size)
-
-{
-       int i;
-       unsigned int last = dst_size / 2;
-
-       for (i = 0; i < last; i++) {
-               *dst++ = src[i] & 0x7f;
-               *dst++ = src[i] >> 7;
-       }
-       return dst;
-}
-
-static 
-unsigned char *
-demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes)
-
-{
-       int i;
-       unsigned char *end = src + src_bytes;
-    
-       end = src + src_bytes;
-
-       /* NOTE: src and dst *CAN* point to the same address */
-
-       for (i = 0; src != end; i++) {
-               dst[i] = *src++;
-               dst[i] |= (*src++)<<7;
-       }
-
-       return dst;
-}
-\f
-/***********************************************************************
-WaveFront: sample, patch and program management.
-***********************************************************************/
-
-static int
-wavefront_delete_sample (int sample_num)
-
-{
-       unsigned char wbuf[2];
-       int x;
-
-       wbuf[0] = sample_num & 0x7f;
-       wbuf[1] = sample_num >> 7;
-
-       if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) {
-               dev.sample_status[sample_num] = WF_ST_EMPTY;
-       }
-
-       return x;
-}
-
-static int
-wavefront_get_sample_status (int assume_rom)
-
-{
-       int i;
-       unsigned char rbuf[32], wbuf[32];
-       unsigned int    sc_real, sc_alias, sc_multi;
-
-       /* check sample status */
-    
-       if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) {
-               printk (KERN_WARNING LOGNAME "cannot request sample count.\n");
-               return -1;
-       } 
-    
-       sc_real = sc_alias = sc_multi = dev.samples_used = 0;
-    
-       for (i = 0; i < WF_MAX_SAMPLE; i++) {
-       
-               wbuf[0] = i & 0x7f;
-               wbuf[1] = i >> 7;
-
-               if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
-                       printk (KERN_WARNING LOGNAME
-                               "cannot identify sample "
-                               "type of slot %d\n", i);
-                       dev.sample_status[i] = WF_ST_EMPTY;
-                       continue;
-               }
-
-               dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]);
-
-               if (assume_rom) {
-                       dev.sample_status[i] |= WF_SLOT_ROM;
-               }
-
-               switch (rbuf[0] & WF_ST_MASK) {
-               case WF_ST_SAMPLE:
-                       sc_real++;
-                       break;
-               case WF_ST_MULTISAMPLE:
-                       sc_multi++;
-                       break;
-               case WF_ST_ALIAS:
-                       sc_alias++;
-                       break;
-               case WF_ST_EMPTY:
-                       break;
-
-               default:
-                       printk (KERN_WARNING LOGNAME "unknown sample type for "
-                               "slot %d (0x%x)\n", 
-                               i, rbuf[0]);
-               }
-
-               if (rbuf[0] != WF_ST_EMPTY) {
-                       dev.samples_used++;
-               } 
-       }
-
-       printk (KERN_INFO LOGNAME
-               "%d samples used (%d real, %d aliases, %d multi), "
-               "%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi,
-               WF_MAX_SAMPLE - dev.samples_used);
-
-
-       return (0);
-
-}
-
-static int
-wavefront_get_patch_status (void)
-
-{
-       unsigned char patchbuf[WF_PATCH_BYTES];
-       unsigned char patchnum[2];
-       wavefront_patch *p;
-       int i, x, cnt, cnt2;
-
-       for (i = 0; i < WF_MAX_PATCH; i++) {
-               patchnum[0] = i & 0x7f;
-               patchnum[1] = i >> 7;
-
-               if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf,
-                                       patchnum)) == 0) {
-
-                       dev.patch_status[i] |= WF_SLOT_FILLED;
-                       p = (wavefront_patch *) patchbuf;
-                       dev.sample_status
-                               [p->sample_number|(p->sample_msb<<7)] |=
-                               WF_SLOT_USED;
-           
-               } else if (x == 3) { /* Bad patch number */
-                       dev.patch_status[i] = 0;
-               } else {
-                       printk (KERN_ERR LOGNAME "upload patch "
-                               "error 0x%x\n", x);
-                       dev.patch_status[i] = 0;
-                       return 1;
-               }
-       }
-
-       /* program status has already filled in slot_used bits */
-
-       for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) {
-               if (dev.patch_status[i] & WF_SLOT_FILLED) {
-                       cnt++;
-               }
-               if (dev.patch_status[i] & WF_SLOT_USED) {
-                       cnt2++;
-               }
-       
-       }
-       printk (KERN_INFO LOGNAME
-               "%d patch slots filled, %d in use\n", cnt, cnt2);
-
-       return (0);
-}
-
-static int
-wavefront_get_program_status (void)
-
-{
-       unsigned char progbuf[WF_PROGRAM_BYTES];
-       wavefront_program prog;
-       unsigned char prognum;
-       int i, x, l, cnt;
-
-       for (i = 0; i < WF_MAX_PROGRAM; i++) {
-               prognum = i;
-
-               if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf,
-                                       &prognum)) == 0) {
-
-                       dev.prog_status[i] |= WF_SLOT_USED;
-
-                       demunge_buf (progbuf, (unsigned char *) &prog,
-                                    WF_PROGRAM_BYTES);
-
-                       for (l = 0; l < WF_NUM_LAYERS; l++) {
-                               if (prog.layer[l].mute) {
-                                       dev.patch_status
-                                               [prog.layer[l].patch_number] |=
-                                               WF_SLOT_USED;
-                               }
-                       }
-               } else if (x == 1) { /* Bad program number */
-                       dev.prog_status[i] = 0;
-               } else {
-                       printk (KERN_ERR LOGNAME "upload program "
-                               "error 0x%x\n", x);
-                       dev.prog_status[i] = 0;
-               }
-       }
-
-       for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) {
-               if (dev.prog_status[i]) {
-                       cnt++;
-               }
-       }
-
-       printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt);
-
-       return (0);
-}
-
-static int
-wavefront_send_patch (wavefront_patch_info *header)
-
-{
-       unsigned char buf[WF_PATCH_BYTES+2];
-       unsigned char *bptr;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n",
-                                     header->number);
-
-       dev.patch_status[header->number] |= WF_SLOT_FILLED;
-
-       bptr = buf;
-       bptr = munge_int32 (header->number, buf, 2);
-       munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES);
-    
-       if (wavefront_cmd (WFC_DOWNLOAD_PATCH, NULL, buf)) {
-               printk (KERN_ERR LOGNAME "download patch failed\n");
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int
-wavefront_send_program (wavefront_patch_info *header)
-
-{
-       unsigned char buf[WF_PROGRAM_BYTES+1];
-       int i;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n",
-               header->number);
-
-       dev.prog_status[header->number] = WF_SLOT_USED;
-
-       /* XXX need to zero existing SLOT_USED bit for program_status[i]
-          where `i' is the program that's being (potentially) overwritten.
-       */
-    
-       for (i = 0; i < WF_NUM_LAYERS; i++) {
-               if (header->hdr.pr.layer[i].mute) {
-                       dev.patch_status[header->hdr.pr.layer[i].patch_number] |=
-                               WF_SLOT_USED;
-
-                       /* XXX need to mark SLOT_USED for sample used by
-                          patch_number, but this means we have to load it. Ick.
-                       */
-               }
-       }
-
-       buf[0] = header->number;
-       munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES);
-    
-       if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, NULL, buf)) {
-               printk (KERN_WARNING LOGNAME "download patch failed\n");        
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int
-wavefront_freemem (void)
-
-{
-       char rbuf[8];
-
-       if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, NULL)) {
-               printk (KERN_WARNING LOGNAME "can't get memory stats.\n");
-               return -1;
-       } else {
-               return demunge_int32 (rbuf, 4);
-       }
-}
-
-static int
-wavefront_send_sample (wavefront_patch_info *header,
-                      UINT16 __user *dataptr,
-                      int data_is_unsigned)
-
-{
-       /* samples are downloaded via a 16-bit wide i/o port
-          (you could think of it as 2 adjacent 8-bit wide ports
-          but its less efficient that way). therefore, all
-          the blocksizes and so forth listed in the documentation,
-          and used conventionally to refer to sample sizes,
-          which are given in 8-bit units (bytes), need to be
-          divided by 2.
-        */
-
-       UINT16 sample_short;
-       UINT32 length;
-       UINT16 __user *data_end = NULL;
-       unsigned int i;
-       const int max_blksize = 4096/2;
-       unsigned int written;
-       unsigned int blocksize;
-       int dma_ack;
-       int blocknum;
-       unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES];
-       unsigned char *shptr;
-       int skip = 0;
-       int initial_skip = 0;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, "
-                                     "type %d, %d bytes from %p\n",
-                                     header->size ? "" : "header ", 
-                                     header->number, header->subkey,
-                                     header->size,
-                                     header->dataptr);
-
-       if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) {
-               int x;
-
-               if ((x = wavefront_find_free_sample ()) < 0) {
-                       return -ENOMEM;
-               }
-               printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x);
-               header->number = x;
-       }
-
-       if (header->size) {
-
-               /* XXX it's a debatable point whether or not RDONLY semantics
-                  on the ROM samples should cover just the sample data or
-                  the sample header. For now, it only covers the sample data,
-                  so anyone is free at all times to rewrite sample headers.
-
-                  My reason for this is that we have the sample headers
-                  available in the WFB file for General MIDI, and so these
-                  can always be reset if needed. The sample data, however,
-                  cannot be recovered without a complete reset and firmware
-                  reload of the ICS2115, which is a very expensive operation.
-
-                  So, doing things this way allows us to honor the notion of
-                  "RESETSAMPLES" reasonably cheaply. Note however, that this
-                  is done purely at user level: there is no WFB parser in
-                  this driver, and so a complete reset (back to General MIDI,
-                  or theoretically some other configuration) is the
-                  responsibility of the user level library. 
-
-                  To try to do this in the kernel would be a little
-                  crazy: we'd need 158K of kernel space just to hold
-                  a copy of the patch/program/sample header data.
-               */
-
-               if (dev.rom_samples_rdonly) {
-                       if (dev.sample_status[header->number] & WF_SLOT_ROM) {
-                               printk (KERN_ERR LOGNAME "sample slot %d "
-                                       "write protected\n",
-                                       header->number);
-                               return -EACCES;
-                       }
-               }
-
-               wavefront_delete_sample (header->number);
-       }
-
-       if (header->size) {
-               dev.freemem = wavefront_freemem ();
-
-               if (dev.freemem < header->size) {
-                       printk (KERN_ERR LOGNAME
-                               "insufficient memory to "
-                               "load %d byte sample.\n",
-                               header->size);
-                       return -ENOMEM;
-               }
-       
-       }
-
-       skip = WF_GET_CHANNEL(&header->hdr.s);
-
-       if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) {
-               printk (KERN_ERR LOGNAME "channel selection only "
-                       "possible on 16-bit samples");
-               return -(EINVAL);
-       }
-
-       switch (skip) {
-       case 0:
-               initial_skip = 0;
-               skip = 1;
-               break;
-       case 1:
-               initial_skip = 0;
-               skip = 2;
-               break;
-       case 2:
-               initial_skip = 1;
-               skip = 2;
-               break;
-       case 3:
-               initial_skip = 2;
-               skip = 3;
-               break;
-       case 4:
-               initial_skip = 3;
-               skip = 4;
-               break;
-       case 5:
-               initial_skip = 4;
-               skip = 5;
-               break;
-       case 6:
-               initial_skip = 5;
-               skip = 6;
-               break;
-       }
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => "
-                                     "initial skip = %d, skip = %d\n",
-                                     WF_GET_CHANNEL (&header->hdr.s),
-                                     initial_skip, skip);
-    
-       /* Be safe, and zero the "Unused" bits ... */
-
-       WF_SET_CHANNEL(&header->hdr.s, 0);
-
-       /* adjust size for 16 bit samples by dividing by two.  We always
-          send 16 bits per write, even for 8 bit samples, so the length
-          is always half the size of the sample data in bytes.
-       */
-
-       length = header->size / 2;
-
-       /* the data we're sent has not been munged, and in fact, the
-          header we have to send isn't just a munged copy either.
-          so, build the sample header right here.
-       */
-
-       shptr = &sample_hdr[0];
-
-       shptr = munge_int32 (header->number, shptr, 2);
-
-       if (header->size) {
-               shptr = munge_int32 (length, shptr, 4);
-       }
-
-       /* Yes, a 4 byte result doesn't contain all of the offset bits,
-          but the offset only uses 24 bits.
-       */
-
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset),
-                            shptr, 4);
-       shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset),
-                            shptr, 4);
-       
-       /* This one is truly weird. What kind of weirdo decided that in
-          a system dominated by 16 and 32 bit integers, they would use
-          a just 12 bits ?
-       */
-       
-       shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3);
-       
-       /* Why is this nybblified, when the MSB is *always* zero ? 
-          Anyway, we can't take address of bitfield, so make a
-          good-faith guess at where it starts.
-       */
-       
-       shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1),
-                            shptr, 2);
-
-       if (wavefront_cmd (header->size ?
-                          WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER,
-                          NULL, sample_hdr)) {
-               printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n",
-                       header->size ? "" : "header ");
-               return -(EIO);
-       }
-
-       if (header->size == 0) {
-               goto sent; /* Sorry. Just had to have one somewhere */
-       }
-    
-       data_end = dataptr + length;
-
-       /* Do any initial skip over an unused channel's data */
-
-       dataptr += initial_skip;
-    
-       for (written = 0, blocknum = 0;
-            written < length; written += max_blksize, blocknum++) {
-       
-               if ((length - written) > max_blksize) {
-                       blocksize = max_blksize;
-               } else {
-                       /* round to nearest 16-byte value */
-                       blocksize = ((length-written+7)&~0x7);
-               }
-
-               if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, NULL, NULL)) {
-                       printk (KERN_WARNING LOGNAME "download block "
-                               "request refused.\n");
-                       return -(EIO);
-               }
-
-               for (i = 0; i < blocksize; i++) {
-
-                       if (dataptr < data_end) {
-               
-                               __get_user (sample_short, dataptr);
-                               dataptr += skip;
-               
-                               if (data_is_unsigned) { /* GUS ? */
-
-                                       if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) {
-                       
-                                               /* 8 bit sample
-                                                resolution, sign
-                                                extend both bytes.
-                                               */
-                       
-                                               ((unsigned char*)
-                                                &sample_short)[0] += 0x7f;
-                                               ((unsigned char*)
-                                                &sample_short)[1] += 0x7f;
-                       
-                                       } else {
-                       
-                                               /* 16 bit sample
-                                                resolution, sign
-                                                extend the MSB.
-                                               */
-                       
-                                               sample_short += 0x7fff;
-                                       }
-                               }
-
-                       } else {
-
-                               /* In padding section of final block:
-
-                                  Don't fetch unsupplied data from
-                                  user space, just continue with
-                                  whatever the final value was.
-                               */
-                       }
-           
-                       if (i < blocksize - 1) {
-                               outw (sample_short, dev.block_port);
-                       } else {
-                               outw (sample_short, dev.last_block_port);
-                       }
-               }
-
-               /* Get "DMA page acknowledge", even though its really
-                  nothing to do with DMA at all.
-               */
-       
-               if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) {
-                       if (dma_ack == -1) {
-                               printk (KERN_ERR LOGNAME "upload sample "
-                                       "DMA ack timeout\n");
-                               return -(EIO);
-                       } else {
-                               printk (KERN_ERR LOGNAME "upload sample "
-                                       "DMA ack error 0x%x\n",
-                                       dma_ack);
-                               return -(EIO);
-                       }
-               }
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE);
-
-       /* Note, label is here because sending the sample header shouldn't
-          alter the sample_status info at all.
-       */
-
- sent:
-       return (0);
-}
-
-static int
-wavefront_send_alias (wavefront_patch_info *header)
-
-{
-       unsigned char alias_hdr[WF_ALIAS_BYTES];
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is "
-                                     "alias for %d\n",
-                                     header->number,
-                                     header->hdr.a.OriginalSample);
-    
-       munge_int32 (header->number, &alias_hdr[0], 2);
-       munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2);
-       munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset),
-                    &alias_hdr[4], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset),
-                    &alias_hdr[8], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset),
-                    &alias_hdr[12], 4);
-       munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset),
-                    &alias_hdr[16], 4);
-       munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3);
-       munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2);
-
-       if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) {
-               printk (KERN_ERR LOGNAME "download alias failed.\n");
-               return -(EIO);
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS);
-
-       return (0);
-}
-
-static int
-wavefront_send_multisample (wavefront_patch_info *header)
-{
-       int i;
-       int num_samples;
-       unsigned char msample_hdr[WF_MSAMPLE_BYTES];
-
-       munge_int32 (header->number, &msample_hdr[0], 2);
-
-       /* You'll recall at this point that the "number of samples" value
-          in a wavefront_multisample struct is actually the log2 of the
-          real number of samples.
-       */
-
-       num_samples = (1<<(header->hdr.ms.NumberOfSamples&7));
-       msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n",
-                                     header->number,
-                                     header->hdr.ms.NumberOfSamples,
-                                     num_samples);
-
-       for (i = 0; i < num_samples; i++) {
-               DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n",
-                      i, header->hdr.ms.SampleNumber[i]);
-               munge_int32 (header->hdr.ms.SampleNumber[i],
-                    &msample_hdr[3+(i*2)], 2);
-       }
-    
-       /* Need a hack here to pass in the number of bytes
-          to be written to the synth. This is ugly, and perhaps
-          one day, I'll fix it.
-       */
-
-       if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE, 
-                          (unsigned char *) ((num_samples*2)+3),
-                          msample_hdr)) {
-               printk (KERN_ERR LOGNAME "download of multisample failed.\n");
-               return -(EIO);
-       }
-
-       dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE);
-
-       return (0);
-}
-
-static int
-wavefront_fetch_multisample (wavefront_patch_info *header)
-{
-       int i;
-       unsigned char log_ns[1];
-       unsigned char number[2];
-       int num_samples;
-
-       munge_int32 (header->number, number, 2);
-    
-       if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) {
-               printk (KERN_ERR LOGNAME "upload multisample failed.\n");
-               return -(EIO);
-       }
-    
-       DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n",
-                               header->number, log_ns[0]);
-
-       header->hdr.ms.NumberOfSamples = log_ns[0];
-
-       /* get the number of samples ... */
-
-       num_samples = (1 << log_ns[0]);
-    
-       for (i = 0; i < num_samples; i++) {
-               s8 d[2];
-       
-               if ((d[0] = wavefront_read ()) == -1) {
-                       printk (KERN_ERR LOGNAME "upload multisample failed "
-                               "during sample loop.\n");
-                       return -(EIO);
-               }
-
-               if ((d[1] = wavefront_read ()) == -1) {
-                       printk (KERN_ERR LOGNAME "upload multisample failed "
-                               "during sample loop.\n");
-                       return -(EIO);
-               }
-       
-               header->hdr.ms.SampleNumber[i] =
-                       demunge_int32 ((unsigned char *) d, 2);
-       
-               DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n",
-                                       i, header->hdr.ms.SampleNumber[i]);
-       }
-
-       return (0);
-}
-
-
-static int
-wavefront_send_drum (wavefront_patch_info *header)
-
-{
-       unsigned char drumbuf[WF_DRUM_BYTES];
-       wavefront_drum *drum = &header->hdr.d;
-       int i;
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI "
-               "note %d, patch = %d\n", 
-               header->number, drum->PatchNumber);
-
-       drumbuf[0] = header->number & 0x7f;
-
-       for (i = 0; i < 4; i++) {
-               munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2);
-       }
-
-       if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) {
-               printk (KERN_ERR LOGNAME "download drum failed.\n");
-               return -(EIO);
-       }
-
-       return (0);
-}
-
-static int 
-wavefront_find_free_sample (void)
-
-{
-       int i;
-
-       for (i = 0; i < WF_MAX_SAMPLE; i++) {
-               if (!(dev.sample_status[i] & WF_SLOT_FILLED)) {
-                       return i;
-               }
-       }
-       printk (KERN_WARNING LOGNAME "no free sample slots!\n");
-       return -1;
-}
-
-static int 
-wavefront_find_free_patch (void)
-
-{
-       int i;
-
-       for (i = 0; i < WF_MAX_PATCH; i++) {
-               if (!(dev.patch_status[i] & WF_SLOT_FILLED)) {
-                       return i;
-               }
-       }
-       printk (KERN_WARNING LOGNAME "no free patch slots!\n");
-       return -1;
-}
-
-static int 
-log2_2048(int n)
-
-{
-       int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143,
-                  6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192,
-                  8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390,
-                  9510, 9626, 9738, 9845, 9949, 10049, 10146};
-       int i;
-
-       /* Returns 2048*log2(n) */
-
-       /* FIXME: this is like doing integer math
-          on quantum particles (RuN) */
-
-       i=0;
-       while(n>=32*256) {
-               n>>=8;
-               i+=2048*8;
-       }
-       while(n>=32) {
-               n>>=1;
-               i+=2048;
-       }
-       i+=tbl[n];
-       return(i);
-}
-
-static int
-wavefront_load_gus_patch (int devno, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag)
-{
-       struct patch_info guspatch;
-       wavefront_patch_info *samp, *pat, *prog;
-       wavefront_patch *patp;
-       wavefront_sample *sampp;
-       wavefront_program *progp;
-
-       int i,base_note;
-       long sizeof_patch;
-       int rc = -ENOMEM;
-
-       samp = kmalloc(3 * sizeof(wavefront_patch_info), GFP_KERNEL);
-       if (!samp)
-               goto free_fail;
-       pat = samp + 1;
-       prog = pat + 1;
-
-       /* Copy in the header of the GUS patch */
-
-       sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; 
-       if (copy_from_user(&((char *) &guspatch)[offs],
-                          &(addr)[offs], sizeof_patch - offs)) {
-               rc = -EFAULT;
-               goto free_fail;
-       }
-
-       if ((i = wavefront_find_free_patch ()) == -1) {
-               rc = -EBUSY;
-               goto free_fail;
-       }
-       pat->number = i;
-       pat->subkey = WF_ST_PATCH;
-       patp = &pat->hdr.p;
-
-       if ((i = wavefront_find_free_sample ()) == -1) {
-               rc = -EBUSY;
-               goto free_fail;
-       }
-       samp->number = i;
-       samp->subkey = WF_ST_SAMPLE;
-       samp->size = guspatch.len;
-       sampp = &samp->hdr.s;
-
-       prog->number = guspatch.instr_no;
-       progp = &prog->hdr.pr;
-
-       /* Setup the patch structure */
-
-       patp->amplitude_bias=guspatch.volume;
-       patp->portamento=0;
-       patp->sample_number= samp->number & 0xff;
-       patp->sample_msb= samp->number >> 8;
-       patp->pitch_bend= /*12*/ 0;
-       patp->mono=1;
-       patp->retrigger=1;
-       patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1;
-       patp->frequency_bias=0;
-       patp->restart=0;
-       patp->reuse=0;
-       patp->reset_lfo=1;
-       patp->fm_src2=0;
-       patp->fm_src1=WF_MOD_MOD_WHEEL;
-       patp->am_src=WF_MOD_PRESSURE;
-       patp->am_amount=127;
-       patp->fc1_mod_amount=0;
-       patp->fc2_mod_amount=0; 
-       patp->fm_amount1=0;
-       patp->fm_amount2=0;
-       patp->envelope1.attack_level=127;
-       patp->envelope1.decay1_level=127;
-       patp->envelope1.decay2_level=127;
-       patp->envelope1.sustain_level=127;
-       patp->envelope1.release_level=0;
-       patp->envelope2.attack_velocity=127;
-       patp->envelope2.attack_level=127;
-       patp->envelope2.decay1_level=127;
-       patp->envelope2.decay2_level=127;
-       patp->envelope2.sustain_level=127;
-       patp->envelope2.release_level=0;
-       patp->envelope2.attack_velocity=127;
-       patp->randomizer=0;
-
-       /* Program for this patch */
-
-       progp->layer[0].patch_number= pat->number; /* XXX is this right ? */
-       progp->layer[0].mute=1;
-       progp->layer[0].pan_or_mod=1;
-       progp->layer[0].pan=7;
-       progp->layer[0].mix_level=127  /* guspatch.volume */;
-       progp->layer[0].split_type=0;
-       progp->layer[0].split_point=0;
-       progp->layer[0].play_below=0;
-
-       for (i = 1; i < 4; i++) {
-               progp->layer[i].mute=0;
-       }
-
-       /* Sample data */
-
-       sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1);
-
-       for (base_note=0;
-            note_to_freq (base_note) < guspatch.base_note;
-            base_note++);
-
-       if ((guspatch.base_note-note_to_freq(base_note))
-           >(note_to_freq(base_note)-guspatch.base_note))
-               base_note++;
-
-       printk(KERN_DEBUG "ref freq=%d,base note=%d\n",
-              guspatch.base_freq,
-              base_note);
-
-       sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq)
-                               + base_note*171);
-       printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias);
-       sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0;
-       sampp->sampleStartOffset.Fraction=0;
-       sampp->sampleStartOffset.Integer=0;
-       sampp->loopStartOffset.Fraction=0;
-       sampp->loopStartOffset.Integer=guspatch.loop_start
-               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-       sampp->loopEndOffset.Fraction=0;
-       sampp->loopEndOffset.Integer=guspatch.loop_end
-               >>((guspatch.mode&WAVE_16_BITS) ? 1:0);
-       sampp->sampleEndOffset.Fraction=0;
-       sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1);
-       sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0;
-       sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0;
-
-       /* Now ship it down */
-
-       wavefront_send_sample (samp,
-                              (unsigned short __user *) &(addr)[sizeof_patch],
-                              (guspatch.mode & WAVE_UNSIGNED) ? 1:0);
-       wavefront_send_patch (pat);
-       wavefront_send_program (prog);
-
-       /* Now pan as best we can ... use the slave/internal MIDI device
-          number if it exists (since it talks to the WaveFront), or the
-          master otherwise.
-       */
-
-       if (dev.mididev > 0) {
-               midi_synth_controller (dev.mididev, guspatch.instr_no, 10,
-                                      ((guspatch.panning << 4) > 127) ?
-                                      127 : (guspatch.panning << 4));
-       }
-       rc = 0;
-
-free_fail:
-       kfree(samp);
-       return rc;
-}
-
-static int
-wavefront_load_patch (const char __user *addr)
-
-
-{
-       wavefront_patch_info header;
-       
-       if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) -
-                           sizeof(wavefront_any))) {
-               printk (KERN_WARNING LOGNAME "bad address for load patch.\n");
-               return -EFAULT;
-       }
-
-       DPRINT (WF_DEBUG_LOAD_PATCH, "download "
-                                     "Sample type: %d "
-                                     "Sample number: %d "
-                                     "Sample size: %d\n",
-                                     header.subkey,
-                                     header.number,
-                                     header.size);
-
-       switch (header.subkey) {
-       case WF_ST_SAMPLE:  /* sample or sample_header, based on patch->size */
-
-               if (copy_from_user((unsigned char *) &header.hdr.s,
-                                  (unsigned char __user *) header.hdrptr,
-                                  sizeof (wavefront_sample)))
-                       return -EFAULT;
-
-               return wavefront_send_sample (&header, header.dataptr, 0);
-
-       case WF_ST_MULTISAMPLE:
-
-               if (copy_from_user(&header.hdr.s, header.hdrptr,
-                                  sizeof(wavefront_multisample)))
-                       return -EFAULT;
-
-               return wavefront_send_multisample (&header);
-
-
-       case WF_ST_ALIAS:
-
-               if (copy_from_user(&header.hdr.a, header.hdrptr,
-                                  sizeof (wavefront_alias)))
-                       return -EFAULT;
-
-               return wavefront_send_alias (&header);
-
-       case WF_ST_DRUM:
-               if (copy_from_user(&header.hdr.d, header.hdrptr,
-                                  sizeof (wavefront_drum)))
-                       return -EFAULT;
-
-               return wavefront_send_drum (&header);
-
-       case WF_ST_PATCH:
-               if (copy_from_user(&header.hdr.p, header.hdrptr,
-                                  sizeof (wavefront_patch)))
-                       return -EFAULT;
-
-               return wavefront_send_patch (&header);
-
-       case WF_ST_PROGRAM:
-               if (copy_from_user(&header.hdr.pr, header.hdrptr,
-                                  sizeof (wavefront_program)))
-                       return -EFAULT;
-
-               return wavefront_send_program (&header);
-
-       default:
-               printk (KERN_ERR LOGNAME "unknown patch type %d.\n",
-                       header.subkey);
-               return -(EINVAL);
-       }
-
-       return 0;
-}
-\f
-/***********************************************************************
-WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces
-***********************************************************************/
-
-static void
-process_sample_hdr (UCHAR8 *buf)
-
-{
-       wavefront_sample s;
-       UCHAR8 *ptr;
-
-       ptr = buf;
-
-       /* The board doesn't send us an exact copy of a "wavefront_sample"
-          in response to an Upload Sample Header command. Instead, we 
-          have to convert the data format back into our data structure,
-          just as in the Download Sample command, where we have to do
-          something very similar in the reverse direction.
-       */
-
-       *((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4;
-       *((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3;
-
-       s.SampleResolution = *ptr & 0x3;
-       s.Loop = *ptr & 0x8;
-       s.Bidirectional = *ptr & 0x10;
-       s.Reverse = *ptr & 0x40;
-
-       /* Now copy it back to where it came from */
-
-       memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample));
-}
-
-static int
-wavefront_synth_control (int cmd, wavefront_control *wc)
-
-{
-       unsigned char patchnumbuf[2];
-       int i;
-
-       DPRINT (WF_DEBUG_CMD, "synth control with "
-               "cmd 0x%x\n", wc->cmd);
-
-       /* Pre-handling of or for various commands */
-
-       switch (wc->cmd) {
-       case WFC_DISABLE_INTERRUPTS:
-               printk (KERN_INFO LOGNAME "interrupts disabled.\n");
-               outb (0x80|0x20, dev.control_port);
-               dev.interrupts_on = 0;
-               return 0;
-
-       case WFC_ENABLE_INTERRUPTS:
-               printk (KERN_INFO LOGNAME "interrupts enabled.\n");
-               outb (0x80|0x40|0x20, dev.control_port);
-               dev.interrupts_on = 1;
-               return 0;
-
-       case WFC_INTERRUPT_STATUS:
-               wc->rbuf[0] = dev.interrupts_on;
-               return 0;
-
-       case WFC_ROMSAMPLES_RDONLY:
-               dev.rom_samples_rdonly = wc->wbuf[0];
-               wc->status = 0;
-               return 0;
-
-       case WFC_IDENTIFY_SLOT_TYPE:
-               i = wc->wbuf[0] | (wc->wbuf[1] << 7);
-               if (i <0 || i >= WF_MAX_SAMPLE) {
-                       printk (KERN_WARNING LOGNAME "invalid slot ID %d\n",
-                               i);
-                       wc->status = EINVAL;
-                       return 0;
-               }
-               wc->rbuf[0] = dev.sample_status[i];
-               wc->status = 0;
-               return 0;
-
-       case WFC_DEBUG_DRIVER:
-               dev.debug = wc->wbuf[0];
-               printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug);
-               return 0;
-
-       case WFC_FX_IOCTL:
-               wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]);
-               return 0;
-
-       case WFC_UPLOAD_PATCH:
-               munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2);
-               memcpy (wc->wbuf, patchnumbuf, 2);
-               break;
-
-       case WFC_UPLOAD_MULTISAMPLE:
-               /* multisamples have to be handled differently, and
-                  cannot be dealt with properly by wavefront_cmd() alone.
-               */
-               wc->status = wavefront_fetch_multisample
-                       ((wavefront_patch_info *) wc->rbuf);
-               return 0;
-
-       case WFC_UPLOAD_SAMPLE_ALIAS:
-               printk (KERN_INFO LOGNAME "support for sample alias upload "
-                       "being considered.\n");
-               wc->status = EINVAL;
-               return -EINVAL;
-       }
-
-       wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf);
-
-       /* Post-handling of certain commands.
-
-          In particular, if the command was an upload, demunge the data
-          so that the user-level doesn't have to think about it.
-       */
-
-       if (wc->status == 0) {
-               switch (wc->cmd) {
-                       /* intercept any freemem requests so that we know
-                          we are always current with the user-level view
-                          of things.
-                       */
-
-               case WFC_REPORT_FREE_MEMORY:
-                       dev.freemem = demunge_int32 (wc->rbuf, 4);
-                       break;
-
-               case WFC_UPLOAD_PATCH:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES);
-                       break;
-
-               case WFC_UPLOAD_PROGRAM:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES);
-                       break;
-
-               case WFC_UPLOAD_EDRUM_PROGRAM:
-                       demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1);
-                       break;
-
-               case WFC_UPLOAD_SAMPLE_HEADER:
-                       process_sample_hdr (wc->rbuf);
-                       break;
-
-               case WFC_UPLOAD_SAMPLE_ALIAS:
-                       printk (KERN_INFO LOGNAME "support for "
-                               "sample aliases still "
-                               "being considered.\n");
-                       break;
-
-               case WFC_VMIDI_OFF:
-                       if (virtual_midi_disable () < 0) {
-                               return -(EIO);
-                       }
-                       break;
-
-               case WFC_VMIDI_ON:
-                       if (virtual_midi_enable () < 0) {
-                               return -(EIO);
-                       }
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-\f
-/***********************************************************************/
-/* WaveFront: Linux file system interface (for access via raw synth)    */
-/***********************************************************************/
-
-static int 
-wavefront_open (struct inode *inode, struct file *file)
-{
-       /* XXX fix me */
-       dev.opened = file->f_flags;
-       return 0;
-}
-
-static int
-wavefront_release(struct inode *inode, struct file *file)
-{
-       lock_kernel();
-       dev.opened = 0;
-       dev.debug = 0;
-       unlock_kernel();
-       return 0;
-}
-
-static int
-wavefront_ioctl(struct inode *inode, struct file *file,
-               unsigned int cmd, unsigned long arg)
-{
-       wavefront_control wc;
-       int err;
-
-       switch (cmd) {
-
-       case WFCTL_WFCMD:
-               if (copy_from_user(&wc, (void __user *) arg, sizeof (wc)))
-                       return -EFAULT;
-               
-               if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-                       if (copy_to_user ((void __user *) arg, &wc, sizeof (wc)))
-                               return -EFAULT;
-               }
-
-               return err;
-               
-       case WFCTL_LOAD_SPP:
-               return wavefront_load_patch ((const char __user *) arg);
-               
-       default:
-               printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd);
-               return -(EINVAL);
-
-       }
-       return 0;
-}
-
-static /*const*/ struct file_operations wavefront_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = wavefront_ioctl,
-       .open           = wavefront_open,
-       .release        = wavefront_release,
-};
-
-\f
-/***********************************************************************/
-/* WaveFront: OSS installation and support interface                   */
-/***********************************************************************/
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-
-static struct synth_info wavefront_info =
-{"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT,
- 0, 32, 0, 0, SYNTH_CAP_INPUT};
-
-static int
-wavefront_oss_open (int devno, int mode)
-
-{
-       dev.opened = mode;
-       return 0;
-}
-
-static void
-wavefront_oss_close (int devno)
-
-{
-       dev.opened = 0;
-       dev.debug = 0;
-       return;
-}
-
-static int
-wavefront_oss_ioctl (int devno, unsigned int cmd, void __user * arg)
-
-{
-       wavefront_control wc;
-       int err;
-
-       switch (cmd) {
-       case SNDCTL_SYNTH_INFO:
-               if(copy_to_user(arg, &wavefront_info, sizeof (wavefront_info)))
-                       return -EFAULT;
-               return 0;
-
-       case SNDCTL_SEQ_RESETSAMPLES:
-//             printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n");
-               return 0; /* don't force an error */
-
-       case SNDCTL_SEQ_PERCMODE:
-               return 0; /* don't force an error */
-
-       case SNDCTL_SYNTH_MEMAVL:
-               if ((dev.freemem = wavefront_freemem ()) < 0) {
-                       printk (KERN_ERR LOGNAME "cannot get memory size\n");
-                       return -EIO;
-               } else {
-                       return dev.freemem;
-               }
-               break;
-
-       case SNDCTL_SYNTH_CONTROL:
-               if(copy_from_user (&wc, arg, sizeof (wc)))
-                       err = -EFAULT;
-               else if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
-                       if(copy_to_user (arg, &wc, sizeof (wc)))
-                               err = -EFAULT;
-               }
-
-               return err;
-
-       default:
-               return -(EINVAL);
-       }
-}
-
-static int
-wavefront_oss_load_patch (int devno, int format, const char __user *addr,
-                         int offs, int count, int pmgr_flag)
-{
-
-       if (format == SYSEX_PATCH) {    /* Handled by midi_synth.c */
-               if (midi_load_patch == NULL) {
-                       printk (KERN_ERR LOGNAME
-                               "SYSEX not loadable: "
-                               "no midi patch loader!\n");
-                       return -(EINVAL);
-               }
-
-               return midi_load_patch (devno, format, addr,
-                                       offs, count, pmgr_flag);
-
-       } else if (format == GUS_PATCH) {
-               return wavefront_load_gus_patch (devno, format,
-                                                addr, offs, count, pmgr_flag);
-
-       } else if (format != WAVEFRONT_PATCH) {
-               printk (KERN_ERR LOGNAME "unknown patch format %d\n", format);
-               return -(EINVAL);
-       }
-
-       if (count < sizeof (wavefront_patch_info)) {
-               printk (KERN_ERR LOGNAME "sample header too short\n");
-               return -(EINVAL);
-       }
-
-       /* "addr" points to a user-space wavefront_patch_info */
-
-       return wavefront_load_patch (addr);
-}      
-
-static struct synth_operations wavefront_operations =
-{
-       .owner          = THIS_MODULE,
-       .id             = "WaveFront",
-       .info           = &wavefront_info,
-       .midi_dev       = 0,
-       .synth_type     = SYNTH_TYPE_SAMPLE,
-       .synth_subtype  = SAMPLE_TYPE_WAVEFRONT,
-       .open           = wavefront_oss_open,
-       .close          = wavefront_oss_close,
-       .ioctl          = wavefront_oss_ioctl,
-       .kill_note      = midi_synth_kill_note,
-       .start_note     = midi_synth_start_note,
-       .set_instr      = midi_synth_set_instr,
-       .reset          = midi_synth_reset,
-       .load_patch     = midi_synth_load_patch,
-       .aftertouch     = midi_synth_aftertouch,
-       .controller     = midi_synth_controller,
-       .panning        = midi_synth_panning,
-       .bender         = midi_synth_bender,
-       .setup_voice    = midi_synth_setup_voice
-};
-#endif /* OSS_SUPPORT_SEQ */
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL
-
-static void __init attach_wavefront (struct address_info *hw_config)
-{
-    (void) install_wavefront ();
-}
-
-static int __init probe_wavefront (struct address_info *hw_config)
-{
-    return !detect_wavefront (hw_config->irq, hw_config->io_base);
-}
-
-static void __exit unload_wavefront (struct address_info *hw_config) 
-{
-    (void) uninstall_wavefront ();
-}
-
-#endif /* OSS_SUPPORT_STATIC_INSTALL */
-
-/***********************************************************************/
-/* WaveFront: Linux modular sound kernel installation interface        */
-/***********************************************************************/
-
-static irqreturn_t
-wavefrontintr(int irq, void *dev_id, struct pt_regs *dummy)
-{
-       struct wf_config *hw = dev_id;
-
-       /*
-          Some comments on interrupts. I attempted a version of this
-          driver that used interrupts throughout the code instead of
-          doing busy and/or sleep-waiting. Alas, it appears that once
-          the Motorola firmware is downloaded, the card *never*
-          generates an RX interrupt. These are successfully generated
-          during firmware loading, and after that wavefront_status()
-          reports that an interrupt is pending on the card from time
-          to time, but it never seems to be delivered to this
-          driver. Note also that wavefront_status() continues to
-          report that RX interrupts are enabled, suggesting that I
-          didn't goof up and disable them by mistake.
-
-          Thus, I stepped back to a prior version of
-          wavefront_wait(), the only place where this really
-          matters. Its sad, but I've looked through the code to check
-          on things, and I really feel certain that the Motorola
-          firmware prevents RX-ready interrupts.
-       */
-
-       if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) {
-               return IRQ_NONE;
-       }
-
-       hw->irq_ok = 1;
-       hw->irq_cnt++;
-       wake_up_interruptible (&hw->interrupt_sleeper);
-       return IRQ_HANDLED;
-}
-
-/* STATUS REGISTER 
-
-0 Host Rx Interrupt Enable (1=Enabled)
-1 Host Rx Register Full (1=Full)
-2 Host Rx Interrupt Pending (1=Interrupt)
-3 Unused
-4 Host Tx Interrupt (1=Enabled)
-5 Host Tx Register empty (1=Empty)
-6 Host Tx Interrupt Pending (1=Interrupt)
-7 Unused
-*/
-
-static int
-wavefront_interrupt_bits (int irq)
-
-{
-       int bits;
-
-       switch (irq) {
-       case 9:
-               bits = 0x00;
-               break;
-       case 5:
-               bits = 0x08;
-               break;
-       case 12:
-               bits = 0x10;
-               break;
-       case 15:
-               bits = 0x18;
-               break;
-       
-       default:
-               printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq);
-               bits = -1;
-       }
-
-       return bits;
-}
-
-static void
-wavefront_should_cause_interrupt (int val, int port, int timeout)
-
-{
-       unsigned long flags;
-
-       /* this will not help on SMP - but at least it compiles */
-       spin_lock_irqsave(&lock, flags);
-       dev.irq_ok = 0;
-       outb (val,port);
-       interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout);
-       spin_unlock_irqrestore(&lock,flags);
-}
-
-static int __init wavefront_hw_reset (void)
-{
-       int bits;
-       int hwv[2];
-       unsigned long irq_mask;
-       short reported_irq;
-
-       /* IRQ already checked in init_module() */
-
-       bits = wavefront_interrupt_bits (dev.irq);
-
-       printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n");
-
-       irq_mask = probe_irq_on ();
-
-       outb (0x0, dev.control_port); 
-       outb (0x80 | 0x40 | bits, dev.data_port);       
-       wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-                                        dev.control_port,
-                                        (reset_time*HZ)/100);
-
-       reported_irq = probe_irq_off (irq_mask);
-
-       if (reported_irq != dev.irq) {
-               if (reported_irq == 0) {
-                       printk (KERN_ERR LOGNAME
-                               "No unassigned interrupts detected "
-                               "after h/w reset\n");
-               } else if (reported_irq < 0) {
-                       printk (KERN_ERR LOGNAME
-                               "Multiple unassigned interrupts detected "
-                               "after h/w reset\n");
-               } else {
-                       printk (KERN_ERR LOGNAME "autodetected IRQ %d not the "
-                               "value provided (%d)\n", reported_irq,
-                               dev.irq);
-               }
-               dev.irq = -1;
-               return 1;
-       } else {
-               printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n",
-                       reported_irq);
-       }
-
-       if (request_irq (dev.irq, wavefrontintr,
-                        IRQF_DISABLED|IRQF_SHARED,
-                        "wavefront synth", &dev) < 0) {
-               printk (KERN_WARNING LOGNAME "IRQ %d not available!\n",
-                       dev.irq);
-               return 1;
-       }
-
-       /* try reset of port */
-      
-       outb (0x0, dev.control_port); 
-  
-       /* At this point, the board is in reset, and the H/W initialization
-          register is accessed at the same address as the data port.
-     
-          Bit 7 - Enable IRQ Driver    
-          0 - Tri-state the Wave-Board drivers for the PC Bus IRQs
-          1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus.
-     
-          Bit 6 - MIDI Interface Select
-
-          0 - Use the MIDI Input from the 26-pin WaveBlaster
-          compatible header as the serial MIDI source
-          1 - Use the MIDI Input from the 9-pin D connector as the
-          serial MIDI source.
-     
-          Bits 5:3 - IRQ Selection
-          0 0 0 - IRQ 2/9
-          0 0 1 - IRQ 5
-          0 1 0 - IRQ 12
-          0 1 1 - IRQ 15
-          1 0 0 - Reserved
-          1 0 1 - Reserved
-          1 1 0 - Reserved
-          1 1 1 - Reserved
-     
-          Bits 2:1 - Reserved
-          Bit 0 - Disable Boot ROM
-          0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM
-          1 - memory accesses to 03FC30-03FFFFH are directed to external 
-          storage.
-     
-       */
-
-       /* configure hardware: IRQ, enable interrupts, 
-          plus external 9-pin MIDI interface selected
-       */
-
-       outb (0x80 | 0x40 | bits, dev.data_port);       
-  
-       /* CONTROL REGISTER
-
-          0 Host Rx Interrupt Enable (1=Enabled)      0x1
-          1 Unused                                    0x2
-          2 Unused                                    0x4
-          3 Unused                                    0x8
-          4 Host Tx Interrupt Enable                 0x10
-          5 Mute (0=Mute; 1=Play)                    0x20
-          6 Master Interrupt Enable (1=Enabled)      0x40
-          7 Master Reset (0=Reset; 1=Run)            0x80
-
-          Take us out of reset, mute output, master + TX + RX interrupts on.
-          
-          We'll get an interrupt presumably to tell us that the TX
-          register is clear.
-       */
-
-       wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1,
-                                        dev.control_port,
-                                        (reset_time*HZ)/100);
-
-       /* Note: data port is now the data port, not the h/w initialization
-          port.
-        */
-
-       if (!dev.irq_ok) {
-               printk (KERN_WARNING LOGNAME
-                       "intr not received after h/w un-reset.\n");
-               goto gone_bad;
-       } 
-
-       dev.interrupts_on = 1;
-       
-       /* Note: data port is now the data port, not the h/w initialization
-          port.
-
-          At this point, only "HW VERSION" or "DOWNLOAD OS" commands
-          will work. So, issue one of them, and wait for TX
-          interrupt. This can take a *long* time after a cold boot,
-          while the ISC ROM does its RAM test. The SDK says up to 4
-          seconds - with 12MB of RAM on a Tropez+, it takes a lot
-          longer than that (~16secs). Note that the card understands
-          the difference between a warm and a cold boot, so
-          subsequent ISC2115 reboots (say, caused by module
-          reloading) will get through this much faster.
-
-          XXX Interesting question: why is no RX interrupt received first ?
-       */
-
-       wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION, 
-                                        dev.data_port, ramcheck_time*HZ);
-
-       if (!dev.irq_ok) {
-               printk (KERN_WARNING LOGNAME
-                       "post-RAM-check interrupt not received.\n");
-               goto gone_bad;
-       } 
-
-       if (!wavefront_wait (STAT_CAN_READ)) {
-               printk (KERN_WARNING LOGNAME
-                       "no response to HW version cmd.\n");
-               goto gone_bad;
-       }
-       
-       if ((hwv[0] = wavefront_read ()) == -1) {
-               printk (KERN_WARNING LOGNAME
-                       "board not responding correctly.\n");
-               goto gone_bad;
-       }
-
-       if (hwv[0] == 0xFF) { /* NAK */
-
-               /* Board's RAM test failed. Try to read error code,
-                  and tell us about it either way.
-               */
-               
-               if ((hwv[0] = wavefront_read ()) == -1) {
-                       printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-                               "(bad error code).\n");
-               } else {
-                       printk (KERN_WARNING LOGNAME "on-board RAM test failed "
-                               "(error code: 0x%x).\n",
-                               hwv[0]);
-               }
-               goto gone_bad;
-       }
-
-       /* We're OK, just get the next byte of the HW version response */
-
-       if ((hwv[1] = wavefront_read ()) == -1) {
-               printk (KERN_WARNING LOGNAME "incorrect h/w response.\n");
-               goto gone_bad;
-       }
-
-       printk (KERN_INFO LOGNAME "hardware version %d.%d\n",
-               hwv[0], hwv[1]);
-
-       return 0;
-
-
-     gone_bad:
-       if (dev.irq >= 0) {
-               free_irq (dev.irq, &dev);
-               dev.irq = -1;
-       }
-       return (1);
-}
-
-static int __init detect_wavefront (int irq, int io_base)
-{
-       unsigned char   rbuf[4], wbuf[4];
-
-       /* TB docs say the device takes up 8 ports, but we know that
-          if there is an FX device present (i.e. a Tropez+) it really
-          consumes 16.
-       */
-
-       if (!request_region (io_base, 16, "wavfront")) {
-               printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
-                       "already in use - ignored\n", dev.base,
-                       dev.base+15);
-               return -1;
-       }
-  
-       dev.irq = irq;
-       dev.base = io_base;
-       dev.israw = 0;
-       dev.debug = debug_default;
-       dev.interrupts_on = 0;
-       dev.irq_cnt = 0;
-       dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */
-
-       if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) {
-
-               dev.fw_version[0] = rbuf[0];
-               dev.fw_version[1] = rbuf[1];
-               printk (KERN_INFO LOGNAME
-                       "firmware %d.%d already loaded.\n",
-                       rbuf[0], rbuf[1]);
-
-               /* check that a command actually works */
-      
-               if (wavefront_cmd (WFC_HARDWARE_VERSION,
-                                  rbuf, wbuf) == 0) {
-                       dev.hw_version[0] = rbuf[0];
-                       dev.hw_version[1] = rbuf[1];
-               } else {
-                       printk (KERN_WARNING LOGNAME "not raw, but no "
-                               "hardware version!\n");
-                       release_region (io_base, 16);
-                       return 0;
-               }
-
-               if (!wf_raw) {
-                       /* will re-acquire region in install_wavefront() */
-                       release_region (io_base, 16);
-                       return 1;
-               } else {
-                       printk (KERN_INFO LOGNAME
-                               "reloading firmware anyway.\n");
-                       dev.israw = 1;
-               }
-
-       } else {
-
-               dev.israw = 1;
-               printk (KERN_INFO LOGNAME
-                       "no response to firmware probe, assume raw.\n");
-
-       }
-
-       init_waitqueue_head (&dev.interrupt_sleeper);
-
-       if (wavefront_hw_reset ()) {
-               printk (KERN_WARNING LOGNAME "hardware reset failed\n");
-               release_region (io_base, 16);
-               return 0;
-       }
-
-       /* Check for FX device, present only on Tropez+ */
-
-       dev.has_fx = (detect_wffx () == 0);
-
-       /* will re-acquire region in install_wavefront() */
-       release_region (io_base, 16);
-       return 1;
-}
-
-#include "os.h"
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-
-
-static int
-wavefront_download_firmware (char *path)
-
-{
-       unsigned char section[WF_SECTION_MAX];
-       char section_length; /* yes, just a char; max value is WF_SECTION_MAX */
-       int section_cnt_downloaded = 0;
-       int fd;
-       int c;
-       int i;
-       mm_segment_t fs;
-
-       /* This tries to be a bit cleverer than the stuff Alan Cox did for
-          the generic sound firmware, in that it actually knows
-          something about the structure of the Motorola firmware. In
-          particular, it uses a version that has been stripped of the
-          20K of useless header information, and had section lengths
-          added, making it possible to load the entire OS without any
-          [kv]malloc() activity, since the longest entity we ever read is
-          42 bytes (well, WF_SECTION_MAX) long.
-       */
-
-       fs = get_fs();
-       set_fs (get_ds());
-
-       if ((fd = sys_open (path, 0, 0)) < 0) {
-               printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n",
-                       path);
-               return 1;
-       }
-
-       while (1) {
-               int x;
-
-               if ((x = sys_read (fd, &section_length, sizeof (section_length))) !=
-                   sizeof (section_length)) {
-                       printk (KERN_ERR LOGNAME "firmware read error.\n");
-                       goto failure;
-               }
-
-               if (section_length == 0) {
-                       break;
-               }
-
-               if (sys_read (fd, section, section_length) != section_length) {
-                       printk (KERN_ERR LOGNAME "firmware section "
-                               "read error.\n");
-                       goto failure;
-               }
-
-               /* Send command */
-       
-               if (wavefront_write (WFC_DOWNLOAD_OS)) {
-                       goto failure;
-               }
-       
-               for (i = 0; i < section_length; i++) {
-                       if (wavefront_write (section[i])) {
-                               goto failure;
-                       }
-               }
-       
-               /* get ACK */
-       
-               if (wavefront_wait (STAT_CAN_READ)) {
-
-                       if ((c = inb (dev.data_port)) != WF_ACK) {
-
-                               printk (KERN_ERR LOGNAME "download "
-                                       "of section #%d not "
-                                       "acknowledged, ack = 0x%x\n",
-                                       section_cnt_downloaded + 1, c);
-                               goto failure;
-               
-                       }
-
-               } else {
-                       printk (KERN_ERR LOGNAME "time out for firmware ACK.\n");
-                       goto failure;
-               }
-
-       }
-
-       sys_close (fd);
-       set_fs (fs);
-       return 0;
-
- failure:
-       sys_close (fd);
-       set_fs (fs);
-       printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n");
-       return 1;
-}
-
-static int __init wavefront_config_midi (void)
-{
-       unsigned char rbuf[4], wbuf[4];
-    
-       if (detect_wf_mpu (dev.irq, dev.base) < 0) {
-               printk (KERN_WARNING LOGNAME
-                       "could not find working MIDI device\n");
-               return -1;
-       } 
-
-       if ((dev.mididev = install_wf_mpu ()) < 0) {
-               printk (KERN_WARNING LOGNAME
-                       "MIDI interfaces not configured\n");
-               return -1;
-       }
-
-       /* Route external MIDI to WaveFront synth (by default) */
-    
-       if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) {
-               printk (KERN_WARNING LOGNAME
-                       "cannot enable MIDI-IN to synth routing.\n");
-               /* XXX error ? */
-       }
-
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       /* Get the regular MIDI patch loading function, so we can
-          use it if we ever get handed a SYSEX patch. This is
-          unlikely, because its so damn slow, but we may as well
-          leave this functionality from maui.c behind, since it
-          could be useful for sequencer applications that can
-          only use MIDI to do patch loading.
-       */
-
-       if (midi_devs[dev.mididev]->converter != NULL) {
-               midi_load_patch = midi_devs[dev.mididev]->converter->load_patch;
-               midi_devs[dev.mididev]->converter->load_patch =
-                   &wavefront_oss_load_patch;
-       }
-
-#endif /* OSS_SUPPORT_SEQ */
-       
-       /* Turn on Virtual MIDI, but first *always* turn it off,
-          since otherwise consectutive reloads of the driver will
-          never cause the hardware to generate the initial "internal" or 
-          "external" source bytes in the MIDI data stream. This
-          is pretty important, since the internal hardware generally will
-          be used to generate none or very little MIDI output, and
-          thus the only source of MIDI data is actually external. Without
-          the switch bytes, the driver will think it all comes from
-          the internal interface. Duh.
-       */
-
-       if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) { 
-               printk (KERN_WARNING LOGNAME
-                       "virtual MIDI mode not disabled\n");
-               return 0; /* We're OK, but missing the external MIDI dev */
-       }
-
-       if ((dev.ext_mididev = virtual_midi_enable ()) < 0) {
-               printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n");
-       } else {
-               if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) {
-                       printk (KERN_WARNING LOGNAME
-                               "cannot enable virtual MIDI mode.\n");
-                       virtual_midi_disable ();
-               } 
-       }
-    
-       return 0;
-}
-
-static int __init wavefront_do_reset (int atboot)
-{
-       char voices[1];
-
-       if (!atboot && wavefront_hw_reset ()) {
-               printk (KERN_WARNING LOGNAME "hw reset failed.\n");
-               goto gone_bad;
-       }
-
-       if (dev.israw) {
-               if (wavefront_download_firmware (ospath)) {
-                       goto gone_bad;
-               }
-
-               dev.israw = 0;
-
-               /* Wait for the OS to get running. The protocol for
-                  this is non-obvious, and was determined by
-                  using port-IO tracing in DOSemu and some
-                  experimentation here.
-                  
-                  Rather than using timed waits, use interrupts creatively.
-               */
-
-               wavefront_should_cause_interrupt (WFC_NOOP,
-                                                 dev.data_port,
-                                                 (osrun_time*HZ));
-
-               if (!dev.irq_ok) {
-                       printk (KERN_WARNING LOGNAME
-                               "no post-OS interrupt.\n");
-                       goto gone_bad;
-               }
-               
-               /* Now, do it again ! */
-               
-               wavefront_should_cause_interrupt (WFC_NOOP,
-                                                 dev.data_port, (10*HZ));
-               
-               if (!dev.irq_ok) {
-                       printk (KERN_WARNING LOGNAME
-                               "no post-OS interrupt(2).\n");
-                       goto gone_bad;
-               }
-
-               /* OK, no (RX/TX) interrupts any more, but leave mute
-                  in effect. 
-               */
-               
-               outb (0x80|0x40, dev.control_port); 
-
-               /* No need for the IRQ anymore */
-               
-               free_irq (dev.irq, &dev);
-
-       }
-
-       if (dev.has_fx && fx_raw) {
-               wffx_init ();
-       }
-
-       /* SETUPSND.EXE asks for sample memory config here, but since i
-          have no idea how to interpret the result, we'll forget
-          about it.
-       */
-       
-       if ((dev.freemem = wavefront_freemem ()) < 0) {
-               goto gone_bad;
-       }
-               
-       printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024);
-
-       if (wavefront_write (0xf0) ||
-           wavefront_write (1) ||
-           (wavefront_read () < 0)) {
-               dev.debug = 0;
-               printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n");
-               goto gone_bad;
-       }
-
-       voices[0] = 32;
-
-       if (wavefront_cmd (WFC_SET_NVOICES, NULL, voices)) {
-               printk (KERN_WARNING LOGNAME
-                       "cannot set number of voices to 32.\n");
-               goto gone_bad;
-       }
-
-
-       return 0;
-
- gone_bad:
-       /* reset that sucker so that it doesn't bother us. */
-
-       outb (0x0, dev.control_port);
-       dev.interrupts_on = 0;
-       if (dev.irq >= 0) {
-               free_irq (dev.irq, &dev);
-       }
-       return 1;
-}
-
-static int __init wavefront_init (int atboot)
-{
-       int samples_are_from_rom;
-
-       if (dev.israw) {
-               samples_are_from_rom = 1;
-       } else {
-               /* XXX is this always true ? */
-               samples_are_from_rom = 0;
-       }
-
-       if (dev.israw || fx_raw) {
-               if (wavefront_do_reset (atboot)) {
-                       return -1;
-               }
-       }
-
-       wavefront_get_sample_status (samples_are_from_rom);
-       wavefront_get_program_status ();
-       wavefront_get_patch_status ();
-
-       /* Start normal operation: unreset, master interrupt enabled, no mute
-       */
-
-       outb (0x80|0x40|0x20, dev.control_port); 
-
-       return (0);
-}
-
-static int __init install_wavefront (void)
-{
-       if (!request_region (dev.base+2, 6, "wavefront synth"))
-               return -1;
-
-       if (dev.has_fx) {
-               if (!request_region (dev.base+8, 8, "wavefront fx")) {
-                       release_region (dev.base+2, 6);
-                       return -1;
-               }
-       }
-
-       if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
-               printk (KERN_ERR LOGNAME "cannot register raw synth\n");
-               goto err_out;
-       }
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
-               printk (KERN_ERR LOGNAME "Too many sequencers\n");
-               /* FIXME: leak: should unregister sound synth */
-               goto err_out;
-       } else {
-               synth_devs[dev.oss_dev] = &wavefront_operations;
-       }
-#endif /* OSS_SUPPORT_SEQ */
-
-       if (wavefront_init (1) < 0) {
-               printk (KERN_WARNING LOGNAME "initialization failed.\n");
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-               sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-
-               goto err_out;
-       }
-    
-       if (wavefront_config_midi ()) {
-               printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
-       }
-
-       return dev.oss_dev;
-
-err_out:
-       release_region (dev.base+2, 6);
-       if (dev.has_fx)
-               release_region (dev.base+8, 8);
-       return -1;
-}
-
-static void __exit uninstall_wavefront (void)
-{
-       /* the first two i/o addresses are freed by the wf_mpu code */
-       release_region (dev.base+2, 6);
-
-       if (dev.has_fx) {
-               release_region (dev.base+8, 8);
-       }
-
-       unregister_sound_synth (dev.synth_dev);
-
-#if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
-       sound_unload_synthdev (dev.oss_dev);
-#endif /* OSS_SUPPORT_SEQ */ 
-       uninstall_wf_mpu ();
-}
-
-/***********************************************************************/
-/*   WaveFront FX control                                              */
-/***********************************************************************/
-
-#include "yss225.h"
-
-/* Control bits for the Load Control Register
- */
-
-#define FX_LSB_TRANSFER 0x01    /* transfer after DSP LSB byte written */
-#define FX_MSB_TRANSFER 0x02    /* transfer after DSP MSB byte written */
-#define FX_AUTO_INCR    0x04    /* auto-increment DSP address after transfer */
-
-static int
-wffx_idle (void) 
-    
-{
-       int i;
-       unsigned int x = 0x80;
-    
-       for (i = 0; i < 1000; i++) {
-               x = inb (dev.fx_status);
-               if ((x & 0x80) == 0) {
-                       break;
-               }
-       }
-    
-       if (x & 0x80) {
-               printk (KERN_ERR LOGNAME "FX device never idle.\n");
-               return 0;
-       }
-    
-       return (1);
-}
-
-int __init detect_wffx (void)
-{
-       /* This is a crude check, but its the best one I have for now.
-          Certainly on the Maui and the Tropez, wffx_idle() will
-          report "never idle", which suggests that this test should
-          work OK.
-       */
-
-       if (inb (dev.fx_status) & 0x80) {
-               printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n");
-               return -1;
-       }
-
-       return 0;
-}      
-
-static void
-wffx_mute (int onoff)
-    
-{
-       if (!wffx_idle()) {
-               return;
-       }
-    
-       outb (onoff ? 0x02 : 0x00, dev.fx_op);
-}
-
-static int
-wffx_memset (int page,
-            int addr, int cnt, unsigned short *data)
-{
-       if (page < 0 || page > 7) {
-               printk (KERN_ERR LOGNAME "FX memset: "
-                       "page must be >= 0 and <= 7\n");
-               return -(EINVAL);
-       }
-
-       if (addr < 0 || addr > 0x7f) {
-               printk (KERN_ERR LOGNAME "FX memset: "
-                       "addr must be >= 0 and <= 7f\n");
-               return -(EINVAL);
-       }
-
-       if (cnt == 1) {
-
-               outb (FX_LSB_TRANSFER, dev.fx_lcr);
-               outb (page, dev.fx_dsp_page);
-               outb (addr, dev.fx_dsp_addr);
-               outb ((data[0] >> 8), dev.fx_dsp_msb);
-               outb ((data[0] & 0xff), dev.fx_dsp_lsb);
-
-               printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n",
-                       page, addr, data[0]);
-       
-       } else {
-               int i;
-
-               outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-               outb (page, dev.fx_dsp_page);
-               outb (addr, dev.fx_dsp_addr);
-
-               for (i = 0; i < cnt; i++) {
-                       outb ((data[i] >> 8), dev.fx_dsp_msb);
-                       outb ((data[i] & 0xff), dev.fx_dsp_lsb);
-                       if (!wffx_idle ()) {
-                               break;
-                       }
-               }
-
-               if (i != cnt) {
-                       printk (KERN_WARNING LOGNAME
-                               "FX memset "
-                               "(0x%x, 0x%x, %p, %d) incomplete\n",
-                               page, addr, data, cnt);
-                       return -(EIO);
-               }
-       }
-
-       return 0;
-}
-
-static int
-wffx_ioctl (wavefront_fx_info *r)
-
-{
-       unsigned short page_data[256];
-       unsigned short *pd;
-
-       switch (r->request) {
-       case WFFX_MUTE:
-               wffx_mute (r->data[0]);
-               return 0;
-
-       case WFFX_MEMSET:
-
-               if (r->data[2] <= 0) {
-                       printk (KERN_ERR LOGNAME "cannot write "
-                               "<= 0 bytes to FX\n");
-                       return -(EINVAL);
-               } else if (r->data[2] == 1) {
-                       pd = (unsigned short *) &r->data[3];
-               } else {
-                       if (r->data[2] > sizeof (page_data)) {
-                               printk (KERN_ERR LOGNAME "cannot write "
-                                       "> 255 bytes to FX\n");
-                               return -(EINVAL);
-                       }
-                       if (copy_from_user(page_data,
-                                          (unsigned char __user *)r->data[3],
-                                          r->data[2]))
-                               return -EFAULT;
-                       pd = page_data;
-               }
-
-               return wffx_memset (r->data[0], /* page */
-                                   r->data[1], /* addr */
-                                   r->data[2], /* cnt */
-                                   pd);
-
-       default:
-               printk (KERN_WARNING LOGNAME
-                       "FX: ioctl %d not yet supported\n",
-                       r->request);
-               return -(EINVAL);
-       }
-}
-
-/* YSS225 initialization.
-
-   This code was developed using DOSEMU. The Turtle Beach SETUPSND
-   utility was run with I/O tracing in DOSEMU enabled, and a reconstruction
-   of the port I/O done, using the Yamaha faxback document as a guide
-   to add more logic to the code. Its really pretty weird.
-
-   There was an alternative approach of just dumping the whole I/O
-   sequence as a series of port/value pairs and a simple loop
-   that output it. However, I hope that eventually I'll get more
-   control over what this code does, and so I tried to stick with
-   a somewhat "algorithmic" approach.
-*/
-
-static int __init wffx_init (void)
-{
-       int i;
-       int j;
-
-       /* Set all bits for all channels on the MOD unit to zero */
-       /* XXX But why do this twice ? */
-
-       for (j = 0; j < 2; j++) {
-               for (i = 0x10; i <= 0xff; i++) {
-           
-                       if (!wffx_idle ()) {
-                               return (-1);
-                       }
-           
-                       outb (i, dev.fx_mod_addr);
-                       outb (0x0, dev.fx_mod_data);
-               }
-       }
-
-       if (!wffx_idle()) return (-1);
-       outb (0x02, dev.fx_op);                        /* mute on */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x44, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x42, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x43, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x7c, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x7e, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x46, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x49, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x47, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x4a, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-
-       /* either because of stupidity by TB's programmers, or because it
-          actually does something, rezero the MOD page.
-       */
-       for (i = 0x10; i <= 0xff; i++) {
-       
-               if (!wffx_idle ()) {
-                       return (-1);
-               }
-       
-               outb (i, dev.fx_mod_addr);
-               outb (0x0, dev.fx_mod_data);
-       }
-       /* load page zero */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x00, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_zero); i += 2) {
-               outb (page_zero[i], dev.fx_dsp_msb);
-               outb (page_zero[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Now load page one */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x01, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_one); i += 2) {
-               outb (page_one[i], dev.fx_dsp_msb);
-               outb (page_one[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x02, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_two); i++) {
-               outb (page_two[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x03, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_three); i++) {
-               outb (page_three[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x04, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_four); i++) {
-               outb (page_four[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Load memory area (page six) */
-    
-       outb (FX_LSB_TRANSFER, dev.fx_lcr); 
-       outb (0x06, dev.fx_dsp_page); 
-
-       for (i = 0; i < sizeof (page_six); i += 3) {
-               outb (page_six[i], dev.fx_dsp_addr);
-               outb (page_six[i+1], dev.fx_dsp_msb);
-               outb (page_six[i+2], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x00, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_seven); i += 2) {
-               outb (page_seven[i], dev.fx_dsp_msb);
-               outb (page_seven[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Now setup the MOD area. We do this algorithmically in order to
-          save a little data space. It could be done in the same fashion
-          as the "pages".
-       */
-
-       for (i = 0x00; i <= 0x0f; i++) {
-               outb (0x01, dev.fx_mod_addr);
-               outb (i, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-               outb (0x02, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xb0; i <= 0xbf; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x20, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xf0; i <= 0xff; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x20, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x10; i <= 0x1d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xff, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x1e, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x1f; i <= 0x2d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xff, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x2e, dev.fx_mod_addr);
-       outb (0x00, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x2f; i <= 0x3e; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x3f, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x40; i <= 0x4d; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x4e, dev.fx_mod_addr);
-       outb (0x0e, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0x4f, dev.fx_mod_addr);
-       outb (0x0e, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-
-       for (i = 0x50; i <= 0x6b; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x6c, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6d, dev.fx_mod_addr);
-       outb (0x00, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6e, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       outb (0x6f, dev.fx_mod_addr);
-       outb (0x40, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0x70; i <= 0x7f; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0xc0, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       for (i = 0x80; i <= 0xaf; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0xc0; i <= 0xdd; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0xde, dev.fx_mod_addr);
-       outb (0x10, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xdf, dev.fx_mod_addr);
-       outb (0x10, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-
-       for (i = 0xe0; i <= 0xef; i++) {
-               outb (i, dev.fx_mod_addr);
-               outb (0x00, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x00; i <= 0x0f; i++) {
-               outb (0x01, dev.fx_mod_addr);
-               outb (i, dev.fx_mod_data);
-               outb (0x02, dev.fx_mod_addr);
-               outb (0x01, dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (0x02, dev.fx_op); /* mute on */
-
-       /* Now set the coefficients and so forth for the programs above */
-
-       for (i = 0; i < sizeof (coefficients); i += 4) {
-               outb (coefficients[i], dev.fx_dsp_page);
-               outb (coefficients[i+1], dev.fx_dsp_addr);
-               outb (coefficients[i+2], dev.fx_dsp_msb);
-               outb (coefficients[i+3], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       /* Some settings (?) that are too small to bundle into loops */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x1e, dev.fx_mod_addr);
-       outb (0x14, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xde, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-       if (!wffx_idle()) return (-1);
-       outb (0xdf, dev.fx_mod_addr);
-       outb (0x20, dev.fx_mod_data);
-    
-       /* some more coefficients */
-
-       if (!wffx_idle()) return (-1);
-       outb (0x06, dev.fx_dsp_page);
-       outb (0x78, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x40, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x03, dev.fx_dsp_addr);
-       outb (0x0f, dev.fx_dsp_msb);
-       outb (0xff, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x0b, dev.fx_dsp_addr);
-       outb (0x0f, dev.fx_dsp_msb);
-       outb (0xff, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x02, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x0a, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x46, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-       if (!wffx_idle()) return (-1);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x49, dev.fx_dsp_addr);
-       outb (0x00, dev.fx_dsp_msb);
-       outb (0x00, dev.fx_dsp_lsb);
-    
-       /* Now, for some strange reason, lets reload every page
-          and all the coefficients over again. I have *NO* idea
-          why this is done. I do know that no sound is produced
-          is this phase is omitted.
-       */
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x00, dev.fx_dsp_page);  
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_zero_v2); i += 2) {
-               outb (page_zero_v2[i], dev.fx_dsp_msb);
-               outb (page_zero_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x01, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_one_v2); i += 2) {
-               outb (page_one_v2[i], dev.fx_dsp_msb);
-               outb (page_one_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       if (!wffx_idle()) return (-1);
-       if (!wffx_idle()) return (-1);
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x02, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_two_v2); i++) {
-               outb (page_two_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x03, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_three_v2); i++) {
-               outb (page_three_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x04, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_four_v2); i++) {
-               outb (page_four_v2[i], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-    
-       outb (FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x06, dev.fx_dsp_page);
-
-       /* Page six v.2 is algorithmic */
-    
-       for (i = 0x10; i <= 0x3e; i += 2) {
-               outb (i, dev.fx_dsp_addr);
-               outb (0x00, dev.fx_dsp_msb);
-               outb (0x00, dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr);
-       outb (0x07, dev.fx_dsp_page);
-       outb (0x10, dev.fx_dsp_addr);
-
-       for (i = 0; i < sizeof (page_seven_v2); i += 2) {
-               outb (page_seven_v2[i], dev.fx_dsp_msb);
-               outb (page_seven_v2[i+1], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0x00; i < sizeof(mod_v2); i += 2) {
-               outb (mod_v2[i], dev.fx_mod_addr);
-               outb (mod_v2[i+1], dev.fx_mod_data);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0; i < sizeof (coefficients2); i += 4) {
-               outb (coefficients2[i], dev.fx_dsp_page);
-               outb (coefficients2[i+1], dev.fx_dsp_addr);
-               outb (coefficients2[i+2], dev.fx_dsp_msb);
-               outb (coefficients2[i+3], dev.fx_dsp_lsb);
-               if (!wffx_idle()) return (-1);
-       }
-
-       for (i = 0; i < sizeof (coefficients3); i += 2) {
-               int x;
-
-               outb (0x07, dev.fx_dsp_page);
-               x = (i % 4) ? 0x4e : 0x4c;
-               outb (x, dev.fx_dsp_addr);
-               outb (coefficients3[i], dev.fx_dsp_msb);
-               outb (coefficients3[i+1], dev.fx_dsp_lsb);
-       }
-
-       outb (0x00, dev.fx_op); /* mute off */
-       if (!wffx_idle()) return (-1);
-
-       return (0);
-}
-
-static int io = -1;
-static int irq = -1;
-
-MODULE_AUTHOR      ("Paul Barton-Davis <pbd@op.net>");
-MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver");
-MODULE_LICENSE("GPL");
-module_param       (io, int, 0);
-module_param       (irq, int, 0);
-
-static int __init init_wavfront (void)
-{
-       printk ("Turtle Beach WaveFront Driver\n"
-               "Copyright (C) by Hannu Solvainen, "
-               "Paul Barton-Davis 1993-1998.\n");
-
-       /* XXX t'would be lovely to ask the CS4232 for these values, eh ? */
-
-       if (io == -1 || irq == -1) {
-               printk (KERN_INFO LOGNAME "irq and io options must be set.\n");
-               return -EINVAL;
-       }
-
-       if (wavefront_interrupt_bits (irq) < 0) {
-               printk (KERN_INFO LOGNAME
-                       "IRQ must be 9, 5, 12 or 15 (not %d)\n", irq);
-               return -ENODEV;
-       }
-
-       if (detect_wavefront (irq, io) < 0) {
-               return -ENODEV;
-       } 
-
-       if (install_wavefront () < 0) {
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static void __exit cleanup_wavfront (void)
-{
-       uninstall_wavefront ();
-}
-
-module_init(init_wavfront);
-module_exit(cleanup_wavfront);
diff --git a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c
deleted file mode 100644 (file)
index 75c0c14..0000000
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * sound/oss/wf_midi.c
- *
- * The low level driver for the WaveFront ICS2115 MIDI interface(s)
- * Note that there is also an MPU-401 emulation (actually, a UART-401
- * emulation) on the CS4232 on the Tropez Plus. This code has nothing
- * to do with that interface at all.
- *
- * The interface is essentially just a UART-401, but is has the
- * interesting property of supporting what Turtle Beach called
- * "Virtual MIDI" mode. In this mode, there are effectively *two*
- * MIDI buses accessible via the interface, one that is routed
- * solely to/from the external WaveFront synthesizer and the other
- * corresponding to the pin/socket connector used to link external
- * MIDI devices to the board.
- *
- * This driver fully supports this mode, allowing two distinct
- * midi devices (/dev/midiNN and /dev/midiNN+1) to be used
- * completely independently, giving 32 channels of MIDI routing,
- * 16 to the WaveFront synth and 16 to the external MIDI bus.
- *
- * Switching between the two is accomplished externally by the driver
- * using the two otherwise unused MIDI bytes. See the code for more details.
- *
- * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c)
- *
- * The main reason to turn off Virtual MIDI mode is when you want to
- * tightly couple the WaveFront synth with an external MIDI
- * device. You won't be able to distinguish the source of any MIDI
- * data except via SysEx ID, but thats probably OK, since for the most
- * part, the WaveFront won't be sending any MIDI data at all.
- *  
- * The main reason to turn on Virtual MIDI Mode is to provide two
- * completely independent 16-channel MIDI buses, one to the
- * WaveFront and one to any external MIDI devices. Given the 32
- * voice nature of the WaveFront, its pretty easy to find a use
- * for all 16 channels driving just that synth.
- *
- */
-
-/*
- * Copyright (C) by Paul Barton-Davis 1998
- * Some portions of this file are derived from work that is:
- *
- *    CopyriGht (C) by Hannu Savolainen 1993-1996
- *
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include "sound_config.h"
-
-#include <linux/wavefront.h>
-
-#ifdef MODULE
-
-struct wf_mpu_config {
-       int             base;
-#define        DATAPORT(d)   (d)->base
-#define        COMDPORT(d)   (d)->base+1
-#define        STATPORT(d)   (d)->base+1
-
-       int             irq;
-       int             opened;
-       int             devno;
-       int             synthno;
-       int             mode;
-#define MODE_MIDI      1
-#define MODE_SYNTH     2
-
-       void            (*inputintr) (int dev, unsigned char data);
-       char isvirtual;                /* do virtual I/O stuff */
-};
-
-static struct wf_mpu_config  devs[2];
-static struct wf_mpu_config *phys_dev = &devs[0];
-static struct wf_mpu_config *virt_dev = &devs[1];
-
-static void start_uart_mode (void);
-static DEFINE_SPINLOCK(lock);
-
-#define        OUTPUT_READY    0x40
-#define        INPUT_AVAIL     0x80
-#define        MPU_ACK         0xFE
-#define        UART_MODE_ON    0x3F
-
-static inline int wf_mpu_status (void)
-{
-       return inb (STATPORT (phys_dev));
-}
-
-static inline int input_avail (void)
-{
-       return !(wf_mpu_status() & INPUT_AVAIL);
-}
-
-static inline int output_ready (void)
-{
-       return !(wf_mpu_status() & OUTPUT_READY);
-}
-
-static inline int  read_data (void)
-{
-       return inb (DATAPORT (phys_dev));
-}
-
-static inline void write_data (unsigned char byte)
-{
-       outb (byte, DATAPORT (phys_dev));
-}
-
-/*
- * States for the input scanner (should be in dev_table.h)
- */
-
-#define MST_SYSMSG             100     /* System message (sysx etc). */
-#define MST_MTC                        102     /* Midi Time Code (MTC) qframe msg */
-#define MST_SONGSEL            103     /* Song select */
-#define MST_SONGPOS            104     /* Song position pointer */
-#define MST_TIMED              105     /* Leading timing byte rcvd */
-
-/* buffer space check for input scanner */
-
-#define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \
-{printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \
-       mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;}
-
-static unsigned char len_tab[] =       /* # of data bytes following a status
-                                        */
-{
-       2,                              /* 8x */
-       2,                              /* 9x */
-       2,                              /* Ax */
-       2,                              /* Bx */
-       1,                              /* Cx */
-       1,                              /* Dx */
-       2,                              /* Ex */
-       0                               /* Fx */
-};
-
-static int
-wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic)
-
-{
-       struct midi_input_info *mi = &midi_devs[devno]->in_info;
-
-       switch (mi->m_state) {
-       case MST_INIT:
-               switch (midic) {
-               case 0xf8:
-                       /* Timer overflow */
-                       break;
-               
-               case 0xfc:
-                       break;
-               
-               case 0xfd:
-                       /* XXX do something useful with this. If there is
-                          an external MIDI timer (e.g. a hardware sequencer,
-                          a useful timer can be derived ...
-                  
-                          For now, no timer support.
-                       */
-                       break;
-               
-               case 0xfe:
-                       return MPU_ACK;
-                       break;
-               
-               case 0xf0:
-               case 0xf1:
-               case 0xf2:
-               case 0xf3:
-               case 0xf4:
-               case 0xf5:
-               case 0xf6:
-               case 0xf7:
-                       break;
-               
-               case 0xf9:
-                       break;
-               
-               case 0xff:
-                       mi->m_state = MST_SYSMSG;
-                       break;
-               
-               default:
-                       if (midic <= 0xef) {
-                               mi->m_state = MST_TIMED;
-                       }
-                       else
-                               printk (KERN_ERR "<MPU: Unknown event %02x> ",
-                                       midic);
-               }
-               break;
-         
-       case MST_TIMED:
-       {
-               int             msg = ((int) (midic & 0xf0) >> 4);
-         
-               mi->m_state = MST_DATA;
-         
-               if (msg < 8) {  /* Data byte */
-             
-                       msg = ((int) (mi->m_prev_status & 0xf0) >> 4);
-                       msg -= 8;
-                       mi->m_left = len_tab[msg] - 1;
-             
-                       mi->m_ptr = 2;
-                       mi->m_buf[0] = mi->m_prev_status;
-                       mi->m_buf[1] = midic;
-
-                       if (mi->m_left <= 0) {
-                               mi->m_state = MST_INIT;
-                               do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                               mi->m_ptr = 0;
-                       }
-               } else if (msg == 0xf) {        /* MPU MARK */
-             
-                       mi->m_state = MST_INIT;
-
-                       switch (midic) {
-                       case 0xf8:
-                               break;
-                   
-                       case 0xf9:
-                               break;
-                   
-                       case 0xfc:
-                               break;
-                   
-                       default:
-                               break;
-                       }
-               } else {
-                       mi->m_prev_status = midic;
-                       msg -= 8;
-                       mi->m_left = len_tab[msg];
-             
-                       mi->m_ptr = 1;
-                       mi->m_buf[0] = midic;
-             
-                       if (mi->m_left <= 0) {
-                               mi->m_state = MST_INIT;
-                               do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                               mi->m_ptr = 0;
-                       }
-               }
-       }
-       break;
-
-       case MST_SYSMSG:
-               switch (midic) {
-               case 0xf0:
-                       mi->m_state = MST_SYSEX;
-                       break;
-           
-               case 0xf1:
-                       mi->m_state = MST_MTC;
-                       break;
-
-               case 0xf2:
-                       mi->m_state = MST_SONGPOS;
-                       mi->m_ptr = 0;
-                       break;
-           
-               case 0xf3:
-                       mi->m_state = MST_SONGSEL;
-                       break;
-           
-               case 0xf6:
-                       mi->m_state = MST_INIT;
-           
-                       /*
-                        *    Real time messages
-                        */
-               case 0xf8:
-                       /* midi clock */
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xfA:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFB:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFC:
-                       mi->m_state = MST_INIT;
-                       /* XXX need ext MIDI timer support */
-                       break;
-           
-               case 0xFE:
-                       /* active sensing */
-                       mi->m_state = MST_INIT;
-                       break;
-           
-               case 0xff:
-                       mi->m_state = MST_INIT;
-                       break;
-
-               default:
-                       printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic);
-                       mi->m_state = MST_INIT;
-               }
-               break;
-
-       case MST_MTC:
-               mi->m_state = MST_INIT;
-               break;
-
-       case MST_SYSEX:
-               if (midic == 0xf7) {
-                       mi->m_state = MST_INIT;
-               } else {
-                       /* XXX fix me */
-               }
-               break;
-
-       case MST_SONGPOS:
-               BUFTEST (mi);
-               mi->m_buf[mi->m_ptr++] = midic;
-               if (mi->m_ptr == 2) {
-                       mi->m_state = MST_INIT;
-                       mi->m_ptr = 0;
-                       /* XXX need ext MIDI timer support */
-               }
-               break;
-
-       case MST_DATA:
-               BUFTEST (mi);
-               mi->m_buf[mi->m_ptr++] = midic;
-               if ((--mi->m_left) <= 0) {
-                       mi->m_state = MST_INIT;
-                       do_midi_msg (synthdev, mi->m_buf, mi->m_ptr);
-                       mi->m_ptr = 0;
-               }
-               break;
-
-       default:
-               printk (KERN_ERR "Bad state %d ", mi->m_state);
-               mi->m_state = MST_INIT;
-       }
-
-       return 1;
-}
-
-static irqreturn_t
-wf_mpuintr(int irq, void *dev_id, struct pt_regs *dummy)
-
-{
-       struct wf_mpu_config *physical_dev = dev_id;
-       static struct wf_mpu_config *input_dev;
-       struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info;
-       int n;
-
-       if (!input_avail()) { /* not for us */
-               return IRQ_NONE;
-       }
-
-       if (mi->m_busy)
-               return IRQ_HANDLED;
-       spin_lock(&lock);
-       mi->m_busy = 1;
-
-       if (!input_dev) {
-               input_dev = physical_dev;
-       }
-
-       n = 50; /* XXX why ? */
-
-       do {
-               unsigned char c = read_data ();
-      
-               if (phys_dev->isvirtual) {
-
-                       if (c == WF_EXTERNAL_SWITCH) {
-                               input_dev = virt_dev;
-                               continue;
-                       } else if (c == WF_INTERNAL_SWITCH) { 
-                               input_dev = phys_dev;
-                               continue;
-                       } /* else just leave it as it is */
-
-               } else {
-                       input_dev = phys_dev;
-               }
-
-               if (input_dev->mode == MODE_SYNTH) {
-         
-                       wf_mpu_input_scanner (input_dev->devno,
-                                             input_dev->synthno, c);
-         
-               } else if (input_dev->opened & OPEN_READ) {
-         
-                       if (input_dev->inputintr) {
-                               input_dev->inputintr (input_dev->devno, c);
-                       } 
-               }
-
-       } while (input_avail() && n-- > 0);
-
-       mi->m_busy = 0;
-       spin_unlock(&lock);
-       return IRQ_HANDLED;
-}
-
-static int
-wf_mpu_open (int dev, int mode,
-            void            (*input) (int dev, unsigned char data),
-            void            (*output) (int dev)
-       )
-{
-       struct wf_mpu_config *devc;
-
-       if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-               return -(ENXIO);
-
-       if (phys_dev->devno == dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return -(EINVAL);
-       }
-
-       if (devc->opened) {
-               return -(EBUSY);
-       }
-
-       devc->mode = MODE_MIDI;
-       devc->opened = mode;
-       devc->synthno = 0;
-
-       devc->inputintr = input;
-       return 0;
-}
-static void
-wf_mpu_close (int dev)
-{
-       struct wf_mpu_config *devc;
-
-       if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL)
-               return;
-
-       if (phys_dev->devno == dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return;
-       }
-
-       devc->mode = 0;
-       devc->inputintr = NULL;
-       devc->opened = 0;
-}
-
-static int
-wf_mpu_out (int dev, unsigned char midi_byte)
-{
-       int             timeout;
-       unsigned long   flags;
-       static int lastoutdev = -1;
-       unsigned char switchch;
-
-       if (phys_dev->isvirtual && lastoutdev != dev) {
-      
-               if (dev == phys_dev->devno) { 
-                       switchch = WF_INTERNAL_SWITCH;
-               } else if (dev == virt_dev->devno) { 
-                       switchch = WF_EXTERNAL_SWITCH;
-               } else {
-                       printk (KERN_ERR "WF-MPU: bad device number %d", dev);
-                       return (0);
-               }
-
-               /* XXX fix me */
-      
-               for (timeout = 30000; timeout > 0 && !output_ready ();
-                    timeout--);
-      
-               spin_lock_irqsave(&lock,flags);
-      
-               if (!output_ready ()) {
-                       printk (KERN_WARNING "WF-MPU: Send switch "
-                               "byte timeout\n");
-                       spin_unlock_irqrestore(&lock,flags);
-                       return 0;
-               }
-      
-               write_data (switchch);
-               spin_unlock_irqrestore(&lock,flags);
-       } 
-
-       lastoutdev = dev;
-
-       /*
-        * Sometimes it takes about 30000 loops before the output becomes ready
-        * (After reset). Normally it takes just about 10 loops.
-        */
-
-       /* XXX fix me */
-
-       for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);
-
-       spin_lock_irqsave(&lock,flags);
-       if (!output_ready ()) {
-               spin_unlock_irqrestore(&lock,flags);
-               printk (KERN_WARNING "WF-MPU: Send data timeout\n");
-               return 0;
-       }
-
-       write_data (midi_byte);
-       spin_unlock_irqrestore(&lock,flags);
-
-       return 1;
-}
-
-static inline int wf_mpu_start_read (int dev) {
-       return 0;
-}
-
-static inline int wf_mpu_end_read (int dev) {
-       return 0;
-}
-
-static int wf_mpu_ioctl (int dev, unsigned cmd, void __user *arg)
-{
-       printk (KERN_WARNING
-               "WF-MPU: Intelligent mode not supported by hardware.\n");
-       return -(EINVAL);
-}
-
-static int wf_mpu_buffer_status (int dev)
-{
-       return 0;
-}
-
-static struct synth_operations wf_mpu_synth_operations[2];
-static struct midi_operations  wf_mpu_midi_operations[2];
-
-static struct midi_operations wf_mpu_midi_proto =
-{
-       .owner          = THIS_MODULE,
-       .info           = {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
-       .in_info        = {0},   /* in_info */
-       .open           = wf_mpu_open,
-       .close          = wf_mpu_close,
-       .ioctl          = wf_mpu_ioctl,
-       .outputc        = wf_mpu_out,
-       .start_read     = wf_mpu_start_read,
-       .end_read       = wf_mpu_end_read,
-       .buffer_status  = wf_mpu_buffer_status,
-};
-
-static struct synth_info wf_mpu_synth_info_proto =
-{"WaveFront MPU-401 interface", 0,
- SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT};
-
-static struct synth_info wf_mpu_synth_info[2];
-
-static int
-wf_mpu_synth_ioctl (int dev, unsigned int cmd, void __user *arg)
-{
-       int             midi_dev;
-       int index;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL)
-               return -(ENXIO);
-
-       if (midi_dev == phys_dev->devno) {
-               index = 0;
-       } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) {
-               index = 1;
-       } else {
-               return -(EINVAL);
-       }
-
-       switch (cmd) {
-
-       case SNDCTL_SYNTH_INFO:
-               if (copy_to_user(arg,
-                             &wf_mpu_synth_info[index],
-                             sizeof (struct synth_info)))
-                       return -EFAULT;
-               return 0;
-       
-       case SNDCTL_SYNTH_MEMAVL:
-               return 0x7fffffff;
-       
-       default:
-               return -EINVAL;
-       }
-}
-
-static int
-wf_mpu_synth_open (int dev, int mode)
-{
-       int             midi_dev;
-       struct wf_mpu_config *devc;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) {
-               return -(ENXIO);
-       }
-  
-       if (phys_dev->devno == midi_dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return -(EINVAL);
-       }
-
-       if (devc->opened) {
-               return -(EBUSY);
-       }
-  
-       devc->mode = MODE_SYNTH;
-       devc->synthno = dev;
-       devc->opened = mode;
-       devc->inputintr = NULL;
-       return 0;
-}
-
-static void
-wf_mpu_synth_close (int dev)
-{
-       int             midi_dev;
-       struct wf_mpu_config *devc;
-
-       midi_dev = synth_devs[dev]->midi_dev;
-
-       if (phys_dev->devno == midi_dev) {
-               devc = phys_dev;
-       } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) {
-               devc = virt_dev;
-       } else {
-               printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev);
-               return;
-       }
-
-       devc->inputintr = NULL;
-       devc->opened = 0;
-       devc->mode = 0;
-}
-
-#define _MIDI_SYNTH_C_
-#define MIDI_SYNTH_NAME        "WaveFront (MIDI)"
-#define MIDI_SYNTH_CAPS        SYNTH_CAP_INPUT
-#include "midi_synth.h"
-
-static struct synth_operations wf_mpu_synth_proto =
-{
-       .owner          = THIS_MODULE,
-       .id             = "WaveFront (ICS2115)",
-       .info           = NULL,  /* info field, filled in during configuration */
-       .midi_dev       = 0,     /* MIDI dev XXX should this be -1 ? */
-       .synth_type     = SYNTH_TYPE_MIDI,
-       .synth_subtype  = SAMPLE_TYPE_WAVEFRONT,
-       .open           = wf_mpu_synth_open,
-       .close          = wf_mpu_synth_close,
-       .ioctl          = wf_mpu_synth_ioctl,
-       .kill_note      = midi_synth_kill_note,
-       .start_note     = midi_synth_start_note,
-       .set_instr      = midi_synth_set_instr,
-       .reset          = midi_synth_reset,
-       .hw_control     = midi_synth_hw_control,
-       .load_patch     = midi_synth_load_patch,
-       .aftertouch     = midi_synth_aftertouch,
-       .controller     = midi_synth_controller,
-       .panning        = midi_synth_panning,
-       .bender         = midi_synth_bender,
-       .setup_voice    = midi_synth_setup_voice,
-       .send_sysex     = midi_synth_send_sysex
-};
-
-static int
-config_wf_mpu (struct wf_mpu_config *dev)
-
-{
-       int is_external;
-       char *name;
-       int index;
-
-       if (dev == phys_dev) {
-               name = "WaveFront internal MIDI";
-               is_external = 0;
-               index = 0;
-               memcpy ((char *) &wf_mpu_synth_operations[index],
-                       (char *) &wf_mpu_synth_proto,
-                       sizeof (struct synth_operations));
-       } else {
-               name = "WaveFront external MIDI";
-               is_external = 1;
-               index = 1;
-               /* no synth operations for an external MIDI interface */
-       }
-
-       memcpy ((char *) &wf_mpu_synth_info[dev->devno],
-               (char *) &wf_mpu_synth_info_proto,
-               sizeof (struct synth_info));
-
-       strcpy (wf_mpu_synth_info[index].name, name);
-
-       wf_mpu_synth_operations[index].midi_dev = dev->devno;
-       wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index];
-
-       memcpy ((char *) &wf_mpu_midi_operations[index],
-               (char *) &wf_mpu_midi_proto,
-               sizeof (struct midi_operations));
-  
-       if (is_external) {
-               wf_mpu_midi_operations[index].converter = NULL;
-       } else {
-               wf_mpu_midi_operations[index].converter =
-                       &wf_mpu_synth_operations[index];
-       }
-
-       strcpy (wf_mpu_midi_operations[index].info.name, name);
-
-       midi_devs[dev->devno] = &wf_mpu_midi_operations[index];
-       midi_devs[dev->devno]->in_info.m_busy = 0;
-       midi_devs[dev->devno]->in_info.m_state = MST_INIT;
-       midi_devs[dev->devno]->in_info.m_ptr = 0;
-       midi_devs[dev->devno]->in_info.m_left = 0;
-       midi_devs[dev->devno]->in_info.m_prev_status = 0;
-
-       devs[index].opened = 0;
-       devs[index].mode = 0;
-
-       return (0);
-}
-
-int virtual_midi_enable (void)
-
-{
-       if ((virt_dev->devno < 0) &&
-           (virt_dev->devno = sound_alloc_mididev()) == -1) {
-               printk (KERN_ERR
-                       "WF-MPU: too many midi devices detected\n");
-               return -1;
-       }
-
-       config_wf_mpu (virt_dev);
-
-       phys_dev->isvirtual = 1;
-       return virt_dev->devno;
-}
-
-int
-virtual_midi_disable (void)
-
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       wf_mpu_close (virt_dev->devno);
-       /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */
-       phys_dev->isvirtual = 0;
-
-       spin_unlock_irqrestore(&lock,flags);
-
-       return 0;
-}
-
-int __init detect_wf_mpu (int irq, int io_base)
-{
-       if (!request_region(io_base, 2, "wavefront midi")) {
-               printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
-                       io_base);
-               return -1;
-       }
-
-       phys_dev->base = io_base;
-       phys_dev->irq = irq;
-       phys_dev->devno = -1;
-       virt_dev->devno = -1;
-
-       return 0;
-}
-
-int __init install_wf_mpu (void)
-{
-       if ((phys_dev->devno = sound_alloc_mididev()) < 0){
-
-               printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n");
-               release_region(phys_dev->base, 2);
-               return -1;
-       }
-
-       phys_dev->isvirtual = 0;
-
-       if (config_wf_mpu (phys_dev)) {
-
-               printk (KERN_WARNING
-                       "WF-MPU: configuration for MIDI device %d failed\n",
-                       phys_dev->devno);
-               sound_unload_mididev (phys_dev->devno);
-
-       }
-
-       /* OK, now we're configured to handle an interrupt ... */
-
-       if (request_irq (phys_dev->irq, wf_mpuintr, IRQF_DISABLED|IRQF_SHARED,
-                        "wavefront midi", phys_dev) < 0) {
-
-               printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n",
-                       phys_dev->irq);
-               return -1;
-
-       }
-
-       /* This being a WaveFront (ICS-2115) emulated MPU-401, we have
-          to switch it into UART (dumb) mode, because otherwise, it
-          won't do anything at all.
-       */
-  
-       start_uart_mode ();
-
-       return phys_dev->devno;
-}
-void
-uninstall_wf_mpu (void)
-
-{
-       release_region (phys_dev->base, 2); 
-       free_irq (phys_dev->irq, phys_dev);
-       sound_unload_mididev (phys_dev->devno);
-
-       if (virt_dev->devno >= 0) {
-               sound_unload_mididev (virt_dev->devno);
-       }
-}
-
-static void
-start_uart_mode (void)
-
-{
-       int             ok, i;
-       unsigned long   flags;
-
-       spin_lock_irqsave(&lock,flags);
-
-       /* XXX fix me */
-
-       for (i = 0; i < 30000 && !output_ready (); i++);
-
-       outb (UART_MODE_ON, COMDPORT(phys_dev));
-
-       for (ok = 0, i = 50000; i > 0 && !ok; i--) {
-               if (input_avail ()) {
-                       if (read_data () == MPU_ACK) {
-                               ok = 1;
-                       }
-               }
-       }
-
-       spin_unlock_irqrestore(&lock,flags);
-}
-#endif
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
deleted file mode 100644 (file)
index 6e22472..0000000
+++ /dev/null
@@ -1,2692 +0,0 @@
-/*
- *  Copyright 1999 Jaroslav Kysela <perex@suse.cz>
- *  Copyright 2000 Alan Cox <alan@redhat.com>
- *  Copyright 2001 Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
- *  Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com>
- *
- *  Yamaha YMF7xx driver.
- *
- *  This code is a result of high-speed collision
- *  between ymfpci.c of ALSA and cs46xx.c of Linux.
- *  -- Pete Zaitcev <zaitcev@yahoo.com>; 2000/09/18
- *
- *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * TODO:
- *  - Use P44Slot for 44.1 playback (beware of idle buzzing in P44Slot).
- *  - 96KHz playback for DVD - use pitch of 2.0.
- *  - Retain DMA buffer on close, do not wait the end of frame.
- *  - Resolve XXX tagged questions.
- *  - Cannot play 5133Hz.
- *  - 2001/01/07 Consider if we can remove voice_lock, like so:
- *     : Allocate/deallocate voices in open/close under semafore.
- *     : We access voices in interrupt, that only for pcms that open.
- *    voice_lock around playback_prepare closes interrupts for insane duration.
- *  - Revisit the way voice_alloc is done - too confusing, overcomplicated.
- *    Should support various channel types, however.
- *  - Remove prog_dmabuf from read/write, leave it in open.
- *  - 2001/01/07 Replace the OPL3 part of CONFIG_SOUND_YMFPCI_LEGACY code with
- *    native synthesizer through a playback slot.
- *  - 2001/11/29 ac97_save_state
- *    Talk to Kai to remove ac97_save_state before it's too late!
- *  - Second AC97
- *  - Restore S/PDIF - Toshibas have it.
- *
- * Kai used pci_alloc_consistent for DMA buffer, which sounds a little
- * unconventional. However, given how small our fragments can be,
- * a little uncached access is perhaps better than endless flushing.
- * On i386 and other I/O-coherent architectures pci_alloc_consistent
- * is entirely harmless.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/soundcard.h>
-#include <linux/ac97_codec.h>
-#include <linux/sound.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# include "sound_config.h"
-# include "mpu401.h"
-#endif
-#include "ymfpci.h"
-
-/*
- * I do not believe in debug levels as I never can guess what
- * part of the code is going to be problematic in the future.
- * Don't forget to run your klogd with -c 8.
- *
- * Example (do not remove):
- * #define YMFDBG(fmt, arg...)  do{ printk(KERN_DEBUG fmt, ##arg); }while(0)
- */
-#define YMFDBGW(fmt, arg...)  /* */    /* write counts */
-#define YMFDBGI(fmt, arg...)  /* */    /* interrupts */
-#define YMFDBGX(fmt, arg...)  /* */    /* ioctl */
-
-static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd);
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice);
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank);
-static int ymf_playback_prepare(struct ymf_state *state);
-static int ymf_capture_prepare(struct ymf_state *state);
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit);
-
-static void ymfpci_aclink_reset(struct pci_dev * pci);
-static void ymfpci_disable_dsp(ymfpci_t *unit);
-static void ymfpci_download_image(ymfpci_t *codec);
-static void ymf_memload(ymfpci_t *unit);
-
-static DEFINE_SPINLOCK(ymf_devs_lock);
-static LIST_HEAD(ymf_devs);
-
-/*
- *  constants
- */
-
-static struct pci_device_id ymf_id_tbl[] = {
-#define DEV(dev, data) \
-       { PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \
-               (unsigned long)data }
-       DEV (PCI_DEVICE_ID_YAMAHA_724,  "YMF724"),
-       DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"),
-       DEV (PCI_DEVICE_ID_YAMAHA_740,  "YMF740"),
-       DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"),
-       DEV (PCI_DEVICE_ID_YAMAHA_744,  "YMF744"),
-       DEV (PCI_DEVICE_ID_YAMAHA_754,  "YMF754"),
-#undef DEV
-       { }
-};
-MODULE_DEVICE_TABLE(pci, ymf_id_tbl);
-
-/*
- *  common I/O routines
- */
-
-static inline void ymfpci_writeb(ymfpci_t *codec, u32 offset, u8 val)
-{
-       writeb(val, codec->reg_area_virt + offset);
-}
-
-static inline u16 ymfpci_readw(ymfpci_t *codec, u32 offset)
-{
-       return readw(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writew(ymfpci_t *codec, u32 offset, u16 val)
-{
-       writew(val, codec->reg_area_virt + offset);
-}
-
-static inline u32 ymfpci_readl(ymfpci_t *codec, u32 offset)
-{
-       return readl(codec->reg_area_virt + offset);
-}
-
-static inline void ymfpci_writel(ymfpci_t *codec, u32 offset, u32 val)
-{
-       writel(val, codec->reg_area_virt + offset);
-}
-
-static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched)
-{
-       signed long end_time;
-       u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
-       
-       end_time = jiffies + 3 * (HZ / 4);
-       do {
-               if ((ymfpci_readw(codec, reg) & 0x8000) == 0)
-                       return 0;
-               if (sched) {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
-       } while (end_time - (signed long)jiffies >= 0);
-       printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n",
-           secondary, ymfpci_readw(codec, reg));
-       return -EBUSY;
-}
-
-static void ymfpci_codec_write(struct ac97_codec *dev, u8 reg, u16 val)
-{
-       ymfpci_t *codec = dev->private_data;
-       u32 cmd;
-
-       spin_lock(&codec->ac97_lock);
-       /* XXX Do make use of dev->id */
-       ymfpci_codec_ready(codec, 0, 0);
-       cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val;
-       ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd);
-       spin_unlock(&codec->ac97_lock);
-}
-
-static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg)
-{
-       int i;
-
-       if (ymfpci_codec_ready(unit, 0, 0))
-               return ~0;
-       ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg);
-       if (ymfpci_codec_ready(unit, 0, 0))
-               return ~0;
-       if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) {
-               for (i = 0; i < 600; i++)
-                       ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-       }
-       return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA);
-}
-
-static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg)
-{
-       ymfpci_t *unit = dev->private_data;
-       u16 ret;
-       
-       spin_lock(&unit->ac97_lock);
-       ret = _ymfpci_codec_read(unit, reg);
-       spin_unlock(&unit->ac97_lock);
-       
-       return ret;
-}
-
-/*
- *  Misc routines
- */
-
-/*
- * Calculate the actual sampling rate relatetively to the base clock (48kHz).
- */
-static u32 ymfpci_calc_delta(u32 rate)
-{
-       switch (rate) {
-       case 8000:      return 0x02aaab00;
-       case 11025:     return 0x03accd00;
-       case 16000:     return 0x05555500;
-       case 22050:     return 0x07599a00;
-       case 32000:     return 0x0aaaab00;
-       case 44100:     return 0x0eb33300;
-       default:        return ((rate << 16) / 48000) << 12;
-       }
-}
-
-static u32 def_rate[8] = {
-       100, 2000, 8000, 11025, 16000, 22050, 32000, 48000
-};
-
-static u32 ymfpci_calc_lpfK(u32 rate)
-{
-       u32 i;
-       static u32 val[8] = {
-               0x00570000, 0x06AA0000, 0x18B20000, 0x20930000,
-               0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000
-       };
-       
-       if (rate == 44100)
-               return 0x40000000;      /* FIXME: What's the right value? */
-       for (i = 0; i < 8; i++)
-               if (rate <= def_rate[i])
-                       return val[i];
-       return val[0];
-}
-
-static u32 ymfpci_calc_lpfQ(u32 rate)
-{
-       u32 i;
-       static u32 val[8] = {
-               0x35280000, 0x34A70000, 0x32020000, 0x31770000,
-               0x31390000, 0x31C90000, 0x33D00000, 0x40000000
-       };
-       
-       if (rate == 44100)
-               return 0x370A0000;
-       for (i = 0; i < 8; i++)
-               if (rate <= def_rate[i])
-                       return val[i];
-       return val[0];
-}
-
-static u32 ymf_calc_lend(u32 rate)
-{
-       return (rate * YMF_SAMPF) / 48000;
-}
-
-/*
- * We ever allow only a few formats, but let's be generic, for smaller surprise.
- */
-static int ymf_pcm_format_width(int format)
-{
-       static int mask16 = AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE;
-
-       if ((format & (format-1)) != 0) {
-               printk(KERN_ERR "ymfpci: format 0x%x is not a power of 2\n", format);
-               return 8;
-       }
-
-       if (format == AFMT_IMA_ADPCM) return 4;
-       if ((format & mask16) != 0) return 16;
-       return 8;
-}
-
-static void ymf_pcm_update_shift(struct ymf_pcm_format *f)
-{
-       f->shift = 0;
-       if (f->voices == 2)
-               f->shift++;
-       if (ymf_pcm_format_width(f->format) == 16)
-               f->shift++;
-}
-
-/* Are you sure 32K is not too much? See if mpg123 skips on loaded systems. */
-#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
-#define DMABUF_MINORDER 1
-
-/*
- * Allocate DMA buffer
- */
-static int alloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-       void *rawbuf = NULL;
-       dma_addr_t dma_addr;
-       int order;
-       struct page *map, *mapend;
-
-       /* alloc as big a chunk as we can */
-       for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) {
-               rawbuf = pci_alloc_consistent(unit->pci, PAGE_SIZE << order, &dma_addr);
-               if (rawbuf)
-                       break;
-       }
-       if (!rawbuf)
-               return -ENOMEM;
-
-#if 0
-       printk(KERN_DEBUG "ymfpci: allocated %ld (order = %d) bytes at %p\n",
-              PAGE_SIZE << order, order, rawbuf);
-#endif
-
-       dmabuf->ready  = dmabuf->mapped = 0;
-       dmabuf->rawbuf = rawbuf;
-       dmabuf->dma_addr = dma_addr;
-       dmabuf->buforder = order;
-
-       /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */
-       mapend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
-       for (map = virt_to_page(rawbuf); map <= mapend; map++)
-               set_bit(PG_reserved, &map->flags);
-
-       return 0;
-}
-
-/*
- * Free DMA buffer
- */
-static void dealloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf)
-{
-       struct page *map, *mapend;
-
-       if (dmabuf->rawbuf) {
-               /* undo marking the pages as reserved */
-               mapend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
-               for (map = virt_to_page(dmabuf->rawbuf); map <= mapend; map++)
-                       clear_bit(PG_reserved, &map->flags);
-
-               pci_free_consistent(unit->pci, PAGE_SIZE << dmabuf->buforder,
-                   dmabuf->rawbuf, dmabuf->dma_addr);
-       }
-       dmabuf->rawbuf = NULL;
-       dmabuf->mapped = dmabuf->ready = 0;
-}
-
-static int prog_dmabuf(struct ymf_state *state, int rec)
-{
-       struct ymf_dmabuf *dmabuf;
-       int w_16;
-       unsigned bufsize;
-       unsigned long flags;
-       int redzone, redfrags;
-       int ret;
-
-       w_16 = ymf_pcm_format_width(state->format.format) == 16;
-       dmabuf = rec ? &state->rpcm.dmabuf : &state->wpcm.dmabuf;
-
-       spin_lock_irqsave(&state->unit->reg_lock, flags);
-       dmabuf->hwptr = dmabuf->swptr = 0;
-       dmabuf->total_bytes = 0;
-       dmabuf->count = 0;
-       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-       /* allocate DMA buffer if not allocated yet */
-       if (!dmabuf->rawbuf)
-               if ((ret = alloc_dmabuf(state->unit, dmabuf)))
-                       return ret;
-
-       /*
-        * Create fake fragment sizes and numbers for OSS ioctls.
-        * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT.
-        */
-       bufsize = PAGE_SIZE << dmabuf->buforder;
-       /* By default we give 4 big buffers. */
-       dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT - 2);
-       if (dmabuf->ossfragshift > 3 &&
-           dmabuf->ossfragshift < dmabuf->fragshift) {
-               /* If OSS set smaller fragments, give more smaller buffers. */
-               dmabuf->fragshift = dmabuf->ossfragshift;
-       }
-       dmabuf->fragsize = 1 << dmabuf->fragshift;
-
-       dmabuf->numfrag = bufsize >> dmabuf->fragshift;
-       dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-
-       if (dmabuf->ossmaxfrags >= 2) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-               redfrags = (redzone + dmabuf->fragsize-1) >> dmabuf->fragshift;
-
-               if (dmabuf->ossmaxfrags + redfrags < dmabuf->numfrag) {
-                       dmabuf->numfrag = dmabuf->ossmaxfrags + redfrags;
-                       dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
-               }
-       }
-
-       memset(dmabuf->rawbuf, w_16 ? 0 : 0x80, dmabuf->dmasize);
-
-       /*
-        *      Now set up the ring 
-        */
-
-       /* XXX   ret = rec? cap_pre(): pbk_pre();  */
-       spin_lock_irqsave(&state->unit->voice_lock, flags);
-       if (rec) {
-               if ((ret = ymf_capture_prepare(state)) != 0) {
-                       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-                       return ret;
-               }
-       } else {
-               if ((ret = ymf_playback_prepare(state)) != 0) {
-                       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-                       return ret;
-               }
-       }
-       spin_unlock_irqrestore(&state->unit->voice_lock, flags);
-
-       /* set the ready flag for the dma buffer (this comment is not stupid) */
-       dmabuf->ready = 1;
-
-#if 0
-       printk(KERN_DEBUG "prog_dmabuf: rate %d format 0x%x,"
-           " numfrag %d fragsize %d dmasize %d\n",
-              state->format.rate, state->format.format, dmabuf->numfrag,
-              dmabuf->fragsize, dmabuf->dmasize);
-#endif
-
-       return 0;
-}
-
-static void ymf_start_dac(struct ymf_state *state)
-{
-       ymf_playback_trigger(state->unit, &state->wpcm, 1);
-}
-
-// static void ymf_start_adc(struct ymf_state *state)
-// {
-//     ymf_capture_trigger(state->unit, &state->rpcm, 1);
-// }
-
-/*
- * Wait until output is drained.
- * This does not kill the hardware for the sake of ioctls.
- */
-static void ymf_wait_dac(struct ymf_state *state)
-{
-       struct ymf_unit *unit = state->unit;
-       struct ymf_pcm *ypcm = &state->wpcm;
-       DECLARE_WAITQUEUE(waita, current);
-       unsigned long flags;
-
-       add_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (ypcm->dmabuf.count != 0 && !ypcm->running) {
-               ymf_playback_trigger(unit, ypcm, 1);
-       }
-
-#if 0
-       if (file->f_flags & O_NONBLOCK) {
-               /*
-                * XXX Our  mistake is to attach DMA buffer to state
-                * rather than to some per-device structure.
-                * Cannot skip waiting, can only make it shorter.
-                */
-       }
-#endif
-
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       while (ypcm->running) {
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-               schedule();
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&ypcm->dmabuf.wait, &waita);
-
-       /*
-        * This function may take up to 4 seconds to reach this point
-        * (32K circular buffer, 8000 Hz). User notices.
-        */
-}
-
-/* Can just stop, without wait. Or can we? */
-static void ymf_stop_adc(struct ymf_state *state)
-{
-       struct ymf_unit *unit = state->unit;
-       unsigned long flags;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       ymf_capture_trigger(unit, &state->rpcm, 0);
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Hardware start management
- */
-
-static void ymfpci_hw_start(ymfpci_t *unit)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (unit->start_count++ == 0) {
-               ymfpci_writel(unit, YDSXGR_MODE,
-                   ymfpci_readl(unit, YDSXGR_MODE) | 3);
-               unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-static void ymfpci_hw_stop(ymfpci_t *unit)
-{
-       unsigned long flags;
-       long timeout = 1000;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-       if (--unit->start_count == 0) {
-               ymfpci_writel(unit, YDSXGR_MODE,
-                   ymfpci_readl(unit, YDSXGR_MODE) & ~3);
-               while (timeout-- > 0) {
-                       if ((ymfpci_readl(unit, YDSXGR_STATUS) & 2) == 0)
-                               break;
-               }
-       }
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-}
-
-/*
- *  Playback voice management
- */
-
-static int voice_alloc(ymfpci_t *codec, ymfpci_voice_type_t type, int pair, ymfpci_voice_t *rvoice[])
-{
-       ymfpci_voice_t *voice, *voice2;
-       int idx;
-
-       for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) {
-               voice = &codec->voices[idx];
-               voice2 = pair ? &codec->voices[idx+1] : NULL;
-               if (voice->use || (voice2 && voice2->use))
-                       continue;
-               voice->use = 1;
-               if (voice2)
-                       voice2->use = 1;
-               switch (type) {
-               case YMFPCI_PCM:
-                       voice->pcm = 1;
-                       if (voice2)
-                               voice2->pcm = 1;
-                       break;
-               case YMFPCI_SYNTH:
-                       voice->synth = 1;
-                       break;
-               case YMFPCI_MIDI:
-                       voice->midi = 1;
-                       break;
-               }
-               ymfpci_hw_start(codec);
-               rvoice[0] = voice;
-               if (voice2) {
-                       ymfpci_hw_start(codec);
-                       rvoice[1] = voice2;
-               }
-               return 0;
-       }
-       return -EBUSY;  /* Your audio channel is open by someone else. */
-}
-
-static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice)
-{
-       ymfpci_hw_stop(unit);
-       pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
-       pvoice->ypcm = NULL;
-}
-
-/*
- */
-
-static void ymf_pcm_interrupt(ymfpci_t *codec, ymfpci_voice_t *voice)
-{
-       struct ymf_pcm *ypcm;
-       int redzone;
-       int pos, delta, swptr;
-       int played, distance;
-       struct ymf_state *state;
-       struct ymf_dmabuf *dmabuf;
-       char silence;
-
-       if ((ypcm = voice->ypcm) == NULL) {
-               return;
-       }
-       if ((state = ypcm->state) == NULL) {
-               ypcm->running = 0;      // lock it
-               return;
-       }
-       dmabuf = &ypcm->dmabuf;
-       spin_lock(&codec->reg_lock);
-       if (ypcm->running) {
-               YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n",
-                  voice->number, codec->active_bank, dmabuf->count,
-                  le32_to_cpu(voice->bank[0].start),
-                  le32_to_cpu(voice->bank[1].start));
-               silence = (ymf_pcm_format_width(state->format.format) == 16) ?
-                   0 : 0x80;
-               /* We need actual left-hand-side redzone size here. */
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= (state->format.shift + 1);
-               swptr = dmabuf->swptr;
-
-               pos = le32_to_cpu(voice->bank[codec->active_bank].start);
-               pos <<= state->format.shift;
-               if (pos < 0 || pos >= dmabuf->dmasize) {        /* ucode bug */
-                       printk(KERN_ERR "ymfpci%d: runaway voice %d: hwptr %d=>%d dmasize %d\n",
-                           codec->dev_audio, voice->number,
-                           dmabuf->hwptr, pos, dmabuf->dmasize);
-                       pos = 0;
-               }
-               if (pos < dmabuf->hwptr) {
-                       delta = dmabuf->dmasize - dmabuf->hwptr;
-                       memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-                       delta += pos;
-                       memset(dmabuf->rawbuf, silence, pos);
-               } else {
-                       delta = pos - dmabuf->hwptr;
-                       memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta);
-               }
-               dmabuf->hwptr = pos;
-
-               if (dmabuf->count == 0) {
-                       printk(KERN_ERR "ymfpci%d: %d: strain: hwptr %d\n",
-                           codec->dev_audio, voice->number, dmabuf->hwptr);
-                       ymf_playback_trigger(codec, ypcm, 0);
-               }
-
-               if (swptr <= pos) {
-                       distance = pos - swptr;
-               } else {
-                       distance = dmabuf->dmasize - (swptr - pos);
-               }
-               if (distance < redzone) {
-                       /*
-                        * hwptr inside redzone => DMA ran out of samples.
-                        */
-                       if (delta < dmabuf->count) {
-                               /*
-                                * Lost interrupt or other screwage.
-                                */
-                               printk(KERN_ERR "ymfpci%d: %d: lost: delta %d"
-                                   " hwptr %d swptr %d distance %d count %d\n",
-                                   codec->dev_audio, voice->number, delta,
-                                   dmabuf->hwptr, swptr, distance, dmabuf->count);
-                       } else {
-                               /*
-                                * Normal end of DMA.
-                                */
-                               YMFDBGI("ymfpci%d: %d: done: delta %d"
-                                   " hwptr %d swptr %d distance %d count %d\n",
-                                   codec->dev_audio, voice->number, delta,
-                                   dmabuf->hwptr, swptr, distance, dmabuf->count);
-                       }
-                       played = dmabuf->count;
-                       if (ypcm->running) {
-                               ymf_playback_trigger(codec, ypcm, 0);
-                       }
-               } else {
-                       /*
-                        * hwptr is chipping away towards a remote swptr.
-                        * Calculate other distance and apply it to count.
-                        */
-                       if (swptr >= pos) {
-                               distance = swptr - pos;
-                       } else {
-                               distance = dmabuf->dmasize - (pos - swptr);
-                       }
-                       if (distance < dmabuf->count) {
-                               played = dmabuf->count - distance;
-                       } else {
-                               played = 0;
-                       }
-               }
-
-               dmabuf->total_bytes += played;
-               dmabuf->count -= played;
-               if (dmabuf->count < dmabuf->dmasize / 2) {
-                       wake_up(&dmabuf->wait);
-               }
-       }
-       spin_unlock(&codec->reg_lock);
-}
-
-static void ymf_cap_interrupt(ymfpci_t *unit, struct ymf_capture *cap)
-{
-       struct ymf_pcm *ypcm;
-       int redzone;
-       struct ymf_state *state;
-       struct ymf_dmabuf *dmabuf;
-       int pos, delta;
-       int cnt;
-
-       if ((ypcm = cap->ypcm) == NULL) {
-               return;
-       }
-       if ((state = ypcm->state) == NULL) {
-               ypcm->running = 0;      // lock it
-               return;
-       }
-       dmabuf = &ypcm->dmabuf;
-       spin_lock(&unit->reg_lock);
-       if (ypcm->running) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= (state->format.shift + 1);
-
-               pos = le32_to_cpu(cap->bank[unit->active_bank].start);
-               // pos <<= state->format.shift;
-               if (pos < 0 || pos >= dmabuf->dmasize) {        /* ucode bug */
-                       printk(KERN_ERR "ymfpci%d: runaway capture %d: hwptr %d=>%d dmasize %d\n",
-                           unit->dev_audio, ypcm->capture_bank_number,
-                           dmabuf->hwptr, pos, dmabuf->dmasize);
-                       pos = 0;
-               }
-               if (pos < dmabuf->hwptr) {
-                       delta = dmabuf->dmasize - dmabuf->hwptr;
-                       delta += pos;
-               } else {
-                       delta = pos - dmabuf->hwptr;
-               }
-               dmabuf->hwptr = pos;
-
-               cnt = dmabuf->count;
-               cnt += delta;
-               if (cnt + redzone > dmabuf->dmasize) {
-                       /* Overflow - bump swptr */
-                       dmabuf->count = dmabuf->dmasize - redzone;
-                       dmabuf->swptr = dmabuf->hwptr + redzone;
-                       if (dmabuf->swptr >= dmabuf->dmasize) {
-                               dmabuf->swptr -= dmabuf->dmasize;
-                       }
-               } else {
-                       dmabuf->count = cnt;
-               }
-
-               dmabuf->total_bytes += delta;
-               if (dmabuf->count) {            /* && is_sleeping  XXX */
-                       wake_up(&dmabuf->wait);
-               }
-       }
-       spin_unlock(&unit->reg_lock);
-}
-
-static int ymf_playback_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-
-       if (ypcm->voices[0] == NULL) {
-               return -EINVAL;
-       }
-       if (cmd != 0) {
-               codec->ctrl_playback[ypcm->voices[0]->number + 1] =
-                   cpu_to_le32(ypcm->voices[0]->bank_ba);
-               if (ypcm->voices[1] != NULL)
-                       codec->ctrl_playback[ypcm->voices[1]->number + 1] =
-                           cpu_to_le32(ypcm->voices[1]->bank_ba);
-               ypcm->running = 1;
-       } else {
-               codec->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
-               if (ypcm->voices[1] != NULL)
-                       codec->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
-               ypcm->running = 0;
-       }
-       return 0;
-}
-
-static void ymf_capture_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd)
-{
-       u32 tmp;
-
-       if (cmd != 0) {
-               tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number);
-               ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-               ypcm->running = 1;
-       } else {
-               tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number);
-               ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp);
-               ypcm->running = 0;
-       }
-}
-
-static int ymfpci_pcm_voice_alloc(struct ymf_pcm *ypcm, int voices)
-{
-       struct ymf_unit *unit;
-       int err;
-
-       unit = ypcm->state->unit;
-       if (ypcm->voices[1] != NULL && voices < 2) {
-               ymfpci_voice_free(unit, ypcm->voices[1]);
-               ypcm->voices[1] = NULL;
-       }
-       if (voices == 1 && ypcm->voices[0] != NULL)
-               return 0;               /* already allocated */
-       if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL)
-               return 0;               /* already allocated */
-       if (voices > 1) {
-               if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) {
-                       ymfpci_voice_free(unit, ypcm->voices[0]);
-                       ypcm->voices[0] = NULL;
-               }               
-               if ((err = voice_alloc(unit, YMFPCI_PCM, 1, ypcm->voices)) < 0)
-                       return err;
-               ypcm->voices[0]->ypcm = ypcm;
-               ypcm->voices[1]->ypcm = ypcm;
-       } else {
-               if ((err = voice_alloc(unit, YMFPCI_PCM, 0, ypcm->voices)) < 0)
-                       return err;
-               ypcm->voices[0]->ypcm = ypcm;
-       }
-       return 0;
-}
-
-static void ymf_pcm_init_voice(ymfpci_voice_t *voice, int stereo,
-    int rate, int w_16, unsigned long addr, unsigned int end, int spdif)
-{
-       u32 format;
-       u32 delta = ymfpci_calc_delta(rate);
-       u32 lpfQ = ymfpci_calc_lpfQ(rate);
-       u32 lpfK = ymfpci_calc_lpfK(rate);
-       ymfpci_playback_bank_t *bank;
-       int nbank;
-
-       /*
-        * The gain is a floating point number. According to the manual,
-        * bit 31 indicates a sign bit, bit 30 indicates an integer part,
-        * and bits [29:15] indicate a decimal fraction part. Thus,
-        * for a gain of 1.0 the constant of 0x40000000 is loaded.
-        */
-       unsigned default_gain = cpu_to_le32(0x40000000);
-
-       format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000);
-       if (stereo)
-               end >>= 1;
-       if (w_16)
-               end >>= 1;
-       for (nbank = 0; nbank < 2; nbank++) {
-               bank = &voice->bank[nbank];
-               bank->format = cpu_to_le32(format);
-               bank->loop_default = 0; /* 0-loops forever, otherwise count */
-               bank->base = cpu_to_le32(addr);
-               bank->loop_start = 0;
-               bank->loop_end = cpu_to_le32(end);
-               bank->loop_frac = 0;
-               bank->eg_gain_end = default_gain;
-               bank->lpfQ = cpu_to_le32(lpfQ);
-               bank->status = 0;
-               bank->num_of_frames = 0;
-               bank->loop_count = 0;
-               bank->start = 0;
-               bank->start_frac = 0;
-               bank->delta =
-               bank->delta_end = cpu_to_le32(delta);
-               bank->lpfK =
-               bank->lpfK_end = cpu_to_le32(lpfK);
-               bank->eg_gain = default_gain;
-               bank->lpfD1 =
-               bank->lpfD2 = 0;
-
-               bank->left_gain = 
-               bank->right_gain =
-               bank->left_gain_end =
-               bank->right_gain_end =
-               bank->eff1_gain =
-               bank->eff2_gain =
-               bank->eff3_gain =
-               bank->eff1_gain_end =
-               bank->eff2_gain_end =
-               bank->eff3_gain_end = 0;
-
-               if (!stereo) {
-                       if (!spdif) {
-                               bank->left_gain = 
-                               bank->right_gain =
-                               bank->left_gain_end =
-                               bank->right_gain_end = default_gain;
-                       } else {
-                               bank->eff2_gain =
-                               bank->eff2_gain_end =
-                               bank->eff3_gain =
-                               bank->eff3_gain_end = default_gain;
-                       }
-               } else {
-                       if (!spdif) {
-                               if ((voice->number & 1) == 0) {
-                                       bank->left_gain =
-                                       bank->left_gain_end = default_gain;
-                               } else {
-                                       bank->format |= cpu_to_le32(1);
-                                       bank->right_gain =
-                                       bank->right_gain_end = default_gain;
-                               }
-                       } else {
-                               if ((voice->number & 1) == 0) {
-                                       bank->eff2_gain =
-                                       bank->eff2_gain_end = default_gain;
-                               } else {
-                                       bank->format |= cpu_to_le32(1);
-                                       bank->eff3_gain =
-                                       bank->eff3_gain_end = default_gain;
-                               }
-                       }
-               }
-       }
-}
-
-/*
- * XXX Capture channel allocation is entirely fake at the moment.
- * We use only one channel and mark it busy as required.
- */
-static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank)
-{
-       struct ymf_capture *cap;
-       int cbank;
-
-       cbank = 1;              /* Only ADC slot is used for now. */
-       cap = &unit->capture[cbank];
-       if (cap->use)
-               return -EBUSY;
-       cap->use = 1;
-       *pbank = cbank;
-       return 0;
-}
-
-static int ymf_playback_prepare(struct ymf_state *state)
-{
-       struct ymf_pcm *ypcm = &state->wpcm;
-       int err, nvoice;
-
-       if ((err = ymfpci_pcm_voice_alloc(ypcm, state->format.voices)) < 0) {
-               /* Somebody started 32 mpg123's in parallel? */
-               printk(KERN_INFO "ymfpci%d: cannot allocate voice\n",
-                   state->unit->dev_audio);
-               return err;
-       }
-
-       for (nvoice = 0; nvoice < state->format.voices; nvoice++) {
-               ymf_pcm_init_voice(ypcm->voices[nvoice],
-                   state->format.voices == 2, state->format.rate,
-                   ymf_pcm_format_width(state->format.format) == 16,
-                   ypcm->dmabuf.dma_addr, ypcm->dmabuf.dmasize,
-                   ypcm->spdif);
-       }
-       return 0;
-}
-
-static int ymf_capture_prepare(struct ymf_state *state)
-{
-       ymfpci_t *unit = state->unit;
-       struct ymf_pcm *ypcm = &state->rpcm;
-       ymfpci_capture_bank_t * bank;
-       /* XXX This is confusing, gotta rename one of them banks... */
-       int nbank;              /* flip-flop bank */
-       int cbank;              /* input [super-]bank */
-       struct ymf_capture *cap;
-       u32 rate, format;
-
-       if (ypcm->capture_bank_number == -1) {
-               if (ymf_capture_alloc(unit, &cbank) != 0)
-                       return -EBUSY;
-
-               ypcm->capture_bank_number = cbank;
-
-               cap = &unit->capture[cbank];
-               cap->bank = unit->bank_capture[cbank][0];
-               cap->ypcm = ypcm;
-               ymfpci_hw_start(unit);
-       }
-
-       // ypcm->frag_size = snd_pcm_lib_transfer_fragment(substream);
-       // frag_size is replaced with nonfragged byte-aligned rolling buffer
-       rate = ((48000 * 4096) / state->format.rate) - 1;
-       format = 0;
-       if (state->format.voices == 2)
-               format |= 2;
-       if (ymf_pcm_format_width(state->format.format) == 8)
-               format |= 1;
-       switch (ypcm->capture_bank_number) {
-       case 0:
-               ymfpci_writel(unit, YDSXGR_RECFORMAT, format);
-               ymfpci_writel(unit, YDSXGR_RECSLOTSR, rate);
-               break;
-       case 1:
-               ymfpci_writel(unit, YDSXGR_ADCFORMAT, format);
-               ymfpci_writel(unit, YDSXGR_ADCSLOTSR, rate);
-               break;
-       }
-       for (nbank = 0; nbank < 2; nbank++) {
-               bank = unit->bank_capture[ypcm->capture_bank_number][nbank];
-               bank->base = cpu_to_le32(ypcm->dmabuf.dma_addr);
-               // bank->loop_end = ypcm->dmabuf.dmasize >> state->format.shift;
-               bank->loop_end = cpu_to_le32(ypcm->dmabuf.dmasize);
-               bank->start = 0;
-               bank->num_of_loops = 0;
-       }
-#if 0 /* s/pdif */
-       if (state->digital.dig_valid)
-               /*state->digital.type == SND_PCM_DIG_AES_IEC958*/
-               ymfpci_writew(codec, YDSXGR_SPDIFOUTSTATUS,
-                   state->digital.dig_status[0] | (state->digital.dig_status[1] << 8));
-#endif
-       return 0;
-}
-
-static irqreturn_t ymf_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       ymfpci_t *codec = dev_id;
-       u32 status, nvoice, mode;
-       struct ymf_voice *voice;
-       struct ymf_capture *cap;
-
-       status = ymfpci_readl(codec, YDSXGR_STATUS);
-       if (status & 0x80000000) {
-               codec->active_bank = ymfpci_readl(codec, YDSXGR_CTRLSELECT) & 1;
-               spin_lock(&codec->voice_lock);
-               for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) {
-                       voice = &codec->voices[nvoice];
-                       if (voice->use)
-                               ymf_pcm_interrupt(codec, voice);
-               }
-               for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) {
-                       cap = &codec->capture[nvoice];
-                       if (cap->use)
-                               ymf_cap_interrupt(codec, cap);
-               }
-               spin_unlock(&codec->voice_lock);
-               spin_lock(&codec->reg_lock);
-               ymfpci_writel(codec, YDSXGR_STATUS, 0x80000000);
-               mode = ymfpci_readl(codec, YDSXGR_MODE) | 2;
-               ymfpci_writel(codec, YDSXGR_MODE, mode);
-               spin_unlock(&codec->reg_lock);
-       }
-
-       status = ymfpci_readl(codec, YDSXGR_INTFLAG);
-       if (status & 1) {
-               /* timer handler */
-               ymfpci_writel(codec, YDSXGR_INTFLAG, ~0);
-       }
-       return IRQ_HANDLED;
-}
-
-static void ymf_pcm_free_substream(struct ymf_pcm *ypcm)
-{
-       unsigned long flags;
-       struct ymf_unit *unit;
-
-       unit = ypcm->state->unit;
-
-       if (ypcm->type == PLAYBACK_VOICE) {
-               spin_lock_irqsave(&unit->voice_lock, flags);
-               if (ypcm->voices[1])
-                       ymfpci_voice_free(unit, ypcm->voices[1]);
-               if (ypcm->voices[0])
-                       ymfpci_voice_free(unit, ypcm->voices[0]);
-               spin_unlock_irqrestore(&unit->voice_lock, flags);
-       } else {
-               if (ypcm->capture_bank_number != -1) {
-                       unit->capture[ypcm->capture_bank_number].use = 0;
-                       ypcm->capture_bank_number = -1;
-                       ymfpci_hw_stop(unit);
-               }
-       }
-}
-
-static struct ymf_state *ymf_state_alloc(ymfpci_t *unit)
-{
-       struct ymf_pcm *ypcm;
-       struct ymf_state *state;
-
-       if ((state = kmalloc(sizeof(struct ymf_state), GFP_KERNEL)) == NULL) {
-               goto out0;
-       }
-       memset(state, 0, sizeof(struct ymf_state));
-
-       ypcm = &state->wpcm;
-       ypcm->state = state;
-       ypcm->type = PLAYBACK_VOICE;
-       ypcm->capture_bank_number = -1;
-       init_waitqueue_head(&ypcm->dmabuf.wait);
-
-       ypcm = &state->rpcm;
-       ypcm->state = state;
-       ypcm->type = CAPTURE_AC97;
-       ypcm->capture_bank_number = -1;
-       init_waitqueue_head(&ypcm->dmabuf.wait);
-
-       state->unit = unit;
-
-       state->format.format = AFMT_U8;
-       state->format.rate = 8000;
-       state->format.voices = 1;
-       ymf_pcm_update_shift(&state->format);
-
-       return state;
-
-out0:
-       return NULL;
-}
-
-/* AES/IEC958 channel status bits */
-#define SND_PCM_AES0_PROFESSIONAL      (1<<0)  /* 0 = consumer, 1 = professional */
-#define SND_PCM_AES0_NONAUDIO          (1<<1)  /* 0 = audio, 1 = non-audio */
-#define SND_PCM_AES0_PRO_EMPHASIS      (7<<2)  /* mask - emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_NOTID        (0<<2)  /* emphasis not indicated */
-#define SND_PCM_AES0_PRO_EMPHASIS_NONE (1<<2)  /* none emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_5015 (3<<2)  /* 50/15us emphasis */
-#define SND_PCM_AES0_PRO_EMPHASIS_CCITT        (7<<2)  /* CCITT J.17 emphasis */
-#define SND_PCM_AES0_PRO_FREQ_UNLOCKED (1<<5)  /* source sample frequency: 0 = locked, 1 = unlocked */
-#define SND_PCM_AES0_PRO_FS            (3<<6)  /* mask - sample frequency */
-#define SND_PCM_AES0_PRO_FS_NOTID      (0<<6)  /* fs not indicated */
-#define SND_PCM_AES0_PRO_FS_44100      (1<<6)  /* 44.1kHz */
-#define SND_PCM_AES0_PRO_FS_48000      (2<<6)  /* 48kHz */
-#define SND_PCM_AES0_PRO_FS_32000      (3<<6)  /* 32kHz */
-#define SND_PCM_AES0_CON_NOT_COPYRIGHT (1<<2)  /* 0 = copyright, 1 = not copyright */
-#define SND_PCM_AES0_CON_EMPHASIS      (7<<3)  /* mask - emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_NONE (0<<3)  /* none emphasis */
-#define SND_PCM_AES0_CON_EMPHASIS_5015 (1<<3)  /* 50/15us emphasis */
-#define SND_PCM_AES0_CON_MODE          (3<<6)  /* mask - mode */
-#define SND_PCM_AES1_PRO_MODE          (15<<0) /* mask - channel mode */
-#define SND_PCM_AES1_PRO_MODE_NOTID    (0<<0)  /* not indicated */
-#define SND_PCM_AES1_PRO_MODE_STEREOPHONIC (2<<0) /* stereophonic - ch A is left */
-#define SND_PCM_AES1_PRO_MODE_SINGLE   (4<<0)  /* single channel */
-#define SND_PCM_AES1_PRO_MODE_TWO      (8<<0)  /* two channels */
-#define SND_PCM_AES1_PRO_MODE_PRIMARY  (12<<0) /* primary/secondary */
-#define SND_PCM_AES1_PRO_MODE_BYTE3    (15<<0) /* vector to byte 3 */
-#define SND_PCM_AES1_PRO_USERBITS      (15<<4) /* mask - user bits */
-#define SND_PCM_AES1_PRO_USERBITS_NOTID        (0<<4)  /* not indicated */
-#define SND_PCM_AES1_PRO_USERBITS_192  (8<<4)  /* 192-bit structure */
-#define SND_PCM_AES1_PRO_USERBITS_UDEF (12<<4) /* user defined application */
-#define SND_PCM_AES1_CON_CATEGORY      0x7f
-#define SND_PCM_AES1_CON_GENERAL       0x00
-#define SND_PCM_AES1_CON_EXPERIMENTAL  0x40
-#define SND_PCM_AES1_CON_SOLIDMEM_MASK 0x0f
-#define SND_PCM_AES1_CON_SOLIDMEM_ID   0x08
-#define SND_PCM_AES1_CON_BROADCAST1_MASK 0x07
-#define SND_PCM_AES1_CON_BROADCAST1_ID 0x04
-#define SND_PCM_AES1_CON_DIGDIGCONV_MASK 0x07
-#define SND_PCM_AES1_CON_DIGDIGCONV_ID 0x02
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_MASK 0x1f
-#define SND_PCM_AES1_CON_ADC_COPYRIGHT_ID 0x06
-#define SND_PCM_AES1_CON_ADC_MASK      0x1f
-#define SND_PCM_AES1_CON_ADC_ID                0x16
-#define SND_PCM_AES1_CON_BROADCAST2_MASK 0x0f
-#define SND_PCM_AES1_CON_BROADCAST2_ID 0x0e
-#define SND_PCM_AES1_CON_LASEROPT_MASK 0x07
-#define SND_PCM_AES1_CON_LASEROPT_ID   0x01
-#define SND_PCM_AES1_CON_MUSICAL_MASK  0x07
-#define SND_PCM_AES1_CON_MUSICAL_ID    0x05
-#define SND_PCM_AES1_CON_MAGNETIC_MASK 0x07
-#define SND_PCM_AES1_CON_MAGNETIC_ID   0x03
-#define SND_PCM_AES1_CON_IEC908_CD     (SND_PCM_AES1_CON_LASEROPT_ID|0x00)
-#define SND_PCM_AES1_CON_NON_IEC908_CD (SND_PCM_AES1_CON_LASEROPT_ID|0x08)
-#define SND_PCM_AES1_CON_PCM_CODER     (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x00)
-#define SND_PCM_AES1_CON_SAMPLER       (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x20)
-#define SND_PCM_AES1_CON_MIXER         (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x10)
-#define SND_PCM_AES1_CON_RATE_CONVERTER        (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x18)
-#define SND_PCM_AES1_CON_SYNTHESIZER   (SND_PCM_AES1_CON_MUSICAL_ID|0x00)
-#define SND_PCM_AES1_CON_MICROPHONE    (SND_PCM_AES1_CON_MUSICAL_ID|0x08)
-#define SND_PCM_AES1_CON_DAT           (SND_PCM_AES1_CON_MAGNETIC_ID|0x00)
-#define SND_PCM_AES1_CON_VCR           (SND_PCM_AES1_CON_MAGNETIC_ID|0x08)
-#define SND_PCM_AES1_CON_ORIGINAL      (1<<7)  /* this bits depends on the category code */
-#define SND_PCM_AES2_PRO_SBITS         (7<<0)  /* mask - sample bits */
-#define SND_PCM_AES2_PRO_SBITS_20      (2<<0)  /* 20-bit - coordination */
-#define SND_PCM_AES2_PRO_SBITS_24      (4<<0)  /* 24-bit - main audio */
-#define SND_PCM_AES2_PRO_SBITS_UDEF    (6<<0)  /* user defined application */
-#define SND_PCM_AES2_PRO_WORDLEN       (7<<3)  /* mask - source word length */
-#define SND_PCM_AES2_PRO_WORDLEN_NOTID (0<<3)  /* not indicated */
-#define SND_PCM_AES2_PRO_WORDLEN_22_18 (2<<3)  /* 22-bit or 18-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_23_19 (4<<3)  /* 23-bit or 19-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_24_20 (5<<3)  /* 24-bit or 20-bit */
-#define SND_PCM_AES2_PRO_WORDLEN_20_16 (6<<3)  /* 20-bit or 16-bit */
-#define SND_PCM_AES2_CON_SOURCE                (15<<0) /* mask - source number */
-#define SND_PCM_AES2_CON_SOURCE_UNSPEC (0<<0)  /* unspecified */
-#define SND_PCM_AES2_CON_CHANNEL       (15<<4) /* mask - channel number */
-#define SND_PCM_AES2_CON_CHANNEL_UNSPEC        (0<<4)  /* unspecified */
-#define SND_PCM_AES3_CON_FS            (15<<0) /* mask - sample frequency */
-#define SND_PCM_AES3_CON_FS_44100      (0<<0)  /* 44.1kHz */
-#define SND_PCM_AES3_CON_FS_48000      (2<<0)  /* 48kHz */
-#define SND_PCM_AES3_CON_FS_32000      (3<<0)  /* 32kHz */
-#define SND_PCM_AES3_CON_CLOCK         (3<<4)  /* mask - clock accuracy */
-#define SND_PCM_AES3_CON_CLOCK_1000PPM (0<<4)  /* 1000 ppm */
-#define SND_PCM_AES3_CON_CLOCK_50PPM   (1<<4)  /* 50 ppm */
-#define SND_PCM_AES3_CON_CLOCK_VARIABLE        (2<<4)  /* variable pitch */
-
-/*
- * User interface
- */
-
-/*
- * in this loop, dmabuf.count signifies the amount of data that is
- * waiting to be copied to the user's buffer.  it is filled by the dma
- * machine and drained by this loop.
- */
-static ssize_t
-ymf_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf;
-       struct ymf_unit *unit = state->unit;
-       DECLARE_WAITQUEUE(waita, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;                        /* This many to go in this revolution */
-
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
-               return ret;
-       ret = 0;
-
-       add_wait_queue(&dmabuf->wait, &waita);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (count > 0) {
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               swptr = dmabuf->swptr;
-               cnt = dmabuf->dmasize - swptr;
-               if (dmabuf->count < cnt)
-                       cnt = dmabuf->count;
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       unsigned long tmo;
-                       /* buffer is empty, start the dma machine and wait for data to be
-                          recorded */
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       if (!state->rpcm.running) {
-                               ymf_capture_trigger(state->unit, &state->rpcm, 1);
-                       }
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       /* This isnt strictly right for the 810  but it'll do */
-                       tmo = (dmabuf->dmasize * HZ) / (state->format.rate * 2);
-                       tmo >>= state->format.shift;
-                       /* There are two situations when sleep_on_timeout returns, one is when
-                          the interrupt is serviced correctly and the process is waked up by
-                          ISR ON TIME. Another is when timeout is expired, which means that
-                          either interrupt is NOT serviced correctly (pending interrupt) or it
-                          is TOO LATE for the process to be scheduled to run (scheduler latency)
-                          which results in a (potential) buffer overrun. And worse, there is
-                          NOTHING we can do to prevent it. */
-                       tmo = schedule_timeout(tmo);
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (tmo == 0 && dmabuf->count == 0) {
-                               printk(KERN_ERR "ymfpci%d: recording schedule timeout, "
-                                   "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
-                                   state->unit->dev_audio,
-                                   dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
-                                   dmabuf->hwptr, dmabuf->swptr);
-                       }
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-
-               if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       break;
-               }
-
-               swptr = (swptr + cnt) % dmabuf->dmasize;
-
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       continue;
-               }
-
-               dmabuf->swptr = swptr;
-               dmabuf->count -= cnt;
-               // spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-               // spin_lock_irqsave(&unit->reg_lock, flags);
-               if (!state->rpcm.running) {
-                       ymf_capture_trigger(unit, &state->rpcm, 1);
-               }
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-       }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-
-       return ret;
-}
-
-static ssize_t
-ymf_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-       struct ymf_unit *unit = state->unit;
-       DECLARE_WAITQUEUE(waita, current);
-       ssize_t ret;
-       unsigned long flags;
-       unsigned int swptr;
-       int cnt;                        /* This many to go in this revolution */
-       int redzone;
-       int delay;
-
-       YMFDBGW("ymf_write: count %d\n", count);
-
-       if (dmabuf->mapped)
-               return -ENXIO;
-       if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
-               return ret;
-       ret = 0;
-
-       /*
-        * Alan's cs46xx works without a red zone - marvel of ingenuity.
-        * We are not so brilliant... Red zone does two things:
-        *  1. allows for safe start after a pause as we have no way
-        *     to know what the actual, relentlessly advancing, hwptr is.
-        *  2. makes computations in ymf_pcm_interrupt simpler.
-        */
-       redzone = ymf_calc_lend(state->format.rate) << state->format.shift;
-       redzone *= 3;   /* 2 redzone + 1 possible uncertainty reserve. */
-
-       add_wait_queue(&dmabuf->wait, &waita);
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (count > 0) {
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       continue;
-               }
-               if (dmabuf->count < 0) {
-                       printk(KERN_ERR
-                          "ymf_write: count %d, was legal in cs46xx\n",
-                           dmabuf->count);
-                       dmabuf->count = 0;
-               }
-               if (dmabuf->count == 0) {
-                       swptr = dmabuf->hwptr;
-                       if (state->wpcm.running) {
-                               /*
-                                * Add uncertainty reserve.
-                                */
-                               cnt = ymf_calc_lend(state->format.rate);
-                               cnt <<= state->format.shift;
-                               if ((swptr += cnt) >= dmabuf->dmasize) {
-                                       swptr -= dmabuf->dmasize;
-                               }
-                       }
-                       dmabuf->swptr = swptr;
-               } else {
-                       /*
-                        * XXX This is not right if dmabuf->count is small -
-                        * about 2*x frame size or less. We cannot count on
-                        * on appending and not causing an artefact.
-                        * Should use a variation of the count==0 case above.
-                        */
-                       swptr = dmabuf->swptr;
-               }
-               cnt = dmabuf->dmasize - swptr;
-               if (dmabuf->count + cnt > dmabuf->dmasize - redzone)
-                       cnt = (dmabuf->dmasize - redzone) - dmabuf->count;
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               if (cnt > count)
-                       cnt = count;
-               if (cnt <= 0) {
-                       YMFDBGW("ymf_write: full, count %d swptr %d\n",
-                          dmabuf->count, dmabuf->swptr);
-                       /*
-                        * buffer is full, start the dma machine and
-                        * wait for data to be played
-                        */
-                       spin_lock_irqsave(&unit->reg_lock, flags);
-                       if (!state->wpcm.running) {
-                               ymf_playback_trigger(unit, &state->wpcm, 1);
-                       }
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       if (file->f_flags & O_NONBLOCK) {
-                               if (!ret) ret = -EAGAIN;
-                               break;
-                       }
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       if (signal_pending(current)) {
-                               if (!ret) ret = -ERESTARTSYS;
-                               break;
-                       }
-                       continue;
-               }
-               if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
-                       if (!ret) ret = -EFAULT;
-                       break;
-               }
-
-               if ((swptr += cnt) >= dmabuf->dmasize) {
-                       swptr -= dmabuf->dmasize;
-               }
-
-               spin_lock_irqsave(&unit->reg_lock, flags);
-               if (unit->suspended) {
-                       spin_unlock_irqrestore(&unit->reg_lock, flags);
-                       continue;
-               }
-               dmabuf->swptr = swptr;
-               dmabuf->count += cnt;
-
-               /*
-                * Start here is a bad idea - may cause startup click
-                * in /bin/play when dmabuf is not full yet.
-                * However, some broken applications do not make
-                * any use of SNDCTL_DSP_SYNC (Doom is the worst).
-                * One frame is about 5.3ms, Doom write size is 46ms.
-                */
-               delay = state->format.rate / 20;        /* 50ms */
-               delay <<= state->format.shift;
-               if (dmabuf->count >= delay && !state->wpcm.running) {
-                       ymf_playback_trigger(unit, &state->wpcm, 1);
-               }
-
-               spin_unlock_irqrestore(&unit->reg_lock, flags);
-
-               count -= cnt;
-               buffer += cnt;
-               ret += cnt;
-       }
-
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&dmabuf->wait, &waita);
-
-       YMFDBGW("ymf_write: ret %d dmabuf.count %d\n", ret, dmabuf->count);
-       return ret;
-}
-
-static unsigned int ymf_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf;
-       int redzone;
-       unsigned long flags;
-       unsigned int mask = 0;
-
-       if (file->f_mode & FMODE_WRITE)
-               poll_wait(file, &state->wpcm.dmabuf.wait, wait);
-       if (file->f_mode & FMODE_READ)
-               poll_wait(file, &state->rpcm.dmabuf.wait, wait);
-
-       spin_lock_irqsave(&state->unit->reg_lock, flags);
-       if (file->f_mode & FMODE_READ) {
-               dmabuf = &state->rpcm.dmabuf;
-               if (dmabuf->count >= (signed)dmabuf->fragsize)
-                       mask |= POLLIN | POLLRDNORM;
-       }
-       if (file->f_mode & FMODE_WRITE) {
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-
-               dmabuf = &state->wpcm.dmabuf;
-               if (dmabuf->mapped) {
-                       if (dmabuf->count >= (signed)dmabuf->fragsize)
-                               mask |= POLLOUT | POLLWRNORM;
-               } else {
-                       /*
-                        * Don't select unless a full fragment is available.
-                        * Otherwise artsd does GETOSPACE, sees 0, and loops.
-                        */
-                       if (dmabuf->count + redzone + dmabuf->fragsize
-                            <= dmabuf->dmasize)
-                               mask |= POLLOUT | POLLWRNORM;
-               }
-       }
-       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-
-       return mask;
-}
-
-static int ymf_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf;
-       int ret;
-       unsigned long size;
-
-       if (vma->vm_flags & VM_WRITE) {
-               if ((ret = prog_dmabuf(state, 0)) != 0)
-                       return ret;
-       } else if (vma->vm_flags & VM_READ) {
-               if ((ret = prog_dmabuf(state, 1)) != 0)
-                       return ret;
-       } else 
-               return -EINVAL;
-
-       if (vma->vm_pgoff != 0)
-               return -EINVAL;
-       size = vma->vm_end - vma->vm_start;
-       if (size > (PAGE_SIZE << dmabuf->buforder))
-               return -EINVAL;
-       if (remap_pfn_range(vma, vma->vm_start,
-                            virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT,
-                            size, vma->vm_page_prot))
-               return -EAGAIN;
-       dmabuf->mapped = 1;
-
-/* P3 */ printk(KERN_INFO "ymfpci: using memory mapped sound, untested!\n");
-       return 0;
-}
-
-static int ymf_ioctl(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       struct ymf_dmabuf *dmabuf;
-       unsigned long flags;
-       audio_buf_info abinfo;
-       count_info cinfo;
-       int redzone;
-       int val;
-       void __user *argp = (void __user *)arg;
-       int __user *p = argp;
-
-       switch (cmd) {
-       case OSS_GETVERSION:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETVER) arg 0x%lx\n", cmd, arg);
-               return put_user(SOUND_VERSION, p);
-
-       case SNDCTL_DSP_RESET:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       ymf_wait_dac(state);
-                       dmabuf = &state->wpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       dmabuf->swptr = dmabuf->hwptr;
-                       dmabuf->count = dmabuf->total_bytes = 0;
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       ymf_stop_adc(state);
-                       dmabuf = &state->rpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       dmabuf->swptr = dmabuf->hwptr;
-                       dmabuf->count = dmabuf->total_bytes = 0;
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               return 0;
-
-       case SNDCTL_DSP_SYNC:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SYNC)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       dmabuf = &state->wpcm.dmabuf;
-                       if (file->f_flags & O_NONBLOCK) {
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               if (dmabuf->count != 0 && !state->wpcm.running) {
-                                       ymf_start_dac(state);
-                               }
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       } else {
-                               ymf_wait_dac(state);
-                       }
-               }
-               /* XXX What does this do for reading? dmabuf->count=0; ? */
-               return 0;
-
-       case SNDCTL_DSP_SPEED: /* set smaple rate */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val);
-               if (val >= 8000 && val <= 48000) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               dmabuf = &state->wpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.rate = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               dmabuf = &state->rpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.rate = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-               }
-               return put_user(state->format.rate, p);
-
-       /*
-        * OSS manual does not mention SNDCTL_DSP_STEREO at all.
-        * All channels are mono and if you want stereo, you
-        * play into two channels with SNDCTL_DSP_CHANNELS.
-        * However, mpg123 calls it. I wonder, why Michael Hipp used it.
-        */
-       case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(STEREO) st %d\n", cmd, val);
-               if (file->f_mode & FMODE_WRITE) {
-                       ymf_wait_dac(state); 
-                       dmabuf = &state->wpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       state->format.voices = val ? 2 : 1;
-                       ymf_pcm_update_shift(&state->format);
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       ymf_stop_adc(state);
-                       dmabuf = &state->rpcm.dmabuf;
-                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                       dmabuf->ready = 0;
-                       state->format.voices = val ? 2 : 1;
-                       ymf_pcm_update_shift(&state->format);
-                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               }
-               return 0;
-
-       case SNDCTL_DSP_GETBLKSIZE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETBLK)\n", cmd);
-               if (file->f_mode & FMODE_WRITE) {
-                       if ((val = prog_dmabuf(state, 0)))
-                               return val;
-                       val = state->wpcm.dmabuf.fragsize;
-                       YMFDBGX("ymf_ioctl: GETBLK w %d\n", val);
-                       return put_user(val, p);
-               }
-               if (file->f_mode & FMODE_READ) {
-                       if ((val = prog_dmabuf(state, 1)))
-                               return val;
-                       val = state->rpcm.dmabuf.fragsize;
-                       YMFDBGX("ymf_ioctl: GETBLK r %d\n", val);
-                       return put_user(val, p);
-               }
-               return -EINVAL;
-
-       case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETFMTS)\n", cmd);
-               return put_user(AFMT_S16_LE|AFMT_U8, p);
-
-       case SNDCTL_DSP_SETFMT: /* Select sample format */
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETFMT) fmt %d\n", cmd, val);
-               if (val == AFMT_S16_LE || val == AFMT_U8) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               dmabuf = &state->wpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.format = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               dmabuf = &state->rpcm.dmabuf;
-                               spin_lock_irqsave(&state->unit->reg_lock, flags);
-                               dmabuf->ready = 0;
-                               state->format.format = val;
-                               ymf_pcm_update_shift(&state->format);
-                               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                       }
-               }
-               return put_user(state->format.format, p);
-
-       case SNDCTL_DSP_CHANNELS:
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val);
-               if (val != 0) {
-                       if (file->f_mode & FMODE_WRITE) {
-                               ymf_wait_dac(state);
-                               if (val == 1 || val == 2) {
-                                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                                       dmabuf = &state->wpcm.dmabuf;
-                                       dmabuf->ready = 0;
-                                       state->format.voices = val;
-                                       ymf_pcm_update_shift(&state->format);
-                                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                               }
-                       }
-                       if (file->f_mode & FMODE_READ) {
-                               ymf_stop_adc(state);
-                               if (val == 1 || val == 2) {
-                                       spin_lock_irqsave(&state->unit->reg_lock, flags);
-                                       dmabuf = &state->rpcm.dmabuf;
-                                       dmabuf->ready = 0;
-                                       state->format.voices = val;
-                                       ymf_pcm_update_shift(&state->format);
-                                       spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-                               }
-                       }
-               }
-               return put_user(state->format.voices, p);
-
-       case SNDCTL_DSP_POST:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd);
-               /*
-                * Quoting OSS PG:
-                *    The ioctl SNDCTL_DSP_POST is a lightweight version of
-                *    SNDCTL_DSP_SYNC. It just tells to the driver that there
-                *    is likely to be a pause in the output. This makes it
-                *    possible for the device to handle the pause more
-                *    intelligently. This ioctl doesn't block the application.
-                *
-                * The paragraph above is a clumsy way to say "flush ioctl".
-                * This ioctl is used by mpg123.
-                */
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               if (state->wpcm.dmabuf.count != 0 && !state->wpcm.running) {
-                       ymf_start_dac(state);
-               }
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return 0;
-
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (get_user(val, p))
-                       return -EFAULT;
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n",
-                   cmd,
-                   (val >> 16) & 0xFFFF, val & 0xFFFF,
-                   (val >> 16) & 0xFFFF, val & 0xFFFF);
-               dmabuf = &state->wpcm.dmabuf;
-               dmabuf->ossfragshift = val & 0xffff;
-               dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
-               if (dmabuf->ossfragshift < 4)
-                       dmabuf->ossfragshift = 4;
-               if (dmabuf->ossfragshift > 15)
-                       dmabuf->ossfragshift = 15;
-               return 0;
-
-       case SNDCTL_DSP_GETOSPACE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETOSPACE)\n", cmd);
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               dmabuf = &state->wpcm.dmabuf;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0)
-                       return val;
-               redzone = ymf_calc_lend(state->format.rate);
-               redzone <<= state->format.shift;
-               redzone *= 3;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               abinfo.fragsize = dmabuf->fragsize;
-               abinfo.bytes = dmabuf->dmasize - dmabuf->count - redzone;
-               abinfo.fragstotal = dmabuf->numfrag;
-               abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETISPACE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd);
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               dmabuf = &state->rpcm.dmabuf;
-               if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0)
-                       return val;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               abinfo.fragsize = dmabuf->fragsize;
-               abinfo.bytes = dmabuf->count;
-               abinfo.fragstotal = dmabuf->numfrag;
-               abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_NONBLOCK:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd);
-               file->f_flags |= O_NONBLOCK;
-               return 0;
-
-       case SNDCTL_DSP_GETCAPS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETCAPS)\n", cmd);
-               /* return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
-                           p); */
-               return put_user(0, p);
-
-       case SNDCTL_DSP_GETIPTR:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd);
-               if (!(file->f_mode & FMODE_READ))
-                       return -EINVAL;
-               dmabuf = &state->rpcm.dmabuf;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-               cinfo.ptr = dmabuf->hwptr;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n",
-                   cinfo.ptr, cinfo.bytes);
-               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_GETOPTR:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd);
-               if (!(file->f_mode & FMODE_WRITE))
-                       return -EINVAL;
-               dmabuf = &state->wpcm.dmabuf;
-               spin_lock_irqsave(&state->unit->reg_lock, flags);
-               cinfo.bytes = dmabuf->total_bytes;
-               cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
-               cinfo.ptr = dmabuf->hwptr;
-               spin_unlock_irqrestore(&state->unit->reg_lock, flags);
-               YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n",
-                   cinfo.ptr, cinfo.bytes);
-               return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
-
-       case SNDCTL_DSP_SETDUPLEX:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd);
-               return 0;               /* Always duplex */
-
-       case SOUND_PCM_READ_RATE:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd);
-               return put_user(state->format.rate, p);
-
-       case SOUND_PCM_READ_CHANNELS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_CH)\n", cmd);
-               return put_user(state->format.voices, p);
-
-       case SOUND_PCM_READ_BITS:
-               YMFDBGX("ymf_ioctl: cmd 0x%x(READ_BITS)\n", cmd);
-               return put_user(AFMT_S16_LE, p);
-
-       case SNDCTL_DSP_MAPINBUF:
-       case SNDCTL_DSP_MAPOUTBUF:
-       case SNDCTL_DSP_SETSYNCRO:
-       case SOUND_PCM_WRITE_FILTER:
-       case SOUND_PCM_READ_FILTER:
-               YMFDBGX("ymf_ioctl: cmd 0x%x unsupported\n", cmd);
-               return -ENOTTY;
-
-       default:
-               /*
-                * Some programs mix up audio devices and ioctls
-                * or perhaps they expect "universal" ioctls,
-                * for instance we get SNDCTL_TMR_CONTINUE here.
-                * (mpg123 -g 100 ends here too - to be fixed.)
-                */
-               YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd);
-               break;
-       }
-       return -ENOTTY;
-}
-
-/*
- * open(2)
- * We use upper part of the minor to distinguish between soundcards.
- * Channels are opened with a clone open.
- */
-static int ymf_open(struct inode *inode, struct file *file)
-{
-       struct list_head *list;
-       ymfpci_t *unit = NULL;
-       int minor;
-       struct ymf_state *state;
-       int err;
-
-       minor = iminor(inode);
-       if ((minor & 0x0F) == 3) {      /* /dev/dspN */
-               ;
-       } else {
-               return -ENXIO;
-       }
-
-       unit = NULL;    /* gcc warns */
-       spin_lock(&ymf_devs_lock);
-       list_for_each(list, &ymf_devs) {
-               unit = list_entry(list, ymfpci_t, ymf_devs);
-               if (((unit->dev_audio ^ minor) & ~0x0F) == 0)
-                       break;
-       }
-       spin_unlock(&ymf_devs_lock);
-       if (unit == NULL)
-               return -ENODEV;
-
-       mutex_lock(&unit->open_mutex);
-
-       if ((state = ymf_state_alloc(unit)) == NULL) {
-               mutex_unlock(&unit->open_mutex);
-               return -ENOMEM;
-       }
-       list_add_tail(&state->chain, &unit->states);
-
-       file->private_data = state;
-
-       /*
-        * ymf_read and ymf_write that we borrowed from cs46xx
-        * allocate buffers with prog_dmabuf(). We call prog_dmabuf
-        * here so that in case of DMA memory exhaustion open
-        * fails rather than write.
-        *
-        * XXX prog_dmabuf allocates voice. Should allocate explicitly, above.
-        */
-       if (file->f_mode & FMODE_WRITE) {
-               if (!state->wpcm.dmabuf.ready) {
-                       if ((err = prog_dmabuf(state, 0)) != 0) {
-                               goto out_nodma;
-                       }
-               }
-       }
-       if (file->f_mode & FMODE_READ) {
-               if (!state->rpcm.dmabuf.ready) {
-                       if ((err = prog_dmabuf(state, 1)) != 0) {
-                               goto out_nodma;
-                       }
-               }
-       }
-
-#if 0 /* test if interrupts work */
-       ymfpci_writew(unit, YDSXGR_TIMERCOUNT, 0xfffe); /* ~ 680ms */
-       ymfpci_writeb(unit, YDSXGR_TIMERCTRL,
-           (YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN));
-#endif
-       mutex_unlock(&unit->open_mutex);
-
-       return nonseekable_open(inode, file);
-
-out_nodma:
-       /*
-        * XXX Broken custom: "goto out_xxx" in other place is
-        * a nestable exception, but here it is not nestable due to semaphore.
-        * XXX Doubtful technique of self-describing objects....
-        */
-       dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-       dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-       ymf_pcm_free_substream(&state->wpcm);
-       ymf_pcm_free_substream(&state->rpcm);
-
-       list_del(&state->chain);
-       kfree(state);
-
-       mutex_unlock(&unit->open_mutex);
-       return err;
-}
-
-static int ymf_release(struct inode *inode, struct file *file)
-{
-       struct ymf_state *state = (struct ymf_state *)file->private_data;
-       ymfpci_t *unit = state->unit;
-
-#if 0 /* test if interrupts work */
-       ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0);
-#endif
-
-       mutex_lock(&unit->open_mutex);
-
-       /*
-        * XXX Solve the case of O_NONBLOCK close - don't deallocate here.
-        * Deallocate when unloading the driver and we can wait.
-        */
-       ymf_wait_dac(state);
-       ymf_stop_adc(state);            /* fortunately, it's immediate */
-       dealloc_dmabuf(unit, &state->wpcm.dmabuf);
-       dealloc_dmabuf(unit, &state->rpcm.dmabuf);
-       ymf_pcm_free_substream(&state->wpcm);
-       ymf_pcm_free_substream(&state->rpcm);
-
-       list_del(&state->chain);
-       file->private_data = NULL;      /* Can you tell I programmed Solaris */
-       kfree(state);
-
-       mutex_unlock(&unit->open_mutex);
-
-       return 0;
-}
-
-/*
- * Mixer operations are based on cs46xx.
- */
-static int ymf_open_mixdev(struct inode *inode, struct file *file)
-{
-       int minor = iminor(inode);
-       struct list_head *list;
-       ymfpci_t *unit;
-       int i;
-
-       spin_lock(&ymf_devs_lock);
-       list_for_each(list, &ymf_devs) {
-               unit = list_entry(list, ymfpci_t, ymf_devs);
-               for (i = 0; i < NR_AC97; i++) {
-                       if (unit->ac97_codec[i] != NULL &&
-                           unit->ac97_codec[i]->dev_mixer == minor) {
-                               spin_unlock(&ymf_devs_lock);
-                               goto match;
-                       }
-               }
-       }
-       spin_unlock(&ymf_devs_lock);
-       return -ENODEV;
-
- match:
-       file->private_data = unit->ac97_codec[i];
-
-       return nonseekable_open(inode, file);
-}
-
-static int ymf_ioctl_mixdev(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
-       struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
-
-       return codec->mixer_ioctl(codec, cmd, arg);
-}
-
-static int ymf_release_mixdev(struct inode *inode, struct file *file)
-{
-       return 0;
-}
-
-static /*const*/ struct file_operations ymf_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = ymf_read,
-       .write          = ymf_write,
-       .poll           = ymf_poll,
-       .ioctl          = ymf_ioctl,
-       .mmap           = ymf_mmap,
-       .open           = ymf_open,
-       .release        = ymf_release,
-};
-
-static /*const*/ struct file_operations ymf_mixer_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .ioctl          = ymf_ioctl_mixdev,
-       .open           = ymf_open_mixdev,
-       .release        = ymf_release_mixdev,
-};
-
-/*
- */
-
-static int ymf_suspend(struct pci_dev *pcidev, pm_message_t unused)
-{
-       struct ymf_unit *unit = pci_get_drvdata(pcidev);
-       unsigned long flags;
-       struct ymf_dmabuf *dmabuf;
-       struct list_head *p;
-       struct ymf_state *state;
-       struct ac97_codec *codec;
-       int i;
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-
-       unit->suspended = 1;
-
-       for (i = 0; i < NR_AC97; i++) {
-               if ((codec = unit->ac97_codec[i]) != NULL)
-                       ac97_save_state(codec);
-       }
-
-       list_for_each(p, &unit->states) {
-               state = list_entry(p, struct ymf_state, chain);
-
-               dmabuf = &state->wpcm.dmabuf;
-               dmabuf->hwptr = dmabuf->swptr = 0;
-               dmabuf->total_bytes = 0;
-               dmabuf->count = 0;
-
-               dmabuf = &state->rpcm.dmabuf;
-               dmabuf->hwptr = dmabuf->swptr = 0;
-               dmabuf->total_bytes = 0;
-               dmabuf->count = 0;
-       }
-
-       ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0);
-       ymfpci_disable_dsp(unit);
-
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-       
-       return 0;
-}
-
-static int ymf_resume(struct pci_dev *pcidev)
-{
-       struct ymf_unit *unit = pci_get_drvdata(pcidev);
-       unsigned long flags;
-       struct list_head *p;
-       struct ymf_state *state;
-       struct ac97_codec *codec;
-       int i;
-
-       ymfpci_aclink_reset(unit->pci);
-       ymfpci_codec_ready(unit, 0, 1);         /* prints diag if not ready. */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       /* XXX At this time the legacy registers are probably deprogrammed. */
-#endif
-
-       ymfpci_download_image(unit);
-
-       ymf_memload(unit);
-
-       spin_lock_irqsave(&unit->reg_lock, flags);
-
-       if (unit->start_count) {
-               ymfpci_writel(unit, YDSXGR_MODE, 3);
-               unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1;
-       }
-
-       for (i = 0; i < NR_AC97; i++) {
-               if ((codec = unit->ac97_codec[i]) != NULL)
-                       ac97_restore_state(codec);
-       }
-
-       unit->suspended = 0;
-       list_for_each(p, &unit->states) {
-               state = list_entry(p, struct ymf_state, chain);
-               wake_up(&state->wpcm.dmabuf.wait);
-               wake_up(&state->rpcm.dmabuf.wait);
-       }
-
-       spin_unlock_irqrestore(&unit->reg_lock, flags);
-       return 0;
-}
-
-/*
- *  initialization routines
- */
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-
-static int ymfpci_setup_legacy(ymfpci_t *unit, struct pci_dev *pcidev)
-{
-       int v;
-       int mpuio = -1, oplio = -1;
-
-       switch (unit->iomidi) {
-       case 0x330:
-               mpuio = 0;
-               break;
-       case 0x300:
-               mpuio = 1;
-               break;
-       case 0x332:
-               mpuio = 2;
-               break;
-       case 0x334:
-               mpuio = 3;
-               break;
-       default: ;
-       }
-
-       switch (unit->iosynth) {
-       case 0x388:
-               oplio = 0;
-               break;
-       case 0x398:
-               oplio = 1;
-               break;
-       case 0x3a0:
-               oplio = 2;
-               break;
-       case 0x3a8:
-               oplio = 3;
-               break;
-       default: ;
-       }
-
-       if (mpuio >= 0 || oplio >= 0) {
-               /* 0x0020: 1 - 10 bits of I/O address decoded, 0 - 16 bits. */
-               v = 0x001e;
-               pci_write_config_word(pcidev, PCIR_LEGCTRL, v);
-
-               switch (pcidev->device) {
-               case PCI_DEVICE_ID_YAMAHA_724:
-               case PCI_DEVICE_ID_YAMAHA_740:
-               case PCI_DEVICE_ID_YAMAHA_724F:
-               case PCI_DEVICE_ID_YAMAHA_740C:
-                       v = 0x8800;
-                       if (mpuio >= 0) { v |= mpuio<<4; }
-                       if (oplio >= 0) { v |= oplio; }
-                       pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-                       break;
-
-               case PCI_DEVICE_ID_YAMAHA_744:
-               case PCI_DEVICE_ID_YAMAHA_754:
-                       v = 0x8800;
-                       pci_write_config_word(pcidev, PCIR_ELEGCTRL, v);
-                       if (oplio >= 0) {
-                               pci_write_config_word(pcidev, PCIR_OPLADR, unit->iosynth);
-                       }
-                       if (mpuio >= 0) {
-                               pci_write_config_word(pcidev, PCIR_MPUADR, unit->iomidi);
-                       }
-                       break;
-
-               default:
-                       printk(KERN_ERR "ymfpci: Unknown device ID: 0x%x\n",
-                           pcidev->device);
-                       return -EINVAL;
-               }
-       }
-
-       return 0;
-}
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static void ymfpci_aclink_reset(struct pci_dev * pci)
-{
-       u8 cmd;
-
-       /*
-        * In the 744, 754 only 0x01 exists, 0x02 is undefined.
-        * It does not seem to hurt to trip both regardless of revision.
-        */
-       pci_read_config_byte(pci, PCIR_DSXGCTRL, &cmd);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03);
-       pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc);
-
-       pci_write_config_word(pci, PCIR_DSXPWRCTRL1, 0);
-       pci_write_config_word(pci, PCIR_DSXPWRCTRL2, 0);
-}
-
-static void ymfpci_enable_dsp(ymfpci_t *codec)
-{
-       ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000001);
-}
-
-static void ymfpci_disable_dsp(ymfpci_t *codec)
-{
-       u32 val;
-       int timeout = 1000;
-
-       val = ymfpci_readl(codec, YDSXGR_CONFIG);
-       if (val)
-               ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000000);
-       while (timeout-- > 0) {
-               val = ymfpci_readl(codec, YDSXGR_STATUS);
-               if ((val & 0x00000002) == 0)
-                       break;
-       }
-}
-
-#include "ymfpci_image.h"
-
-static void ymfpci_download_image(ymfpci_t *codec)
-{
-       int i, ver_1e;
-       u16 ctrl;
-
-       ymfpci_writel(codec, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
-       ymfpci_disable_dsp(codec);
-       ymfpci_writel(codec, YDSXGR_MODE, 0x00010000);
-       ymfpci_writel(codec, YDSXGR_MODE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_MAPOFREC, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_MAPOFEFFECT, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0x00000000);
-       ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0x00000000);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-
-       /* setup DSP instruction code */
-       for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
-               ymfpci_writel(codec, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]);
-
-       switch (codec->pci->device) {
-       case PCI_DEVICE_ID_YAMAHA_724F:
-       case PCI_DEVICE_ID_YAMAHA_740C:
-       case PCI_DEVICE_ID_YAMAHA_744:
-       case PCI_DEVICE_ID_YAMAHA_754:
-               ver_1e = 1;
-               break;
-       default:
-               ver_1e = 0;
-       }
-
-       if (ver_1e) {
-               /* setup control instruction code */
-               for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-                       ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst1E[i]);
-       } else {
-               for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
-                       ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst[i]);
-       }
-
-       ymfpci_enable_dsp(codec);
-
-       /* 0.02s sounds not too bad, we may do schedule_timeout() later. */
-       mdelay(20); /* seems we need some delay after downloading image.. */
-}
-
-static int ymfpci_memalloc(ymfpci_t *codec)
-{
-       unsigned int playback_ctrl_size;
-       unsigned int bank_size_playback;
-       unsigned int bank_size_capture;
-       unsigned int bank_size_effect;
-       unsigned int size;
-       unsigned int off;
-       char *ptr;
-       dma_addr_t pba;
-       int voice, bank;
-
-       playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES;
-       bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2;
-       bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2;
-       bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2;
-       codec->work_size = YDSXG_DEFAULT_WORK_SIZE;
-
-       size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) +
-           ((bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) +
-           ((bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) +
-           ((bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) +
-           codec->work_size;
-
-       ptr = pci_alloc_consistent(codec->pci, size + 0xff, &pba);
-       if (ptr == NULL)
-               return -ENOMEM;
-       codec->dma_area_va = ptr;
-       codec->dma_area_ba = pba;
-       codec->dma_area_size = size + 0xff;
-
-       off = (unsigned long)ptr & 0xff;
-       if (off) {
-               ptr += 0x100 - off;
-               pba += 0x100 - off;
-       }
-
-       /*
-        * Hardware requires only ptr[playback_ctrl_size] zeroed,
-        * but in our judgement it is a wrong kind of savings, so clear it all.
-        */
-       memset(ptr, 0, size);
-
-       codec->ctrl_playback = (u32 *)ptr;
-       codec->ctrl_playback_ba = pba;
-       codec->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
-       ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-       pba += (playback_ctrl_size + 0x00ff) & ~0x00ff;
-
-       off = 0;
-       for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
-               codec->voices[voice].number = voice;
-               codec->voices[voice].bank =
-                   (ymfpci_playback_bank_t *) (ptr + off);
-               codec->voices[voice].bank_ba = pba + off;
-               off += 2 * bank_size_playback;          /* 2 banks */
-       }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       off = 0;
-       codec->bank_base_capture = pba;
-       for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
-               for (bank = 0; bank < 2; bank++) {
-                       codec->bank_capture[voice][bank] =
-                           (ymfpci_capture_bank_t *) (ptr + off);
-                       off += bank_size_capture;
-               }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       off = 0;
-       codec->bank_base_effect = pba;
-       for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
-               for (bank = 0; bank < 2; bank++) {
-                       codec->bank_effect[voice][bank] =
-                           (ymfpci_effect_bank_t *) (ptr + off);
-                       off += bank_size_effect;
-               }
-       off = (off + 0xff) & ~0xff;
-       ptr += off;
-       pba += off;
-
-       codec->work_base = pba;
-
-       return 0;
-}
-
-static void ymfpci_memfree(ymfpci_t *codec)
-{
-       ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0);
-       ymfpci_writel(codec, YDSXGR_WORKBASE, 0);
-       ymfpci_writel(codec, YDSXGR_WORKSIZE, 0);
-       pci_free_consistent(codec->pci,
-           codec->dma_area_size, codec->dma_area_va, codec->dma_area_ba);
-}
-
-static void ymf_memload(ymfpci_t *unit)
-{
-
-       ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, unit->ctrl_playback_ba);
-       ymfpci_writel(unit, YDSXGR_RECCTRLBASE, unit->bank_base_capture);
-       ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, unit->bank_base_effect);
-       ymfpci_writel(unit, YDSXGR_WORKBASE, unit->work_base);
-       ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2);
-
-       /* S/PDIF output initialization */
-       ymfpci_writew(unit, YDSXGR_SPDIFOUTCTRL, 0);
-       ymfpci_writew(unit, YDSXGR_SPDIFOUTSTATUS,
-               SND_PCM_AES0_CON_EMPHASIS_NONE |
-               (SND_PCM_AES1_CON_ORIGINAL << 8) |
-               (SND_PCM_AES1_CON_PCM_CODER << 8));
-
-       /* S/PDIF input initialization */
-       ymfpci_writew(unit, YDSXGR_SPDIFINCTRL, 0);
-
-       /* move this volume setup to mixer */
-       ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff);
-       ymfpci_writel(unit, YDSXGR_BUF441OUTVOL, 0);
-       ymfpci_writel(unit, YDSXGR_NATIVEADCINVOL, 0x3fff3fff);
-       ymfpci_writel(unit, YDSXGR_NATIVEDACINVOL, 0x3fff3fff);
-}
-
-static int ymf_ac97_init(ymfpci_t *unit, int num_ac97)
-{
-       struct ac97_codec *codec;
-       u16 eid;
-
-       if ((codec = ac97_alloc_codec()) == NULL)
-               return -ENOMEM;
-
-       /* initialize some basic codec information, other fields will be filled
-          in ac97_probe_codec */
-       codec->private_data = unit;
-       codec->id = num_ac97;
-
-       codec->codec_read = ymfpci_codec_read;
-       codec->codec_write = ymfpci_codec_write;
-
-       if (ac97_probe_codec(codec) == 0) {
-               printk(KERN_ERR "ymfpci: ac97_probe_codec failed\n");
-               goto out_kfree;
-       }
-
-       eid = ymfpci_codec_read(codec, AC97_EXTENDED_ID);
-       if (eid==0xFFFF) {
-               printk(KERN_WARNING "ymfpci: no codec attached ?\n");
-               goto out_kfree;
-       }
-
-       unit->ac97_features = eid;
-
-       if ((codec->dev_mixer = register_sound_mixer(&ymf_mixer_fops, -1)) < 0) {
-               printk(KERN_ERR "ymfpci: couldn't register mixer!\n");
-               goto out_kfree;
-       }
-
-       unit->ac97_codec[num_ac97] = codec;
-
-       return 0;
- out_kfree:
-       ac97_release_codec(codec);
-       return -ENODEV;
-}
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-# ifdef MODULE
-static int mpu_io;
-static int synth_io;
-module_param(mpu_io, int, 0);
-module_param(synth_io, int, 0);
-# else
-static int mpu_io     = 0x330;
-static int synth_io   = 0x388;
-# endif
-static int assigned;
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_device_id *ent)
-{
-       u16 ctrl;
-       unsigned long base;
-       ymfpci_t *codec;
-
-       int err;
-
-       if ((err = pci_enable_device(pcidev)) != 0) {
-               printk(KERN_ERR "ymfpci: pci_enable_device failed\n");
-               return err;
-       }
-       base = pci_resource_start(pcidev, 0);
-
-       if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "ymfpci: no core\n");
-               return -ENOMEM;
-       }
-       memset(codec, 0, sizeof(*codec));
-
-       spin_lock_init(&codec->reg_lock);
-       spin_lock_init(&codec->voice_lock);
-       spin_lock_init(&codec->ac97_lock);
-       mutex_init(&codec->open_mutex);
-       INIT_LIST_HEAD(&codec->states);
-       codec->pci = pcidev;
-
-       pci_read_config_byte(pcidev, PCI_REVISION_ID, &codec->rev);
-
-       if (request_mem_region(base, 0x8000, "ymfpci") == NULL) {
-               printk(KERN_ERR "ymfpci: unable to request mem region\n");
-               goto out_free;
-       }
-
-       if ((codec->reg_area_virt = ioremap(base, 0x8000)) == NULL) {
-               printk(KERN_ERR "ymfpci: unable to map registers\n");
-               goto out_release_region;
-       }
-
-       pci_set_master(pcidev);
-
-       printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n",
-           (char *)ent->driver_data, base, pcidev->irq);
-
-       ymfpci_aclink_reset(pcidev);
-       if (ymfpci_codec_ready(codec, 0, 1) < 0)
-               goto out_unmap;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       if (assigned == 0) {
-               codec->iomidi = mpu_io;
-               codec->iosynth = synth_io;
-               if (ymfpci_setup_legacy(codec, pcidev) < 0)
-                       goto out_unmap;
-               assigned = 1;
-       }
-#endif
-
-       ymfpci_download_image(codec);
-
-       if (ymfpci_memalloc(codec) < 0)
-               goto out_disable_dsp;
-       ymf_memload(codec);
-
-       if (request_irq(pcidev->irq, ymf_interrupt, IRQF_SHARED, "ymfpci", codec) != 0) {
-               printk(KERN_ERR "ymfpci: unable to request IRQ %d\n",
-                   pcidev->irq);
-               goto out_memfree;
-       }
-
-       /* register /dev/dsp */
-       if ((codec->dev_audio = register_sound_dsp(&ymf_fops, -1)) < 0) {
-               printk(KERN_ERR "ymfpci: unable to register dsp\n");
-               goto out_free_irq;
-       }
-
-       /*
-        * Poke just the primary for the moment.
-        */
-       if ((err = ymf_ac97_init(codec, 0)) != 0)
-               goto out_unregister_sound_dsp;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       codec->opl3_data.name = "ymfpci";
-       codec->mpu_data.name  = "ymfpci";
-
-       codec->opl3_data.io_base = codec->iosynth;
-       codec->opl3_data.irq     = -1;
-
-       codec->mpu_data.io_base  = codec->iomidi;
-       codec->mpu_data.irq      = -1;  /* May be different from our PCI IRQ. */
-
-       if (codec->iomidi) {
-               if (!probe_uart401(&codec->mpu_data, THIS_MODULE)) {
-                       codec->iomidi = 0;      /* XXX kludge */
-               }
-       }
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-
-       /* put it into driver list */
-       spin_lock(&ymf_devs_lock);
-       list_add_tail(&codec->ymf_devs, &ymf_devs);
-       spin_unlock(&ymf_devs_lock);
-       pci_set_drvdata(pcidev, codec);
-
-       return 0;
-
- out_unregister_sound_dsp:
-       unregister_sound_dsp(codec->dev_audio);
- out_free_irq:
-       free_irq(pcidev->irq, codec);
- out_memfree:
-       ymfpci_memfree(codec);
- out_disable_dsp:
-       ymfpci_disable_dsp(codec);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-       ymfpci_writel(codec, YDSXGR_STATUS, ~0);
- out_unmap:
-       iounmap(codec->reg_area_virt);
- out_release_region:
-       release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
- out_free:
-       if (codec->ac97_codec[0])
-               ac97_release_codec(codec->ac97_codec[0]);
-       return -ENODEV;
-}
-
-static void __devexit ymf_remove_one(struct pci_dev *pcidev)
-{
-       __u16 ctrl;
-       ymfpci_t *codec = pci_get_drvdata(pcidev);
-
-       /* remove from list of devices */
-       spin_lock(&ymf_devs_lock);
-       list_del(&codec->ymf_devs);
-       spin_unlock(&ymf_devs_lock);
-
-       unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer);
-       ac97_release_codec(codec->ac97_codec[0]);
-       unregister_sound_dsp(codec->dev_audio);
-       free_irq(pcidev->irq, codec);
-       ymfpci_memfree(codec);
-       ymfpci_writel(codec, YDSXGR_STATUS, ~0);
-       ymfpci_disable_dsp(codec);
-       ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL);
-       ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
-       iounmap(codec->reg_area_virt);
-       release_mem_region(pci_resource_start(pcidev, 0), 0x8000);
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       if (codec->iomidi) {
-               unload_uart401(&codec->mpu_data);
-       }
-#endif /* CONFIG_SOUND_YMFPCI_LEGACY */
-}
-
-MODULE_AUTHOR("Jaroslav Kysela");
-MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio");
-MODULE_LICENSE("GPL");
-
-static struct pci_driver ymfpci_driver = {
-       .name           = "ymfpci",
-       .id_table       = ymf_id_tbl,
-       .probe          = ymf_probe_one,
-       .remove         = __devexit_p(ymf_remove_one),
-       .suspend        = ymf_suspend,
-       .resume         = ymf_resume
-};
-
-static int __init ymf_init_module(void)
-{
-       return pci_register_driver(&ymfpci_driver);
-}
-
-static void __exit ymf_cleanup_module (void)
-{
-       pci_unregister_driver(&ymfpci_driver);
-}
-
-module_init(ymf_init_module);
-module_exit(ymf_cleanup_module);
diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h
deleted file mode 100644 (file)
index ac1785f..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-#ifndef __YMFPCI_H
-#define __YMFPCI_H
-
-/*
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *  Definitions for Yahama YMF724/740/744/754 chips
- *
- *
- *   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-#include <linux/config.h>
-#include <linux/mutex.h>
-
-/*
- *  Direct registers
- */
-
-/* #define YMFREG(codec, reg)          (codec->port + YDSXGR_##reg) */
-
-#define        YDSXGR_INTFLAG                  0x0004
-#define        YDSXGR_ACTIVITY                 0x0006
-#define        YDSXGR_GLOBALCTRL               0x0008
-#define        YDSXGR_ZVCTRL                   0x000A
-#define        YDSXGR_TIMERCTRL                0x0010
-#define        YDSXGR_TIMERCTRL_TEN             0x0001
-#define        YDSXGR_TIMERCTRL_TIEN            0x0002
-#define        YDSXGR_TIMERCOUNT               0x0012
-#define        YDSXGR_SPDIFOUTCTRL             0x0018
-#define        YDSXGR_SPDIFOUTSTATUS           0x001C
-#define        YDSXGR_EEPROMCTRL               0x0020
-#define        YDSXGR_SPDIFINCTRL              0x0034
-#define        YDSXGR_SPDIFINSTATUS            0x0038
-#define        YDSXGR_DSPPROGRAMDL             0x0048
-#define        YDSXGR_DLCNTRL                  0x004C
-#define        YDSXGR_GPIOININTFLAG            0x0050
-#define        YDSXGR_GPIOININTENABLE          0x0052
-#define        YDSXGR_GPIOINSTATUS             0x0054
-#define        YDSXGR_GPIOOUTCTRL              0x0056
-#define        YDSXGR_GPIOFUNCENABLE           0x0058
-#define        YDSXGR_GPIOTYPECONFIG           0x005A
-#define        YDSXGR_AC97CMDDATA              0x0060
-#define        YDSXGR_AC97CMDADR               0x0062
-#define        YDSXGR_PRISTATUSDATA            0x0064
-#define        YDSXGR_PRISTATUSADR             0x0066
-#define        YDSXGR_SECSTATUSDATA            0x0068
-#define        YDSXGR_SECSTATUSADR             0x006A
-#define        YDSXGR_SECCONFIG                0x0070
-#define        YDSXGR_LEGACYOUTVOL             0x0080
-#define        YDSXGR_LEGACYOUTVOLL            0x0080
-#define        YDSXGR_LEGACYOUTVOLR            0x0082
-#define        YDSXGR_NATIVEDACOUTVOL          0x0084
-#define        YDSXGR_NATIVEDACOUTVOLL         0x0084
-#define        YDSXGR_NATIVEDACOUTVOLR         0x0086
-#define        YDSXGR_SPDIFOUTVOL              0x0088
-#define        YDSXGR_SPDIFOUTVOLL             0x0088
-#define        YDSXGR_SPDIFOUTVOLR             0x008A
-#define        YDSXGR_AC3OUTVOL                0x008C
-#define        YDSXGR_AC3OUTVOLL               0x008C
-#define        YDSXGR_AC3OUTVOLR               0x008E
-#define        YDSXGR_PRIADCOUTVOL             0x0090
-#define        YDSXGR_PRIADCOUTVOLL            0x0090
-#define        YDSXGR_PRIADCOUTVOLR            0x0092
-#define        YDSXGR_LEGACYLOOPVOL            0x0094
-#define        YDSXGR_LEGACYLOOPVOLL           0x0094
-#define        YDSXGR_LEGACYLOOPVOLR           0x0096
-#define        YDSXGR_NATIVEDACLOOPVOL         0x0098
-#define        YDSXGR_NATIVEDACLOOPVOLL        0x0098
-#define        YDSXGR_NATIVEDACLOOPVOLR        0x009A
-#define        YDSXGR_SPDIFLOOPVOL             0x009C
-#define        YDSXGR_SPDIFLOOPVOLL            0x009E
-#define        YDSXGR_SPDIFLOOPVOLR            0x009E
-#define        YDSXGR_AC3LOOPVOL               0x00A0
-#define        YDSXGR_AC3LOOPVOLL              0x00A0
-#define        YDSXGR_AC3LOOPVOLR              0x00A2
-#define        YDSXGR_PRIADCLOOPVOL            0x00A4
-#define        YDSXGR_PRIADCLOOPVOLL           0x00A4
-#define        YDSXGR_PRIADCLOOPVOLR           0x00A6
-#define        YDSXGR_NATIVEADCINVOL           0x00A8
-#define        YDSXGR_NATIVEADCINVOLL          0x00A8
-#define        YDSXGR_NATIVEADCINVOLR          0x00AA
-#define        YDSXGR_NATIVEDACINVOL           0x00AC
-#define        YDSXGR_NATIVEDACINVOLL          0x00AC
-#define        YDSXGR_NATIVEDACINVOLR          0x00AE
-#define        YDSXGR_BUF441OUTVOL             0x00B0
-#define        YDSXGR_BUF441OUTVOLL            0x00B0
-#define        YDSXGR_BUF441OUTVOLR            0x00B2
-#define        YDSXGR_BUF441LOOPVOL            0x00B4
-#define        YDSXGR_BUF441LOOPVOLL           0x00B4
-#define        YDSXGR_BUF441LOOPVOLR           0x00B6
-#define        YDSXGR_SPDIFOUTVOL2             0x00B8
-#define        YDSXGR_SPDIFOUTVOL2L            0x00B8
-#define        YDSXGR_SPDIFOUTVOL2R            0x00BA
-#define        YDSXGR_SPDIFLOOPVOL2            0x00BC
-#define        YDSXGR_SPDIFLOOPVOL2L           0x00BC
-#define        YDSXGR_SPDIFLOOPVOL2R           0x00BE
-#define        YDSXGR_ADCSLOTSR                0x00C0
-#define        YDSXGR_RECSLOTSR                0x00C4
-#define        YDSXGR_ADCFORMAT                0x00C8
-#define        YDSXGR_RECFORMAT                0x00CC
-#define        YDSXGR_P44SLOTSR                0x00D0
-#define        YDSXGR_STATUS                   0x0100
-#define        YDSXGR_CTRLSELECT               0x0104
-#define        YDSXGR_MODE                     0x0108
-#define        YDSXGR_SAMPLECOUNT              0x010C
-#define        YDSXGR_NUMOFSAMPLES             0x0110
-#define        YDSXGR_CONFIG                   0x0114
-#define        YDSXGR_PLAYCTRLSIZE             0x0140
-#define        YDSXGR_RECCTRLSIZE              0x0144
-#define        YDSXGR_EFFCTRLSIZE              0x0148
-#define        YDSXGR_WORKSIZE                 0x014C
-#define        YDSXGR_MAPOFREC                 0x0150
-#define        YDSXGR_MAPOFEFFECT              0x0154
-#define        YDSXGR_PLAYCTRLBASE             0x0158
-#define        YDSXGR_RECCTRLBASE              0x015C
-#define        YDSXGR_EFFCTRLBASE              0x0160
-#define        YDSXGR_WORKBASE                 0x0164
-#define        YDSXGR_DSPINSTRAM               0x1000
-#define        YDSXGR_CTRLINSTRAM              0x4000
-
-#define YDSXG_AC97READCMD              0x8000
-#define YDSXG_AC97WRITECMD             0x0000
-
-#define PCIR_LEGCTRL                   0x40
-#define PCIR_ELEGCTRL                  0x42
-#define PCIR_DSXGCTRL                  0x48
-#define PCIR_DSXPWRCTRL1               0x4a
-#define PCIR_DSXPWRCTRL2               0x4e
-#define PCIR_OPLADR                    0x60
-#define PCIR_SBADR                     0x62
-#define PCIR_MPUADR                    0x64
-
-#define YDSXG_DSPLENGTH                        0x0080
-#define YDSXG_CTRLLENGTH               0x3000
-
-#define YDSXG_DEFAULT_WORK_SIZE                0x0400
-
-#define YDSXG_PLAYBACK_VOICES          64
-#define YDSXG_CAPTURE_VOICES           2
-#define YDSXG_EFFECT_VOICES            5
-
-/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
-#define NR_AC97                2
-
-#define YMF_SAMPF                      256     /* Samples per frame @48000 */
-
-/*
- * The slot/voice control bank (2 of these per voice)
- */
-
-typedef struct stru_ymfpci_playback_bank {
-       u32 format;
-       u32 loop_default;
-       u32 base;                       /* 32-bit address */
-       u32 loop_start;                 /* 32-bit offset */
-       u32 loop_end;                   /* 32-bit offset */
-       u32 loop_frac;                  /* 8-bit fraction - loop_start */
-       u32 delta_end;                  /* pitch delta end */
-       u32 lpfK_end;
-       u32 eg_gain_end;
-       u32 left_gain_end;
-       u32 right_gain_end;
-       u32 eff1_gain_end;
-       u32 eff2_gain_end;
-       u32 eff3_gain_end;
-       u32 lpfQ;
-       u32 status;             /* P3: Always 0 for some reason. */
-       u32 num_of_frames;
-       u32 loop_count;
-       u32 start;              /* P3: J. reads this to know where chip is. */
-       u32 start_frac;
-       u32 delta;
-       u32 lpfK;
-       u32 eg_gain;
-       u32 left_gain;
-       u32 right_gain;
-       u32 eff1_gain;
-       u32 eff2_gain;
-       u32 eff3_gain;
-       u32 lpfD1;
-       u32 lpfD2;
-} ymfpci_playback_bank_t;
-
-typedef struct stru_ymfpci_capture_bank {
-       u32 base;                       /* 32-bit address (aligned at 4) */
-       u32 loop_end;                   /* size in BYTES (aligned at 4) */
-       u32 start;                      /* 32-bit offset */
-       u32 num_of_loops;               /* counter */
-} ymfpci_capture_bank_t;
-
-typedef struct stru_ymfpci_effect_bank {
-       u32 base;                       /* 32-bit address */
-       u32 loop_end;                   /* 32-bit offset */
-       u32 start;                      /* 32-bit offset */
-       u32 temp;
-} ymfpci_effect_bank_t;
-
-typedef struct ymf_voice ymfpci_voice_t;
-/*
- * Throughout the code Yaroslav names YMF unit pointer "codec"
- * even though it does not correspond to any codec. Must be historic.
- * We replace it with "unit" over time.
- * AC97 parts use "codec" to denote a codec, naturally.
- */
-typedef struct ymf_unit ymfpci_t;
-
-typedef enum {
-       YMFPCI_PCM,
-       YMFPCI_SYNTH,
-       YMFPCI_MIDI
-} ymfpci_voice_type_t;
-
-struct ymf_voice {
-       // ymfpci_t *codec;
-       int number;
-       char use, pcm, synth, midi;     // bool
-       ymfpci_playback_bank_t *bank;
-       struct ymf_pcm *ypcm;
-       dma_addr_t bank_ba;
-};
-
-struct ymf_capture {
-       // struct ymf_unit *unit;
-       int use;
-       ymfpci_capture_bank_t *bank;
-       struct ymf_pcm *ypcm;
-};
-
-struct ymf_unit {
-       u8 rev;                         /* PCI revision */
-       void __iomem *reg_area_virt;
-       void *dma_area_va;
-       dma_addr_t dma_area_ba;
-       unsigned int dma_area_size;
-
-       dma_addr_t bank_base_capture;
-       dma_addr_t bank_base_effect;
-       dma_addr_t work_base;
-       unsigned int work_size;
-
-       u32 *ctrl_playback;
-       dma_addr_t ctrl_playback_ba;
-       ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
-       ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
-       ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
-
-       int start_count;
-       int suspended;
-
-       u32 active_bank;
-       struct ymf_voice voices[YDSXG_PLAYBACK_VOICES];
-       struct ymf_capture capture[YDSXG_CAPTURE_VOICES];
-
-       struct ac97_codec *ac97_codec[NR_AC97];
-       u16 ac97_features;
-
-       struct pci_dev *pci;
-
-#ifdef CONFIG_SOUND_YMFPCI_LEGACY
-       /* legacy hardware resources */
-       unsigned int iosynth, iomidi;
-       struct address_info opl3_data, mpu_data;
-#endif
-
-       spinlock_t reg_lock;
-       spinlock_t voice_lock;
-       spinlock_t ac97_lock;
-
-       /* soundcore stuff */
-       int dev_audio;
-       struct mutex open_mutex;
-
-       struct list_head ymf_devs;
-       struct list_head states;        /* List of states for this unit */
-};
-
-struct ymf_dmabuf {
-       dma_addr_t dma_addr;
-       void *rawbuf;
-       unsigned buforder;
-
-       /* OSS buffer management stuff */
-       unsigned numfrag;
-       unsigned fragshift;
-
-       /* our buffer acts like a circular ring */
-       unsigned hwptr;         /* where dma last started */
-       unsigned swptr;         /* where driver last clear/filled */
-       int count;              /* fill count */
-       unsigned total_bytes;   /* total bytes dmaed by hardware */
-
-       wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */
-
-       /* redundant, but makes calculations easier */
-       unsigned fragsize;
-       unsigned dmasize;       /* Total rawbuf[] size */
-
-       /* OSS stuff */
-       unsigned mapped:1;
-       unsigned ready:1;
-       unsigned ossfragshift;
-       int ossmaxfrags;
-       unsigned subdivision;
-};
-
-struct ymf_pcm_format {
-       int format;                     /* OSS format */
-       int rate;                       /* rate in Hz */
-       int voices;                     /* number of voices */
-       int shift;                      /* redundant, computed from the above */
-};
-
-typedef enum {
-       PLAYBACK_VOICE,
-       CAPTURE_REC,
-       CAPTURE_AC97,
-       EFFECT_DRY_LEFT,
-       EFFECT_DRY_RIGHT,
-       EFFECT_EFF1,
-       EFFECT_EFF2,
-       EFFECT_EFF3
-} ymfpci_pcm_type_t;
-
-/* This is variant record, but we hate unions. Little waste on pointers []. */
-struct ymf_pcm {
-       ymfpci_pcm_type_t type;
-       struct ymf_state *state;
-
-       ymfpci_voice_t *voices[2];
-       int capture_bank_number;
-
-       struct ymf_dmabuf dmabuf;
-       int running;
-       int spdif;
-};
-
-/*
- * "Software" or virtual channel, an instance of opened /dev/dsp.
- * It may have two physical channels (pcms) for duplex operations.
- */
-
-struct ymf_state {
-       struct list_head chain;
-       struct ymf_unit *unit;                  /* backpointer */
-       struct ymf_pcm rpcm, wpcm;
-       struct ymf_pcm_format format;
-};
-
-#endif                         /* __YMFPCI_H */
diff --git a/sound/oss/ymfpci_image.h b/sound/oss/ymfpci_image.h
deleted file mode 100644 (file)
index 112f2ff..0000000
+++ /dev/null
@@ -1,1565 +0,0 @@
-#ifndef _HWMCODE_
-#define _HWMCODE_
-
-static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
-       0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
-       0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
-       0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
-       0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-
-static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
-       0x000007, 0x240007, 0x0C0007, 0x1C0007,
-       0x060007, 0x700002, 0x000020, 0x030040,
-       0x007104, 0x004286, 0x030040, 0x000F0D,
-       0x000810, 0x20043A, 0x000282, 0x00020D,
-       0x000810, 0x20043A, 0x001282, 0x200E82,
-       0x001A82, 0x032D0D, 0x000810, 0x10043A,
-       0x02D38D, 0x000810, 0x18043A, 0x00010D,
-       0x020015, 0x0000FD, 0x000020, 0x038860,
-       0x039060, 0x038060, 0x038040, 0x038040,
-       0x038040, 0x018040, 0x000A7D, 0x038040,
-       0x038040, 0x018040, 0x200402, 0x000882,
-       0x08001A, 0x000904, 0x015986, 0x000007,
-       0x260007, 0x000007, 0x000007, 0x018A06,
-       0x000007, 0x030C8D, 0x000810, 0x18043A,
-       0x260007, 0x00087D, 0x018042, 0x00160A,
-       0x04A206, 0x000007, 0x00218D, 0x000810,
-       0x08043A, 0x21C206, 0x000007, 0x0007FD,
-       0x018042, 0x08000A, 0x000904, 0x029386,
-       0x000195, 0x090D04, 0x000007, 0x000820,
-       0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
-       0x032206, 0x018040, 0x000A7D, 0x038042,
-       0x13804A, 0x18000A, 0x001820, 0x059060,
-       0x058860, 0x018040, 0x0000FD, 0x018042,
-       0x70000A, 0x000115, 0x071144, 0x032386,
-       0x030000, 0x007020, 0x034A06, 0x018040,
-       0x00348D, 0x000810, 0x08043A, 0x21EA06,
-       0x000007, 0x02D38D, 0x000810, 0x18043A,
-       0x018206, 0x000007, 0x240007, 0x000F8D,
-       0x000810, 0x00163A, 0x002402, 0x005C02,
-       0x0028FD, 0x000020, 0x018040, 0x08000D,
-       0x000815, 0x510984, 0x000007, 0x00004D,
-       0x000E5D, 0x000E02, 0x00418D, 0x000810,
-       0x08043A, 0x2C8A06, 0x000007, 0x00008D,
-       0x000924, 0x000F02, 0x00458D, 0x000810,
-       0x08043A, 0x2C8A06, 0x000007, 0x00387D,
-       0x018042, 0x08000A, 0x001015, 0x010984,
-       0x018386, 0x000007, 0x01AA06, 0x000007,
-       0x0008FD, 0x018042, 0x18000A, 0x001904,
-       0x218086, 0x280007, 0x001810, 0x28043A,
-       0x280C02, 0x00000D, 0x000810, 0x28143A,
-       0x08808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00020D, 0x189904, 0x000007,
-       0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x055A86, 0x000007,
-       0x000100, 0x000A20, 0x00047D, 0x018040,
-       0x018042, 0x20000A, 0x003015, 0x012144,
-       0x034986, 0x000007, 0x002104, 0x034986,
-       0x000007, 0x000F8D, 0x000810, 0x280C3A,
-       0x023944, 0x06C986, 0x000007, 0x001810,
-       0x28043A, 0x08810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x002810, 0x78003A,
-       0x00688D, 0x000810, 0x08043A, 0x288A06,
-       0x000007, 0x00400D, 0x001015, 0x189904,
-       0x292904, 0x393904, 0x000007, 0x060206,
-       0x000007, 0x0004F5, 0x00007D, 0x000020,
-       0x00008D, 0x010860, 0x018040, 0x00047D,
-       0x038042, 0x21804A, 0x18000A, 0x021944,
-       0x215886, 0x000007, 0x004075, 0x71F104,
-       0x000007, 0x010042, 0x28000A, 0x002904,
-       0x212086, 0x000007, 0x003C0D, 0x30A904,
-       0x000007, 0x00077D, 0x018042, 0x08000A,
-       0x000904, 0x07DA86, 0x00057D, 0x002820,
-       0x03B060, 0x07F206, 0x018040, 0x003020,
-       0x03A860, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x07FA86, 0x000007,
-       0x00057D, 0x018042, 0x28040A, 0x000E8D,
-       0x000810, 0x280C3A, 0x00000D, 0x000810,
-       0x28143A, 0x09000D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x003DFD, 0x000020,
-       0x018040, 0x00107D, 0x008D8D, 0x000810,
-       0x08043A, 0x288A06, 0x000007, 0x000815,
-       0x08001A, 0x010984, 0x095186, 0x00137D,
-       0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x038A60, 0x018040, 0x007FBD, 0x383DC4,
-       0x000007, 0x001A7D, 0x001375, 0x018042,
-       0x09004A, 0x10000A, 0x0B8D04, 0x139504,
-       0x000007, 0x000820, 0x019060, 0x001104,
-       0x212086, 0x010040, 0x0017FD, 0x018042,
-       0x08000A, 0x000904, 0x212286, 0x000007,
-       0x00197D, 0x038042, 0x09804A, 0x10000A,
-       0x000924, 0x001664, 0x0011FD, 0x038042,
-       0x2B804A, 0x19804A, 0x00008D, 0x218944,
-       0x000007, 0x002244, 0x0AE186, 0x000007,
-       0x001A64, 0x002A24, 0x00197D, 0x080102,
-       0x100122, 0x000820, 0x039060, 0x018040,
-       0x003DFD, 0x00008D, 0x000820, 0x018040,
-       0x001375, 0x001A7D, 0x010042, 0x09804A,
-       0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
-       0x309144, 0x000007, 0x00060D, 0x000A15,
-       0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
-       0x000464, 0x01B3E4, 0x0232E4, 0x000464,
-       0x000464, 0x000464, 0x000464, 0x00040D,
-       0x08B1C4, 0x000007, 0x000820, 0x000BF5,
-       0x030040, 0x00197D, 0x038042, 0x09804A,
-       0x000A24, 0x08000A, 0x080E64, 0x000007,
-       0x100122, 0x000820, 0x031060, 0x010040,
-       0x0064AC, 0x00027D, 0x000020, 0x018040,
-       0x00107D, 0x018042, 0x0011FD, 0x3B804A,
-       0x09804A, 0x20000A, 0x000095, 0x1A1144,
-       0x00A144, 0x0D2086, 0x00040D, 0x00B984,
-       0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
-       0x09804A, 0x28000A, 0x000095, 0x010924,
-       0x002A64, 0x0D1186, 0x000007, 0x002904,
-       0x0D2286, 0x000007, 0x0D2A06, 0x080002,
-       0x00008D, 0x00387D, 0x000820, 0x018040,
-       0x00127D, 0x018042, 0x10000A, 0x003904,
-       0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
-       0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
-       0x000015, 0x00082D, 0x02C78D, 0x000820,
-       0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
-       0x0E7186, 0x400025, 0x00008D, 0x110944,
-       0x000007, 0x00018D, 0x109504, 0x000007,
-       0x009164, 0x000424, 0x000424, 0x000424,
-       0x100102, 0x280002, 0x02C68D, 0x000820,
-       0x0EC206, 0x00018D, 0x00042D, 0x00008D,
-       0x109504, 0x000007, 0x00020D, 0x109184,
-       0x000007, 0x02C70D, 0x000820, 0x00008D,
-       0x0038FD, 0x018040, 0x003BFD, 0x001020,
-       0x03A860, 0x000815, 0x313184, 0x212184,
-       0x000007, 0x03B060, 0x03A060, 0x018040,
-       0x0022FD, 0x000095, 0x010924, 0x000424,
-       0x000424, 0x001264, 0x100102, 0x000820,
-       0x039060, 0x018040, 0x001924, 0x00FB8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x000424,
-       0x000424, 0x00117D, 0x018042, 0x08000A,
-       0x000A24, 0x280502, 0x280C02, 0x09800D,
-       0x000820, 0x0002FD, 0x018040, 0x200007,
-       0x0022FD, 0x018042, 0x08000A, 0x000095,
-       0x280DC4, 0x011924, 0x00197D, 0x018042,
-       0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
-       0x113144, 0x0A8D04, 0x000007, 0x080A44,
-       0x129504, 0x000007, 0x0023FD, 0x001020,
-       0x038040, 0x101244, 0x000007, 0x000820,
-       0x039060, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x10FA86, 0x000007,
-       0x003BFD, 0x000100, 0x000A10, 0x0B807A,
-       0x13804A, 0x090984, 0x000007, 0x000095,
-       0x013D04, 0x118086, 0x10000A, 0x100002,
-       0x090984, 0x000007, 0x038042, 0x11804A,
-       0x090D04, 0x000007, 0x10000A, 0x090D84,
-       0x000007, 0x00257D, 0x000820, 0x018040,
-       0x00010D, 0x000810, 0x28143A, 0x00127D,
-       0x018042, 0x20000A, 0x00197D, 0x018042,
-       0x00117D, 0x31804A, 0x10000A, 0x003124,
-       0x01280D, 0x00397D, 0x000820, 0x058040,
-       0x038042, 0x09844A, 0x000606, 0x08040A,
-       0x300102, 0x003124, 0x000424, 0x000424,
-       0x001224, 0x280502, 0x001A4C, 0x130186,
-       0x700002, 0x00002D, 0x030000, 0x00387D,
-       0x018042, 0x10000A, 0x132A06, 0x002124,
-       0x0000AD, 0x100002, 0x00010D, 0x000924,
-       0x006B24, 0x01368D, 0x00397D, 0x000820,
-       0x058040, 0x038042, 0x09844A, 0x000606,
-       0x08040A, 0x003264, 0x00008D, 0x000A24,
-       0x001020, 0x00227D, 0x018040, 0x013C0D,
-       0x000810, 0x08043A, 0x29D206, 0x000007,
-       0x002820, 0x00207D, 0x018040, 0x00117D,
-       0x038042, 0x13804A, 0x33800A, 0x00387D,
-       0x018042, 0x08000A, 0x000904, 0x163A86,
-       0x000007, 0x00008D, 0x030964, 0x01478D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x380102,
-       0x000424, 0x000424, 0x001224, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x14A286,
-       0x000007, 0x280502, 0x001A4C, 0x163986,
-       0x000007, 0x032164, 0x00632C, 0x003DFD,
-       0x018042, 0x08000A, 0x000095, 0x090904,
-       0x000007, 0x000820, 0x001A4C, 0x156186,
-       0x018040, 0x030000, 0x157A06, 0x002124,
-       0x00010D, 0x000924, 0x006B24, 0x015B8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x003A64,
-       0x000095, 0x001224, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x15DA86, 0x000007,
-       0x01628D, 0x000810, 0x08043A, 0x29D206,
-       0x000007, 0x14D206, 0x000007, 0x007020,
-       0x08010A, 0x10012A, 0x0020FD, 0x038860,
-       0x039060, 0x018040, 0x00227D, 0x018042,
-       0x003DFD, 0x08000A, 0x31844A, 0x000904,
-       0x16D886, 0x18008B, 0x00008D, 0x189904,
-       0x00312C, 0x17AA06, 0x000007, 0x00324C,
-       0x173386, 0x000007, 0x001904, 0x173086,
-       0x000007, 0x000095, 0x199144, 0x00222C,
-       0x003124, 0x00636C, 0x000E3D, 0x001375,
-       0x000BFD, 0x010042, 0x09804A, 0x10000A,
-       0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
-       0x000007, 0x00008D, 0x189904, 0x00226C,
-       0x00322C, 0x30050A, 0x301DAB, 0x002083,
-       0x0018FD, 0x018042, 0x08000A, 0x018924,
-       0x300502, 0x001083, 0x001875, 0x010042,
-       0x10000A, 0x00008D, 0x010924, 0x001375,
-       0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
-       0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
-       0x305C8B, 0x006083, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x187A86, 0x000007,
-       0x001E2D, 0x0005FD, 0x018042, 0x08000A,
-       0x028924, 0x280502, 0x00060D, 0x000810,
-       0x280C3A, 0x00008D, 0x000810, 0x28143A,
-       0x0A808D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x001275, 0x030042, 0x21004A,
-       0x00008D, 0x1A0944, 0x000007, 0x01980D,
-       0x000810, 0x08043A, 0x2B2206, 0x000007,
-       0x0001F5, 0x030042, 0x0D004A, 0x10000A,
-       0x089144, 0x000007, 0x000820, 0x010040,
-       0x0025F5, 0x0A3144, 0x000007, 0x000820,
-       0x032860, 0x030040, 0x00217D, 0x038042,
-       0x0B804A, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x00008D, 0x000124, 0x00012C,
-       0x000E64, 0x001A64, 0x00636C, 0x08010A,
-       0x10012A, 0x000820, 0x031060, 0x030040,
-       0x0020FD, 0x018042, 0x08000A, 0x00227D,
-       0x018042, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x00197D, 0x018042, 0x08000A,
-       0x0022FD, 0x038042, 0x10000A, 0x000820,
-       0x031060, 0x030040, 0x090D04, 0x000007,
-       0x000820, 0x030040, 0x038042, 0x0B804A,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x038042, 0x13804A, 0x19804A, 0x110D04,
-       0x198D04, 0x000007, 0x08000A, 0x001020,
-       0x031860, 0x030860, 0x030040, 0x00008D,
-       0x0B0944, 0x000007, 0x000820, 0x010040,
-       0x0005F5, 0x030042, 0x08000A, 0x000820,
-       0x010040, 0x0000F5, 0x010042, 0x08000A,
-       0x000904, 0x1C6086, 0x001E75, 0x030042,
-       0x01044A, 0x000C0A, 0x1C7206, 0x000007,
-       0x000402, 0x000C02, 0x00177D, 0x001AF5,
-       0x018042, 0x03144A, 0x031C4A, 0x03244A,
-       0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
-       0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
-       0x030042, 0x0B004A, 0x1B804A, 0x13804A,
-       0x20000A, 0x089144, 0x19A144, 0x0389E4,
-       0x0399EC, 0x005502, 0x005D0A, 0x030042,
-       0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-       0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-       0x006502, 0x006D0A, 0x030042, 0x0B004A,
-       0x19004A, 0x2B804A, 0x13804A, 0x21804A,
-       0x30000A, 0x089144, 0x19A144, 0x2AB144,
-       0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
-       0x03A9E4, 0x000702, 0x00107D, 0x000415,
-       0x018042, 0x08000A, 0x0109E4, 0x000F02,
-       0x002AF5, 0x0019FD, 0x010042, 0x09804A,
-       0x10000A, 0x000934, 0x001674, 0x0029F5,
-       0x010042, 0x10000A, 0x00917C, 0x002075,
-       0x010042, 0x08000A, 0x000904, 0x1ED286,
-       0x0026F5, 0x0027F5, 0x030042, 0x09004A,
-       0x10000A, 0x000A3C, 0x00167C, 0x001A75,
-       0x000BFD, 0x010042, 0x51804A, 0x48000A,
-       0x160007, 0x001075, 0x010042, 0x282C0A,
-       0x281D12, 0x282512, 0x001F32, 0x1E0007,
-       0x0E0007, 0x001975, 0x010042, 0x002DF5,
-       0x0D004A, 0x10000A, 0x009144, 0x1FB286,
-       0x010042, 0x28340A, 0x000E5D, 0x00008D,
-       0x000375, 0x000820, 0x010040, 0x05D2F4,
-       0x54D104, 0x00735C, 0x205386, 0x000007,
-       0x0C0007, 0x080007, 0x0A0007, 0x02040D,
-       0x000810, 0x08043A, 0x332206, 0x000007,
-       0x205A06, 0x000007, 0x080007, 0x002275,
-       0x010042, 0x20000A, 0x002104, 0x212086,
-       0x001E2D, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x209286, 0x000007, 0x002010,
-       0x30043A, 0x00057D, 0x0180C3, 0x08000A,
-       0x028924, 0x280502, 0x280C02, 0x0A810D,
-       0x000820, 0x0002F5, 0x010040, 0x220007,
-       0x0004FD, 0x018042, 0x70000A, 0x030000,
-       0x007020, 0x06FA06, 0x018040, 0x02180D,
-       0x000810, 0x08043A, 0x2B2206, 0x000007,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x218A86, 0x000007, 0x01F206, 0x000007,
-       0x000875, 0x0009FD, 0x00010D, 0x220A06,
-       0x000295, 0x000B75, 0x00097D, 0x00000D,
-       0x000515, 0x010042, 0x18000A, 0x001904,
-       0x287886, 0x0006F5, 0x001020, 0x010040,
-       0x0004F5, 0x000820, 0x010040, 0x000775,
-       0x010042, 0x09804A, 0x10000A, 0x001124,
-       0x000904, 0x22BA86, 0x000815, 0x080102,
-       0x101204, 0x22DA06, 0x000575, 0x081204,
-       0x000007, 0x100102, 0x000575, 0x000425,
-       0x021124, 0x100102, 0x000820, 0x031060,
-       0x010040, 0x001924, 0x287886, 0x00008D,
-       0x000464, 0x009D04, 0x278886, 0x180102,
-       0x000575, 0x010042, 0x28040A, 0x00018D,
-       0x000924, 0x280D02, 0x00000D, 0x000924,
-       0x281502, 0x10000D, 0x000820, 0x0002F5,
-       0x010040, 0x200007, 0x001175, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x23C286,
-       0x000007, 0x000100, 0x080B20, 0x130B60,
-       0x1B0B60, 0x030A60, 0x010040, 0x050042,
-       0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
-       0x0006F5, 0x010042, 0x28140A, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x24CA86, 0x004015, 0x000095, 0x010D04,
-       0x24B886, 0x100022, 0x10002A, 0x24E206,
-       0x000007, 0x333104, 0x2AA904, 0x000007,
-       0x032124, 0x280502, 0x001124, 0x000424,
-       0x000424, 0x003224, 0x00292C, 0x00636C,
-       0x25F386, 0x000007, 0x02B164, 0x000464,
-       0x000464, 0x00008D, 0x000A64, 0x280D02,
-       0x10008D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x00008D, 0x38B904, 0x000007,
-       0x03296C, 0x30010A, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x25BA86, 0x000007,
-       0x02312C, 0x28050A, 0x00008D, 0x01096C,
-       0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x001124, 0x000424,
-       0x000424, 0x003224, 0x300102, 0x032944,
-       0x267A86, 0x000007, 0x300002, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x26C086, 0x003124, 0x000464, 0x300102,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x26CA86, 0x000007, 0x003124, 0x300502,
-       0x003924, 0x300583, 0x000883, 0x0005F5,
-       0x010042, 0x28040A, 0x00008D, 0x008124,
-       0x280D02, 0x00008D, 0x008124, 0x281502,
-       0x10018D, 0x000820, 0x0002F5, 0x010040,
-       0x220007, 0x001025, 0x000575, 0x030042,
-       0x09004A, 0x10000A, 0x0A0904, 0x121104,
-       0x000007, 0x001020, 0x050860, 0x050040,
-       0x0006FD, 0x018042, 0x09004A, 0x10000A,
-       0x0000A5, 0x0A0904, 0x121104, 0x000007,
-       0x000820, 0x019060, 0x010040, 0x0002F5,
-       0x010042, 0x08000A, 0x000904, 0x284286,
-       0x000007, 0x230A06, 0x000007, 0x000606,
-       0x000007, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x289286, 0x000007, 0x000100,
-       0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
-       0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
-       0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
-       0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
-       0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
-       0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
-       0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
-       0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
-       0x000606, 0x018040, 0x00008D, 0x000A64,
-       0x280D02, 0x000A24, 0x00027D, 0x018042,
-       0x10000A, 0x001224, 0x0003FD, 0x018042,
-       0x08000A, 0x000904, 0x2A8286, 0x000007,
-       0x00018D, 0x000A24, 0x000464, 0x000464,
-       0x080102, 0x000924, 0x000424, 0x000424,
-       0x100102, 0x02000D, 0x009144, 0x2AD986,
-       0x000007, 0x0001FD, 0x018042, 0x08000A,
-       0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
-       0x000820, 0x0002FD, 0x018040, 0x200007,
-       0x00027D, 0x001020, 0x000606, 0x018040,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x2B2A86, 0x000007, 0x00037D, 0x018042,
-       0x08000A, 0x000904, 0x2B5A86, 0x000007,
-       0x000075, 0x002E7D, 0x010042, 0x0B804A,
-       0x000020, 0x000904, 0x000686, 0x010040,
-       0x31844A, 0x30048B, 0x000883, 0x00008D,
-       0x000810, 0x28143A, 0x00008D, 0x000810,
-       0x280C3A, 0x000675, 0x010042, 0x08000A,
-       0x003815, 0x010924, 0x280502, 0x0B000D,
-       0x000820, 0x0002F5, 0x010040, 0x000606,
-       0x220007, 0x000464, 0x000464, 0x000606,
-       0x000007, 0x000134, 0x007F8D, 0x00093C,
-       0x281D12, 0x282512, 0x001F32, 0x0E0007,
-       0x00010D, 0x00037D, 0x000820, 0x018040,
-       0x05D2F4, 0x000007, 0x080007, 0x00037D,
-       0x018042, 0x08000A, 0x000904, 0x2D0286,
-       0x000007, 0x000606, 0x000007, 0x000007,
-       0x000012, 0x100007, 0x320007, 0x600007,
-       0x100080, 0x48001A, 0x004904, 0x2D6186,
-       0x000007, 0x001210, 0x58003A, 0x000145,
-       0x5C5D04, 0x000007, 0x000080, 0x48001A,
-       0x004904, 0x2DB186, 0x000007, 0x001210,
-       0x50003A, 0x005904, 0x2E0886, 0x000045,
-       0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
-       0x004224, 0x500102, 0x200502, 0x000082,
-       0x40001A, 0x004104, 0x2E3986, 0x000007,
-       0x003865, 0x40001A, 0x004020, 0x00104D,
-       0x04C184, 0x301B86, 0x000040, 0x040007,
-       0x000165, 0x000145, 0x004020, 0x000040,
-       0x000765, 0x080080, 0x40001A, 0x004104,
-       0x2EC986, 0x000007, 0x001210, 0x40003A,
-       0x004104, 0x2F2286, 0x00004D, 0x0000CD,
-       0x004810, 0x20043A, 0x000882, 0x40001A,
-       0x004104, 0x2F3186, 0x000007, 0x004820,
-       0x005904, 0x300886, 0x000040, 0x0007E5,
-       0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
-       0x4216E0, 0x021260, 0x000040, 0x000032,
-       0x400075, 0x00007D, 0x07D574, 0x200512,
-       0x000082, 0x40001A, 0x004104, 0x2FE186,
-       0x000007, 0x037206, 0x640007, 0x060007,
-       0x0000E5, 0x000020, 0x000040, 0x000A65,
-       0x000020, 0x020040, 0x020040, 0x000040,
-       0x000165, 0x000042, 0x70000A, 0x007104,
-       0x30A286, 0x000007, 0x018206, 0x640007,
-       0x050000, 0x007020, 0x000040, 0x037206,
-       0x640007, 0x000007, 0x00306D, 0x028860,
-       0x029060, 0x08000A, 0x028860, 0x008040,
-       0x100012, 0x00100D, 0x009184, 0x314186,
-       0x000E0D, 0x009184, 0x325186, 0x000007,
-       0x300007, 0x001020, 0x003B6D, 0x008040,
-       0x000080, 0x08001A, 0x000904, 0x316186,
-       0x000007, 0x001220, 0x000DED, 0x008040,
-       0x008042, 0x10000A, 0x40000D, 0x109544,
-       0x000007, 0x001020, 0x000DED, 0x008040,
-       0x008042, 0x20040A, 0x000082, 0x08001A,
-       0x000904, 0x31F186, 0x000007, 0x003B6D,
-       0x008042, 0x08000A, 0x000E15, 0x010984,
-       0x329B86, 0x600007, 0x08001A, 0x000C15,
-       0x010984, 0x328386, 0x000020, 0x1A0007,
-       0x0002ED, 0x008040, 0x620007, 0x00306D,
-       0x028042, 0x0A804A, 0x000820, 0x0A804A,
-       0x000606, 0x10804A, 0x000007, 0x282512,
-       0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
-       0x000786, 0x000007, 0x0C0007, 0x0A0007,
-       0x1C0007, 0x003465, 0x020040, 0x004820,
-       0x025060, 0x40000A, 0x024060, 0x000040,
-       0x454944, 0x000007, 0x004020, 0x003AE5,
-       0x000040, 0x0028E5, 0x000042, 0x48000A,
-       0x004904, 0x386886, 0x002C65, 0x000042,
-       0x40000A, 0x0000D5, 0x454104, 0x000007,
-       0x000655, 0x054504, 0x34F286, 0x0001D5,
-       0x054504, 0x34F086, 0x002B65, 0x000042,
-       0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
-       0x000007, 0x454504, 0x000007, 0x0000CD,
-       0x444944, 0x000007, 0x454504, 0x000007,
-       0x00014D, 0x554944, 0x000007, 0x045144,
-       0x34E986, 0x002C65, 0x000042, 0x48000A,
-       0x4CD104, 0x000007, 0x04C144, 0x34F386,
-       0x000007, 0x160007, 0x002CE5, 0x040042,
-       0x40000A, 0x004020, 0x000040, 0x002965,
-       0x000042, 0x40000A, 0x004104, 0x356086,
-       0x000007, 0x002402, 0x36A206, 0x005C02,
-       0x0025E5, 0x000042, 0x40000A, 0x004274,
-       0x002AE5, 0x000042, 0x40000A, 0x004274,
-       0x500112, 0x0029E5, 0x000042, 0x40000A,
-       0x004234, 0x454104, 0x000007, 0x004020,
-       0x000040, 0x003EE5, 0x000020, 0x000040,
-       0x002DE5, 0x400152, 0x50000A, 0x045144,
-       0x364A86, 0x0000C5, 0x003EE5, 0x004020,
-       0x000040, 0x002BE5, 0x000042, 0x40000A,
-       0x404254, 0x000007, 0x002AE5, 0x004020,
-       0x000040, 0x500132, 0x040134, 0x005674,
-       0x0029E5, 0x020042, 0x42000A, 0x000042,
-       0x50000A, 0x05417C, 0x0028E5, 0x000042,
-       0x48000A, 0x0000C5, 0x4CC144, 0x371086,
-       0x0026E5, 0x0027E5, 0x020042, 0x40004A,
-       0x50000A, 0x00423C, 0x00567C, 0x0028E5,
-       0x004820, 0x000040, 0x281D12, 0x282512,
-       0x001F72, 0x002965, 0x000042, 0x40000A,
-       0x004104, 0x37AA86, 0x0E0007, 0x160007,
-       0x1E0007, 0x003EE5, 0x000042, 0x40000A,
-       0x004104, 0x37E886, 0x002D65, 0x000042,
-       0x28340A, 0x003465, 0x020042, 0x42004A,
-       0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
-       0x54D104, 0x00735C, 0x385186, 0x000007,
-       0x000606, 0x080007, 0x0C0007, 0x080007,
-       0x0A0007, 0x0001E5, 0x020045, 0x004020,
-       0x000060, 0x000365, 0x000040, 0x002E65,
-       0x001A20, 0x0A1A60, 0x000040, 0x003465,
-       0x020042, 0x42004A, 0x004020, 0x4A004A,
-       0x000606, 0x50004A, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000
-};
-
-// --------------------------------------------
-//  DS-1E Controller InstructionRAM Code
-//     1999/06/21
-//     Buf441 slot is Enabled.
-// --------------------------------------------
-// 04/09  creat
-// 04/12  stop nise fix
-// 06/21  WorkingOff timming
-static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
-       0x000007, 0x240007, 0x0C0007, 0x1C0007,
-       0x060007, 0x700002, 0x000020, 0x030040,
-       0x007104, 0x004286, 0x030040, 0x000F0D,
-       0x000810, 0x20043A, 0x000282, 0x00020D,
-       0x000810, 0x20043A, 0x001282, 0x200E82,
-       0x00800D, 0x000810, 0x20043A, 0x001A82,
-       0x03460D, 0x000810, 0x10043A, 0x02EC0D,
-       0x000810, 0x18043A, 0x00010D, 0x020015,
-       0x0000FD, 0x000020, 0x038860, 0x039060,
-       0x038060, 0x038040, 0x038040, 0x038040,
-       0x018040, 0x000A7D, 0x038040, 0x038040,
-       0x018040, 0x200402, 0x000882, 0x08001A,
-       0x000904, 0x017186, 0x000007, 0x260007,
-       0x400007, 0x000007, 0x03258D, 0x000810,
-       0x18043A, 0x260007, 0x284402, 0x00087D,
-       0x018042, 0x00160A, 0x05A206, 0x000007,
-       0x440007, 0x00230D, 0x000810, 0x08043A,
-       0x22FA06, 0x000007, 0x0007FD, 0x018042,
-       0x08000A, 0x000904, 0x02AB86, 0x000195,
-       0x090D04, 0x000007, 0x000820, 0x0000F5,
-       0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
-       0x018040, 0x000A7D, 0x038042, 0x13804A,
-       0x18000A, 0x001820, 0x059060, 0x058860,
-       0x018040, 0x0000FD, 0x018042, 0x70000A,
-       0x000115, 0x071144, 0x033B86, 0x030000,
-       0x007020, 0x036206, 0x018040, 0x00360D,
-       0x000810, 0x08043A, 0x232206, 0x000007,
-       0x02EC0D, 0x000810, 0x18043A, 0x019A06,
-       0x000007, 0x240007, 0x000F8D, 0x000810,
-       0x00163A, 0x002402, 0x005C02, 0x0028FD,
-       0x000020, 0x018040, 0x08000D, 0x000815,
-       0x510984, 0x000007, 0x00004D, 0x000E5D,
-       0x000E02, 0x00430D, 0x000810, 0x08043A,
-       0x2E1206, 0x000007, 0x00008D, 0x000924,
-       0x000F02, 0x00470D, 0x000810, 0x08043A,
-       0x2E1206, 0x000007, 0x480480, 0x001210,
-       0x28043A, 0x00778D, 0x000810, 0x280C3A,
-       0x00068D, 0x000810, 0x28143A, 0x284402,
-       0x03258D, 0x000810, 0x18043A, 0x07FF8D,
-       0x000820, 0x0002FD, 0x018040, 0x260007,
-       0x200007, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x051286, 0x000007, 0x240007,
-       0x02EC0D, 0x000810, 0x18043A, 0x00387D,
-       0x018042, 0x08000A, 0x001015, 0x010984,
-       0x019B86, 0x000007, 0x01B206, 0x000007,
-       0x0008FD, 0x018042, 0x18000A, 0x001904,
-       0x22B886, 0x280007, 0x001810, 0x28043A,
-       0x280C02, 0x00000D, 0x000810, 0x28143A,
-       0x08808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00020D, 0x189904, 0x000007,
-       0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x065A86, 0x000007,
-       0x000100, 0x000A20, 0x00047D, 0x018040,
-       0x018042, 0x20000A, 0x003015, 0x012144,
-       0x036186, 0x000007, 0x002104, 0x036186,
-       0x000007, 0x000F8D, 0x000810, 0x280C3A,
-       0x023944, 0x07C986, 0x000007, 0x001810,
-       0x28043A, 0x08810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x002810, 0x78003A,
-       0x00788D, 0x000810, 0x08043A, 0x2A1206,
-       0x000007, 0x00400D, 0x001015, 0x189904,
-       0x292904, 0x393904, 0x000007, 0x070206,
-       0x000007, 0x0004F5, 0x00007D, 0x000020,
-       0x00008D, 0x010860, 0x018040, 0x00047D,
-       0x038042, 0x21804A, 0x18000A, 0x021944,
-       0x229086, 0x000007, 0x004075, 0x71F104,
-       0x000007, 0x010042, 0x28000A, 0x002904,
-       0x225886, 0x000007, 0x003C0D, 0x30A904,
-       0x000007, 0x00077D, 0x018042, 0x08000A,
-       0x000904, 0x08DA86, 0x00057D, 0x002820,
-       0x03B060, 0x08F206, 0x018040, 0x003020,
-       0x03A860, 0x018040, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x08FA86, 0x000007,
-       0x00057D, 0x018042, 0x28040A, 0x000E8D,
-       0x000810, 0x280C3A, 0x00000D, 0x000810,
-       0x28143A, 0x09000D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x003DFD, 0x000020,
-       0x018040, 0x00107D, 0x009D8D, 0x000810,
-       0x08043A, 0x2A1206, 0x000007, 0x000815,
-       0x08001A, 0x010984, 0x0A5186, 0x00137D,
-       0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x038A60, 0x018040, 0x00107D, 0x018042,
-       0x08000A, 0x000215, 0x010984, 0x3A8186,
-       0x000007, 0x007FBD, 0x383DC4, 0x000007,
-       0x001A7D, 0x001375, 0x018042, 0x09004A,
-       0x10000A, 0x0B8D04, 0x139504, 0x000007,
-       0x000820, 0x019060, 0x001104, 0x225886,
-       0x010040, 0x0017FD, 0x018042, 0x08000A,
-       0x000904, 0x225A86, 0x000007, 0x00197D,
-       0x038042, 0x09804A, 0x10000A, 0x000924,
-       0x001664, 0x0011FD, 0x038042, 0x2B804A,
-       0x19804A, 0x00008D, 0x218944, 0x000007,
-       0x002244, 0x0C1986, 0x000007, 0x001A64,
-       0x002A24, 0x00197D, 0x080102, 0x100122,
-       0x000820, 0x039060, 0x018040, 0x003DFD,
-       0x00008D, 0x000820, 0x018040, 0x001375,
-       0x001A7D, 0x010042, 0x09804A, 0x10000A,
-       0x00021D, 0x0189E4, 0x2992E4, 0x309144,
-       0x000007, 0x00060D, 0x000A15, 0x000C1D,
-       0x001025, 0x00A9E4, 0x012BE4, 0x000464,
-       0x01B3E4, 0x0232E4, 0x000464, 0x000464,
-       0x000464, 0x000464, 0x00040D, 0x08B1C4,
-       0x000007, 0x000820, 0x000BF5, 0x030040,
-       0x00197D, 0x038042, 0x09804A, 0x000A24,
-       0x08000A, 0x080E64, 0x000007, 0x100122,
-       0x000820, 0x031060, 0x010040, 0x0064AC,
-       0x00027D, 0x000020, 0x018040, 0x00107D,
-       0x018042, 0x0011FD, 0x3B804A, 0x09804A,
-       0x20000A, 0x000095, 0x1A1144, 0x00A144,
-       0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
-       0x0018FD, 0x018042, 0x0010FD, 0x09804A,
-       0x28000A, 0x000095, 0x010924, 0x002A64,
-       0x0E4986, 0x000007, 0x002904, 0x0E5A86,
-       0x000007, 0x0E6206, 0x080002, 0x00008D,
-       0x00387D, 0x000820, 0x018040, 0x00127D,
-       0x018042, 0x10000A, 0x003904, 0x0F0986,
-       0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
-       0x000025, 0x0FB206, 0x00002D, 0x000015,
-       0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
-       0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
-       0x400025, 0x00008D, 0x110944, 0x000007,
-       0x00018D, 0x109504, 0x000007, 0x009164,
-       0x000424, 0x000424, 0x000424, 0x100102,
-       0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
-       0x00018D, 0x00042D, 0x00008D, 0x109504,
-       0x000007, 0x00020D, 0x109184, 0x000007,
-       0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
-       0x018040, 0x003BFD, 0x001020, 0x03A860,
-       0x000815, 0x313184, 0x212184, 0x000007,
-       0x03B060, 0x03A060, 0x018040, 0x0022FD,
-       0x000095, 0x010924, 0x000424, 0x000424,
-       0x001264, 0x100102, 0x000820, 0x039060,
-       0x018040, 0x001924, 0x010F0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x000424, 0x000424,
-       0x00117D, 0x018042, 0x08000A, 0x000A24,
-       0x280502, 0x280C02, 0x09800D, 0x000820,
-       0x0002FD, 0x018040, 0x200007, 0x0022FD,
-       0x018042, 0x08000A, 0x000095, 0x280DC4,
-       0x011924, 0x00197D, 0x018042, 0x0011FD,
-       0x09804A, 0x10000A, 0x0000B5, 0x113144,
-       0x0A8D04, 0x000007, 0x080A44, 0x129504,
-       0x000007, 0x0023FD, 0x001020, 0x038040,
-       0x101244, 0x000007, 0x000820, 0x039060,
-       0x018040, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x123286, 0x000007, 0x003BFD,
-       0x000100, 0x000A10, 0x0B807A, 0x13804A,
-       0x090984, 0x000007, 0x000095, 0x013D04,
-       0x12B886, 0x10000A, 0x100002, 0x090984,
-       0x000007, 0x038042, 0x11804A, 0x090D04,
-       0x000007, 0x10000A, 0x090D84, 0x000007,
-       0x00257D, 0x000820, 0x018040, 0x00010D,
-       0x000810, 0x28143A, 0x00127D, 0x018042,
-       0x20000A, 0x00197D, 0x018042, 0x00117D,
-       0x31804A, 0x10000A, 0x003124, 0x013B8D,
-       0x00397D, 0x000820, 0x058040, 0x038042,
-       0x09844A, 0x000606, 0x08040A, 0x300102,
-       0x003124, 0x000424, 0x000424, 0x001224,
-       0x280502, 0x001A4C, 0x143986, 0x700002,
-       0x00002D, 0x030000, 0x00387D, 0x018042,
-       0x10000A, 0x146206, 0x002124, 0x0000AD,
-       0x100002, 0x00010D, 0x000924, 0x006B24,
-       0x014A0D, 0x00397D, 0x000820, 0x058040,
-       0x038042, 0x09844A, 0x000606, 0x08040A,
-       0x003264, 0x00008D, 0x000A24, 0x001020,
-       0x00227D, 0x018040, 0x014F8D, 0x000810,
-       0x08043A, 0x2B5A06, 0x000007, 0x002820,
-       0x00207D, 0x018040, 0x00117D, 0x038042,
-       0x13804A, 0x33800A, 0x00387D, 0x018042,
-       0x08000A, 0x000904, 0x177286, 0x000007,
-       0x00008D, 0x030964, 0x015B0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x380102, 0x000424,
-       0x000424, 0x001224, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x15DA86, 0x000007,
-       0x280502, 0x001A4C, 0x177186, 0x000007,
-       0x032164, 0x00632C, 0x003DFD, 0x018042,
-       0x08000A, 0x000095, 0x090904, 0x000007,
-       0x000820, 0x001A4C, 0x169986, 0x018040,
-       0x030000, 0x16B206, 0x002124, 0x00010D,
-       0x000924, 0x006B24, 0x016F0D, 0x00397D,
-       0x000820, 0x058040, 0x038042, 0x09844A,
-       0x000606, 0x08040A, 0x003A64, 0x000095,
-       0x001224, 0x0002FD, 0x018042, 0x08000A,
-       0x000904, 0x171286, 0x000007, 0x01760D,
-       0x000810, 0x08043A, 0x2B5A06, 0x000007,
-       0x160A06, 0x000007, 0x007020, 0x08010A,
-       0x10012A, 0x0020FD, 0x038860, 0x039060,
-       0x018040, 0x00227D, 0x018042, 0x003DFD,
-       0x08000A, 0x31844A, 0x000904, 0x181086,
-       0x18008B, 0x00008D, 0x189904, 0x00312C,
-       0x18E206, 0x000007, 0x00324C, 0x186B86,
-       0x000007, 0x001904, 0x186886, 0x000007,
-       0x000095, 0x199144, 0x00222C, 0x003124,
-       0x00636C, 0x000E3D, 0x001375, 0x000BFD,
-       0x010042, 0x09804A, 0x10000A, 0x038AEC,
-       0x0393EC, 0x00224C, 0x18E186, 0x000007,
-       0x00008D, 0x189904, 0x00226C, 0x00322C,
-       0x30050A, 0x301DAB, 0x002083, 0x0018FD,
-       0x018042, 0x08000A, 0x018924, 0x300502,
-       0x001083, 0x001875, 0x010042, 0x10000A,
-       0x00008D, 0x010924, 0x001375, 0x330542,
-       0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
-       0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
-       0x006083, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x19B286, 0x000007, 0x001E2D,
-       0x0005FD, 0x018042, 0x08000A, 0x028924,
-       0x280502, 0x00060D, 0x000810, 0x280C3A,
-       0x00008D, 0x000810, 0x28143A, 0x0A808D,
-       0x000820, 0x0002F5, 0x010040, 0x220007,
-       0x001275, 0x030042, 0x21004A, 0x00008D,
-       0x1A0944, 0x000007, 0x01AB8D, 0x000810,
-       0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
-       0x030042, 0x0D004A, 0x10000A, 0x089144,
-       0x000007, 0x000820, 0x010040, 0x0025F5,
-       0x0A3144, 0x000007, 0x000820, 0x032860,
-       0x030040, 0x00217D, 0x038042, 0x0B804A,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x00008D, 0x000124, 0x00012C, 0x000E64,
-       0x001A64, 0x00636C, 0x08010A, 0x10012A,
-       0x000820, 0x031060, 0x030040, 0x0020FD,
-       0x018042, 0x08000A, 0x00227D, 0x018042,
-       0x10000A, 0x000820, 0x031060, 0x030040,
-       0x00197D, 0x018042, 0x08000A, 0x0022FD,
-       0x038042, 0x10000A, 0x000820, 0x031060,
-       0x030040, 0x090D04, 0x000007, 0x000820,
-       0x030040, 0x038042, 0x0B804A, 0x10000A,
-       0x000820, 0x031060, 0x030040, 0x038042,
-       0x13804A, 0x19804A, 0x110D04, 0x198D04,
-       0x000007, 0x08000A, 0x001020, 0x031860,
-       0x030860, 0x030040, 0x00008D, 0x0B0944,
-       0x000007, 0x000820, 0x010040, 0x0005F5,
-       0x030042, 0x08000A, 0x000820, 0x010040,
-       0x0000F5, 0x010042, 0x08000A, 0x000904,
-       0x1D9886, 0x001E75, 0x030042, 0x01044A,
-       0x000C0A, 0x1DAA06, 0x000007, 0x000402,
-       0x000C02, 0x00177D, 0x001AF5, 0x018042,
-       0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
-       0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
-       0x00043D, 0x0013F5, 0x001AFD, 0x030042,
-       0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-       0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-       0x005502, 0x005D0A, 0x030042, 0x0B004A,
-       0x1B804A, 0x13804A, 0x20000A, 0x089144,
-       0x19A144, 0x0389E4, 0x0399EC, 0x006502,
-       0x006D0A, 0x030042, 0x0B004A, 0x19004A,
-       0x2B804A, 0x13804A, 0x21804A, 0x30000A,
-       0x089144, 0x19A144, 0x2AB144, 0x0389E4,
-       0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
-       0x000702, 0x00107D, 0x000415, 0x018042,
-       0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
-       0x0019FD, 0x010042, 0x09804A, 0x10000A,
-       0x000934, 0x001674, 0x0029F5, 0x010042,
-       0x10000A, 0x00917C, 0x002075, 0x010042,
-       0x08000A, 0x000904, 0x200A86, 0x0026F5,
-       0x0027F5, 0x030042, 0x09004A, 0x10000A,
-       0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
-       0x010042, 0x51804A, 0x48000A, 0x160007,
-       0x001075, 0x010042, 0x282C0A, 0x281D12,
-       0x282512, 0x001F32, 0x1E0007, 0x0E0007,
-       0x001975, 0x010042, 0x002DF5, 0x0D004A,
-       0x10000A, 0x009144, 0x20EA86, 0x010042,
-       0x28340A, 0x000E5D, 0x00008D, 0x000375,
-       0x000820, 0x010040, 0x05D2F4, 0x54D104,
-       0x00735C, 0x218B86, 0x000007, 0x0C0007,
-       0x080007, 0x0A0007, 0x02178D, 0x000810,
-       0x08043A, 0x34B206, 0x000007, 0x219206,
-       0x000007, 0x080007, 0x002275, 0x010042,
-       0x20000A, 0x002104, 0x225886, 0x001E2D,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x21CA86, 0x000007, 0x002010, 0x30043A,
-       0x00057D, 0x0180C3, 0x08000A, 0x028924,
-       0x280502, 0x280C02, 0x0A810D, 0x000820,
-       0x0002F5, 0x010040, 0x220007, 0x0004FD,
-       0x018042, 0x70000A, 0x030000, 0x007020,
-       0x07FA06, 0x018040, 0x022B8D, 0x000810,
-       0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x22C286,
-       0x000007, 0x020206, 0x000007, 0x000875,
-       0x0009FD, 0x00010D, 0x234206, 0x000295,
-       0x000B75, 0x00097D, 0x00000D, 0x000515,
-       0x010042, 0x18000A, 0x001904, 0x2A0086,
-       0x0006F5, 0x001020, 0x010040, 0x0004F5,
-       0x000820, 0x010040, 0x000775, 0x010042,
-       0x09804A, 0x10000A, 0x001124, 0x000904,
-       0x23F286, 0x000815, 0x080102, 0x101204,
-       0x241206, 0x000575, 0x081204, 0x000007,
-       0x100102, 0x000575, 0x000425, 0x021124,
-       0x100102, 0x000820, 0x031060, 0x010040,
-       0x001924, 0x2A0086, 0x00008D, 0x000464,
-       0x009D04, 0x291086, 0x180102, 0x000575,
-       0x010042, 0x28040A, 0x00018D, 0x000924,
-       0x280D02, 0x00000D, 0x000924, 0x281502,
-       0x10000D, 0x000820, 0x0002F5, 0x010040,
-       0x200007, 0x001175, 0x0002FD, 0x018042,
-       0x08000A, 0x000904, 0x24FA86, 0x000007,
-       0x000100, 0x080B20, 0x130B60, 0x1B0B60,
-       0x030A60, 0x010040, 0x050042, 0x3D004A,
-       0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
-       0x010042, 0x28140A, 0x0004F5, 0x010042,
-       0x08000A, 0x000315, 0x010D04, 0x260286,
-       0x004015, 0x000095, 0x010D04, 0x25F086,
-       0x100022, 0x10002A, 0x261A06, 0x000007,
-       0x333104, 0x2AA904, 0x000007, 0x032124,
-       0x280502, 0x284402, 0x001124, 0x400102,
-       0x000424, 0x000424, 0x003224, 0x00292C,
-       0x00636C, 0x277386, 0x000007, 0x02B164,
-       0x000464, 0x000464, 0x00008D, 0x000A64,
-       0x280D02, 0x10008D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x00008D, 0x38B904,
-       0x000007, 0x03296C, 0x30010A, 0x0002F5,
-       0x010042, 0x08000A, 0x000904, 0x270286,
-       0x000007, 0x00212C, 0x28050A, 0x00316C,
-       0x00046C, 0x00046C, 0x28450A, 0x001124,
-       0x006B64, 0x100102, 0x00008D, 0x01096C,
-       0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x004124, 0x000424,
-       0x000424, 0x003224, 0x300102, 0x032944,
-       0x27FA86, 0x000007, 0x300002, 0x0004F5,
-       0x010042, 0x08000A, 0x000315, 0x010D04,
-       0x284086, 0x003124, 0x000464, 0x300102,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x284A86, 0x000007, 0x284402, 0x003124,
-       0x300502, 0x003924, 0x300583, 0x000883,
-       0x0005F5, 0x010042, 0x28040A, 0x00008D,
-       0x008124, 0x280D02, 0x00008D, 0x008124,
-       0x281502, 0x10018D, 0x000820, 0x0002F5,
-       0x010040, 0x220007, 0x001025, 0x000575,
-       0x030042, 0x09004A, 0x10000A, 0x0A0904,
-       0x121104, 0x000007, 0x001020, 0x050860,
-       0x050040, 0x0006FD, 0x018042, 0x09004A,
-       0x10000A, 0x0000A5, 0x0A0904, 0x121104,
-       0x000007, 0x000820, 0x019060, 0x010040,
-       0x0002F5, 0x010042, 0x08000A, 0x000904,
-       0x29CA86, 0x000007, 0x244206, 0x000007,
-       0x000606, 0x000007, 0x0002F5, 0x010042,
-       0x08000A, 0x000904, 0x2A1A86, 0x000007,
-       0x000100, 0x080B20, 0x138B60, 0x1B8B60,
-       0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
-       0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
-       0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
-       0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
-       0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
-       0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-       0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
-       0x038A60, 0x000606, 0x018040, 0x00008D,
-       0x000A64, 0x280D02, 0x000A24, 0x00027D,
-       0x018042, 0x10000A, 0x001224, 0x0003FD,
-       0x018042, 0x08000A, 0x000904, 0x2C0A86,
-       0x000007, 0x00018D, 0x000A24, 0x000464,
-       0x000464, 0x080102, 0x000924, 0x000424,
-       0x000424, 0x100102, 0x02000D, 0x009144,
-       0x2C6186, 0x000007, 0x0001FD, 0x018042,
-       0x08000A, 0x000A44, 0x2C4386, 0x018042,
-       0x0A000D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00027D, 0x001020, 0x000606,
-       0x018040, 0x0002F5, 0x010042, 0x08000A,
-       0x000904, 0x2CB286, 0x000007, 0x00037D,
-       0x018042, 0x08000A, 0x000904, 0x2CE286,
-       0x000007, 0x000075, 0x002E7D, 0x010042,
-       0x0B804A, 0x000020, 0x000904, 0x000686,
-       0x010040, 0x31844A, 0x30048B, 0x000883,
-       0x00008D, 0x000810, 0x28143A, 0x00008D,
-       0x000810, 0x280C3A, 0x000675, 0x010042,
-       0x08000A, 0x003815, 0x010924, 0x280502,
-       0x0B000D, 0x000820, 0x0002F5, 0x010040,
-       0x000606, 0x220007, 0x000464, 0x000464,
-       0x000606, 0x000007, 0x000134, 0x007F8D,
-       0x00093C, 0x281D12, 0x282512, 0x001F32,
-       0x0E0007, 0x00010D, 0x00037D, 0x000820,
-       0x018040, 0x05D2F4, 0x000007, 0x080007,
-       0x00037D, 0x018042, 0x08000A, 0x000904,
-       0x2E8A86, 0x000007, 0x000606, 0x000007,
-       0x000007, 0x000012, 0x100007, 0x320007,
-       0x600007, 0x460007, 0x100080, 0x48001A,
-       0x004904, 0x2EF186, 0x000007, 0x001210,
-       0x58003A, 0x000145, 0x5C5D04, 0x000007,
-       0x000080, 0x48001A, 0x004904, 0x2F4186,
-       0x000007, 0x001210, 0x50003A, 0x005904,
-       0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
-       0x7FFF7D, 0x07D524, 0x004224, 0x500102,
-       0x200502, 0x000082, 0x40001A, 0x004104,
-       0x2FC986, 0x000007, 0x003865, 0x40001A,
-       0x004020, 0x00104D, 0x04C184, 0x31AB86,
-       0x000040, 0x040007, 0x000165, 0x000145,
-       0x004020, 0x000040, 0x000765, 0x080080,
-       0x40001A, 0x004104, 0x305986, 0x000007,
-       0x001210, 0x40003A, 0x004104, 0x30B286,
-       0x00004D, 0x0000CD, 0x004810, 0x20043A,
-       0x000882, 0x40001A, 0x004104, 0x30C186,
-       0x000007, 0x004820, 0x005904, 0x319886,
-       0x000040, 0x0007E5, 0x200480, 0x2816A0,
-       0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
-       0x000040, 0x000032, 0x400075, 0x00007D,
-       0x07D574, 0x200512, 0x000082, 0x40001A,
-       0x004104, 0x317186, 0x000007, 0x038A06,
-       0x640007, 0x0000E5, 0x000020, 0x000040,
-       0x000A65, 0x000020, 0x020040, 0x020040,
-       0x000040, 0x000165, 0x000042, 0x70000A,
-       0x007104, 0x323286, 0x000007, 0x060007,
-       0x019A06, 0x640007, 0x050000, 0x007020,
-       0x000040, 0x038A06, 0x640007, 0x000007,
-       0x00306D, 0x028860, 0x029060, 0x08000A,
-       0x028860, 0x008040, 0x100012, 0x00100D,
-       0x009184, 0x32D186, 0x000E0D, 0x009184,
-       0x33E186, 0x000007, 0x300007, 0x001020,
-       0x003B6D, 0x008040, 0x000080, 0x08001A,
-       0x000904, 0x32F186, 0x000007, 0x001220,
-       0x000DED, 0x008040, 0x008042, 0x10000A,
-       0x40000D, 0x109544, 0x000007, 0x001020,
-       0x000DED, 0x008040, 0x008042, 0x20040A,
-       0x000082, 0x08001A, 0x000904, 0x338186,
-       0x000007, 0x003B6D, 0x008042, 0x08000A,
-       0x000E15, 0x010984, 0x342B86, 0x600007,
-       0x08001A, 0x000C15, 0x010984, 0x341386,
-       0x000020, 0x1A0007, 0x0002ED, 0x008040,
-       0x620007, 0x00306D, 0x028042, 0x0A804A,
-       0x000820, 0x0A804A, 0x000606, 0x10804A,
-       0x000007, 0x282512, 0x001F32, 0x05D2F4,
-       0x54D104, 0x00735C, 0x000786, 0x000007,
-       0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
-       0x020040, 0x004820, 0x025060, 0x40000A,
-       0x024060, 0x000040, 0x454944, 0x000007,
-       0x004020, 0x003AE5, 0x000040, 0x0028E5,
-       0x000042, 0x48000A, 0x004904, 0x39F886,
-       0x002C65, 0x000042, 0x40000A, 0x0000D5,
-       0x454104, 0x000007, 0x000655, 0x054504,
-       0x368286, 0x0001D5, 0x054504, 0x368086,
-       0x002B65, 0x000042, 0x003AE5, 0x50004A,
-       0x40000A, 0x45C3D4, 0x000007, 0x454504,
-       0x000007, 0x0000CD, 0x444944, 0x000007,
-       0x454504, 0x000007, 0x00014D, 0x554944,
-       0x000007, 0x045144, 0x367986, 0x002C65,
-       0x000042, 0x48000A, 0x4CD104, 0x000007,
-       0x04C144, 0x368386, 0x000007, 0x160007,
-       0x002CE5, 0x040042, 0x40000A, 0x004020,
-       0x000040, 0x002965, 0x000042, 0x40000A,
-       0x004104, 0x36F086, 0x000007, 0x002402,
-       0x383206, 0x005C02, 0x0025E5, 0x000042,
-       0x40000A, 0x004274, 0x002AE5, 0x000042,
-       0x40000A, 0x004274, 0x500112, 0x0029E5,
-       0x000042, 0x40000A, 0x004234, 0x454104,
-       0x000007, 0x004020, 0x000040, 0x003EE5,
-       0x000020, 0x000040, 0x002DE5, 0x400152,
-       0x50000A, 0x045144, 0x37DA86, 0x0000C5,
-       0x003EE5, 0x004020, 0x000040, 0x002BE5,
-       0x000042, 0x40000A, 0x404254, 0x000007,
-       0x002AE5, 0x004020, 0x000040, 0x500132,
-       0x040134, 0x005674, 0x0029E5, 0x020042,
-       0x42000A, 0x000042, 0x50000A, 0x05417C,
-       0x0028E5, 0x000042, 0x48000A, 0x0000C5,
-       0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
-       0x020042, 0x40004A, 0x50000A, 0x00423C,
-       0x00567C, 0x0028E5, 0x004820, 0x000040,
-       0x281D12, 0x282512, 0x001F72, 0x002965,
-       0x000042, 0x40000A, 0x004104, 0x393A86,
-       0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
-       0x000042, 0x40000A, 0x004104, 0x397886,
-       0x002D65, 0x000042, 0x28340A, 0x003465,
-       0x020042, 0x42004A, 0x004020, 0x4A004A,
-       0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
-       0x39E186, 0x000007, 0x000606, 0x080007,
-       0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
-       0x020045, 0x004020, 0x000060, 0x000365,
-       0x000040, 0x002E65, 0x001A20, 0x0A1A60,
-       0x000040, 0x003465, 0x020042, 0x42004A,
-       0x004020, 0x4A004A, 0x000606, 0x50004A,
-       0x0017FD, 0x018042, 0x08000A, 0x000904,
-       0x225A86, 0x000007, 0x00107D, 0x018042,
-       0x0011FD, 0x33804A, 0x19804A, 0x20000A,
-       0x000095, 0x2A1144, 0x01A144, 0x3B9086,
-       0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
-       0x018042, 0x0010FD, 0x09804A, 0x38000A,
-       0x000095, 0x010924, 0x003A64, 0x3B8186,
-       0x000007, 0x003904, 0x3B9286, 0x000007,
-       0x3B9A06, 0x00000D, 0x00008D, 0x000820,
-       0x00387D, 0x018040, 0x700002, 0x00117D,
-       0x018042, 0x00197D, 0x29804A, 0x30000A,
-       0x380002, 0x003124, 0x000424, 0x000424,
-       0x002A24, 0x280502, 0x00068D, 0x000810,
-       0x28143A, 0x00750D, 0x00B124, 0x002264,
-       0x3D0386, 0x284402, 0x000810, 0x280C3A,
-       0x0B800D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00758D, 0x00B124, 0x100102,
-       0x012144, 0x3E4986, 0x001810, 0x10003A,
-       0x00387D, 0x018042, 0x08000A, 0x000904,
-       0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
-       0x00008D, 0x023164, 0x000A64, 0x280D02,
-       0x0B808D, 0x000820, 0x0002FD, 0x018040,
-       0x200007, 0x00387D, 0x018042, 0x08000A,
-       0x000904, 0x3E3286, 0x030000, 0x0002FD,
-       0x018042, 0x08000A, 0x000904, 0x3D8286,
-       0x000007, 0x002810, 0x28043A, 0x00750D,
-       0x030924, 0x002264, 0x280D02, 0x02316C,
-       0x28450A, 0x0B810D, 0x000820, 0x0002FD,
-       0x018040, 0x200007, 0x00008D, 0x000A24,
-       0x3E4A06, 0x100102, 0x001810, 0x10003A,
-       0x0000BD, 0x003810, 0x30043A, 0x00187D,
-       0x018042, 0x0018FD, 0x09804A, 0x20000A,
-       0x0000AD, 0x028924, 0x07212C, 0x001010,
-       0x300583, 0x300D8B, 0x3014BB, 0x301C83,
-       0x002083, 0x00137D, 0x038042, 0x33844A,
-       0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
-       0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
-       0x001E0D, 0x0005FD, 0x018042, 0x20000A,
-       0x020924, 0x00068D, 0x00A96C, 0x00009D,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x3F6A86, 0x000007, 0x280502, 0x280D0A,
-       0x284402, 0x001810, 0x28143A, 0x0C008D,
-       0x000820, 0x0002FD, 0x018040, 0x220007,
-       0x003904, 0x225886, 0x001E0D, 0x00057D,
-       0x018042, 0x20000A, 0x020924, 0x0000A5,
-       0x0002FD, 0x018042, 0x08000A, 0x000904,
-       0x402A86, 0x000007, 0x280502, 0x280C02,
-       0x002010, 0x28143A, 0x0C010D, 0x000820,
-       0x0002FD, 0x018040, 0x225A06, 0x220007,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000,
-       0x000000, 0x000000, 0x000000, 0x000000
-};
-
-#endif //_HWMCODE_
diff --git a/sound/oss/yss225.c b/sound/oss/yss225.c
deleted file mode 100644 (file)
index e700400..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-#include <linux/init.h>
-
-unsigned char page_zero[] __initdata = {
-0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
-0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00,
-0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19,
-0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01,
-0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00,
-0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02,
-0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17,
-0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00,
-0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02,
-0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40,
-0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02,
-0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00,
-0x1d, 0x02, 0xdf
-};    
-
-unsigned char page_one[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
-0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00,
-0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
-0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00,
-0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7,
-0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00,
-0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0,
-0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03,
-0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00,
-0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02,
-0x60, 0x00, 0x1b
-};
-
-unsigned char page_two[] __initdata = {
-0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4,
-0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07,
-0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46,
-0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46,
-0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07,
-0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05,
-0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05,
-0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44
-};
-
-unsigned char page_three[] __initdata = {
-0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
-0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40,
-0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00,
-0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40
-};
-
-unsigned char page_four[] __initdata = {
-0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
-0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00,
-0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60,
-0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00,
-0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22,
-0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01
-};
-
-unsigned char page_six[] __initdata = {
-0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
-0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e,
-0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00,
-0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24,
-0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00,
-0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00,
-0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a,
-0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d,
-0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50,
-0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00,
-0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17,
-0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66,
-0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c,
-0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00,
-0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c,
-0x80, 0x00, 0x7e, 0x80, 0x80
-};
-
-unsigned char page_seven[] __initdata = {
-0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f,
-0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff,
-0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f,
-0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38,
-0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06,
-0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b,
-0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06,
-0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55,
-0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14,
-0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93,
-0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00
-};
-
-unsigned char page_zero_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_one_v2[] __initdata = {
-0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_two_v2[] __initdata = {
-0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_three_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-unsigned char page_four_v2[] __initdata = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00
-};
-
-unsigned char page_seven_v2[] __initdata = {
-0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-unsigned char mod_v2[] __initdata = {
-0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02,
-0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05,
-0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0,
-0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20,
-0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3,
-0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff,
-0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16,
-0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff,
-0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31,
-0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00,
-0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44,
-0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00,
-0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57,
-0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00,
-0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72,
-0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0,
-0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85,
-0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00,
-0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0,
-0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00,
-0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3,
-0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00,
-0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6,
-0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00,
-0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02,
-0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03,
-0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01,
-0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01
-};
-unsigned char coefficients[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03,
-0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49,
-0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01,
-0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00,
-0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47,
-0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07,
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00,
-0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01,
-0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43,
-0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07,
-0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00,
-0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02,
-0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44,
-0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07,
-0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40,
-0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a,
-0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56,
-0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07,
-0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda,
-0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05,
-0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79,
-0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07,
-0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52,
-0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03,
-0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a,
-0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06,
-0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3,
-0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20,
-0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c,
-0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06,
-0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48,
-0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02,
-0xba
-};
-unsigned char coefficients2[] __initdata = {
-0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f,
-0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d,
-0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07,
-0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00,
-0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00
-};
-unsigned char coefficients3[] __initdata = { 
-0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00,
-0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc,
-0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01,
-0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99,
-0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02,
-0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f,
-0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03,
-0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c,
-0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03,
-0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51,
-0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04,
-0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e,
-0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05,
-0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14,
-0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06,
-0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1,
-0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07,
-0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7,
-0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08,
-0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3,
-0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09,
-0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99,
-0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a,
-0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66,
-0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a,
-0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c,
-0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b,
-0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28,
-0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c,
-0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e,
-0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d,
-0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb,
-0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e,
-0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1,
-0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f,
-0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae,
-0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff
-};
-
diff --git a/sound/oss/yss225.h b/sound/oss/yss225.h
deleted file mode 100644 (file)
index 56d8b6b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __yss255_h__
-#define __yss255_h__
-
-extern unsigned char page_zero[256];
-extern unsigned char page_one[256];
-extern unsigned char page_two[128];
-extern unsigned char page_three[128];
-extern unsigned char page_four[128];
-extern unsigned char page_six[192];
-extern unsigned char page_seven[256];
-extern unsigned char page_zero_v2[96];
-extern unsigned char page_one_v2[96];
-extern unsigned char page_two_v2[48];
-extern unsigned char page_three_v2[48];
-extern unsigned char page_four_v2[48];
-extern unsigned char page_seven_v2[96];
-extern unsigned char mod_v2[304];
-extern unsigned char coefficients[364];
-extern unsigned char coefficients2[56];
-extern unsigned char coefficients3[404];
-
-
-#endif /* __ys225_h__ */
-
index 0b0a016ca6d691563eac593634bc9dbdb3a39a7f..5322c50c9617c2f8aa0850b60e873a5caef26c2d 100644 (file)
@@ -365,25 +365,6 @@ int register_sound_dsp(const struct file_operations *fops, int dev)
 
 EXPORT_SYMBOL(register_sound_dsp);
 
-/**
- *     register_sound_synth - register a synth device
- *     @fops: File operations for the driver
- *     @dev: Unit number to allocate
- *
- *     Allocate a synth device. Unit is the number of the synth device requested.
- *     Pass -1 to request the next free synth unit. On success the allocated
- *     number is returned, on failure a negative error code is returned.
- */
-
-
-int register_sound_synth(const struct file_operations *fops, int dev)
-{
-       return sound_insert_unit(&chains[9], fops, dev, 9, 137,
-                                "synth", S_IRUSR | S_IWUSR, NULL);
-}
-
-EXPORT_SYMBOL(register_sound_synth);
-
 /**
  *     unregister_sound_special - unregister a special sound device
  *     @unit: unit number to allocate
@@ -449,21 +430,6 @@ void unregister_sound_dsp(int unit)
 
 EXPORT_SYMBOL(unregister_sound_dsp);
 
-/**
- *     unregister_sound_synth - unregister a synth device
- *     @unit: unit number to allocate
- *
- *     Release a sound device that was allocated with register_sound_synth().
- *     The unit passed is the return value from the register function.
- */
-
-void unregister_sound_synth(int unit)
-{
-       return sound_remove_unit(&chains[9], unit);
-}
-
-EXPORT_SYMBOL(unregister_sound_synth);
-
 /*
  *     Now our file operations
  */