[POWERPC] Remove the unused HTDMSOUND driver
authorAdrian Bunk <bunk@stusta.de>
Sat, 28 Apr 2007 19:19:56 +0000 (05:19 +1000)
committerPaul Mackerras <paulus@samba.org>
Mon, 30 Apr 2007 01:02:05 +0000 (11:02 +1000)
Recently, someone fixed a syntax error in the HTDMSOUND driver
introduced 4 years ago.

Unfortunately not by trying to compile this driver for his hardware but
by code inspection - which seems to be a strong indication that there
are no users left for this OSS sound driver.

This patch therefore removes it.

Signed-off-by: Adrian Bunk <bunk@stusta.de>
Acked-by: Dan Malek <dan@embeddedalley.com>
Acked-by: Marcelo Tosatti <marcelo@kvack.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/ppc/8xx_io/Kconfig
arch/ppc/8xx_io/Makefile
arch/ppc/8xx_io/cs4218.h [deleted file]
arch/ppc/8xx_io/cs4218_tdm.c [deleted file]
arch/ppc/platforms/rpxclassic.h
arch/ppc/platforms/rpxhiox.h [deleted file]
arch/ppc/platforms/rpxlite.h
arch/ppc/syslib/m8xx_setup.c

index 57dacf9..c623e44 100644 (file)
@@ -74,10 +74,6 @@ config ENET_BIG_BUFFERS
          Allocate large buffers for MPC8xx Ethernet. Increases throughput
          and decreases the likelihood of dropped packets, but costs memory.
 
-config HTDMSOUND
-       bool "Embedded Planet HIOX Audio"
-       depends on SOUND=y
-
 # This doesn't really belong here, but it is convenient to ask
 # 8xx specific questions.
 comment "Generic MPC8xx Options"
index d876018..1051a06 100644 (file)
@@ -7,4 +7,3 @@ obj-y                   := commproc.o
 obj-$(CONFIG_FEC_ENET) += fec.o
 obj-$(CONFIG_SCC_ENET) += enet.o
 obj-$(CONFIG_UCODE_PATCH) += micropatch.o
-obj-$(CONFIG_HTDMSOUND) += cs4218_tdm.o
diff --git a/arch/ppc/8xx_io/cs4218.h b/arch/ppc/8xx_io/cs4218.h
deleted file mode 100644 (file)
index e5f9430..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-#ifndef _cs4218_h_
-/*
- *  Hacked version of linux/drivers/sound/dmasound/dmasound.h
- *
- *
- *  Minor numbers for the sound driver.
- *
- *  Unfortunately Creative called the codec chip of SB as a DSP. For this
- *  reason the /dev/dsp is reserved for digitized audio use. There is a
- *  device for true DSP processors but it will be called something else.
- *  In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-#define _cs4218_h_
-
-#include <linux/types.h>
-
-#define SND_NDEVS      256     /* Number of supported devices */
-#define SND_DEV_CTL    0       /* Control port /dev/mixer */
-#define SND_DEV_SEQ    1       /* Sequencer output /dev/sequencer (FM
-                                  synthesizer and MIDI output) */
-#define SND_DEV_MIDIN  2       /* Raw midi access */
-#define SND_DEV_DSP    3       /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO  4       /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16  5       /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6       /* /dev/sndstat */
-/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2   8       /* /dev/sequencer, level 2 interface */
-#define SND_DEV_SNDPROC 9      /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS    SND_DEV_SNDPROC
-
-/* switch on various prinks */
-#define DEBUG_DMASOUND 1
-
-#define MAX_AUDIO_DEV  5
-#define MAX_MIXER_DEV  4
-#define MAX_SYNTH_DEV  3
-#define MAX_MIDI_DEV   6
-#define MAX_TIMER_DEV  3
-
-#define MAX_CATCH_RADIUS       10
-
-#define le2be16(x)     (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
-#define le2be16dbl(x)  (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
-
-#define IOCTL_IN(arg, ret) \
-       do { int error = get_user(ret, (int *)(arg)); \
-               if (error) return error; \
-       } while (0)
-#define IOCTL_OUT(arg, ret)    ioctl_return((int *)(arg), ret)
-
-static inline int ioctl_return(int *addr, int value)
-{
-       return value < 0 ? value : put_user(value, addr);
-}
-
-#define HAS_RECORD
-
-    /*
-     *  Initialization
-     */
-
-/* description of the set-up applies to either hard or soft settings */
-
-typedef struct {
-    int format;                /* AFMT_* */
-    int stereo;                /* 0 = mono, 1 = stereo */
-    int size;          /* 8/16 bit*/
-    int speed;         /* speed */
-} SETTINGS;
-
-    /*
-     *  Machine definitions
-     */
-
-typedef struct {
-    const char *name;
-    const char *name2;
-    void (*open)(void);
-    void (*release)(void);
-    void *(*dma_alloc)(unsigned int, gfp_t);
-    void (*dma_free)(void *, unsigned int);
-    int (*irqinit)(void);
-#ifdef MODULE
-    void (*irqcleanup)(void);
-#endif
-    void (*init)(void);
-    void (*silence)(void);
-    int (*setFormat)(int);
-    int (*setVolume)(int);
-    int (*setBass)(int);
-    int (*setTreble)(int);
-    int (*setGain)(int);
-    void (*play)(void);
-    void (*record)(void);              /* optional */
-    void (*mixer_init)(void);          /* optional */
-    int (*mixer_ioctl)(u_int, u_long); /* optional */
-    int (*write_sq_setup)(void);       /* optional */
-    int (*read_sq_setup)(void);                /* optional */
-    int (*sq_open)(mode_t);            /* optional */
-    int (*state_info)(char *, size_t); /* optional */
-    void (*abort_read)(void);          /* optional */
-    int min_dsp_speed;
-    int max_dsp_speed;
-    int version ;
-    int hardware_afmts ;               /* OSS says we only return h'ware info */
-                                       /* when queried via SNDCTL_DSP_GETFMTS */
-    int capabilities ;         /* low-level reply to SNDCTL_DSP_GETCAPS */
-    SETTINGS default_hard ;    /* open() or init() should set something valid */
-    SETTINGS default_soft ;    /* you can make it look like old OSS, if you want to */
-} MACHINE;
-
-    /*
-     *  Low level stuff
-     */
-
-typedef struct {
-    ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-    ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-} TRANS;
-
-
-    /*
-     * Sound queue stuff, the heart of the driver
-     */
-
-struct sound_queue {
-    /* buffers allocated for this queue */
-    int numBufs;               /* real limits on what the user can have */
-    int bufSize;               /* in bytes */
-    char **buffers;
-
-    /* current parameters */
-    int locked ;               /* params cannot be modified when != 0 */
-    int user_frags ;           /* user requests this many */
-    int user_frag_size ;       /* of this size */
-    int max_count;             /* actual # fragments <= numBufs */
-    int block_size;            /* internal block size in bytes */
-    int max_active;            /* in-use fragments <= max_count */
-
-    /* it shouldn't be necessary to declare any of these volatile */
-    int front, rear, count;
-    int rear_size;
-    /*
-     * The use of the playing field depends on the hardware
-     *
-     * Atari, PMac: The number of frames that are loaded/playing
-     *
-     * Amiga: Bit 0 is set: a frame is loaded
-     *        Bit 1 is set: a frame is playing
-     */
-    int active;
-    wait_queue_head_t action_queue, open_queue, sync_queue;
-    int open_mode;
-    int busy, syncing, xruns, died;
-};
-
-#define SLEEP(queue)           interruptible_sleep_on_timeout(&queue, HZ)
-#define WAKE_UP(queue)         (wake_up_interruptible(&queue))
-
-#endif /* _cs4218_h_ */
diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c
deleted file mode 100644 (file)
index a956f28..0000000
+++ /dev/null
@@ -1,2833 +0,0 @@
-
-/* This is a modified version of linux/drivers/sound/dmasound.c to
- * support the CS4218 codec on the 8xx TDM port.  Thanks to everyone
- * that contributed to the dmasound software (which includes me :-).
- *
- * The CS4218 is configured in Mode 4, sub-mode 0.  This provides
- * left/right data only on the TDM port, as a 32-bit word, per frame
- * pulse.  The control of the CS4218 is provided by some other means,
- * like the SPI port.
- * Dan Malek (dmalek@jlc.net)
- */
-
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/major.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/sound.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-/* Should probably do something different with this path name.....
- * Actually, I should just stop using it...
- */
-#include "cs4218.h"
-#include <linux/soundcard.h>
-
-#include <asm/mpc8xx.h>
-#include <asm/8xx_immap.h>
-#include <asm/commproc.h>
-
-#define DMASND_CS4218          5
-
-#define MAX_CATCH_RADIUS       10
-#define MIN_BUFFERS            4
-#define MIN_BUFSIZE            4
-#define MAX_BUFSIZE            128
-
-#define HAS_8BIT_TABLES
-
-static int sq_unit = -1;
-static int mixer_unit = -1;
-static int state_unit = -1;
-static int irq_installed = 0;
-static char **sound_buffers = NULL;
-static char **sound_read_buffers = NULL;
-
-static DEFINE_SPINLOCK(cs4218_lock);
-
-/* Local copies of things we put in the control register.  Output
- * volume, like most codecs is really attenuation.
- */
-static int cs4218_rate_index;
-
-/*
- * Stuff for outputting a beep.  The values range from -327 to +327
- * so we can multiply by an amplitude in the range 0..100 to get a
- * signed short value to put in the output buffer.
- */
-static short beep_wform[256] = {
-       0,      40,     79,     117,    153,    187,    218,    245,
-       269,    288,    304,    316,    323,    327,    327,    324,
-       318,    310,    299,    288,    275,    262,    249,    236,
-       224,    213,    204,    196,    190,    186,    183,    182,
-       182,    183,    186,    189,    192,    196,    200,    203,
-       206,    208,    209,    209,    209,    207,    204,    201,
-       197,    193,    188,    183,    179,    174,    170,    166,
-       163,    161,    160,    159,    159,    160,    161,    162,
-       164,    166,    168,    169,    171,    171,    171,    170,
-       169,    167,    163,    159,    155,    150,    144,    139,
-       133,    128,    122,    117,    113,    110,    107,    105,
-       103,    103,    103,    103,    104,    104,    105,    105,
-       105,    103,    101,    97,     92,     86,     78,     68,
-       58,     45,     32,     18,     3,      -11,    -26,    -41,
-       -55,    -68,    -79,    -88,    -95,    -100,   -102,   -102,
-       -99,    -93,    -85,    -75,    -62,    -48,    -33,    -16,
-       0,      16,     33,     48,     62,     75,     85,     93,
-       99,     102,    102,    100,    95,     88,     79,     68,
-       55,     41,     26,     11,     -3,     -18,    -32,    -45,
-       -58,    -68,    -78,    -86,    -92,    -97,    -101,   -103,
-       -105,   -105,   -105,   -104,   -104,   -103,   -103,   -103,
-       -103,   -105,   -107,   -110,   -113,   -117,   -122,   -128,
-       -133,   -139,   -144,   -150,   -155,   -159,   -163,   -167,
-       -169,   -170,   -171,   -171,   -171,   -169,   -168,   -166,
-       -164,   -162,   -161,   -160,   -159,   -159,   -160,   -161,
-       -163,   -166,   -170,   -174,   -179,   -183,   -188,   -193,
-       -197,   -201,   -204,   -207,   -209,   -209,   -209,   -208,
-       -206,   -203,   -200,   -196,   -192,   -189,   -186,   -183,
-       -182,   -182,   -183,   -186,   -190,   -196,   -204,   -213,
-       -224,   -236,   -249,   -262,   -275,   -288,   -299,   -310,
-       -318,   -324,   -327,   -327,   -323,   -316,   -304,   -288,
-       -269,   -245,   -218,   -187,   -153,   -117,   -79,    -40,
-};
-
-#define BEEP_SPEED     5       /* 22050 Hz sample rate */
-#define BEEP_BUFLEN    512
-#define BEEP_VOLUME    15      /* 0 - 100 */
-
-static int beep_volume = BEEP_VOLUME;
-static int beep_playing = 0;
-static int beep_state = 0;
-static short *beep_buf;
-static void (*orig_mksound)(unsigned int, unsigned int);
-
-/* This is found someplace else......I guess in the keyboard driver
- * we don't include.
- */
-static void (*kd_mksound)(unsigned int, unsigned int);
-
-static int catchRadius = 0;
-static int numBufs = 4, bufSize = 32;
-static int numReadBufs = 4, readbufSize = 32;
-
-
-/* TDM/Serial transmit and receive buffer descriptors.
-*/
-static volatile cbd_t  *rx_base, *rx_cur, *tx_base, *tx_cur;
-
-module_param(catchRadius, int, 0);
-module_param(numBufs, int, 0);
-module_param(bufSize, int, 0);
-module_param(numreadBufs, int, 0);
-module_param(readbufSize, int, 0);
-
-#define arraysize(x)   (sizeof(x)/sizeof(*(x)))
-#define le2be16(x)     (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
-#define le2be16dbl(x)  (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
-
-#define IOCTL_IN(arg, ret) \
-       do { int error = get_user(ret, (int *)(arg)); \
-               if (error) return error; \
-       } while (0)
-#define IOCTL_OUT(arg, ret)    ioctl_return((int *)(arg), ret)
-
-/* CS4218 serial port control in mode 4.
-*/
-#define CS_INTMASK     ((uint)0x40000000)
-#define CS_DO1         ((uint)0x20000000)
-#define CS_LATTEN      ((uint)0x1f000000)
-#define CS_RATTEN      ((uint)0x00f80000)
-#define CS_MUTE                ((uint)0x00040000)
-#define CS_ISL         ((uint)0x00020000)
-#define CS_ISR         ((uint)0x00010000)
-#define CS_LGAIN       ((uint)0x0000f000)
-#define CS_RGAIN       ((uint)0x00000f00)
-
-#define CS_LATTEN_SET(X)       (((X) & 0x1f) << 24)
-#define CS_RATTEN_SET(X)       (((X) & 0x1f) << 19)
-#define CS_LGAIN_SET(X)                (((X) & 0x0f) << 12)
-#define CS_RGAIN_SET(X)                (((X) & 0x0f) << 8)
-
-#define CS_LATTEN_GET(X)       (((X) >> 24) & 0x1f)
-#define CS_RATTEN_GET(X)       (((X) >> 19) & 0x1f)
-#define CS_LGAIN_GET(X)                (((X) >> 12) & 0x0f)
-#define CS_RGAIN_GET(X)                (((X) >> 8) & 0x0f)
-
-/* The control register is effectively write only.  We have to keep a copy
- * of what we write.
- */
-static uint    cs4218_control;
-
-/* A place to store expanding information.
-*/
-static int     expand_bal;
-static int     expand_data;
-
-/* Since I can't make the microcode patch work for the SPI, I just
- * clock the bits using software.
- */
-static void    sw_spi_init(void);
-static void    sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt);
-static uint    cs4218_ctl_write(uint ctlreg);
-
-/*** Some low level helpers **************************************************/
-
-/* 16 bit mu-law */
-
-static short ulaw2dma16[] = {
-       -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
-       -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
-       -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
-       -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
-       -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
-       -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
-       -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
-       -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
-       -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
-       -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
-       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
-       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
-       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
-       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
-       -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
-       -56,    -48,    -40,    -32,    -24,    -16,    -8,     0,
-       32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
-       23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
-       15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
-       11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
-       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
-       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
-       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
-       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
-       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
-       1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
-       876,    844,    812,    780,    748,    716,    684,    652,
-       620,    588,    556,    524,    492,    460,    428,    396,
-       372,    356,    340,    324,    308,    292,    276,    260,
-       244,    228,    212,    196,    180,    164,    148,    132,
-       120,    112,    104,    96,     88,     80,     72,     64,
-       56,     48,     40,     32,     24,     16,     8,      0,
-};
-
-/* 16 bit A-law */
-
-static short alaw2dma16[] = {
-       -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
-       -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
-       -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
-       -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
-       -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-       -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
-       -11008, -10496, -12032, -11520, -8960,  -8448,  -9984,  -9472,
-       -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
-       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
-       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
-       -88,    -72,    -120,   -104,   -24,    -8,     -56,    -40,
-       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
-       -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
-       -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
-       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
-       -944,   -912,   -1008,  -976,   -816,   -784,   -880,   -848,
-       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
-       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
-       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
-       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
-       22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
-       30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
-       11008,  10496,  12032,  11520,  8960,   8448,   9984,   9472,
-       15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
-       344,    328,    376,    360,    280,    264,    312,    296,
-       472,    456,    504,    488,    408,    392,    440,    424,
-       88,     72,     120,    104,    24,     8,      56,     40,
-       216,    200,    248,    232,    152,    136,    184,    168,
-       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
-       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
-       688,    656,    752,    720,    560,    528,    624,    592,
-       944,    912,    1008,   976,    816,    784,    880,    848,
-};
-
-
-/*** Translations ************************************************************/
-
-
-static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft);
-static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft);
-static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft);
-static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft);
-
-
-/*** Low level stuff *********************************************************/
-
-struct cs_sound_settings {
-       MACHINE mach;           /* machine dependent things */
-       SETTINGS hard;          /* hardware settings */
-       SETTINGS soft;          /* software settings */
-       SETTINGS dsp;           /* /dev/dsp default settings */
-       TRANS *trans_write;     /* supported translations for playback */
-       TRANS *trans_read;      /* supported translations for record */
-       int volume_left;        /* volume (range is machine dependent) */
-       int volume_right;
-       int bass;               /* tone (range is machine dependent) */
-       int treble;
-       int gain;
-       int minDev;             /* minor device number currently open */
-};
-
-static struct cs_sound_settings sound;
-
-static void *CS_Alloc(unsigned int size, gfp_t flags);
-static void CS_Free(void *ptr, unsigned int size);
-static int CS_IrqInit(void);
-#ifdef MODULE
-static void CS_IrqCleanup(void);
-#endif /* MODULE */
-static void CS_Silence(void);
-static void CS_Init(void);
-static void CS_Play(void);
-static void CS_Record(void);
-static int CS_SetFormat(int format);
-static int CS_SetVolume(int volume);
-static void cs4218_tdm_tx_intr(void *devid);
-static void cs4218_tdm_rx_intr(void *devid);
-static void cs4218_intr(void *devid);
-static int cs_get_volume(uint reg);
-static int cs_volume_setter(int volume, int mute);
-static int cs_get_gain(uint reg);
-static int cs_set_gain(int gain);
-static void cs_mksound(unsigned int hz, unsigned int ticks);
-static void cs_nosound(unsigned long xx);
-
-/*** Mid level stuff *********************************************************/
-
-
-static void sound_silence(void);
-static void sound_init(void);
-static int sound_set_format(int format);
-static int sound_set_speed(int speed);
-static int sound_set_stereo(int stereo);
-static int sound_set_volume(int volume);
-
-static ssize_t sound_copy_translate(const u_char *userPtr,
-                                   size_t userCount,
-                                   u_char frame[], ssize_t *frameUsed,
-                                   ssize_t frameLeft);
-static ssize_t sound_copy_translate_read(const u_char *userPtr,
-                                   size_t userCount,
-                                   u_char frame[], ssize_t *frameUsed,
-                                   ssize_t frameLeft);
-
-
-/*
- * /dev/mixer abstraction
- */
-
-struct sound_mixer {
-    int busy;
-    int modify_counter;
-};
-
-static struct sound_mixer mixer;
-
-static struct sound_queue sq;
-static struct sound_queue read_sq;
-
-#define sq_block_address(i)    (sq.buffers[i])
-#define SIGNAL_RECEIVED        (signal_pending(current))
-#define NON_BLOCKING(open_mode)        (open_mode & O_NONBLOCK)
-#define ONE_SECOND     HZ      /* in jiffies (100ths of a second) */
-#define NO_TIME_LIMIT  0xffffffff
-
-/*
- * /dev/sndstat
- */
-
-struct sound_state {
-       int busy;
-       char buf[512];
-       int len, ptr;
-};
-
-static struct sound_state state;
-
-/*** Common stuff ********************************************************/
-
-static long long sound_lseek(struct file *file, long long offset, int orig);
-
-/*** Config & Setup **********************************************************/
-
-void dmasound_setup(char *str, int *ints);
-
-/*** Translations ************************************************************/
-
-
-/* ++TeSche: radically changed for new expanding purposes...
- *
- * These two routines now deal with copying/expanding/translating the samples
- * from user space into our buffer at the right frequency. They take care about
- * how much data there's actually to read, how much buffer space there is and
- * to convert samples into the right frequency/encoding. They will only work on
- * complete samples so it may happen they leave some bytes in the input stream
- * if the user didn't write a multiple of the current sample size. They both
- * return the number of bytes they've used from both streams so you may detect
- * such a situation. Luckily all programs should be able to cope with that.
- *
- * I think I've optimized anything as far as one can do in plain C, all
- * variables should fit in registers and the loops are really short. There's
- * one loop for every possible situation. Writing a more generalized and thus
- * parameterized loop would only produce slower code. Feel free to optimize
- * this in assembler if you like. :)
- *
- * I think these routines belong here because they're not yet really hardware
- * independent, especially the fact that the Falcon can play 16bit samples
- * only in stereo is hardcoded in both of them!
- *
- * ++geert: split in even more functions (one per format)
- */
-
-static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = table[data];
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = table[data];
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = data << 8;
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = data << 8;
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-               if (get_user(data, userPtr++))
-                       return -EFAULT;
-               val = (data ^ 0x80) << 8;
-               *p++ = val;
-               if (stereo) {
-                       if (get_user(data, userPtr++))
-                               return -EFAULT;
-                       val = (data ^ 0x80) << 8;
-               }
-               *p++ = val;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-/* This is the default format of the codec.  Signed, 16-bit stereo
- * generated by an application shouldn't have to be copied at all.
- * We should just get the phsical address of the buffers and update
- * the TDM BDs directly.
- */
-static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int stereo = sound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min(userCount, frameLeft);
-       if (!stereo) {
-               short *up = (short *) userPtr;
-               while (count > 0) {
-                       short data;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       *fp++ = data;
-                       *fp++ = data;
-                       count--;
-               }
-       } else {
-               if (copy_from_user(fp, userPtr, count * 4))
-                       return -EFAULT;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       int stereo = sound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-       short *up = (short *) userPtr;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               int data;
-               if (get_user(data, up++))
-                       return -EFAULT;
-               data ^= mask;
-               *fp++ = data;
-               if (stereo) {
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       data ^= mask;
-               }
-               *fp++ = data;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-
-static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       unsigned short *table = (unsigned short *)
-               (sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16);
-       unsigned int data = expand_data;
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       int bal = expand_bal;
-       int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-       int utotal, ftotal;
-       int stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = table[c];
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + table[c];
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       int bal = expand_bal;
-       int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-       int stereo = sound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = c << 8;
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + (c << 8);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       int bal = expand_bal;
-       int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-       int stereo = sound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               u_char c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(c, userPtr++))
-                               return -EFAULT;
-                       data = (c ^ 0x80) << 8;
-                       if (stereo) {
-                               if (get_user(c, userPtr++))
-                                       return -EFAULT;
-                               data = (data << 16) + ((c ^ 0x80) << 8);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 2: utotal;
-}
-
-
-static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       unsigned short *up = (unsigned short *) userPtr;
-       int bal = expand_bal;
-       int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-       int stereo = sound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               unsigned short c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       if (stereo) {
-                               if (get_user(c, up++))
-                                       return -EFAULT;
-                               data = (data << 16) + c;
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-
-static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount,
-                           u_char frame[], ssize_t *frameUsed,
-                           ssize_t frameLeft)
-{
-       int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       unsigned int *p = (unsigned int *) &frame[*frameUsed];
-       unsigned int data = expand_data;
-       unsigned short *up = (unsigned short *) userPtr;
-       int bal = expand_bal;
-       int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
-       int stereo = sound.soft.stereo;
-       int utotal, ftotal;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       ftotal = frameLeft;
-       utotal = userCount;
-       while (frameLeft) {
-               unsigned short c;
-               if (bal < 0) {
-                       if (userCount == 0)
-                               break;
-                       if (get_user(data, up++))
-                               return -EFAULT;
-                       data ^= mask;
-                       if (stereo) {
-                               if (get_user(c, up++))
-                                       return -EFAULT;
-                               data = (data << 16) + (c ^ mask);
-                       } else
-                               data = (data << 16) + data;
-                       userCount--;
-                       bal += hSpeed;
-               }
-               *p++ = data;
-               frameLeft--;
-               bal -= sSpeed;
-       }
-       expand_bal = bal;
-       expand_data = data;
-       *frameUsed += (ftotal - frameLeft) * 4;
-       utotal -= userCount;
-       return stereo? utotal * 4: utotal * 2;
-}
-
-static ssize_t cs4218_ct_s8_read(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-
-               val = *p++;
-               data = val >> 8;
-               if (put_user(data, (u_char *)userPtr++))
-                       return -EFAULT;
-               if (stereo) {
-                       val = *p;
-                       data = val >> 8;
-                       if (put_user(data, (u_char *)userPtr++))
-                               return -EFAULT;
-               }
-               p++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t cs4218_ct_u8_read(const u_char *userPtr, size_t userCount,
-                         u_char frame[], ssize_t *frameUsed,
-                         ssize_t frameLeft)
-{
-       ssize_t count, used;
-       short *p = (short *) &frame[*frameUsed];
-       int val, stereo = sound.soft.stereo;
-
-       frameLeft >>= 2;
-       if (stereo)
-               userCount >>= 1;
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               u_char data;
-
-               val = *p++;
-               data = (val >> 8) ^ 0x80;
-               if (put_user(data, (u_char *)userPtr++))
-                       return -EFAULT;
-               if (stereo) {
-                       val = *p;
-                       data = (val >> 8) ^ 0x80;
-                       if (put_user(data, (u_char *)userPtr++))
-                               return -EFAULT;
-               }
-               p++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 2: used;
-}
-
-
-static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int stereo = sound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min(userCount, frameLeft);
-       if (!stereo) {
-               short *up = (short *) userPtr;
-               while (count > 0) {
-                       short data;
-                       data = *fp;
-                       if (put_user(data, up++))
-                               return -EFAULT;
-                       fp+=2;
-                       count--;
-               }
-       } else {
-               if (copy_to_user((u_char *)userPtr, fp, count * 4))
-                       return -EFAULT;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount,
-                          u_char frame[], ssize_t *frameUsed,
-                          ssize_t frameLeft)
-{
-       ssize_t count, used;
-       int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-       int stereo = sound.soft.stereo;
-       short *fp = (short *) &frame[*frameUsed];
-       short *up = (short *) userPtr;
-
-       frameLeft >>= 2;
-       userCount >>= (stereo? 2: 1);
-       used = count = min(userCount, frameLeft);
-       while (count > 0) {
-               int data;
-
-               data = *fp++;
-               data ^= mask;
-               if (put_user(data, up++))
-                       return -EFAULT;
-               if (stereo) {
-                       data = *fp;
-                       data ^= mask;
-                       if (put_user(data, up++))
-                               return -EFAULT;
-               }
-               fp++;
-               count--;
-       }
-       *frameUsed += used * 4;
-       return stereo? used * 4: used * 2;
-}
-
-static TRANS transCSNormal = {
-       cs4218_ct_law, cs4218_ct_law, cs4218_ct_s8, cs4218_ct_u8,
-       cs4218_ct_s16, cs4218_ct_u16, cs4218_ct_s16, cs4218_ct_u16
-};
-
-static TRANS transCSExpand = {
-       cs4218_ctx_law, cs4218_ctx_law, cs4218_ctx_s8, cs4218_ctx_u8,
-       cs4218_ctx_s16, cs4218_ctx_u16, cs4218_ctx_s16, cs4218_ctx_u16
-};
-
-static TRANS transCSNormalRead = {
-       NULL, NULL, cs4218_ct_s8_read, cs4218_ct_u8_read,
-       cs4218_ct_s16_read, cs4218_ct_u16_read,
-       cs4218_ct_s16_read, cs4218_ct_u16_read
-};
-
-/*** Low level stuff *********************************************************/
-
-static void *CS_Alloc(unsigned int size, gfp_t flags)
-{
-       int     order;
-
-       size >>= 13;
-       for (order=0; order < 5; order++) {
-               if (size == 0)
-                       break;
-               size >>= 1;
-       }
-       return (void *)__get_free_pages(flags, order);
-}
-
-static void CS_Free(void *ptr, unsigned int size)
-{
-       int     order;
-
-       size >>= 13;
-       for (order=0; order < 5; order++) {
-               if (size == 0)
-                       break;
-               size >>= 1;
-       }
-       free_pages((ulong)ptr, order);
-}
-
-static int __init CS_IrqInit(void)
-{
-       cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL);
-       return 1;
-}
-
-#ifdef MODULE
-static void CS_IrqCleanup(void)
-{
-       volatile smc_t          *sp;
-       volatile cpm8xx_t       *cp;
-
-       /* First disable transmitter and receiver.
-       */
-       sp = &cpmp->cp_smc[1];
-       sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
-
-       /* And now shut down the SMC.
-       */
-       cp = cpmp;      /* Get pointer to Communication Processor */
-       cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
-                               CPM_CR_STOP_TX) | CPM_CR_FLG;
-       while (cp->cp_cpcr & CPM_CR_FLG);
-
-       /* Release the interrupt handler.
-       */
-       cpm_free_handler(CPMVEC_SMC2);
-
-       kfree(beep_buf);
-       kd_mksound = orig_mksound;
-}
-#endif /* MODULE */
-
-static void CS_Silence(void)
-{
-       volatile smc_t          *sp;
-
-       /* Disable transmitter.
-       */
-       sp = &cpmp->cp_smc[1];
-       sp->smc_smcmr &= ~SMCMR_TEN;
-}
-
-/* Frequencies depend upon external oscillator.  There are two
- * choices, 12.288 and 11.2896 MHz.  The RPCG audio supports both through
- * and external control register selection bit.
- */
-static int cs4218_freqs[] = {
-    /* 12.288  11.2896  */
-       48000, 44100,
-       32000, 29400,
-       24000, 22050,
-       19200, 17640,
-       16000, 14700,
-       12000, 11025,
-        9600,  8820,
-        8000,  7350
-};
-
-static void CS_Init(void)
-{
-       int i, tolerance;
-
-       switch (sound.soft.format) {
-       case AFMT_S16_LE:
-       case AFMT_U16_LE:
-               sound.hard.format = AFMT_S16_LE;
-               break;
-       default:
-               sound.hard.format = AFMT_S16_BE;
-               break;
-       }
-       sound.hard.stereo = 1;
-       sound.hard.size = 16;
-
-       /*
-        * If we have a sample rate which is within catchRadius percent
-        * of the requested value, we don't have to expand the samples.
-        * Otherwise choose the next higher rate.
-        */
-       i = (sizeof(cs4218_freqs) / sizeof(int));
-       do {
-               tolerance = catchRadius * cs4218_freqs[--i] / 100;
-       } while (sound.soft.speed > cs4218_freqs[i] + tolerance && i > 0);
-       if (sound.soft.speed >= cs4218_freqs[i] - tolerance)
-               sound.trans_write = &transCSNormal;
-       else
-               sound.trans_write = &transCSExpand;
-       sound.trans_read = &transCSNormalRead;
-       sound.hard.speed = cs4218_freqs[i];
-       cs4218_rate_index = i;
-
-       /* The CS4218 has seven selectable clock dividers for the sample
-        * clock.  The HIOX then provides one of two external rates.
-        * An even numbered frequency table index uses the high external
-        * clock rate.
-        */
-       *(uint *)HIOX_CSR4_ADDR &= ~(HIOX_CSR4_AUDCLKHI | HIOX_CSR4_AUDCLKSEL);
-       if ((i & 1) == 0)
-               *(uint *)HIOX_CSR4_ADDR |= HIOX_CSR4_AUDCLKHI;
-       i >>= 1;
-       *(uint *)HIOX_CSR4_ADDR |= (i & HIOX_CSR4_AUDCLKSEL);
-
-       expand_bal = -sound.soft.speed;
-}
-
-static int CS_SetFormat(int format)
-{
-       int size;
-
-       switch (format) {
-       case AFMT_QUERY:
-               return sound.soft.format;
-       case AFMT_MU_LAW:
-       case AFMT_A_LAW:
-       case AFMT_U8:
-       case AFMT_S8:
-               size = 8;
-               break;
-       case AFMT_S16_BE:
-       case AFMT_U16_BE:
-       case AFMT_S16_LE:
-       case AFMT_U16_LE:
-               size = 16;
-               break;
-       default: /* :-) */
-               printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
-                      format);
-               size = 8;
-               format = AFMT_U8;
-       }
-
-       sound.soft.format = format;
-       sound.soft.size = size;
-       if (sound.minDev == SND_DEV_DSP) {
-               sound.dsp.format = format;
-               sound.dsp.size = size;
-       }
-
-       CS_Init();
-
-       return format;
-}
-
-/* Volume is the amount of attenuation we tell the codec to impose
- * on the outputs.  There are 32 levels, with 0 the "loudest".
- */
-#define CS_VOLUME_TO_MASK(x)   (31 - ((((x) - 1) * 31) / 99))
-#define CS_MASK_TO_VOLUME(y)   (100 - ((y) * 99 / 31))
-
-static int cs_get_volume(uint reg)
-{
-       int volume;
-
-       volume = CS_MASK_TO_VOLUME(CS_LATTEN_GET(reg));
-       volume |= CS_MASK_TO_VOLUME(CS_RATTEN_GET(reg)) << 8;
-       return volume;
-}
-
-static int cs_volume_setter(int volume, int mute)
-{
-       uint tempctl;
-
-       if (mute && volume == 0) {
-               tempctl = cs4218_control | CS_MUTE;
-       } else {
-               tempctl = cs4218_control & ~CS_MUTE;
-               tempctl = tempctl & ~(CS_LATTEN | CS_RATTEN);
-               tempctl |= CS_LATTEN_SET(CS_VOLUME_TO_MASK(volume & 0xff));
-               tempctl |= CS_RATTEN_SET(CS_VOLUME_TO_MASK((volume >> 8) & 0xff));
-               volume = cs_get_volume(tempctl);
-       }
-       if (tempctl != cs4218_control) {
-               cs4218_ctl_write(tempctl);
-       }
-       return volume;
-}
-
-
-/* Gain has 16 steps from 0 to 15.  These are in 1.5dB increments from
- * 0 (no gain) to 22.5 dB.
- */
-#define CS_RECLEVEL_TO_GAIN(v) \
-       ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
-#define CS_GAIN_TO_RECLEVEL(v) (((v) * 20 + 2) / 3)
-
-static int cs_get_gain(uint reg)
-{
-       int gain;
-
-       gain = CS_GAIN_TO_RECLEVEL(CS_LGAIN_GET(reg));
-       gain |= CS_GAIN_TO_RECLEVEL(CS_RGAIN_GET(reg)) << 8;
-       return gain;
-}
-
-static int cs_set_gain(int gain)
-{
-       uint tempctl;
-
-       tempctl = cs4218_control & ~(CS_LGAIN | CS_RGAIN);
-       tempctl |= CS_LGAIN_SET(CS_RECLEVEL_TO_GAIN(gain & 0xff));
-       tempctl |= CS_RGAIN_SET(CS_RECLEVEL_TO_GAIN((gain >> 8) & 0xff));
-       gain = cs_get_gain(tempctl);
-
-       if (tempctl != cs4218_control) {
-               cs4218_ctl_write(tempctl);
-       }
-       return gain;
-}
-
-static int CS_SetVolume(int volume)
-{
-       return cs_volume_setter(volume, CS_MUTE);
-}
-
-static void CS_Play(void)
-{
-       int i, count;
-       unsigned long flags;
-       volatile cbd_t  *bdp;
-       volatile cpm8xx_t *cp;
-
-       /* Protect buffer */
-       spin_lock_irqsave(&cs4218_lock, flags);
-#if 0
-       if (awacs_beep_state) {
-               /* sound takes precedence over beeps */
-               out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
-               out_le32(&awacs->control,
-                        (in_le32(&awacs->control) & ~0x1f00)
-                        | (awacs_rate_index << 8));
-               out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
-               out_le32(&awacs_txdma->cmdptr, virt_to_bus(&(awacs_tx_cmds[(sq.front+sq.active) % sq.max_count])));
-
-               beep_playing = 0;
-               awacs_beep_state = 0;
-       }
-#endif
-       i = sq.front + sq.active;
-       if (i >= sq.max_count)
-               i -= sq.max_count;
-       while (sq.active < 2 && sq.active < sq.count) {
-               count = (sq.count == sq.active + 1)?sq.rear_size:sq.block_size;
-               if (count < sq.block_size && !sq.syncing)
-                       /* last block not yet filled, and we're not syncing. */
-                       break;
-
-               bdp = &tx_base[i];
-               bdp->cbd_datlen = count;
-
-               flush_dcache_range((ulong)sound_buffers[i],
-                                       (ulong)(sound_buffers[i] + count));
-
-               if (++i >= sq.max_count)
-                       i = 0;
-
-               if (sq.active == 0) {
-                       /* The SMC does not load its fifo until the first
-                        * TDM frame pulse, so the transmit data gets shifted
-                        * by one word.  To compensate for this, we incorrectly
-                        * transmit the first buffer and shorten it by one
-                        * word.  Subsequent buffers are then aligned properly.
-                        */
-                       bdp->cbd_datlen -= 2;
-
-                       /* Start up the SMC Transmitter.
-                       */
-                       cp = cpmp;
-                       cp->cp_smc[1].smc_smcmr |= SMCMR_TEN;
-                       cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
-                                       CPM_CR_RESTART_TX) | CPM_CR_FLG;
-                       while (cp->cp_cpcr & CPM_CR_FLG);
-               }
-
-               /* Buffer is ready now.
-               */
-               bdp->cbd_sc |= BD_SC_READY;
-
-               ++sq.active;
-       }
-       spin_unlock_irqrestore(&cs4218_lock, flags);
-}
-
-
-static void CS_Record(void)
-{
-       unsigned long flags;
-       volatile smc_t          *sp;
-
-       if (read_sq.active)
-               return;
-
-       /* Protect buffer */
-       spin_lock_irqsave(&cs4218_lock, flags);
-
-       /* This is all we have to do......Just start it up.
-       */
-       sp = &cpmp->cp_smc[1];
-       sp->smc_smcmr |= SMCMR_REN;
-
-       read_sq.active = 1;
-
-        spin_unlock_irqrestore(&cs4218_lock, flags);
-}
-
-
-static void
-cs4218_tdm_tx_intr(void *devid)
-{
-       int i = sq.front;
-       volatile cbd_t *bdp;
-
-       while (sq.active > 0) {
-               bdp = &tx_base[i];
-               if (bdp->cbd_sc & BD_SC_READY)
-                       break;  /* this frame is still going */
-               --sq.count;
-               --sq.active;
-               if (++i >= sq.max_count)
-                       i = 0;
-       }
-       if (i != sq.front)
-               WAKE_UP(sq.action_queue);
-       sq.front = i;
-
-       CS_Play();
-
-       if (!sq.active)
-               WAKE_UP(sq.sync_queue);
-}
-
-
-static void
-cs4218_tdm_rx_intr(void *devid)
-{
-
-       /* We want to blow 'em off when shutting down.
-       */
-       if (read_sq.active == 0)
-               return;
-
-       /* Check multiple buffers in case we were held off from
-        * interrupt processing for a long time.  Geeze, I really hope
-        * this doesn't happen.
-        */
-       while ((rx_base[read_sq.rear].cbd_sc & BD_SC_EMPTY) == 0) {
-
-               /* Invalidate the data cache range for this buffer.
-               */
-               invalidate_dcache_range(
-                   (uint)(sound_read_buffers[read_sq.rear]),
-                   (uint)(sound_read_buffers[read_sq.rear] + read_sq.block_size));
-
-               /* Make buffer available again and move on.
-               */
-               rx_base[read_sq.rear].cbd_sc |= BD_SC_EMPTY;
-               read_sq.rear++;
-
-               /* Wrap the buffer ring.
-               */
-               if (read_sq.rear >= read_sq.max_active)
-                       read_sq.rear = 0;
-
-               /* If we have caught up to the front buffer, bump it.
-                * This will cause weird (but not fatal) results if the
-                * read loop is currently using this buffer.  The user is
-                * behind in this case anyway, so weird things are going
-                * to happen.
-                */
-               if (read_sq.rear == read_sq.front) {
-                       read_sq.front++;
-                       if (read_sq.front >= read_sq.max_active)
-                               read_sq.front = 0;
-               }
-       }
-
-       WAKE_UP(read_sq.action_queue);
-}
-
-static void cs_nosound(unsigned long xx)
-{
-       unsigned long flags;
-
-       /* not sure if this is needed, since hardware command is #if 0'd */
-       spin_lock_irqsave(&cs4218_lock, flags);
-       if (beep_playing) {
-#if 0
-               st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
-#endif
-               beep_playing = 0;
-       }
-       spin_unlock_irqrestore(&cs4218_lock, flags);
-}
-
-static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
-
-static void cs_mksound(unsigned int hz, unsigned int ticks)
-{
-       unsigned long flags;
-       int beep_speed = BEEP_SPEED;
-       int srate = cs4218_freqs[beep_speed];
-       int period, ncycles, nsamples;
-       int i, j, f;
-       short *p;
-       static int beep_hz_cache;
-       static int beep_nsamples_cache;
-       static int beep_volume_cache;
-
-       if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
-#if 1
-               /* this is a hack for broken X server code */
-               hz = 750;
-               ticks = 12;
-#else
-               /* cancel beep currently playing */
-               awacs_nosound(0);
-               return;
-#endif
-       }
-       /* lock while modifying beep_timer */
-       spin_lock_irqsave(&cs4218_lock, flags);
-       del_timer(&beep_timer);
-       if (ticks) {
-               beep_timer.expires = jiffies + ticks;
-               add_timer(&beep_timer);
-       }
-       if (beep_playing || sq.active || beep_buf == NULL) {
-               spin_unlock_irqrestore(&cs4218_lock, flags);
-               return;         /* too hard, sorry :-( */
-       }
-       beep_playing = 1;
-#if 0
-       st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
-#endif
-       spin_unlock_irqrestore(&cs4218_lock, flags);
-
-       if (hz == beep_hz_cache && beep_volume == beep_volume_cache) {
-               nsamples = beep_nsamples_cache;
-       } else {
-               period = srate * 256 / hz;      /* fixed point */
-               ncycles = BEEP_BUFLEN * 256 / period;
-               nsamples = (period * ncycles) >> 8;
-               f = ncycles * 65536 / nsamples;
-               j = 0;
-               p = beep_buf;
-               for (i = 0; i < nsamples; ++i, p += 2) {
-                       p[0] = p[1] = beep_wform[j >> 8] * beep_volume;
-                       j = (j + f) & 0xffff;
-               }
-               beep_hz_cache = hz;
-               beep_volume_cache = beep_volume;
-               beep_nsamples_cache = nsamples;
-       }
-
-#if 0
-       st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
-       st_le16(&beep_dbdma_cmd->xfer_status, 0);
-       st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
-       st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
-       awacs_beep_state = 1;
-
-       spin_lock_irqsave(&cs4218_lock, flags);
-       if (beep_playing) {     /* i.e. haven't been terminated already */
-               out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
-               out_le32(&awacs->control,
-                        (in_le32(&awacs->control) & ~0x1f00)
-                        | (beep_speed << 8));
-               out_le32(&awacs->byteswap, 0);
-               out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
-               out_le32(&awacs_txdma->control, RUN | (RUN << 16));
-       }
-       spin_unlock_irqrestore(&cs4218_lock, flags);
-#endif
-}
-
-static MACHINE mach_cs4218 = {
-       .owner =        THIS_MODULE,
-       .name =         "HIOX CS4218",
-       .name2 =        "Built-in Sound",
-       .dma_alloc =    CS_Alloc,
-       .dma_free =     CS_Free,
-       .irqinit =      CS_IrqInit,
-#ifdef MODULE
-       .irqcleanup =   CS_IrqCleanup,
-#endif /* MODULE */
-       .init =         CS_Init,
-       .silence =      CS_Silence,
-       .setFormat =    CS_SetFormat,
-       .setVolume =    CS_SetVolume,
-       .play =         CS_Play
-};
-
-
-/*** Mid level stuff *********************************************************/
-
-
-static void sound_silence(void)
-{
-       /* update hardware settings one more */
-       (*sound.mach.init)();
-
-       (*sound.mach.silence)();
-}
-
-
-static void sound_init(void)
-{
-       (*sound.mach.init)();
-}
-
-
-static int sound_set_format(int format)
-{
-       return(*sound.mach.setFormat)(format);
-}
-
-
-static int sound_set_speed(int speed)
-{
-       if (speed < 0)
-               return(sound.soft.speed);
-
-       sound.soft.speed = speed;
-       (*sound.mach.init)();
-       if (sound.minDev == SND_DEV_DSP)
-               sound.dsp.speed = sound.soft.speed;
-
-       return(sound.soft.speed);
-}
-
-
-static int sound_set_stereo(int stereo)
-{
-       if (stereo < 0)
-               return(sound.soft.stereo);
-
-       stereo = !!stereo;    /* should be 0 or 1 now */
-
-       sound.soft.stereo = stereo;
-       if (sound.minDev == SND_DEV_DSP)
-               sound.dsp.stereo = stereo;
-       (*sound.mach.init)();
-
-       return(stereo);
-}
-
-
-static int sound_set_volume(int volume)
-{
-       return(*sound.mach.setVolume)(volume);
-}
-
-static ssize_t sound_copy_translate(const u_char *userPtr,
-                                   size_t userCount,
-                                   u_char frame[], ssize_t *frameUsed,
-                                   ssize_t frameLeft)
-{
-       ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
-
-       switch (sound.soft.format) {
-       case AFMT_MU_LAW:
-               ct_func = sound.trans_write->ct_ulaw;
-               break;
-       case AFMT_A_LAW:
-               ct_func = sound.trans_write->ct_alaw;
-               break;
-       case AFMT_S8:
-               ct_func = sound.trans_write->ct_s8;
-               break;
-       case AFMT_U8:
-               ct_func = sound.trans_write->ct_u8;
-               break;
-       case AFMT_S16_BE:
-               ct_func = sound.trans_write->ct_s16be;
-               break;
-       case AFMT_U16_BE:
-               ct_func = sound.trans_write->ct_u16be;
-               break;
-       case AFMT_S16_LE:
-               ct_func = sound.trans_write->ct_s16le;
-               break;
-       case AFMT_U16_LE:
-               ct_func = sound.trans_write->ct_u16le;
-               break;
-       }
-       if (ct_func)
-               return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
-       else
-               return 0;
-}
-
-static ssize_t sound_copy_translate_read(const u_char *userPtr,
-                                   size_t userCount,
-                                   u_char frame[], ssize_t *frameUsed,
-                                   ssize_t frameLeft)
-{
-       ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
-
-       switch (sound.soft.format) {
-       case AFMT_MU_LAW:
-               ct_func = sound.trans_read->ct_ulaw;
-               break;
-       case AFMT_A_LAW:
-               ct_func = sound.trans_read->ct_alaw;
-               break;
-       case AFMT_S8:
-               ct_func = sound.trans_read->ct_s8;
-               break;
-       case AFMT_U8:
-               ct_func = sound.trans_read->ct_u8;
-               break;
-       case AFMT_S16_BE:
-               ct_func = sound.trans_read->ct_s16be;
-               break;
-       case AFMT_U16_BE:
-               ct_func = sound.trans_read->ct_u16be;
-               break;
-       case AFMT_S16_LE:
-               ct_func = sound.trans_read->ct_s16le;
-               break;
-       case AFMT_U16_LE:
-               ct_func = sound.trans_read->ct_u16le;
-               break;
-       }
-       if (ct_func)
-               return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
-       else
-               return 0;
-}
-
-
-/*
- * /dev/mixer abstraction
- */
-
-static int mixer_open(struct inode *inode, struct file *file)
-{
-       mixer.busy = 1;
-       return nonseekable_open(inode, file);
-}
-
-
-static int mixer_release(struct inode *inode, struct file *file)
-{
-       mixer.busy = 0;
-       return 0;
-}
-
-
-static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                      u_long arg)
-{
-       int data;
-       uint tmpcs;
-
-       if (_SIOC_DIR(cmd) & _SIOC_WRITE)
-           mixer.modify_counter++;
-       if (cmd == OSS_GETVERSION)
-           return IOCTL_OUT(arg, SOUND_VERSION);
-       switch (cmd) {
-               case SOUND_MIXER_INFO: {
-                   mixer_info info;
-                   strlcpy(info.id, "CS4218_TDM", sizeof(info.id));
-                   strlcpy(info.name, "CS4218_TDM", sizeof(info.name));
-                   info.name[sizeof(info.name)-1] = 0;
-                   info.modify_counter = mixer.modify_counter;
-                   if (copy_to_user((int *)arg, &info, sizeof(info)))
-                               return -EFAULT;
-                   return 0;
-               }
-               case SOUND_MIXER_READ_DEVMASK:
-                       data = SOUND_MASK_VOLUME | SOUND_MASK_LINE
-                               | SOUND_MASK_MIC | SOUND_MASK_RECLEV
-                               | SOUND_MASK_ALTPCM;
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_READ_RECMASK:
-                       data = SOUND_MASK_LINE | SOUND_MASK_MIC;
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_READ_RECSRC:
-                       if (cs4218_control & CS_DO1)
-                               data = SOUND_MASK_LINE;
-                       else
-                               data = SOUND_MASK_MIC;
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_WRITE_RECSRC:
-                       IOCTL_IN(arg, data);
-                       data &= (SOUND_MASK_LINE | SOUND_MASK_MIC);
-                       if (data & SOUND_MASK_LINE)
-                               tmpcs = cs4218_control |
-                                               (CS_ISL | CS_ISR | CS_DO1);
-                       if (data & SOUND_MASK_MIC)
-                               tmpcs = cs4218_control &
-                                               ~(CS_ISL | CS_ISR | CS_DO1);
-                       if (tmpcs != cs4218_control)
-                               cs4218_ctl_write(tmpcs);
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_READ_STEREODEVS:
-                       data = SOUND_MASK_VOLUME | SOUND_MASK_RECLEV;
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_READ_CAPS:
-                       return IOCTL_OUT(arg, 0);
-               case SOUND_MIXER_READ_VOLUME:
-                       data = (cs4218_control & CS_MUTE)? 0:
-                               cs_get_volume(cs4218_control);
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_WRITE_VOLUME:
-                       IOCTL_IN(arg, data);
-                       return IOCTL_OUT(arg, sound_set_volume(data));
-               case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
-                       IOCTL_IN(arg, data);
-                       beep_volume = data & 0xff;
-                       /* fall through */
-               case SOUND_MIXER_READ_ALTPCM:
-                       return IOCTL_OUT(arg, beep_volume);
-               case SOUND_MIXER_WRITE_RECLEV:
-                       IOCTL_IN(arg, data);
-                       data = cs_set_gain(data);
-                       return IOCTL_OUT(arg, data);
-               case SOUND_MIXER_READ_RECLEV:
-                       data = cs_get_gain(cs4218_control);
-                       return IOCTL_OUT(arg, data);
-       }
-
-       return -EINVAL;
-}
-
-
-static const struct file_operations mixer_fops =
-{
-       .owner =        THIS_MODULE,
-       .llseek =       sound_lseek,
-       .ioctl =        mixer_ioctl,
-       .open =         mixer_open,
-       .release =      mixer_release,
-};
-
-
-static void __init mixer_init(void)
-{
-       mixer_unit = register_sound_mixer(&mixer_fops, -1);
-       if (mixer_unit < 0)
-               return;
-
-       mixer.busy = 0;
-       sound.treble = 0;
-       sound.bass = 0;
-
-       /* Set Line input, no gain, no attenuation.
-       */
-       cs4218_control = CS_ISL | CS_ISR | CS_DO1;
-       cs4218_control |= CS_LGAIN_SET(0) | CS_RGAIN_SET(0);
-       cs4218_control |= CS_LATTEN_SET(0) | CS_RATTEN_SET(0);
-       cs4218_ctl_write(cs4218_control);
-}
-
-
-/*
- * Sound queue stuff, the heart of the driver
- */
-
-
-static int sq_allocate_buffers(void)
-{
-       int i;
-
-       if (sound_buffers)
-               return 0;
-       sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
-       if (!sound_buffers)
-               return -ENOMEM;
-       for (i = 0; i < numBufs; i++) {
-               sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
-               if (!sound_buffers[i]) {
-                       while (i--)
-                               sound.mach.dma_free (sound_buffers[i], bufSize << 10);
-                       kfree (sound_buffers);
-                       sound_buffers = 0;
-                       return -ENOMEM;
-               }
-       }
-       return 0;
-}
-
-
-static void sq_release_buffers(void)
-{
-       int i;
-
-       if (sound_buffers) {
-               for (i = 0; i < numBufs; i++)
-                       sound.mach.dma_free (sound_buffers[i], bufSize << 10);
-               kfree (sound_buffers);
-               sound_buffers = 0;
-       }
-}
-
-
-static int sq_allocate_read_buffers(void)
-{
-       int i;
-
-       if (sound_read_buffers)
-               return 0;
-       sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL);
-       if (!sound_read_buffers)
-               return -ENOMEM;
-       for (i = 0; i < numBufs; i++) {
-               sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10,
-                                                             GFP_KERNEL);
-               if (!sound_read_buffers[i]) {
-                       while (i--)
-                               sound.mach.dma_free (sound_read_buffers[i],
-                                                    readbufSize << 10);
-                       kfree (sound_read_buffers);
-                       sound_read_buffers = 0;
-                       return -ENOMEM;
-               }
-       }
-       return 0;
-}
-
-static void sq_release_read_buffers(void)
-{
-       int i;
-
-       if (sound_read_buffers) {
-               cpmp->cp_smc[1].smc_smcmr &= ~SMCMR_REN;
-               for (i = 0; i < numReadBufs; i++)
-                       sound.mach.dma_free (sound_read_buffers[i],
-                                            bufSize << 10);
-               kfree (sound_read_buffers);
-               sound_read_buffers = 0;
-       }
-}
-
-
-static void sq_setup(int numBufs, int bufSize, char **write_buffers)
-{
-       int i;
-       volatile cbd_t *bdp;
-       volatile cpm8xx_t       *cp;
-       volatile smc_t  *sp;
-
-       /* Make sure the SMC transmit is shut down.
-       */
-       cp = cpmp;
-       sp = &cpmp->cp_smc[1];
-       sp->smc_smcmr &= ~SMCMR_TEN;
-
-       sq.max_count = numBufs;
-       sq.max_active = numBufs;
-       sq.block_size = bufSize;
-       sq.buffers = write_buffers;
-
-       sq.front = sq.count = 0;
-       sq.rear = -1;
-       sq.syncing = 0;
-       sq.active = 0;
-
-       bdp = tx_base;
-       for (i=0; i<numBufs; i++) {
-               bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]);
-               bdp++;
-       }
-
-       /* This causes the SMC to sync up with the first buffer again.
-       */
-       cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_TX) | CPM_CR_FLG;
-       while (cp->cp_cpcr & CPM_CR_FLG);
-}
-
-static void read_sq_setup(int numBufs, int bufSize, char **read_buffers)
-{
-       int i;
-       volatile cbd_t *bdp;
-       volatile cpm8xx_t       *cp;
-       volatile smc_t  *sp;
-
-       /* Make sure the SMC receive is shut down.
-       */
-       cp = cpmp;
-       sp = &cpmp->cp_smc[1];
-       sp->smc_smcmr &= ~SMCMR_REN;
-
-       read_sq.max_count = numBufs;
-       read_sq.max_active = numBufs;
-       read_sq.block_size = bufSize;
-       read_sq.buffers = read_buffers;
-
-       read_sq.front = read_sq.count = 0;
-       read_sq.rear = 0;
-       read_sq.rear_size = 0;
-       read_sq.syncing = 0;
-       read_sq.active = 0;
-
-       bdp = rx_base;
-       for (i=0; i<numReadBufs; i++) {
-               bdp->cbd_bufaddr = virt_to_bus(read_buffers[i]);
-               bdp->cbd_datlen = read_sq.block_size;
-               bdp++;
-       }
-
-       /* This causes the SMC to sync up with the first buffer again.
-       */
-       cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_RX) | CPM_CR_FLG;
-       while (cp->cp_cpcr & CPM_CR_FLG);
-}
-
-
-static void sq_play(void)
-{
-       (*sound.mach.play)();
-}
-
-
-/* ++TeSche: radically changed this one too */
-
-static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
-                       loff_t *ppos)
-{
-       ssize_t uWritten = 0;
-       u_char *dest;
-       ssize_t uUsed, bUsed, bLeft;
-
-       /* ++TeSche: Is something like this necessary?
-        * Hey, that's an honest question! Or does any other part of the
-        * filesystem already checks this situation? I really don't know.
-        */
-       if (uLeft == 0)
-               return 0;
-
-       /* The interrupt doesn't start to play the last, incomplete frame.
-        * Thus we can append to it without disabling the interrupts! (Note
-        * also that sq.rear isn't affected by the interrupt.)
-        */
-
-       if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
-               dest = sq_block_address(sq.rear);
-               bUsed = sq.rear_size;
-               uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
-               if (uUsed <= 0)
-                       return uUsed;
-               src += uUsed;
-               uWritten += uUsed;
-               uLeft -= uUsed;
-               sq.rear_size = bUsed;
-       }
-
-       do {
-               while (sq.count == sq.max_active) {
-                       sq_play();
-                       if (NON_BLOCKING(sq.open_mode))
-                               return uWritten > 0 ? uWritten : -EAGAIN;
-                       SLEEP(sq.action_queue);
-                       if (SIGNAL_RECEIVED)
-                               return uWritten > 0 ? uWritten : -EINTR;
-               }
-
-               /* Here, we can avoid disabling the interrupt by first
-                * copying and translating the data, and then updating
-                * the sq variables. Until this is done, the interrupt
-                * won't see the new frame and we can work on it
-                * undisturbed.
-                */
-
-               dest = sq_block_address((sq.rear+1) % sq.max_count);
-               bUsed = 0;
-               bLeft = sq.block_size;
-               uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
-               if (uUsed <= 0)
-                       break;
-               src += uUsed;
-               uWritten += uUsed;
-               uLeft -= uUsed;
-               if (bUsed) {
-                       sq.rear = (sq.rear+1) % sq.max_count;
-                       sq.rear_size = bUsed;
-                       sq.count++;
-               }
-       } while (bUsed);   /* uUsed may have been 0 */
-
-       sq_play();
-
-       return uUsed < 0? uUsed: uWritten;
-}
-
-
-/***********/
-
-/* Here is how the values are used for reading.
- * The value 'active' simply indicates the DMA is running.  This is
- * done so the driver semantics are DMA starts when the first read is
- * posted.  The value 'front' indicates the buffer we should next
- * send to the user.  The value 'rear' indicates the buffer the DMA is
- * currently filling.  When 'front' == 'rear' the buffer "ring" is
- * empty (we always have an empty available).  The 'rear_size' is used
- * to track partial offsets into the current buffer.  Right now, I just keep
- * The DMA running.  If the reader can't keep up, the interrupt tosses
- * the oldest buffer.  We could also shut down the DMA in this case.
- */
-static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
-                       loff_t *ppos)
-{
-
-       ssize_t uRead, bLeft, bUsed, uUsed;
-
-       if (uLeft == 0)
-               return 0;
-
-       if (!read_sq.active)
-               CS_Record();    /* Kick off the record process. */
-
-       uRead = 0;
-
-       /* Move what the user requests, depending upon other options.
-       */
-       while (uLeft > 0) {
-
-               /* When front == rear, the DMA is not done yet.
-               */
-               while (read_sq.front == read_sq.rear) {
-                       if (NON_BLOCKING(read_sq.open_mode)) {
-                              return uRead > 0 ? uRead : -EAGAIN;
-                       }
-                       SLEEP(read_sq.action_queue);
-                       if (SIGNAL_RECEIVED)
-                               return uRead > 0 ? uRead : -EINTR;
-               }
-
-               /* The amount we move is either what is left in the
-                * current buffer or what the user wants.
-                */
-               bLeft = read_sq.block_size - read_sq.rear_size;
-               bUsed = read_sq.rear_size;
-               uUsed = sound_copy_translate_read(dst, uLeft,
-                       read_sq.buffers[read_sq.front], &bUsed, bLeft);
-               if (uUsed <= 0)
-                       return uUsed;
-               dst += uUsed;
-               uRead += uUsed;
-               uLeft -= uUsed;
-               read_sq.rear_size += bUsed;
-               if (read_sq.rear_size >= read_sq.block_size) {
-                       read_sq.rear_size = 0;
-                       read_sq.front++;
-                       if (read_sq.front >= read_sq.max_active)
-                               read_sq.front = 0;
-               }
-       }
-       return uRead;
-}
-
-static int sq_open(struct inode *inode, struct file *file)
-{
-       int rc = 0;
-
-       if (file->f_mode & FMODE_WRITE) {
-               if (sq.busy) {
-                       rc = -EBUSY;
-                       if (NON_BLOCKING(file->f_flags))
-                               goto err_out;
-                       rc = -EINTR;
-                       while (sq.busy) {
-                               SLEEP(sq.open_queue);
-                               if (SIGNAL_RECEIVED)
-                                       goto err_out;
-                       }
-               }
-               sq.busy = 1; /* Let's play spot-the-race-condition */
-
-               if (sq_allocate_buffers()) goto err_out_nobusy;
-
-               sq_setup(numBufs, bufSize<<10,sound_buffers);
-               sq.open_mode = file->f_mode;
-       }
-
-
-       if (file->f_mode & FMODE_READ) {
-               if (read_sq.busy) {
-                       rc = -EBUSY;
-                       if (NON_BLOCKING(file->f_flags))
-                               goto err_out;
-                       rc = -EINTR;
-                       while (read_sq.busy) {
-                               SLEEP(read_sq.open_queue);
-                               if (SIGNAL_RECEIVED)
-                                       goto err_out;
-                       }
-                       rc = 0;
-               }
-               read_sq.busy = 1;
-               if (sq_allocate_read_buffers()) goto err_out_nobusy;
-
-               read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers);
-               read_sq.open_mode = file->f_mode;
-       }
-
-       /* Start up the 4218 by:
-        * Reset.
-        * Enable, unreset.
-        */
-       *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_RSTAUDIO;
-       eieio();
-       *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_ENAUDIO;
-       mdelay(50);
-       *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
-
-       /* We need to send the current control word in case someone
-        * opened /dev/mixer and changed things while we were shut
-        * down.  Chances are good the initialization that follows
-        * would have done this, but it is still possible it wouldn't.
-        */
-       cs4218_ctl_write(cs4218_control);
-
-       sound.minDev = iminor(inode) & 0x0f;
-       sound.soft = sound.dsp;
-       sound.hard = sound.dsp;
-       sound_init();
-       if ((iminor(inode) & 0x0f) == SND_DEV_AUDIO) {
-               sound_set_speed(8000);
-               sound_set_stereo(0);
-               sound_set_format(AFMT_MU_LAW);
-       }
-
-       return nonseekable_open(inode, file);
-
-err_out_nobusy:
-       if (file->f_mode & FMODE_WRITE) {
-               sq.busy = 0;
-               WAKE_UP(sq.open_queue);
-       }
-       if (file->f_mode & FMODE_READ) {
-               read_sq.busy = 0;
-               WAKE_UP(read_sq.open_queue);
-       }
-err_out:
-       return rc;
-}
-
-
-static void sq_reset(void)
-{
-       sound_silence();
-       sq.active = 0;
-       sq.count = 0;
-       sq.front = (sq.rear+1) % sq.max_count;
-#if 0
-       init_tdm_buffers();
-#endif
-}
-
-
-static int sq_fsync(struct file *filp, struct dentry *dentry)
-{
-       int rc = 0;
-
-       sq.syncing = 1;
-       sq_play();      /* there may be an incomplete frame waiting */
-
-       while (sq.active) {
-               SLEEP(sq.sync_queue);
-               if (SIGNAL_RECEIVED) {
-                       /* While waiting for audio output to drain, an
-                        * interrupt occurred.  Stop audio output immediately
-                        * and clear the queue. */
-                       sq_reset();
-                       rc = -EINTR;
-                       break;
-               }
-       }
-
-       sq.syncing = 0;
-       return rc;
-}
-
-static int sq_release(struct inode *inode, struct file *file)
-{
-       int rc = 0;
-
-       if (sq.busy)
-               rc = sq_fsync(file, file->f_path.dentry);
-       sound.soft = sound.dsp;
-       sound.hard = sound.dsp;
-       sound_silence();
-
-       sq_release_read_buffers();
-       sq_release_buffers();
-
-       if (file->f_mode & FMODE_READ) {
-               read_sq.busy = 0;
-               WAKE_UP(read_sq.open_queue);
-       }
-
-       if (file->f_mode & FMODE_WRITE) {
-               sq.busy = 0;
-               WAKE_UP(sq.open_queue);
-       }
-
-       /* Shut down the SMC.
-       */
-       cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN);
-
-       /* Shut down the codec.
-       */
-       *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
-       eieio();
-       *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO;
-
-       /* Wake up a process waiting for the queue being released.
-        * Note: There may be several processes waiting for a call
-        * to open() returning. */
-
-       return rc;
-}
-
-
-static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
-                   u_long arg)
-{
-       u_long fmt;
-       int data;
-#if 0
-       int size, nbufs;
-#else
-       int size;
-#endif
-
-       switch (cmd) {
-       case SNDCTL_DSP_RESET:
-               sq_reset();
-               return 0;
-       case SNDCTL_DSP_POST:
-       case SNDCTL_DSP_SYNC:
-               return sq_fsync(file, file->f_path.dentry);
-
-               /* ++TeSche: before changing any of these it's
-                * probably wise to wait until sound playing has
-                * settled down. */
-       case SNDCTL_DSP_SPEED:
-               sq_fsync(file, file->f_path.dentry);
-               IOCTL_IN(arg, data);
-               return IOCTL_OUT(arg, sound_set_speed(data));
-       case SNDCTL_DSP_STEREO:
-               sq_fsync(file, file->f_path.dentry);
-               IOCTL_IN(arg, data);
-               return IOCTL_OUT(arg, sound_set_stereo(data));
-       case SOUND_PCM_WRITE_CHANNELS:
-               sq_fsync(file, file->f_path.dentry);
-               IOCTL_IN(arg, data);
-               return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
-       case SNDCTL_DSP_SETFMT:
-               sq_fsync(file, file->f_path.dentry);
-               IOCTL_IN(arg, data);
-               return IOCTL_OUT(arg, sound_set_format(data));
-       case SNDCTL_DSP_GETFMTS:
-               fmt = 0;
-               if (sound.trans_write) {
-                       if (sound.trans_write->ct_ulaw)
-                               fmt |= AFMT_MU_LAW;
-                       if (sound.trans_write->ct_alaw)
-                               fmt |= AFMT_A_LAW;
-                       if (sound.trans_write->ct_s8)
-                               fmt |= AFMT_S8;
-                       if (sound.trans_write->ct_u8)
-                               fmt |= AFMT_U8;
-                       if (sound.trans_write->ct_s16be)
-                               fmt |= AFMT_S16_BE;
-                       if (sound.trans_write->ct_u16be)
-                               fmt |= AFMT_U16_BE;
-                       if (sound.trans_write->ct_s16le)
-                               fmt |= AFMT_S16_LE;
-                       if (sound.trans_write->ct_u16le)
-                               fmt |= AFMT_U16_LE;
-               }
-               return IOCTL_OUT(arg, fmt);
-       case SNDCTL_DSP_GETBLKSIZE:
-               size = sq.block_size
-                       * sound.soft.size * (sound.soft.stereo + 1)
-                       / (sound.hard.size * (sound.hard.stereo + 1));
-               return IOCTL_OUT(arg, size);
-       case SNDCTL_DSP_SUBDIVIDE:
-               break;
-#if 0  /* Sorry can't do this at the moment.  The CPM allocated buffers
-        * long ago that can't be changed.
-        */
-       case SNDCTL_DSP_SETFRAGMENT:
-               if (sq.count || sq.active || sq.syncing)
-                       return -EINVAL;
-               IOCTL_IN(arg, size);
-               nbufs = size >> 16;
-               if (nbufs < 2 || nbufs > numBufs)
-                       nbufs = numBufs;
-               size &= 0xffff;
-               if (size >= 8 && size <= 30) {
-                       size = 1 << size;
-                       size *= sound.hard.size * (sound.hard.stereo + 1);
-                       size /= sound.soft.size * (sound.soft.stereo + 1);
-                       if (size > (bufSize << 10))
-                               size = bufSize << 10;
-               } else
-                       size = bufSize << 10;
-               sq_setup(numBufs, size, sound_buffers);
-               sq.max_active = nbufs;
-               return 0;
-#endif
-
-       default:
-               return mixer_ioctl(inode, file, cmd, arg);
-       }
-       return -EINVAL;
-}
-
-
-
-static const struct file_operations sq_fops =
-{
-       .owner =        THIS_MODULE,
-       .llseek =       sound_lseek,
-       .read =         sq_read,                        /* sq_read */
-       .write =        sq_write,
-       .ioctl =        sq_ioctl,
-       .open =         sq_open,
-       .release =      sq_release,
-};
-
-
-static void __init sq_init(void)
-{
-       sq_unit = register_sound_dsp(&sq_fops, -1);
-       if (sq_unit < 0)
-               return;
-
-       init_waitqueue_head(&sq.action_queue);
-       init_waitqueue_head(&sq.open_queue);
-       init_waitqueue_head(&sq.sync_queue);
-       init_waitqueue_head(&read_sq.action_queue);
-       init_waitqueue_head(&read_sq.open_queue);
-       init_waitqueue_head(&read_sq.sync_queue);
-
-       sq.busy = 0;
-       read_sq.busy = 0;
-
-       /* whatever you like as startup mode for /dev/dsp,
-        * (/dev/audio hasn't got a startup mode). note that
-        * once changed a new open() will *not* restore these!
-        */
-       sound.dsp.format = AFMT_S16_BE;
-       sound.dsp.stereo = 1;
-       sound.dsp.size = 16;
-
-       /* set minimum rate possible without expanding */
-       sound.dsp.speed = 8000;
-
-       /* before the first open to /dev/dsp this wouldn't be set */
-       sound.soft = sound.dsp;
-       sound.hard = sound.dsp;
-
-       sound_silence();
-}
-
-/*
- * /dev/sndstat
- */
-
-
-/* state.buf should not overflow! */
-
-static int state_open(struct inode *inode, struct file *file)
-{
-       char *buffer = state.buf, *mach = "", cs4218_buf[50];
-       int len = 0;
-
-       if (state.busy)
-               return -EBUSY;
-
-       state.ptr = 0;
-       state.busy = 1;
-
-       sprintf(cs4218_buf, "Crystal CS4218 on TDM, ");
-       mach = cs4218_buf;
-
-       len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
-
-       len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
-       switch (sound.soft.format) {
-       case AFMT_MU_LAW:
-               len += sprintf(buffer+len, " (mu-law)");
-               break;
-       case AFMT_A_LAW:
-               len += sprintf(buffer+len, " (A-law)");
-               break;
-       case AFMT_U8:
-               len += sprintf(buffer+len, " (unsigned 8 bit)");
-               break;
-       case AFMT_S8:
-               len += sprintf(buffer+len, " (signed 8 bit)");
-               break;
-       case AFMT_S16_BE:
-               len += sprintf(buffer+len, " (signed 16 bit big)");
-               break;
-       case AFMT_U16_BE:
-               len += sprintf(buffer+len, " (unsigned 16 bit big)");
-               break;
-       case AFMT_S16_LE:
-               len += sprintf(buffer+len, " (signed 16 bit little)");
-               break;
-       case AFMT_U16_LE:
-               len += sprintf(buffer+len, " (unsigned 16 bit little)");
-               break;
-       }
-       len += sprintf(buffer+len, "\n");
-       len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
-                      sound.soft.speed, sound.hard.speed);
-       len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
-                      sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
-       len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d"
-                      " sq.max_active = %d\n",
-                      sq.block_size, sq.max_count, sq.max_active);
-       len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
-                      sq.rear_size);
-       len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
-                      sq.active, sq.syncing);
-       state.len = len;
-       return nonseekable_open(inode, file);
-}
-
-
-static int state_release(struct inode *inode, struct file *file)
-{
-       state.busy = 0;
-       return 0;
-}
-
-
-static ssize_t state_read(struct file *file, char *buf, size_t count,
-                         loff_t *ppos)
-{
-       int n = state.len - state.ptr;
-       if (n > count)
-               n = count;
-       if (n <= 0)
-               return 0;
-       if (copy_to_user(buf, &state.buf[state.ptr], n))
-               return -EFAULT;
-       state.ptr += n;
-       return n;
-}
-
-
-static const struct file_operations state_fops =
-{
-       .owner =        THIS_MODULE,
-       .llseek =       sound_lseek,
-       .read =         state_read,
-       .open =         state_open,
-       .release =      state_release,
-};
-
-
-static void __init state_init(void)
-{
-       state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
-       if (state_unit < 0)
-               return;
-       state.busy = 0;
-}
-
-
-/*** Common stuff ********************************************************/
-
-static long long sound_lseek(struct file *file, long long offset, int orig)
-{
-       return -ESPIPE;
-}
-
-
-/*** Config & Setup **********************************************************/
-
-
-int __init tdm8xx_sound_init(void)
-{
-       int i, has_sound;
-       uint                    dp_offset;
-       volatile uint           *sirp;
-       volatile cbd_t          *bdp;
-       volatile cpm8xx_t       *cp;
-       volatile smc_t          *sp;
-       volatile smc_uart_t     *up;
-       volatile immap_t        *immap;
-
-       has_sound = 0;
-
-       /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes.
-       */
-       cp = cpmp;      /* Get pointer to Communication Processor */
-       immap = (immap_t *)IMAP_ADDR;   /* and to internal registers */
-
-       /* Set all TDMa control bits to zero.  This enables most features
-        * we want.
-        */
-       cp->cp_simode &= ~0x00000fff;
-
-       /* Enable common receive/transmit clock pins, use IDL format.
-        * Sync on falling edge, transmit rising clock, receive falling
-        * clock, delay 1 bit on both Tx and Rx.  Common Tx/Rx clocks and
-        * sync.
-        * Connect SMC2 to TSA.
-        */
-       cp->cp_simode |= 0x80000141;
-
-       /* Configure port A pins for TDMa operation.
-        * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used.
-        */
-       immap->im_ioport.iop_papar |= 0x01c0; /* Enable TDMa functions */
-       immap->im_ioport.iop_padir |= 0x00c0; /* Enable TDMa Tx/Rx */
-       immap->im_ioport.iop_padir &= ~0x0100; /* Enable L1RCLKa */
-
-       immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */
-       immap->im_ioport.iop_pcdir &= ~0x0800;
-
-       /* Initialize the SI TDM routing table.  We use TDMa only.
-        * The receive table and transmit table each have only one
-        * entry, to capture/send four bytes after each frame pulse.
-        * The 16-bit ram entry is 0000 0001 1000 1111. (SMC2)
-        */
-       cp->cp_sigmr = 0;
-       sirp = (uint *)cp->cp_siram;
-
-       *sirp = 0x018f0000;             /* Receive entry */
-       sirp += 64;
-       *sirp = 0x018f0000;             /* Tramsmit entry */
-
-       /* Enable single TDMa routing.
-       */
-       cp->cp_sigmr = 0x04;
-
-       /* Initialize the SMC for transparent operation.
-       */
-       sp = &cpmp->cp_smc[1];
-       up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
-
-       /* We need to allocate a transmit and receive buffer
-        * descriptors from dual port ram.
-        */
-       dp_addr = cpm_dpalloc(sizeof(cbd_t) * numReadBufs, 8);
-
-       /* Set the physical address of the host memory
-        * buffers in the buffer descriptors, and the
-        * virtual address for us to work with.
-        */
-       bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
-       up->smc_rbase = dp_offset;
-       rx_cur = rx_base = (cbd_t *)bdp;
-
-       for (i=0; i<(numReadBufs-1); i++) {
-               bdp->cbd_bufaddr = 0;
-               bdp->cbd_datlen = 0;
-               bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
-               bdp++;
-       }
-       bdp->cbd_bufaddr = 0;
-       bdp->cbd_datlen = 0;
-       bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
-
-       /* Now, do the same for the transmit buffers.
-       */
-       dp_offset = cpm_dpalloc(sizeof(cbd_t) * numBufs, 8);
-
-       bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
-       up->smc_tbase = dp_offset;
-       tx_cur = tx_base = (cbd_t *)bdp;
-
-       for (i=0; i<(numBufs-1); i++) {
-               bdp->cbd_bufaddr = 0;
-               bdp->cbd_datlen = 0;
-               bdp->cbd_sc = BD_SC_INTRPT;
-               bdp++;
-       }
-       bdp->cbd_bufaddr = 0;
-       bdp->cbd_datlen = 0;
-       bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
-
-       /* Set transparent SMC mode.
-        * A few things are specific to our application.  The codec interface
-        * is MSB first, hence the REVD selection.  The CD/CTS pulse are
-        * used by the TSA to indicate the frame start to the SMC.
-        */
-       up->smc_rfcr = SCC_EB;
-       up->smc_tfcr = SCC_EB;
-       up->smc_mrblr = readbufSize * 1024;
-
-       /* Set 16-bit reversed data, transparent mode.
-       */
-       sp->smc_smcmr = smcr_mk_clen(15) |
-               SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS;
-
-       /* Enable and clear events.
-        * Because of FIFO delays, all we need is the receive interrupt
-        * and we can process both the current receive and current
-        * transmit interrupt within a few microseconds of the transmit.
-        */
-       sp->smc_smce = 0xff;
-       sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX;
-
-       /* Send the CPM an initialize command.
-       */
-       cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
-                               CPM_CR_INIT_TRX) | CPM_CR_FLG;
-       while (cp->cp_cpcr & CPM_CR_FLG);
-
-       sound.mach = mach_cs4218;
-       has_sound = 1;
-
-       /* Initialize beep stuff */
-       orig_mksound = kd_mksound;
-       kd_mksound = cs_mksound;
-       beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
-       if (beep_buf == NULL)
-               printk(KERN_WARNING "dmasound: no memory for "
-                      "beep buffer\n");
-
-       if (!has_sound)
-               return -ENODEV;
-
-       /* Initialize the software SPI.
-       */
-       sw_spi_init();
-
-       /* Set up sound queue, /dev/audio and /dev/dsp. */
-
-       /* Set default settings. */
-       sq_init();
-
-       /* Set up /dev/sndstat. */
-       state_init();
-
-       /* Set up /dev/mixer. */
-       mixer_init();
-
-       if (!sound.mach.irqinit()) {
-               printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
-               return -ENODEV;
-       }
-#ifdef MODULE
-       irq_installed = 1;
-#endif
-
-       printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
-              numBufs, bufSize);
-
-       return 0;
-}
-
-/* Due to FIFOs and bit delays, the transmit interrupt occurs a few
- * microseconds ahead of the receive interrupt.
- * When we get an interrupt, we service the transmit first, then
- * check for a receive to prevent the overhead of returning through
- * the interrupt handler only to get back here right away during
- * full duplex operation.
- */
-static void
-cs4218_intr(void *dev_id)
-{
-       volatile smc_t  *sp;
-       volatile cpm8xx_t       *cp;
-
-       sp = &cpmp->cp_smc[1];
-
-       if (sp->smc_smce & SCCM_TX) {
-               sp->smc_smce = SCCM_TX;
-               cs4218_tdm_tx_intr((void *)sp);
-       }
-
-       if (sp->smc_smce & SCCM_RX) {
-               sp->smc_smce = SCCM_RX;
-               cs4218_tdm_rx_intr((void *)sp);
-       }
-
-       if (sp->smc_smce & SCCM_TXE) {
-               /* Transmit underrun.  This happens with the application
-                * didn't keep up sending buffers.  We tell the SMC to
-                * restart, which will cause it to poll the current (next)
-                * BD.  If the user supplied data since this occurred,
-                * we just start running again.  If they didn't, the SMC
-                * will poll the descriptor until data is placed there.
-                */
-               sp->smc_smce = SCCM_TXE;
-               cp = cpmp;      /* Get pointer to Communication Processor */
-               cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
-                                       CPM_CR_RESTART_TX) | CPM_CR_FLG;
-               while (cp->cp_cpcr & CPM_CR_FLG);
-       }
-}
-
-
-#define MAXARGS                8       /* Should be sufficient for now */
-
-void __init dmasound_setup(char *str, int *ints)
-{
-       /* check the bootstrap parameter for "dmasound=" */
-
-       switch (ints[0]) {
-       case 3:
-               if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
-                       printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
-               else
-                       catchRadius = ints[3];
-               /* fall through */
-       case 2:
-               if (ints[1] < MIN_BUFFERS)
-                       printk("dmasound_setup: invalid number of buffers, using default = %d\n", numBufs);
-               else
-                       numBufs = ints[1];
-               if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
-                       printk("dmasound_setup: invalid buffer size, using default = %d\n", bufSize);
-               else
-                       bufSize = ints[2];
-               break;
-       case 0:
-               break;
-       default:
-               printk("dmasound_setup: invalid number of arguments\n");
-       }
-}
-
-/* Software SPI functions.
- * These are on Port B.
- */
-#define PB_SPICLK      ((uint)0x00000002)
-#define PB_SPIMOSI     ((uint)0x00000004)
-#define PB_SPIMISO     ((uint)0x00000008)
-
-static
-void   sw_spi_init(void)
-{
-       volatile cpm8xx_t       *cp;
-       volatile uint           *hcsr4;
-
-       hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
-       cp = cpmp;      /* Get pointer to Communication Processor */
-
-       *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
-
-       /* Make these Port B signals general purpose I/O.
-        * First, make sure the clock is low.
-        */
-       cp->cp_pbdat &= ~PB_SPICLK;
-       cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO);
-
-       /* Clock and Master Output are outputs.
-       */
-       cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI);
-
-       /* Master Input.
-       */
-       cp->cp_pbdir &= ~PB_SPIMISO;
-
-}
-
-/* Write the CS4218 control word out the SPI port.  While the
- * the control word is going out, the status word is arriving.
- */
-static
-uint   cs4218_ctl_write(uint ctlreg)
-{
-       uint    status;
-
-       sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4);
-
-       /* Shadow the control register.....I guess we could do
-        * the same for the status, but for now we just return it
-        * and let the caller decide.
-        */
-       cs4218_control = ctlreg;
-       return status;
-}
-
-static
-void   sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt)
-{
-       int     bits, i;
-       u_char  outbyte, inbyte;
-       volatile cpm8xx_t       *cp;
-       volatile uint           *hcsr4;
-
-       hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
-       cp = cpmp;      /* Get pointer to Communication Processor */
-
-       /* The timing on the bus is pretty slow.  Code inefficiency
-        * and eieio() is our friend here :-).
-        */
-       cp->cp_pbdat &= ~PB_SPICLK;
-       *hcsr4 |= HIOX_CSR4_AUDSPISEL;  /* Enable SPI select */
-       eieio();
-
-       /* Clock in/out the bytes.  Data is valid on the falling edge
-        * of the clock.  Data is MSB first.
-        */
-       for (i=0; i<bcnt; i++) {
-               outbyte = *obuf++;
-               inbyte = 0;
-               for (bits=0; bits<8; bits++) {
-                       eieio();
-                       cp->cp_pbdat |= PB_SPICLK;
-                       eieio();
-                       if (outbyte & 0x80)
-                               cp->cp_pbdat |= PB_SPIMOSI;
-                       else
-                               cp->cp_pbdat &= ~PB_SPIMOSI;
-                       eieio();
-                       cp->cp_pbdat &= ~PB_SPICLK;
-                       eieio();
-                       outbyte <<= 1;
-                       inbyte <<= 1;
-                       if (cp->cp_pbdat & PB_SPIMISO)
-                               inbyte |= 1;
-               }
-               *ibuf++ = inbyte;
-       }
-
-       *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
-       eieio();
-}
-
-void cleanup_module(void)
-{
-       if (irq_installed) {
-               sound_silence();
-#ifdef MODULE
-               sound.mach.irqcleanup();
-#endif
-       }
-
-       sq_release_read_buffers();
-       sq_release_buffers();
-
-       if (mixer_unit >= 0)
-               unregister_sound_mixer(mixer_unit);
-       if (state_unit >= 0)
-               unregister_sound_special(state_unit);
-       if (sq_unit >= 0)
-               unregister_sound_dsp(sq_unit);
-}
-
-module_init(tdm8xx_sound_init);
-module_exit(cleanup_module);
-
index 57a2a55..a3c1118 100644 (file)
@@ -69,10 +69,6 @@ extern bd_t m8xx_board_info;
 #define BCSR2_QSPACESEL                ((uint)0x00004000)
 #define BCSR2_FETHLEDMODE      ((uint)0x00000800)      /* CLLF */
 
-#if defined(CONFIG_HTDMSOUND)
-#include <platforms/rpxhiox.h>
-#endif
-
 /* define IO_BASE for pcmcia, CLLF only */
 #if !defined(CONFIG_PCI)
 #define _IO_BASE 0x80000000
diff --git a/arch/ppc/platforms/rpxhiox.h b/arch/ppc/platforms/rpxhiox.h
deleted file mode 100644 (file)
index c3fa5a6..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * The Embedded Planet HIOX expansion card definitions.
- * There were a few different versions of these cards, but only
- * the one that escaped real production is defined here.
- *
- * Copyright (c) 2000 Dan Malek (dmalek@jlc.net)
- */
-#ifndef __MACH_RPX_HIOX_DEFS
-#define __MACH_RPX_HIOX_DEFS
-
-#define HIOX_CSR_ADDR          ((uint)0xfac00000)
-#define HIOX_CSR_SIZE          ((uint)(4 * 1024))
-#define HIOX_CSR0_ADDR         HIOX_CSR_ADDR
-#define HIOX_CSR4_ADDR         ((uint)0xfac00004)
-
-#define HIOX_CSR0_DEFAULT      ((uint)0x380f3c00)
-#define HIOX_CSR0_ENSCC2       ((uint)0x80000000)
-#define HIOX_CSR0_ENSMC2       ((uint)0x04000000)
-#define HIOX_CSR0_ENVDOCLK     ((uint)0x02000000)
-#define HIOX_CSR0_VDORST_HL    ((uint)0x01000000)
-#define HIOX_CSR0_RS232SEL     ((uint)0x0000c000)
-#define HIOX_CSR0_SCC3SEL      ((uint)0x0000c000)
-#define HIOX_CSR0_SMC1SEL      ((uint)0x00008000)
-#define HIOX_CSR0_SCC1SEL      ((uint)0x00004000)
-#define HIOX_CSR0_ENTOUCH      ((uint)0x00000080)
-#define HIOX_CSR0_PDOWN100     ((uint)0x00000060)
-#define HIOX_CSR0_PDOWN10      ((uint)0x00000040)
-#define HIOX_CSR0_PDOWN1       ((uint)0x00000020)
-#define HIOX_CSR0_TSELSPI      ((uint)0x00000010)
-#define HIOX_CSR0_TIRQSTAT     ((uint)0x00000008)
-#define HIOX_CSR4_DEFAULT      ((uint)0x00000000)
-#define HIOX_CSR4_ENTIRQ2      ((uint)0x20000000)
-#define HIOX_CSR4_ENTIRQ3      ((uint)0x10000000)
-#define HIOX_CSR4_ENAUDIO      ((uint)0x00000080)
-#define HIOX_CSR4_RSTAUDIO     ((uint)0x00000040)      /* 0 == reset */
-#define HIOX_CSR4_AUDCLKHI     ((uint)0x00000020)
-#define HIOX_CSR4_AUDSPISEL    ((uint)0x00000010)
-#define HIOX_CSR4_AUDIRQSTAT   ((uint)0x00000008)
-#define HIOX_CSR4_AUDCLKSEL    ((uint)0x00000007)
-
-#endif
index 7197806..b615501 100644 (file)
@@ -57,10 +57,6 @@ extern bd_t m8xx_board_info;
 #define BCSR1_PCVCTL6          ((uint)0x00020000)
 #define BCSR1_PCVCTL7          ((uint)0x00010000)
 
-#if defined(CONFIG_HTDMSOUND)
-#include <platforms/rpxhiox.h>
-#endif
-
 /* define IO_BASE for pcmcia */
 #define _IO_BASE 0x80000000
 #define _IO_BASE_SIZE 0x1000
index 01e48d8..9caf850 100644 (file)
@@ -413,7 +413,7 @@ m8xx_map_io(void)
        io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
 #endif
 #endif
-#if defined(CONFIG_HTDMSOUND) || defined(CONFIG_RPXTOUCH) || defined(CONFIG_FB_RPX)
+#if defined(CONFIG_RPXTOUCH) || defined(CONFIG_FB_RPX)
        io_block_mapping(HIOX_CSR_ADDR, HIOX_CSR_ADDR, HIOX_CSR_SIZE, _PAGE_IO);
 #endif
 #ifdef CONFIG_FADS