ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ppc / 8xx_io / cs4218_tdm.c
1
2 /* This is a modified version of linux/drivers/sound/dmasound.c to
3  * support the CS4218 codec on the 8xx TDM port.  Thanks to everyone
4  * that contributed to the dmasound software (which includes me :-).
5  *
6  * The CS4218 is configured in Mode 4, sub-mode 0.  This provides
7  * left/right data only on the TDM port, as a 32-bit word, per frame
8  * pulse.  The control of the CS4218 is provided by some other means,
9  * like the SPI port.
10  * Dan Malek (dmalek@jlc.net)
11  */
12
13 #include <linux/module.h>
14 #include <linux/sched.h>
15 #include <linux/timer.h>
16 #include <linux/major.h>
17 #include <linux/config.h>
18 #include <linux/fcntl.h>
19 #include <linux/errno.h>
20 #include <linux/mm.h>
21 #include <linux/slab.h>
22 #include <linux/sound.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25
26 #include <asm/system.h>
27 #include <asm/irq.h>
28 #include <asm/pgtable.h>
29 #include <asm/uaccess.h>
30 #include <asm/io.h>
31
32 /* Should probably do something different with this path name.....
33  * Actually, I should just stop using it...
34  */
35 #include "cs4218.h"
36 #include <linux/soundcard.h>
37
38 #include <asm/mpc8xx.h>
39 #include <asm/8xx_immap.h>
40 #include <asm/commproc.h>
41
42 #define DMASND_CS4218           5
43
44 #define MAX_CATCH_RADIUS        10
45 #define MIN_BUFFERS             4
46 #define MIN_BUFSIZE             4
47 #define MAX_BUFSIZE             128
48
49 #define HAS_8BIT_TABLES
50
51 static int sq_unit = -1;
52 static int mixer_unit = -1;
53 static int state_unit = -1;
54 static int irq_installed = 0;
55 static char **sound_buffers = NULL;
56 static char **sound_read_buffers = NULL;
57
58 /* Local copies of things we put in the control register.  Output
59  * volume, like most codecs is really attenuation.
60  */
61 static int cs4218_rate_index;
62
63 /*
64  * Stuff for outputting a beep.  The values range from -327 to +327
65  * so we can multiply by an amplitude in the range 0..100 to get a
66  * signed short value to put in the output buffer.
67  */
68 static short beep_wform[256] = {
69         0,      40,     79,     117,    153,    187,    218,    245,
70         269,    288,    304,    316,    323,    327,    327,    324,
71         318,    310,    299,    288,    275,    262,    249,    236,
72         224,    213,    204,    196,    190,    186,    183,    182,
73         182,    183,    186,    189,    192,    196,    200,    203,
74         206,    208,    209,    209,    209,    207,    204,    201,
75         197,    193,    188,    183,    179,    174,    170,    166,
76         163,    161,    160,    159,    159,    160,    161,    162,
77         164,    166,    168,    169,    171,    171,    171,    170,
78         169,    167,    163,    159,    155,    150,    144,    139,
79         133,    128,    122,    117,    113,    110,    107,    105,
80         103,    103,    103,    103,    104,    104,    105,    105,
81         105,    103,    101,    97,     92,     86,     78,     68,
82         58,     45,     32,     18,     3,      -11,    -26,    -41,
83         -55,    -68,    -79,    -88,    -95,    -100,   -102,   -102,
84         -99,    -93,    -85,    -75,    -62,    -48,    -33,    -16,
85         0,      16,     33,     48,     62,     75,     85,     93,
86         99,     102,    102,    100,    95,     88,     79,     68,
87         55,     41,     26,     11,     -3,     -18,    -32,    -45,
88         -58,    -68,    -78,    -86,    -92,    -97,    -101,   -103,
89         -105,   -105,   -105,   -104,   -104,   -103,   -103,   -103,
90         -103,   -105,   -107,   -110,   -113,   -117,   -122,   -128,
91         -133,   -139,   -144,   -150,   -155,   -159,   -163,   -167,
92         -169,   -170,   -171,   -171,   -171,   -169,   -168,   -166,
93         -164,   -162,   -161,   -160,   -159,   -159,   -160,   -161,
94         -163,   -166,   -170,   -174,   -179,   -183,   -188,   -193,
95         -197,   -201,   -204,   -207,   -209,   -209,   -209,   -208,
96         -206,   -203,   -200,   -196,   -192,   -189,   -186,   -183,
97         -182,   -182,   -183,   -186,   -190,   -196,   -204,   -213,
98         -224,   -236,   -249,   -262,   -275,   -288,   -299,   -310,
99         -318,   -324,   -327,   -327,   -323,   -316,   -304,   -288,
100         -269,   -245,   -218,   -187,   -153,   -117,   -79,    -40,
101 };
102
103 #define BEEP_SPEED      5       /* 22050 Hz sample rate */
104 #define BEEP_BUFLEN     512
105 #define BEEP_VOLUME     15      /* 0 - 100 */
106
107 static int beep_volume = BEEP_VOLUME;
108 static int beep_playing = 0;
109 static int beep_state = 0;
110 static short *beep_buf;
111 static void (*orig_mksound)(unsigned int, unsigned int);
112
113 /* This is found someplace else......I guess in the keyboard driver
114  * we don't include.
115  */
116 static void (*kd_mksound)(unsigned int, unsigned int);
117
118 static int catchRadius = 0;
119 static int numBufs = 4, bufSize = 32;
120 static int numReadBufs = 4, readbufSize = 32;
121
122
123 /* TDM/Serial transmit and receive buffer descriptors.
124 */
125 static volatile cbd_t   *rx_base, *rx_cur, *tx_base, *tx_cur;
126
127 MODULE_PARM(catchRadius, "i");
128 MODULE_PARM(numBufs, "i");
129 MODULE_PARM(bufSize, "i");
130 MODULE_PARM(numreadBufs, "i");
131 MODULE_PARM(readbufSize, "i");
132
133 #define arraysize(x)    (sizeof(x)/sizeof(*(x)))
134 #define le2be16(x)      (((x)<<8 & 0xff00) | ((x)>>8 & 0x00ff))
135 #define le2be16dbl(x)   (((x)<<8 & 0xff00ff00) | ((x)>>8 & 0x00ff00ff))
136
137 #define IOCTL_IN(arg, ret) \
138         do { int error = get_user(ret, (int *)(arg)); \
139                 if (error) return error; \
140         } while (0)
141 #define IOCTL_OUT(arg, ret)     ioctl_return((int *)(arg), ret)
142
143 /* CS4218 serial port control in mode 4.
144 */
145 #define CS_INTMASK      ((uint)0x40000000)
146 #define CS_DO1          ((uint)0x20000000)
147 #define CS_LATTEN       ((uint)0x1f000000)
148 #define CS_RATTEN       ((uint)0x00f80000)
149 #define CS_MUTE         ((uint)0x00040000)
150 #define CS_ISL          ((uint)0x00020000)
151 #define CS_ISR          ((uint)0x00010000)
152 #define CS_LGAIN        ((uint)0x0000f000)
153 #define CS_RGAIN        ((uint)0x00000f00)
154
155 #define CS_LATTEN_SET(X)        (((X) & 0x1f) << 24)
156 #define CS_RATTEN_SET(X)        (((X) & 0x1f) << 19)
157 #define CS_LGAIN_SET(X)         (((X) & 0x0f) << 12)
158 #define CS_RGAIN_SET(X)         (((X) & 0x0f) << 8)
159
160 #define CS_LATTEN_GET(X)        (((X) >> 24) & 0x1f)
161 #define CS_RATTEN_GET(X)        (((X) >> 19) & 0x1f)
162 #define CS_LGAIN_GET(X)         (((X) >> 12) & 0x0f)
163 #define CS_RGAIN_GET(X)         (((X) >> 8) & 0x0f)
164
165 /* The control register is effectively write only.  We have to keep a copy
166  * of what we write.
167  */
168 static  uint    cs4218_control;
169
170 /* A place to store expanding information.
171 */
172 static int      expand_bal;
173 static int      expand_data;
174
175 /* Since I can't make the microcode patch work for the SPI, I just
176  * clock the bits using software.
177  */
178 static  void    sw_spi_init(void);
179 static  void    sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt);
180 static  uint    cs4218_ctl_write(uint ctlreg);
181
182 /*** Some low level helpers **************************************************/
183
184 /* 16 bit mu-law */
185
186 static short ulaw2dma16[] = {
187         -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
188         -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
189         -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
190         -11900, -11388, -10876, -10364, -9852,  -9340,  -8828,  -8316,
191         -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
192         -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
193         -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
194         -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
195         -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
196         -1372,  -1308,  -1244,  -1180,  -1116,  -1052,  -988,   -924,
197         -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
198         -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
199         -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
200         -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
201         -120,   -112,   -104,   -96,    -88,    -80,    -72,    -64,
202         -56,    -48,    -40,    -32,    -24,    -16,    -8,     0,
203         32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
204         23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
205         15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
206         11900,  11388,  10876,  10364,  9852,   9340,   8828,   8316,
207         7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
208         5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
209         3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
210         2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
211         1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
212         1372,   1308,   1244,   1180,   1116,   1052,   988,    924,
213         876,    844,    812,    780,    748,    716,    684,    652,
214         620,    588,    556,    524,    492,    460,    428,    396,
215         372,    356,    340,    324,    308,    292,    276,    260,
216         244,    228,    212,    196,    180,    164,    148,    132,
217         120,    112,    104,    96,     88,     80,     72,     64,
218         56,     48,     40,     32,     24,     16,     8,      0,
219 };
220
221 /* 16 bit A-law */
222
223 static short alaw2dma16[] = {
224         -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
225         -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
226         -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
227         -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
228         -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
229         -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
230         -11008, -10496, -12032, -11520, -8960,  -8448,  -9984,  -9472,
231         -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
232         -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
233         -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
234         -88,    -72,    -120,   -104,   -24,    -8,     -56,    -40,
235         -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
236         -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
237         -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
238         -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
239         -944,   -912,   -1008,  -976,   -816,   -784,   -880,   -848,
240         5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
241         7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
242         2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
243         3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
244         22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
245         30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
246         11008,  10496,  12032,  11520,  8960,   8448,   9984,   9472,
247         15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
248         344,    328,    376,    360,    280,    264,    312,    296,
249         472,    456,    504,    488,    408,    392,    440,    424,
250         88,     72,     120,    104,    24,     8,      56,     40,
251         216,    200,    248,    232,    152,    136,    184,    168,
252         1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
253         1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
254         688,    656,    752,    720,    560,    528,    624,    592,
255         944,    912,    1008,   976,    816,    784,    880,    848,
256 };
257
258
259 /*** Translations ************************************************************/
260
261
262 static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount,
263                            u_char frame[], ssize_t *frameUsed,
264                            ssize_t frameLeft);
265 static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount,
266                           u_char frame[], ssize_t *frameUsed,
267                           ssize_t frameLeft);
268 static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount,
269                           u_char frame[], ssize_t *frameUsed,
270                           ssize_t frameLeft);
271 static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount,
272                            u_char frame[], ssize_t *frameUsed,
273                            ssize_t frameLeft);
274 static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount,
275                            u_char frame[], ssize_t *frameUsed,
276                            ssize_t frameLeft);
277 static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount,
278                             u_char frame[], ssize_t *frameUsed,
279                             ssize_t frameLeft);
280 static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount,
281                            u_char frame[], ssize_t *frameUsed,
282                            ssize_t frameLeft);
283 static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount,
284                            u_char frame[], ssize_t *frameUsed,
285                            ssize_t frameLeft);
286 static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount,
287                             u_char frame[], ssize_t *frameUsed,
288                             ssize_t frameLeft);
289 static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount,
290                             u_char frame[], ssize_t *frameUsed,
291                             ssize_t frameLeft);
292 static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount,
293                            u_char frame[], ssize_t *frameUsed,
294                            ssize_t frameLeft);
295 static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount,
296                            u_char frame[], ssize_t *frameUsed,
297                            ssize_t frameLeft);
298
299
300 /*** Low level stuff *********************************************************/
301
302 struct cs_sound_settings {
303         MACHINE mach;           /* machine dependent things */
304         SETTINGS hard;          /* hardware settings */
305         SETTINGS soft;          /* software settings */
306         SETTINGS dsp;           /* /dev/dsp default settings */
307         TRANS *trans_write;     /* supported translations for playback */
308         TRANS *trans_read;      /* supported translations for record */
309         int volume_left;        /* volume (range is machine dependent) */
310         int volume_right;
311         int bass;               /* tone (range is machine dependent) */
312         int treble;
313         int gain;
314         int minDev;             /* minor device number currently open */
315 };
316
317 static struct cs_sound_settings sound;
318
319 static void *CS_Alloc(unsigned int size, int flags);
320 static void CS_Free(void *ptr, unsigned int size);
321 static int CS_IrqInit(void);
322 #ifdef MODULE
323 static void CS_IrqCleanup(void);
324 #endif /* MODULE */
325 static void CS_Silence(void);
326 static void CS_Init(void);
327 static void CS_Play(void);
328 static void CS_Record(void);
329 static int CS_SetFormat(int format);
330 static int CS_SetVolume(int volume);
331 static void cs4218_tdm_tx_intr(void *devid);
332 static void cs4218_tdm_rx_intr(void *devid);
333 static void cs4218_intr(void *devid, struct pt_regs *regs);
334 static int cs_get_volume(uint reg);
335 static int cs_volume_setter(int volume, int mute);
336 static int cs_get_gain(uint reg);
337 static int cs_set_gain(int gain);
338 static void cs_mksound(unsigned int hz, unsigned int ticks);
339 static void cs_nosound(unsigned long xx);
340
341 /*** Mid level stuff *********************************************************/
342
343
344 static void sound_silence(void);
345 static void sound_init(void);
346 static int sound_set_format(int format);
347 static int sound_set_speed(int speed);
348 static int sound_set_stereo(int stereo);
349 static int sound_set_volume(int volume);
350
351 static ssize_t sound_copy_translate(const u_char *userPtr,
352                                     size_t userCount,
353                                     u_char frame[], ssize_t *frameUsed,
354                                     ssize_t frameLeft);
355 static ssize_t sound_copy_translate_read(const u_char *userPtr,
356                                     size_t userCount,
357                                     u_char frame[], ssize_t *frameUsed,
358                                     ssize_t frameLeft);
359
360
361 /*
362  * /dev/mixer abstraction
363  */
364
365 struct sound_mixer {
366     int busy;
367     int modify_counter;
368 };
369
370 static struct sound_mixer mixer;
371
372 static struct sound_queue sq;
373 static struct sound_queue read_sq;
374
375 #define sq_block_address(i)     (sq.buffers[i])
376 #define SIGNAL_RECEIVED (signal_pending(current))
377 #define NON_BLOCKING(open_mode) (open_mode & O_NONBLOCK)
378 #define ONE_SECOND      HZ      /* in jiffies (100ths of a second) */
379 #define NO_TIME_LIMIT   0xffffffff
380
381 /*
382  * /dev/sndstat
383  */
384
385 struct sound_state {
386         int busy;
387         char buf[512];
388         int len, ptr;
389 };
390
391 static struct sound_state state;
392
393 /*** Common stuff ********************************************************/
394
395 static long long sound_lseek(struct file *file, long long offset, int orig);
396
397 /*** Config & Setup **********************************************************/
398
399 void dmasound_setup(char *str, int *ints);
400
401 /*** Translations ************************************************************/
402
403
404 /* ++TeSche: radically changed for new expanding purposes...
405  *
406  * These two routines now deal with copying/expanding/translating the samples
407  * from user space into our buffer at the right frequency. They take care about
408  * how much data there's actually to read, how much buffer space there is and
409  * to convert samples into the right frequency/encoding. They will only work on
410  * complete samples so it may happen they leave some bytes in the input stream
411  * if the user didn't write a multiple of the current sample size. They both
412  * return the number of bytes they've used from both streams so you may detect
413  * such a situation. Luckily all programs should be able to cope with that.
414  *
415  * I think I've optimized anything as far as one can do in plain C, all
416  * variables should fit in registers and the loops are really short. There's
417  * one loop for every possible situation. Writing a more generalized and thus
418  * parameterized loop would only produce slower code. Feel free to optimize
419  * this in assembler if you like. :)
420  *
421  * I think these routines belong here because they're not yet really hardware
422  * independent, especially the fact that the Falcon can play 16bit samples
423  * only in stereo is hardcoded in both of them!
424  *
425  * ++geert: split in even more functions (one per format)
426  */
427
428 static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount,
429                            u_char frame[], ssize_t *frameUsed,
430                            ssize_t frameLeft)
431 {
432         short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
433         ssize_t count, used;
434         short *p = (short *) &frame[*frameUsed];
435         int val, stereo = sound.soft.stereo;
436
437         frameLeft >>= 2;
438         if (stereo)
439                 userCount >>= 1;
440         used = count = min(userCount, frameLeft);
441         while (count > 0) {
442                 u_char data;
443                 if (get_user(data, userPtr++))
444                         return -EFAULT;
445                 val = table[data];
446                 *p++ = val;
447                 if (stereo) {
448                         if (get_user(data, userPtr++))
449                                 return -EFAULT;
450                         val = table[data];
451                 }
452                 *p++ = val;
453                 count--;
454         }
455         *frameUsed += used * 4;
456         return stereo? used * 2: used;
457 }
458
459
460 static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount,
461                           u_char frame[], ssize_t *frameUsed,
462                           ssize_t frameLeft)
463 {
464         ssize_t count, used;
465         short *p = (short *) &frame[*frameUsed];
466         int val, stereo = sound.soft.stereo;
467
468         frameLeft >>= 2;
469         if (stereo)
470                 userCount >>= 1;
471         used = count = min(userCount, frameLeft);
472         while (count > 0) {
473                 u_char data;
474                 if (get_user(data, userPtr++))
475                         return -EFAULT;
476                 val = data << 8;
477                 *p++ = val;
478                 if (stereo) {
479                         if (get_user(data, userPtr++))
480                                 return -EFAULT;
481                         val = data << 8;
482                 }
483                 *p++ = val;
484                 count--;
485         }
486         *frameUsed += used * 4;
487         return stereo? used * 2: used;
488 }
489
490
491 static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount,
492                           u_char frame[], ssize_t *frameUsed,
493                           ssize_t frameLeft)
494 {
495         ssize_t count, used;
496         short *p = (short *) &frame[*frameUsed];
497         int val, stereo = sound.soft.stereo;
498
499         frameLeft >>= 2;
500         if (stereo)
501                 userCount >>= 1;
502         used = count = min(userCount, frameLeft);
503         while (count > 0) {
504                 u_char data;
505                 if (get_user(data, userPtr++))
506                         return -EFAULT;
507                 val = (data ^ 0x80) << 8;
508                 *p++ = val;
509                 if (stereo) {
510                         if (get_user(data, userPtr++))
511                                 return -EFAULT;
512                         val = (data ^ 0x80) << 8;
513                 }
514                 *p++ = val;
515                 count--;
516         }
517         *frameUsed += used * 4;
518         return stereo? used * 2: used;
519 }
520
521
522 /* This is the default format of the codec.  Signed, 16-bit stereo
523  * generated by an application shouldn't have to be copied at all.
524  * We should just get the phsical address of the buffers and update
525  * the TDM BDs directly.
526  */
527 static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount,
528                            u_char frame[], ssize_t *frameUsed,
529                            ssize_t frameLeft)
530 {
531         ssize_t count, used;
532         int stereo = sound.soft.stereo;
533         short *fp = (short *) &frame[*frameUsed];
534
535         frameLeft >>= 2;
536         userCount >>= (stereo? 2: 1);
537         used = count = min(userCount, frameLeft);
538         if (!stereo) {
539                 short *up = (short *) userPtr;
540                 while (count > 0) {
541                         short data;
542                         if (get_user(data, up++))
543                                 return -EFAULT;
544                         *fp++ = data;
545                         *fp++ = data;
546                         count--;
547                 }
548         } else {
549                 if (copy_from_user(fp, userPtr, count * 4))
550                         return -EFAULT;
551         }
552         *frameUsed += used * 4;
553         return stereo? used * 4: used * 2;
554 }
555
556 static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount,
557                            u_char frame[], ssize_t *frameUsed,
558                            ssize_t frameLeft)
559 {
560         ssize_t count, used;
561         int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
562         int stereo = sound.soft.stereo;
563         short *fp = (short *) &frame[*frameUsed];
564         short *up = (short *) userPtr;
565
566         frameLeft >>= 2;
567         userCount >>= (stereo? 2: 1);
568         used = count = min(userCount, frameLeft);
569         while (count > 0) {
570                 int data;
571                 if (get_user(data, up++))
572                         return -EFAULT;
573                 data ^= mask;
574                 *fp++ = data;
575                 if (stereo) {
576                         if (get_user(data, up++))
577                                 return -EFAULT;
578                         data ^= mask;
579                 }
580                 *fp++ = data;
581                 count--;
582         }
583         *frameUsed += used * 4;
584         return stereo? used * 4: used * 2;
585 }
586
587
588 static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount,
589                             u_char frame[], ssize_t *frameUsed,
590                             ssize_t frameLeft)
591 {
592         unsigned short *table = (unsigned short *)
593                 (sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16);
594         unsigned int data = expand_data;
595         unsigned int *p = (unsigned int *) &frame[*frameUsed];
596         int bal = expand_bal;
597         int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
598         int utotal, ftotal;
599         int stereo = sound.soft.stereo;
600
601         frameLeft >>= 2;
602         if (stereo)
603                 userCount >>= 1;
604         ftotal = frameLeft;
605         utotal = userCount;
606         while (frameLeft) {
607                 u_char c;
608                 if (bal < 0) {
609                         if (userCount == 0)
610                                 break;
611                         if (get_user(c, userPtr++))
612                                 return -EFAULT;
613                         data = table[c];
614                         if (stereo) {
615                                 if (get_user(c, userPtr++))
616                                         return -EFAULT;
617                                 data = (data << 16) + table[c];
618                         } else
619                                 data = (data << 16) + data;
620                         userCount--;
621                         bal += hSpeed;
622                 }
623                 *p++ = data;
624                 frameLeft--;
625                 bal -= sSpeed;
626         }
627         expand_bal = bal;
628         expand_data = data;
629         *frameUsed += (ftotal - frameLeft) * 4;
630         utotal -= userCount;
631         return stereo? utotal * 2: utotal;
632 }
633
634
635 static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount,
636                            u_char frame[], ssize_t *frameUsed,
637                            ssize_t frameLeft)
638 {
639         unsigned int *p = (unsigned int *) &frame[*frameUsed];
640         unsigned int data = expand_data;
641         int bal = expand_bal;
642         int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
643         int stereo = sound.soft.stereo;
644         int utotal, ftotal;
645
646         frameLeft >>= 2;
647         if (stereo)
648                 userCount >>= 1;
649         ftotal = frameLeft;
650         utotal = userCount;
651         while (frameLeft) {
652                 u_char c;
653                 if (bal < 0) {
654                         if (userCount == 0)
655                                 break;
656                         if (get_user(c, userPtr++))
657                                 return -EFAULT;
658                         data = c << 8;
659                         if (stereo) {
660                                 if (get_user(c, userPtr++))
661                                         return -EFAULT;
662                                 data = (data << 16) + (c << 8);
663                         } else
664                                 data = (data << 16) + data;
665                         userCount--;
666                         bal += hSpeed;
667                 }
668                 *p++ = data;
669                 frameLeft--;
670                 bal -= sSpeed;
671         }
672         expand_bal = bal;
673         expand_data = data;
674         *frameUsed += (ftotal - frameLeft) * 4;
675         utotal -= userCount;
676         return stereo? utotal * 2: utotal;
677 }
678
679
680 static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount,
681                            u_char frame[], ssize_t *frameUsed,
682                            ssize_t frameLeft)
683 {
684         unsigned int *p = (unsigned int *) &frame[*frameUsed];
685         unsigned int data = expand_data;
686         int bal = expand_bal;
687         int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
688         int stereo = sound.soft.stereo;
689         int utotal, ftotal;
690
691         frameLeft >>= 2;
692         if (stereo)
693                 userCount >>= 1;
694         ftotal = frameLeft;
695         utotal = userCount;
696         while (frameLeft) {
697                 u_char c;
698                 if (bal < 0) {
699                         if (userCount == 0)
700                                 break;
701                         if (get_user(c, userPtr++))
702                                 return -EFAULT;
703                         data = (c ^ 0x80) << 8;
704                         if (stereo) {
705                                 if (get_user(c, userPtr++))
706                                         return -EFAULT;
707                                 data = (data << 16) + ((c ^ 0x80) << 8);
708                         } else
709                                 data = (data << 16) + data;
710                         userCount--;
711                         bal += hSpeed;
712                 }
713                 *p++ = data;
714                 frameLeft--;
715                 bal -= sSpeed;
716         }
717         expand_bal = bal;
718         expand_data = data;
719         *frameUsed += (ftotal - frameLeft) * 4;
720         utotal -= userCount;
721         return stereo? utotal * 2: utotal;
722 }
723
724
725 static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount,
726                             u_char frame[], ssize_t *frameUsed,
727                             ssize_t frameLeft)
728 {
729         unsigned int *p = (unsigned int *) &frame[*frameUsed];
730         unsigned int data = expand_data;
731         unsigned short *up = (unsigned short *) userPtr;
732         int bal = expand_bal;
733         int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
734         int stereo = sound.soft.stereo;
735         int utotal, ftotal;
736
737         frameLeft >>= 2;
738         userCount >>= (stereo? 2: 1);
739         ftotal = frameLeft;
740         utotal = userCount;
741         while (frameLeft) {
742                 unsigned short c;
743                 if (bal < 0) {
744                         if (userCount == 0)
745                                 break;
746                         if (get_user(data, up++))
747                                 return -EFAULT;
748                         if (stereo) {
749                                 if (get_user(c, up++))
750                                         return -EFAULT;
751                                 data = (data << 16) + c;
752                         } else
753                                 data = (data << 16) + data;
754                         userCount--;
755                         bal += hSpeed;
756                 }
757                 *p++ = data;
758                 frameLeft--;
759                 bal -= sSpeed;
760         }
761         expand_bal = bal;
762         expand_data = data;
763         *frameUsed += (ftotal - frameLeft) * 4;
764         utotal -= userCount;
765         return stereo? utotal * 4: utotal * 2;
766 }
767
768
769 static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount,
770                             u_char frame[], ssize_t *frameUsed,
771                             ssize_t frameLeft)
772 {
773         int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
774         unsigned int *p = (unsigned int *) &frame[*frameUsed];
775         unsigned int data = expand_data;
776         unsigned short *up = (unsigned short *) userPtr;
777         int bal = expand_bal;
778         int hSpeed = sound.hard.speed, sSpeed = sound.soft.speed;
779         int stereo = sound.soft.stereo;
780         int utotal, ftotal;
781
782         frameLeft >>= 2;
783         userCount >>= (stereo? 2: 1);
784         ftotal = frameLeft;
785         utotal = userCount;
786         while (frameLeft) {
787                 unsigned short c;
788                 if (bal < 0) {
789                         if (userCount == 0)
790                                 break;
791                         if (get_user(data, up++))
792                                 return -EFAULT;
793                         data ^= mask;
794                         if (stereo) {
795                                 if (get_user(c, up++))
796                                         return -EFAULT;
797                                 data = (data << 16) + (c ^ mask);
798                         } else
799                                 data = (data << 16) + data;
800                         userCount--;
801                         bal += hSpeed;
802                 }
803                 *p++ = data;
804                 frameLeft--;
805                 bal -= sSpeed;
806         }
807         expand_bal = bal;
808         expand_data = data;
809         *frameUsed += (ftotal - frameLeft) * 4;
810         utotal -= userCount;
811         return stereo? utotal * 4: utotal * 2;
812 }
813
814 static ssize_t cs4218_ct_s8_read(const u_char *userPtr, size_t userCount,
815                           u_char frame[], ssize_t *frameUsed,
816                           ssize_t frameLeft)
817 {
818         ssize_t count, used;
819         short *p = (short *) &frame[*frameUsed];
820         int val, stereo = sound.soft.stereo;
821
822         frameLeft >>= 2;
823         if (stereo)
824                 userCount >>= 1;
825         used = count = min(userCount, frameLeft);
826         while (count > 0) {
827                 u_char data;
828
829                 val = *p++;
830                 data = val >> 8;
831                 if (put_user(data, (u_char *)userPtr++))
832                         return -EFAULT;
833                 if (stereo) {
834                         val = *p;
835                         data = val >> 8;
836                         if (put_user(data, (u_char *)userPtr++))
837                                 return -EFAULT;
838                 }
839                 p++;
840                 count--;
841         }
842         *frameUsed += used * 4;
843         return stereo? used * 2: used;
844 }
845
846
847 static ssize_t cs4218_ct_u8_read(const u_char *userPtr, size_t userCount,
848                           u_char frame[], ssize_t *frameUsed,
849                           ssize_t frameLeft)
850 {
851         ssize_t count, used;
852         short *p = (short *) &frame[*frameUsed];
853         int val, stereo = sound.soft.stereo;
854
855         frameLeft >>= 2;
856         if (stereo)
857                 userCount >>= 1;
858         used = count = min(userCount, frameLeft);
859         while (count > 0) {
860                 u_char data;
861
862                 val = *p++;
863                 data = (val >> 8) ^ 0x80;
864                 if (put_user(data, (u_char *)userPtr++))
865                         return -EFAULT;
866                 if (stereo) {
867                         val = *p;
868                         data = (val >> 8) ^ 0x80;
869                         if (put_user(data, (u_char *)userPtr++))
870                                 return -EFAULT;
871                 }
872                 p++;
873                 count--;
874         }
875         *frameUsed += used * 4;
876         return stereo? used * 2: used;
877 }
878
879
880 static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount,
881                            u_char frame[], ssize_t *frameUsed,
882                            ssize_t frameLeft)
883 {
884         ssize_t count, used;
885         int stereo = sound.soft.stereo;
886         short *fp = (short *) &frame[*frameUsed];
887
888         frameLeft >>= 2;
889         userCount >>= (stereo? 2: 1);
890         used = count = min(userCount, frameLeft);
891         if (!stereo) {
892                 short *up = (short *) userPtr;
893                 while (count > 0) {
894                         short data;
895                         data = *fp;
896                         if (put_user(data, up++))
897                                 return -EFAULT;
898                         fp+=2;
899                         count--;
900                 }
901         } else {
902                 if (copy_to_user((u_char *)userPtr, fp, count * 4))
903                         return -EFAULT;
904         }
905         *frameUsed += used * 4;
906         return stereo? used * 4: used * 2;
907 }
908
909 static ssize_t cs4218_ct_u16_read(const u_char *userPtr, size_t userCount,
910                            u_char frame[], ssize_t *frameUsed,
911                            ssize_t frameLeft)
912 {
913         ssize_t count, used;
914         int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
915         int stereo = sound.soft.stereo;
916         short *fp = (short *) &frame[*frameUsed];
917         short *up = (short *) userPtr;
918
919         frameLeft >>= 2;
920         userCount >>= (stereo? 2: 1);
921         used = count = min(userCount, frameLeft);
922         while (count > 0) {
923                 int data;
924
925                 data = *fp++;
926                 data ^= mask;
927                 if (put_user(data, up++))
928                         return -EFAULT;
929                 if (stereo) {
930                         data = *fp;
931                         data ^= mask;
932                         if (put_user(data, up++))
933                                 return -EFAULT;
934                 }
935                 fp++;
936                 count--;
937         }
938         *frameUsed += used * 4;
939         return stereo? used * 4: used * 2;
940 }
941
942 static TRANS transCSNormal = {
943         cs4218_ct_law, cs4218_ct_law, cs4218_ct_s8, cs4218_ct_u8,
944         cs4218_ct_s16, cs4218_ct_u16, cs4218_ct_s16, cs4218_ct_u16
945 };
946
947 static TRANS transCSExpand = {
948         cs4218_ctx_law, cs4218_ctx_law, cs4218_ctx_s8, cs4218_ctx_u8,
949         cs4218_ctx_s16, cs4218_ctx_u16, cs4218_ctx_s16, cs4218_ctx_u16
950 };
951
952 static TRANS transCSNormalRead = {
953         NULL, NULL, cs4218_ct_s8_read, cs4218_ct_u8_read,
954         cs4218_ct_s16_read, cs4218_ct_u16_read,
955         cs4218_ct_s16_read, cs4218_ct_u16_read
956 };
957
958 /*** Low level stuff *********************************************************/
959
960 static void *CS_Alloc(unsigned int size, int flags)
961 {
962         int     order;
963
964         size >>= 13;
965         for (order=0; order < 5; order++) {
966                 if (size == 0)
967                         break;
968                 size >>= 1;
969         }
970         return (void *)__get_free_pages(flags, order);
971 }
972
973 static void CS_Free(void *ptr, unsigned int size)
974 {
975         int     order;
976
977         size >>= 13;
978         for (order=0; order < 5; order++) {
979                 if (size == 0)
980                         break;
981                 size >>= 1;
982         }
983         free_pages((ulong)ptr, order);
984 }
985
986 static int __init CS_IrqInit(void)
987 {
988         cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL);
989         return 1;
990 }
991
992 #ifdef MODULE
993 static void CS_IrqCleanup(void)
994 {
995         volatile smc_t          *sp;
996         volatile cpm8xx_t       *cp;
997
998         /* First disable transmitter and receiver.
999         */
1000         sp = &cpmp->cp_smc[1];
1001         sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
1002
1003         /* And now shut down the SMC.
1004         */
1005         cp = cpmp;      /* Get pointer to Communication Processor */
1006         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
1007                                 CPM_CR_STOP_TX) | CPM_CR_FLG;
1008         while (cp->cp_cpcr & CPM_CR_FLG);
1009
1010         /* Release the interrupt handler.
1011         */
1012         cpm_free_handler(CPMVEC_SMC2);
1013
1014         if (beep_buf)
1015                 kfree(beep_buf);
1016         kd_mksound = orig_mksound;
1017 }
1018 #endif /* MODULE */
1019
1020 static void CS_Silence(void)
1021 {
1022         volatile smc_t          *sp;
1023
1024         /* Disable transmitter.
1025         */
1026         sp = &cpmp->cp_smc[1];
1027         sp->smc_smcmr &= ~SMCMR_TEN;
1028 }
1029
1030 /* Frequencies depend upon external oscillator.  There are two
1031  * choices, 12.288 and 11.2896 MHz.  The RPCG audio supports both through
1032  * and external control register selection bit.
1033  */
1034 static int cs4218_freqs[] = {
1035     /* 12.288  11.2896  */
1036         48000, 44100,
1037         32000, 29400,
1038         24000, 22050,
1039         19200, 17640,
1040         16000, 14700,
1041         12000, 11025,
1042          9600,  8820,
1043          8000,  7350
1044 };
1045
1046 static void CS_Init(void)
1047 {
1048         int i, tolerance;
1049
1050         switch (sound.soft.format) {
1051         case AFMT_S16_LE:
1052         case AFMT_U16_LE:
1053                 sound.hard.format = AFMT_S16_LE;
1054                 break;
1055         default:
1056                 sound.hard.format = AFMT_S16_BE;
1057                 break;
1058         }
1059         sound.hard.stereo = 1;
1060         sound.hard.size = 16;
1061
1062         /*
1063          * If we have a sample rate which is within catchRadius percent
1064          * of the requested value, we don't have to expand the samples.
1065          * Otherwise choose the next higher rate.
1066          */
1067         i = (sizeof(cs4218_freqs) / sizeof(int));
1068         do {
1069                 tolerance = catchRadius * cs4218_freqs[--i] / 100;
1070         } while (sound.soft.speed > cs4218_freqs[i] + tolerance && i > 0);
1071         if (sound.soft.speed >= cs4218_freqs[i] - tolerance)
1072                 sound.trans_write = &transCSNormal;
1073         else
1074                 sound.trans_write = &transCSExpand;
1075         sound.trans_read = &transCSNormalRead;
1076         sound.hard.speed = cs4218_freqs[i];
1077         cs4218_rate_index = i;
1078
1079         /* The CS4218 has seven selectable clock dividers for the sample
1080          * clock.  The HIOX then provides one of two external rates.
1081          * An even numbered frequency table index uses the high external
1082          * clock rate.
1083          */
1084         *(uint *)HIOX_CSR4_ADDR &= ~(HIOX_CSR4_AUDCLKHI | HIOX_CSR4_AUDCLKSEL);
1085         if ((i & 1) == 0)
1086                 *(uint *)HIOX_CSR4_ADDR |= HIOX_CSR4_AUDCLKHI;
1087         i >>= 1;
1088         *(uint *)HIOX_CSR4_ADDR |= (i & HIOX_CSR4_AUDCLKSEL);
1089
1090         expand_bal = -sound.soft.speed;
1091 }
1092
1093 static int CS_SetFormat(int format)
1094 {
1095         int size;
1096
1097         switch (format) {
1098         case AFMT_QUERY:
1099                 return sound.soft.format;
1100         case AFMT_MU_LAW:
1101         case AFMT_A_LAW:
1102         case AFMT_U8:
1103         case AFMT_S8:
1104                 size = 8;
1105                 break;
1106         case AFMT_S16_BE:
1107         case AFMT_U16_BE:
1108         case AFMT_S16_LE:
1109         case AFMT_U16_LE:
1110                 size = 16;
1111                 break;
1112         default: /* :-) */
1113                 printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
1114                        format);
1115                 size = 8;
1116                 format = AFMT_U8;
1117         }
1118
1119         sound.soft.format = format;
1120         sound.soft.size = size;
1121         if (sound.minDev == SND_DEV_DSP) {
1122                 sound.dsp.format = format;
1123                 sound.dsp.size = size;
1124         }
1125
1126         CS_Init();
1127
1128         return format;
1129 }
1130
1131 /* Volume is the amount of attenuation we tell the codec to impose
1132  * on the outputs.  There are 32 levels, with 0 the "loudest".
1133  */
1134 #define CS_VOLUME_TO_MASK(x)    (31 - ((((x) - 1) * 31) / 99))
1135 #define CS_MASK_TO_VOLUME(y)    (100 - ((y) * 99 / 31))
1136
1137 static int cs_get_volume(uint reg)
1138 {
1139         int volume;
1140
1141         volume = CS_MASK_TO_VOLUME(CS_LATTEN_GET(reg));
1142         volume |= CS_MASK_TO_VOLUME(CS_RATTEN_GET(reg)) << 8;
1143         return volume;
1144 }
1145
1146 static int cs_volume_setter(int volume, int mute)
1147 {
1148         uint tempctl;
1149
1150         if (mute && volume == 0) {
1151                 tempctl = cs4218_control | CS_MUTE;
1152         } else {
1153                 tempctl = cs4218_control & ~CS_MUTE;
1154                 tempctl = tempctl & ~(CS_LATTEN | CS_RATTEN);
1155                 tempctl |= CS_LATTEN_SET(CS_VOLUME_TO_MASK(volume & 0xff));
1156                 tempctl |= CS_RATTEN_SET(CS_VOLUME_TO_MASK((volume >> 8) & 0xff));
1157                 volume = cs_get_volume(tempctl);
1158         }
1159         if (tempctl != cs4218_control) {
1160                 cs4218_ctl_write(tempctl);
1161         }
1162         return volume;
1163 }
1164
1165
1166 /* Gain has 16 steps from 0 to 15.  These are in 1.5dB increments from
1167  * 0 (no gain) to 22.5 dB.
1168  */
1169 #define CS_RECLEVEL_TO_GAIN(v) \
1170         ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1171 #define CS_GAIN_TO_RECLEVEL(v) (((v) * 20 + 2) / 3)
1172
1173 static int cs_get_gain(uint reg)
1174 {
1175         int gain;
1176
1177         gain = CS_GAIN_TO_RECLEVEL(CS_LGAIN_GET(reg));
1178         gain |= CS_GAIN_TO_RECLEVEL(CS_RGAIN_GET(reg)) << 8;
1179         return gain;
1180 }
1181
1182 static int cs_set_gain(int gain)
1183 {
1184         uint tempctl;
1185
1186         tempctl = cs4218_control & ~(CS_LGAIN | CS_RGAIN);
1187         tempctl |= CS_LGAIN_SET(CS_RECLEVEL_TO_GAIN(gain & 0xff));
1188         tempctl |= CS_RGAIN_SET(CS_RECLEVEL_TO_GAIN((gain >> 8) & 0xff));
1189         gain = cs_get_gain(tempctl);
1190
1191         if (tempctl != cs4218_control) {
1192                 cs4218_ctl_write(tempctl);
1193         }
1194         return gain;
1195 }
1196
1197 static int CS_SetVolume(int volume)
1198 {
1199         return cs_volume_setter(volume, CS_MUTE);
1200 }
1201
1202 static void CS_Play(void)
1203 {
1204         int i, count;
1205         unsigned long flags;
1206         volatile cbd_t  *bdp;
1207         volatile cpm8xx_t *cp;
1208
1209         save_flags(flags); cli();
1210 #if 0
1211         if (awacs_beep_state) {
1212                 /* sound takes precedence over beeps */
1213                 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
1214                 out_le32(&awacs->control,
1215                          (in_le32(&awacs->control) & ~0x1f00)
1216                          | (awacs_rate_index << 8));
1217                 out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
1218                 out_le32(&awacs_txdma->cmdptr, virt_to_bus(&(awacs_tx_cmds[(sq.front+sq.active) % sq.max_count])));
1219
1220                 beep_playing = 0;
1221                 awacs_beep_state = 0;
1222         }
1223 #endif
1224         i = sq.front + sq.active;
1225         if (i >= sq.max_count)
1226                 i -= sq.max_count;
1227         while (sq.active < 2 && sq.active < sq.count) {
1228                 count = (sq.count == sq.active + 1)?sq.rear_size:sq.block_size;
1229                 if (count < sq.block_size && !sq.syncing)
1230                         /* last block not yet filled, and we're not syncing. */
1231                         break;
1232
1233                 bdp = &tx_base[i];
1234                 bdp->cbd_datlen = count;
1235
1236                 flush_dcache_range((ulong)sound_buffers[i],
1237                                         (ulong)(sound_buffers[i] + count));
1238
1239                 if (++i >= sq.max_count)
1240                         i = 0;
1241
1242                 if (sq.active == 0) {
1243                         /* The SMC does not load its fifo until the first
1244                          * TDM frame pulse, so the transmit data gets shifted
1245                          * by one word.  To compensate for this, we incorrectly
1246                          * transmit the first buffer and shorten it by one
1247                          * word.  Subsequent buffers are then aligned properly.
1248                          */
1249                         bdp->cbd_datlen -= 2;
1250
1251                         /* Start up the SMC Transmitter.
1252                         */
1253                         cp = cpmp;
1254                         cp->cp_smc[1].smc_smcmr |= SMCMR_TEN;
1255                         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
1256                                         CPM_CR_RESTART_TX) | CPM_CR_FLG;
1257                         while (cp->cp_cpcr & CPM_CR_FLG);
1258                 }
1259
1260                 /* Buffer is ready now.
1261                 */
1262                 bdp->cbd_sc |= BD_SC_READY;
1263
1264                 ++sq.active;
1265         }
1266         restore_flags(flags);
1267 }
1268
1269
1270 static void CS_Record(void)
1271 {
1272         unsigned long flags;
1273         volatile smc_t          *sp;
1274
1275         if (read_sq.active)
1276                 return;
1277
1278         save_flags(flags); cli();
1279
1280         /* This is all we have to do......Just start it up.
1281         */
1282         sp = &cpmp->cp_smc[1];
1283         sp->smc_smcmr |= SMCMR_REN;
1284
1285         read_sq.active = 1;
1286
1287         restore_flags(flags);
1288 }
1289
1290
1291 static void
1292 cs4218_tdm_tx_intr(void *devid)
1293 {
1294         int i = sq.front;
1295         volatile cbd_t *bdp;
1296
1297         while (sq.active > 0) {
1298                 bdp = &tx_base[i];
1299                 if (bdp->cbd_sc & BD_SC_READY)
1300                         break;  /* this frame is still going */
1301                 --sq.count;
1302                 --sq.active;
1303                 if (++i >= sq.max_count)
1304                         i = 0;
1305         }
1306         if (i != sq.front)
1307                 WAKE_UP(sq.action_queue);
1308         sq.front = i;
1309
1310         CS_Play();
1311
1312         if (!sq.active)
1313                 WAKE_UP(sq.sync_queue);
1314 }
1315
1316
1317 static void
1318 cs4218_tdm_rx_intr(void *devid)
1319 {
1320
1321         /* We want to blow 'em off when shutting down.
1322         */
1323         if (read_sq.active == 0)
1324                 return;
1325
1326         /* Check multiple buffers in case we were held off from
1327          * interrupt processing for a long time.  Geeze, I really hope
1328          * this doesn't happen.
1329          */
1330         while ((rx_base[read_sq.rear].cbd_sc & BD_SC_EMPTY) == 0) {
1331
1332                 /* Invalidate the data cache range for this buffer.
1333                 */
1334                 invalidate_dcache_range(
1335                     (uint)(sound_read_buffers[read_sq.rear]),
1336                     (uint)(sound_read_buffers[read_sq.rear] + read_sq.block_size));
1337
1338                 /* Make buffer available again and move on.
1339                 */
1340                 rx_base[read_sq.rear].cbd_sc |= BD_SC_EMPTY;
1341                 read_sq.rear++;
1342
1343                 /* Wrap the buffer ring.
1344                 */
1345                 if (read_sq.rear >= read_sq.max_active)
1346                         read_sq.rear = 0;
1347
1348                 /* If we have caught up to the front buffer, bump it.
1349                  * This will cause weird (but not fatal) results if the
1350                  * read loop is currently using this buffer.  The user is
1351                  * behind in this case anyway, so weird things are going
1352                  * to happen.
1353                  */
1354                 if (read_sq.rear == read_sq.front) {
1355                         read_sq.front++;
1356                         if (read_sq.front >= read_sq.max_active)
1357                                 read_sq.front = 0;
1358                 }
1359         }
1360
1361         WAKE_UP(read_sq.action_queue);
1362 }
1363
1364 static void cs_nosound(unsigned long xx)
1365 {
1366         unsigned long flags;
1367
1368         save_flags(flags); cli();
1369         if (beep_playing) {
1370 #if 0
1371                 st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
1372 #endif
1373                 beep_playing = 0;
1374         }
1375         restore_flags(flags);
1376 }
1377
1378 static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0);
1379 };
1380
1381 static void cs_mksound(unsigned int hz, unsigned int ticks)
1382 {
1383         unsigned long flags;
1384         int beep_speed = BEEP_SPEED;
1385         int srate = cs4218_freqs[beep_speed];
1386         int period, ncycles, nsamples;
1387         int i, j, f;
1388         short *p;
1389         static int beep_hz_cache;
1390         static int beep_nsamples_cache;
1391         static int beep_volume_cache;
1392
1393         if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
1394 #if 1
1395                 /* this is a hack for broken X server code */
1396                 hz = 750;
1397                 ticks = 12;
1398 #else
1399                 /* cancel beep currently playing */
1400                 awacs_nosound(0);
1401                 return;
1402 #endif
1403         }
1404         save_flags(flags); cli();
1405         del_timer(&beep_timer);
1406         if (ticks) {
1407                 beep_timer.expires = jiffies + ticks;
1408                 add_timer(&beep_timer);
1409         }
1410         if (beep_playing || sq.active || beep_buf == NULL) {
1411                 restore_flags(flags);
1412                 return;         /* too hard, sorry :-( */
1413         }
1414         beep_playing = 1;
1415 #if 0
1416         st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
1417 #endif
1418         restore_flags(flags);
1419
1420         if (hz == beep_hz_cache && beep_volume == beep_volume_cache) {
1421                 nsamples = beep_nsamples_cache;
1422         } else {
1423                 period = srate * 256 / hz;      /* fixed point */
1424                 ncycles = BEEP_BUFLEN * 256 / period;
1425                 nsamples = (period * ncycles) >> 8;
1426                 f = ncycles * 65536 / nsamples;
1427                 j = 0;
1428                 p = beep_buf;
1429                 for (i = 0; i < nsamples; ++i, p += 2) {
1430                         p[0] = p[1] = beep_wform[j >> 8] * beep_volume;
1431                         j = (j + f) & 0xffff;
1432                 }
1433                 beep_hz_cache = hz;
1434                 beep_volume_cache = beep_volume;
1435                 beep_nsamples_cache = nsamples;
1436         }
1437
1438 #if 0
1439         st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
1440         st_le16(&beep_dbdma_cmd->xfer_status, 0);
1441         st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
1442         st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
1443         awacs_beep_state = 1;
1444
1445         save_flags(flags); cli();
1446         if (beep_playing) {     /* i.e. haven't been terminated already */
1447                 out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
1448                 out_le32(&awacs->control,
1449                          (in_le32(&awacs->control) & ~0x1f00)
1450                          | (beep_speed << 8));
1451                 out_le32(&awacs->byteswap, 0);
1452                 out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
1453                 out_le32(&awacs_txdma->control, RUN | (RUN << 16));
1454         }
1455 #endif
1456         restore_flags(flags);
1457 }
1458
1459 static void CS_open(void)
1460 {
1461         MOD_INC_USE_COUNT;
1462 }
1463
1464 static void CS_release(void)
1465 {
1466         MOD_DEC_USE_COUNT;
1467 }
1468
1469 static MACHINE mach_cs4218 = {
1470         .name =         "HIOX CS4218",
1471         .name2 =        "Built-in Sound",
1472         .open =         CS_open,
1473         .release =      CS_release,
1474         .dma_alloc =    CS_Alloc,
1475         .dma_free =     CS_Free,
1476         .irqinit =      CS_IrqInit,
1477 #ifdef MODULE
1478         .irqcleanup =   CS_IrqCleanup,
1479 #endif /* MODULE */
1480         .init =         CS_Init,
1481         .silence =      CS_Silence,
1482         .setFormat =    CS_SetFormat,
1483         .setVolume =    CS_SetVolume,
1484         .play =         CS_Play
1485 };
1486
1487
1488 /*** Mid level stuff *********************************************************/
1489
1490
1491 static void sound_silence(void)
1492 {
1493         /* update hardware settings one more */
1494         (*sound.mach.init)();
1495
1496         (*sound.mach.silence)();
1497 }
1498
1499
1500 static void sound_init(void)
1501 {
1502         (*sound.mach.init)();
1503 }
1504
1505
1506 static int sound_set_format(int format)
1507 {
1508         return(*sound.mach.setFormat)(format);
1509 }
1510
1511
1512 static int sound_set_speed(int speed)
1513 {
1514         if (speed < 0)
1515                 return(sound.soft.speed);
1516
1517         sound.soft.speed = speed;
1518         (*sound.mach.init)();
1519         if (sound.minDev == SND_DEV_DSP)
1520                 sound.dsp.speed = sound.soft.speed;
1521
1522         return(sound.soft.speed);
1523 }
1524
1525
1526 static int sound_set_stereo(int stereo)
1527 {
1528         if (stereo < 0)
1529                 return(sound.soft.stereo);
1530
1531         stereo = !!stereo;    /* should be 0 or 1 now */
1532
1533         sound.soft.stereo = stereo;
1534         if (sound.minDev == SND_DEV_DSP)
1535                 sound.dsp.stereo = stereo;
1536         (*sound.mach.init)();
1537
1538         return(stereo);
1539 }
1540
1541
1542 static int sound_set_volume(int volume)
1543 {
1544         return(*sound.mach.setVolume)(volume);
1545 }
1546
1547 static ssize_t sound_copy_translate(const u_char *userPtr,
1548                                     size_t userCount,
1549                                     u_char frame[], ssize_t *frameUsed,
1550                                     ssize_t frameLeft)
1551 {
1552         ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1553
1554         switch (sound.soft.format) {
1555         case AFMT_MU_LAW:
1556                 ct_func = sound.trans_write->ct_ulaw;
1557                 break;
1558         case AFMT_A_LAW:
1559                 ct_func = sound.trans_write->ct_alaw;
1560                 break;
1561         case AFMT_S8:
1562                 ct_func = sound.trans_write->ct_s8;
1563                 break;
1564         case AFMT_U8:
1565                 ct_func = sound.trans_write->ct_u8;
1566                 break;
1567         case AFMT_S16_BE:
1568                 ct_func = sound.trans_write->ct_s16be;
1569                 break;
1570         case AFMT_U16_BE:
1571                 ct_func = sound.trans_write->ct_u16be;
1572                 break;
1573         case AFMT_S16_LE:
1574                 ct_func = sound.trans_write->ct_s16le;
1575                 break;
1576         case AFMT_U16_LE:
1577                 ct_func = sound.trans_write->ct_u16le;
1578                 break;
1579         }
1580         if (ct_func)
1581                 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1582         else
1583                 return 0;
1584 }
1585
1586 static ssize_t sound_copy_translate_read(const u_char *userPtr,
1587                                     size_t userCount,
1588                                     u_char frame[], ssize_t *frameUsed,
1589                                     ssize_t frameLeft)
1590 {
1591         ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1592
1593         switch (sound.soft.format) {
1594         case AFMT_MU_LAW:
1595                 ct_func = sound.trans_read->ct_ulaw;
1596                 break;
1597         case AFMT_A_LAW:
1598                 ct_func = sound.trans_read->ct_alaw;
1599                 break;
1600         case AFMT_S8:
1601                 ct_func = sound.trans_read->ct_s8;
1602                 break;
1603         case AFMT_U8:
1604                 ct_func = sound.trans_read->ct_u8;
1605                 break;
1606         case AFMT_S16_BE:
1607                 ct_func = sound.trans_read->ct_s16be;
1608                 break;
1609         case AFMT_U16_BE:
1610                 ct_func = sound.trans_read->ct_u16be;
1611                 break;
1612         case AFMT_S16_LE:
1613                 ct_func = sound.trans_read->ct_s16le;
1614                 break;
1615         case AFMT_U16_LE:
1616                 ct_func = sound.trans_read->ct_u16le;
1617                 break;
1618         }
1619         if (ct_func)
1620                 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1621         else
1622                 return 0;
1623 }
1624
1625
1626 /*
1627  * /dev/mixer abstraction
1628  */
1629
1630 static int mixer_open(struct inode *inode, struct file *file)
1631 {
1632         mixer.busy = 1;
1633         return 0;
1634 }
1635
1636
1637 static int mixer_release(struct inode *inode, struct file *file)
1638 {
1639         mixer.busy = 0;
1640         return 0;
1641 }
1642
1643
1644 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
1645                        u_long arg)
1646 {
1647         int data;
1648         uint tmpcs;
1649
1650         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
1651             mixer.modify_counter++;
1652         if (cmd == OSS_GETVERSION)
1653             return IOCTL_OUT(arg, SOUND_VERSION);
1654         switch (cmd) {
1655                 case SOUND_MIXER_INFO: {
1656                     mixer_info info;
1657                     strlcpy(info.id, "CS4218_TDM", sizeof(info.id));
1658                     strlcpy(info.name, "CS4218_TDM", sizeof(info.name));
1659                     info.name[sizeof(info.name)-1] = 0;
1660                     info.modify_counter = mixer.modify_counter;
1661                     if (copy_to_user((int *)arg, &info, sizeof(info)))
1662                                 return -EFAULT;
1663                     return 0;
1664                 }
1665                 case SOUND_MIXER_READ_DEVMASK:
1666                         data = SOUND_MASK_VOLUME | SOUND_MASK_LINE
1667                                 | SOUND_MASK_MIC | SOUND_MASK_RECLEV
1668                                 | SOUND_MASK_ALTPCM;
1669                         return IOCTL_OUT(arg, data);
1670                 case SOUND_MIXER_READ_RECMASK:
1671                         data = SOUND_MASK_LINE | SOUND_MASK_MIC;
1672                         return IOCTL_OUT(arg, data);
1673                 case SOUND_MIXER_READ_RECSRC:
1674                         if (cs4218_control & CS_DO1)
1675                                 data = SOUND_MASK_LINE;
1676                         else
1677                                 data = SOUND_MASK_MIC;
1678                         return IOCTL_OUT(arg, data);
1679                 case SOUND_MIXER_WRITE_RECSRC:
1680                         IOCTL_IN(arg, data);
1681                         data &= (SOUND_MASK_LINE | SOUND_MASK_MIC);
1682                         if (data & SOUND_MASK_LINE)
1683                                 tmpcs = cs4218_control |
1684                                                 (CS_ISL | CS_ISR | CS_DO1);
1685                         if (data & SOUND_MASK_MIC)
1686                                 tmpcs = cs4218_control &
1687                                                 ~(CS_ISL | CS_ISR | CS_DO1);
1688                         if (tmpcs != cs4218_control)
1689                                 cs4218_ctl_write(tmpcs);
1690                         return IOCTL_OUT(arg, data);
1691                 case SOUND_MIXER_READ_STEREODEVS:
1692                         data = SOUND_MASK_VOLUME | SOUND_MASK_RECLEV;
1693                         return IOCTL_OUT(arg, data);
1694                 case SOUND_MIXER_READ_CAPS:
1695                         return IOCTL_OUT(arg, 0);
1696                 case SOUND_MIXER_READ_VOLUME:
1697                         data = (cs4218_control & CS_MUTE)? 0:
1698                                 cs_get_volume(cs4218_control);
1699                         return IOCTL_OUT(arg, data);
1700                 case SOUND_MIXER_WRITE_VOLUME:
1701                         IOCTL_IN(arg, data);
1702                         return IOCTL_OUT(arg, sound_set_volume(data));
1703                 case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
1704                         IOCTL_IN(arg, data);
1705                         beep_volume = data & 0xff;
1706                         /* fall through */
1707                 case SOUND_MIXER_READ_ALTPCM:
1708                         return IOCTL_OUT(arg, beep_volume);
1709                 case SOUND_MIXER_WRITE_RECLEV:
1710                         IOCTL_IN(arg, data);
1711                         data = cs_set_gain(data);
1712                         return IOCTL_OUT(arg, data);
1713                 case SOUND_MIXER_READ_RECLEV:
1714                         data = cs_get_gain(cs4218_control);
1715                         return IOCTL_OUT(arg, data);
1716         }
1717
1718         return -EINVAL;
1719 }
1720
1721
1722 static struct file_operations mixer_fops =
1723 {
1724         .owner =        THIS_MODULE,
1725         .llseek =       sound_lseek,
1726         .ioctl =        mixer_ioctl,
1727         .open =         mixer_open,
1728         .release =      mixer_release,
1729 };
1730
1731
1732 static void __init mixer_init(void)
1733 {
1734         mixer_unit = register_sound_mixer(&mixer_fops, -1);
1735         if (mixer_unit < 0)
1736                 return;
1737
1738         mixer.busy = 0;
1739         sound.treble = 0;
1740         sound.bass = 0;
1741
1742         /* Set Line input, no gain, no attenuation.
1743         */
1744         cs4218_control = CS_ISL | CS_ISR | CS_DO1;
1745         cs4218_control |= CS_LGAIN_SET(0) | CS_RGAIN_SET(0);
1746         cs4218_control |= CS_LATTEN_SET(0) | CS_RATTEN_SET(0);
1747         cs4218_ctl_write(cs4218_control);
1748 }
1749
1750
1751 /*
1752  * Sound queue stuff, the heart of the driver
1753  */
1754
1755
1756 static int sq_allocate_buffers(void)
1757 {
1758         int i;
1759
1760         if (sound_buffers)
1761                 return 0;
1762         sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
1763         if (!sound_buffers)
1764                 return -ENOMEM;
1765         for (i = 0; i < numBufs; i++) {
1766                 sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
1767                 if (!sound_buffers[i]) {
1768                         while (i--)
1769                                 sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1770                         kfree (sound_buffers);
1771                         sound_buffers = 0;
1772                         return -ENOMEM;
1773                 }
1774         }
1775         return 0;
1776 }
1777
1778
1779 static void sq_release_buffers(void)
1780 {
1781         int i;
1782
1783         if (sound_buffers) {
1784                 for (i = 0; i < numBufs; i++)
1785                         sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1786                 kfree (sound_buffers);
1787                 sound_buffers = 0;
1788         }
1789 }
1790
1791
1792 static int sq_allocate_read_buffers(void)
1793 {
1794         int i;
1795
1796         if (sound_read_buffers)
1797                 return 0;
1798         sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL);
1799         if (!sound_read_buffers)
1800                 return -ENOMEM;
1801         for (i = 0; i < numBufs; i++) {
1802                 sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10,
1803                                                               GFP_KERNEL);
1804                 if (!sound_read_buffers[i]) {
1805                         while (i--)
1806                                 sound.mach.dma_free (sound_read_buffers[i],
1807                                                      readbufSize << 10);
1808                         kfree (sound_read_buffers);
1809                         sound_read_buffers = 0;
1810                         return -ENOMEM;
1811                 }
1812         }
1813         return 0;
1814 }
1815
1816 static void sq_release_read_buffers(void)
1817 {
1818         int i;
1819
1820         if (sound_read_buffers) {
1821                 cpmp->cp_smc[1].smc_smcmr &= ~SMCMR_REN;
1822                 for (i = 0; i < numReadBufs; i++)
1823                         sound.mach.dma_free (sound_read_buffers[i],
1824                                              bufSize << 10);
1825                 kfree (sound_read_buffers);
1826                 sound_read_buffers = 0;
1827         }
1828 }
1829
1830
1831 static void sq_setup(int numBufs, int bufSize, char **write_buffers)
1832 {
1833         int i;
1834         volatile cbd_t *bdp;
1835         volatile cpm8xx_t       *cp;
1836         volatile smc_t  *sp;
1837
1838         /* Make sure the SMC transmit is shut down.
1839         */
1840         cp = cpmp;
1841         sp = &cpmp->cp_smc[1];
1842         sp->smc_smcmr &= ~SMCMR_TEN;
1843
1844         sq.max_count = numBufs;
1845         sq.max_active = numBufs;
1846         sq.block_size = bufSize;
1847         sq.buffers = write_buffers;
1848
1849         sq.front = sq.count = 0;
1850         sq.rear = -1;
1851         sq.syncing = 0;
1852         sq.active = 0;
1853
1854         bdp = tx_base;
1855         for (i=0; i<numBufs; i++) {
1856                 bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]);
1857                 bdp++;
1858         }
1859
1860         /* This causes the SMC to sync up with the first buffer again.
1861         */
1862         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_TX) | CPM_CR_FLG;
1863         while (cp->cp_cpcr & CPM_CR_FLG);
1864 }
1865
1866 static void read_sq_setup(int numBufs, int bufSize, char **read_buffers)
1867 {
1868         int i;
1869         volatile cbd_t *bdp;
1870         volatile cpm8xx_t       *cp;
1871         volatile smc_t  *sp;
1872
1873         /* Make sure the SMC receive is shut down.
1874         */
1875         cp = cpmp;
1876         sp = &cpmp->cp_smc[1];
1877         sp->smc_smcmr &= ~SMCMR_REN;
1878
1879         read_sq.max_count = numBufs;
1880         read_sq.max_active = numBufs;
1881         read_sq.block_size = bufSize;
1882         read_sq.buffers = read_buffers;
1883
1884         read_sq.front = read_sq.count = 0;
1885         read_sq.rear = 0;
1886         read_sq.rear_size = 0;
1887         read_sq.syncing = 0;
1888         read_sq.active = 0;
1889
1890         bdp = rx_base;
1891         for (i=0; i<numReadBufs; i++) {
1892                 bdp->cbd_bufaddr = virt_to_bus(read_buffers[i]);
1893                 bdp->cbd_datlen = read_sq.block_size;
1894                 bdp++;
1895         }
1896
1897         /* This causes the SMC to sync up with the first buffer again.
1898         */
1899         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_RX) | CPM_CR_FLG;
1900         while (cp->cp_cpcr & CPM_CR_FLG);
1901 }
1902
1903
1904 static void sq_play(void)
1905 {
1906         (*sound.mach.play)();
1907 }
1908
1909
1910 /* ++TeSche: radically changed this one too */
1911
1912 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
1913                         loff_t *ppos)
1914 {
1915         ssize_t uWritten = 0;
1916         u_char *dest;
1917         ssize_t uUsed, bUsed, bLeft;
1918
1919         /* ++TeSche: Is something like this necessary?
1920          * Hey, that's an honest question! Or does any other part of the
1921          * filesystem already checks this situation? I really don't know.
1922          */
1923         if (uLeft == 0)
1924                 return 0;
1925
1926         /* The interrupt doesn't start to play the last, incomplete frame.
1927          * Thus we can append to it without disabling the interrupts! (Note
1928          * also that sq.rear isn't affected by the interrupt.)
1929          */
1930
1931         if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
1932                 dest = sq_block_address(sq.rear);
1933                 bUsed = sq.rear_size;
1934                 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1935                 if (uUsed <= 0)
1936                         return uUsed;
1937                 src += uUsed;
1938                 uWritten += uUsed;
1939                 uLeft -= uUsed;
1940                 sq.rear_size = bUsed;
1941         }
1942
1943         do {
1944                 while (sq.count == sq.max_active) {
1945                         sq_play();
1946                         if (NON_BLOCKING(sq.open_mode))
1947                                 return uWritten > 0 ? uWritten : -EAGAIN;
1948                         SLEEP(sq.action_queue);
1949                         if (SIGNAL_RECEIVED)
1950                                 return uWritten > 0 ? uWritten : -EINTR;
1951                 }
1952
1953                 /* Here, we can avoid disabling the interrupt by first
1954                  * copying and translating the data, and then updating
1955                  * the sq variables. Until this is done, the interrupt
1956                  * won't see the new frame and we can work on it
1957                  * undisturbed.
1958                  */
1959
1960                 dest = sq_block_address((sq.rear+1) % sq.max_count);
1961                 bUsed = 0;
1962                 bLeft = sq.block_size;
1963                 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1964                 if (uUsed <= 0)
1965                         break;
1966                 src += uUsed;
1967                 uWritten += uUsed;
1968                 uLeft -= uUsed;
1969                 if (bUsed) {
1970                         sq.rear = (sq.rear+1) % sq.max_count;
1971                         sq.rear_size = bUsed;
1972                         sq.count++;
1973                 }
1974         } while (bUsed);   /* uUsed may have been 0 */
1975
1976         sq_play();
1977
1978         return uUsed < 0? uUsed: uWritten;
1979 }
1980
1981
1982 /***********/
1983
1984 /* Here is how the values are used for reading.
1985  * The value 'active' simply indicates the DMA is running.  This is
1986  * done so the driver semantics are DMA starts when the first read is
1987  * posted.  The value 'front' indicates the buffer we should next
1988  * send to the user.  The value 'rear' indicates the buffer the DMA is
1989  * currently filling.  When 'front' == 'rear' the buffer "ring" is
1990  * empty (we always have an empty available).  The 'rear_size' is used
1991  * to track partial offsets into the current buffer.  Right now, I just keep
1992  * The DMA running.  If the reader can't keep up, the interrupt tosses
1993  * the oldest buffer.  We could also shut down the DMA in this case.
1994  */
1995 static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
1996                        loff_t *ppos)
1997 {
1998
1999         ssize_t uRead, bLeft, bUsed, uUsed;
2000
2001         if (uLeft == 0)
2002                 return 0;
2003
2004         if (!read_sq.active)
2005                 CS_Record();    /* Kick off the record process. */
2006
2007         uRead = 0;
2008
2009         /* Move what the user requests, depending upon other options.
2010         */
2011         while (uLeft > 0) {
2012
2013                 /* When front == rear, the DMA is not done yet.
2014                 */
2015                 while (read_sq.front == read_sq.rear) {
2016                         if (NON_BLOCKING(read_sq.open_mode)) {
2017                                return uRead > 0 ? uRead : -EAGAIN;
2018                         }
2019                         SLEEP(read_sq.action_queue);
2020                         if (SIGNAL_RECEIVED)
2021                                 return uRead > 0 ? uRead : -EINTR;
2022                 }
2023
2024                 /* The amount we move is either what is left in the
2025                  * current buffer or what the user wants.
2026                  */
2027                 bLeft = read_sq.block_size - read_sq.rear_size;
2028                 bUsed = read_sq.rear_size;
2029                 uUsed = sound_copy_translate_read(dst, uLeft,
2030                         read_sq.buffers[read_sq.front], &bUsed, bLeft);
2031                 if (uUsed <= 0)
2032                         return uUsed;
2033                 dst += uUsed;
2034                 uRead += uUsed;
2035                 uLeft -= uUsed;
2036                 read_sq.rear_size += bUsed;
2037                 if (read_sq.rear_size >= read_sq.block_size) {
2038                         read_sq.rear_size = 0;
2039                         read_sq.front++;
2040                         if (read_sq.front >= read_sq.max_active)
2041                                 read_sq.front = 0;
2042                 }
2043         }
2044         return uRead;
2045 }
2046
2047 static int sq_open(struct inode *inode, struct file *file)
2048 {
2049         int rc = 0;
2050
2051         if (file->f_mode & FMODE_WRITE) {
2052                 if (sq.busy) {
2053                         rc = -EBUSY;
2054                         if (NON_BLOCKING(file->f_flags))
2055                                 goto err_out;
2056                         rc = -EINTR;
2057                         while (sq.busy) {
2058                                 SLEEP(sq.open_queue);
2059                                 if (SIGNAL_RECEIVED)
2060                                         goto err_out;
2061                         }
2062                 }
2063                 sq.busy = 1; /* Let's play spot-the-race-condition */
2064
2065                 if (sq_allocate_buffers()) goto err_out_nobusy;
2066
2067                 sq_setup(numBufs, bufSize<<10,sound_buffers);
2068                 sq.open_mode = file->f_mode;
2069         }
2070
2071
2072         if (file->f_mode & FMODE_READ) {
2073                 if (read_sq.busy) {
2074                         rc = -EBUSY;
2075                         if (NON_BLOCKING(file->f_flags))
2076                                 goto err_out;
2077                         rc = -EINTR;
2078                         while (read_sq.busy) {
2079                                 SLEEP(read_sq.open_queue);
2080                                 if (SIGNAL_RECEIVED)
2081                                         goto err_out;
2082                         }
2083                         rc = 0;
2084                 }
2085                 read_sq.busy = 1;
2086                 if (sq_allocate_read_buffers()) goto err_out_nobusy;
2087
2088                 read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers);
2089                 read_sq.open_mode = file->f_mode;
2090         }
2091
2092         /* Start up the 4218 by:
2093          * Reset.
2094          * Enable, unreset.
2095          */
2096         *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_RSTAUDIO;
2097         eieio();
2098         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_ENAUDIO;
2099         mdelay(50);
2100         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2101
2102         /* We need to send the current control word in case someone
2103          * opened /dev/mixer and changed things while we were shut
2104          * down.  Chances are good the initialization that follows
2105          * would have done this, but it is still possible it wouldn't.
2106          */
2107         cs4218_ctl_write(cs4218_control);
2108
2109         sound.minDev = iminor(inode) & 0x0f;
2110         sound.soft = sound.dsp;
2111         sound.hard = sound.dsp;
2112         sound_init();
2113         if ((iminor(inode) & 0x0f) == SND_DEV_AUDIO) {
2114                 sound_set_speed(8000);
2115                 sound_set_stereo(0);
2116                 sound_set_format(AFMT_MU_LAW);
2117         }
2118
2119         return 0;
2120
2121 err_out_nobusy:
2122         if (file->f_mode & FMODE_WRITE) {
2123                 sq.busy = 0;
2124                 WAKE_UP(sq.open_queue);
2125         }
2126         if (file->f_mode & FMODE_READ) {
2127                 read_sq.busy = 0;
2128                 WAKE_UP(read_sq.open_queue);
2129         }
2130 err_out:
2131         return rc;
2132 }
2133
2134
2135 static void sq_reset(void)
2136 {
2137         sound_silence();
2138         sq.active = 0;
2139         sq.count = 0;
2140         sq.front = (sq.rear+1) % sq.max_count;
2141 #if 0
2142         init_tdm_buffers();
2143 #endif
2144 }
2145
2146
2147 static int sq_fsync(struct file *filp, struct dentry *dentry)
2148 {
2149         int rc = 0;
2150
2151         sq.syncing = 1;
2152         sq_play();      /* there may be an incomplete frame waiting */
2153
2154         while (sq.active) {
2155                 SLEEP(sq.sync_queue);
2156                 if (SIGNAL_RECEIVED) {
2157                         /* While waiting for audio output to drain, an
2158                          * interrupt occurred.  Stop audio output immediately
2159                          * and clear the queue. */
2160                         sq_reset();
2161                         rc = -EINTR;
2162                         break;
2163                 }
2164         }
2165
2166         sq.syncing = 0;
2167         return rc;
2168 }
2169
2170 static int sq_release(struct inode *inode, struct file *file)
2171 {
2172         int rc = 0;
2173
2174         if (sq.busy)
2175                 rc = sq_fsync(file, file->f_dentry);
2176         sound.soft = sound.dsp;
2177         sound.hard = sound.dsp;
2178         sound_silence();
2179
2180         sq_release_read_buffers();
2181         sq_release_buffers();
2182
2183         if (file->f_mode & FMODE_READ) {
2184                 read_sq.busy = 0;
2185                 WAKE_UP(read_sq.open_queue);
2186         }
2187
2188         if (file->f_mode & FMODE_WRITE) {
2189                 sq.busy = 0;
2190                 WAKE_UP(sq.open_queue);
2191         }
2192
2193         /* Shut down the SMC.
2194         */
2195         cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN);
2196
2197         /* Shut down the codec.
2198         */
2199         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2200         eieio();
2201         *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO;
2202
2203         /* Wake up a process waiting for the queue being released.
2204          * Note: There may be several processes waiting for a call
2205          * to open() returning. */
2206
2207         return rc;
2208 }
2209
2210
2211 static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
2212                     u_long arg)
2213 {
2214         u_long fmt;
2215         int data;
2216 #if 0
2217         int size, nbufs;
2218 #else
2219         int size;
2220 #endif
2221
2222         switch (cmd) {
2223         case SNDCTL_DSP_RESET:
2224                 sq_reset();
2225                 return 0;
2226         case SNDCTL_DSP_POST:
2227         case SNDCTL_DSP_SYNC:
2228                 return sq_fsync(file, file->f_dentry);
2229
2230                 /* ++TeSche: before changing any of these it's
2231                  * probably wise to wait until sound playing has
2232                  * settled down. */
2233         case SNDCTL_DSP_SPEED:
2234                 sq_fsync(file, file->f_dentry);
2235                 IOCTL_IN(arg, data);
2236                 return IOCTL_OUT(arg, sound_set_speed(data));
2237         case SNDCTL_DSP_STEREO:
2238                 sq_fsync(file, file->f_dentry);
2239                 IOCTL_IN(arg, data);
2240                 return IOCTL_OUT(arg, sound_set_stereo(data));
2241         case SOUND_PCM_WRITE_CHANNELS:
2242                 sq_fsync(file, file->f_dentry);
2243                 IOCTL_IN(arg, data);
2244                 return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
2245         case SNDCTL_DSP_SETFMT:
2246                 sq_fsync(file, file->f_dentry);
2247                 IOCTL_IN(arg, data);
2248                 return IOCTL_OUT(arg, sound_set_format(data));
2249         case SNDCTL_DSP_GETFMTS:
2250                 fmt = 0;
2251                 if (sound.trans_write) {
2252                         if (sound.trans_write->ct_ulaw)
2253                                 fmt |= AFMT_MU_LAW;
2254                         if (sound.trans_write->ct_alaw)
2255                                 fmt |= AFMT_A_LAW;
2256                         if (sound.trans_write->ct_s8)
2257                                 fmt |= AFMT_S8;
2258                         if (sound.trans_write->ct_u8)
2259                                 fmt |= AFMT_U8;
2260                         if (sound.trans_write->ct_s16be)
2261                                 fmt |= AFMT_S16_BE;
2262                         if (sound.trans_write->ct_u16be)
2263                                 fmt |= AFMT_U16_BE;
2264                         if (sound.trans_write->ct_s16le)
2265                                 fmt |= AFMT_S16_LE;
2266                         if (sound.trans_write->ct_u16le)
2267                                 fmt |= AFMT_U16_LE;
2268                 }
2269                 return IOCTL_OUT(arg, fmt);
2270         case SNDCTL_DSP_GETBLKSIZE:
2271                 size = sq.block_size
2272                         * sound.soft.size * (sound.soft.stereo + 1)
2273                         / (sound.hard.size * (sound.hard.stereo + 1));
2274                 return IOCTL_OUT(arg, size);
2275         case SNDCTL_DSP_SUBDIVIDE:
2276                 break;
2277 #if 0   /* Sorry can't do this at the moment.  The CPM allocated buffers
2278          * long ago that can't be changed.
2279          */
2280         case SNDCTL_DSP_SETFRAGMENT:
2281                 if (sq.count || sq.active || sq.syncing)
2282                         return -EINVAL;
2283                 IOCTL_IN(arg, size);
2284                 nbufs = size >> 16;
2285                 if (nbufs < 2 || nbufs > numBufs)
2286                         nbufs = numBufs;
2287                 size &= 0xffff;
2288                 if (size >= 8 && size <= 30) {
2289                         size = 1 << size;
2290                         size *= sound.hard.size * (sound.hard.stereo + 1);
2291                         size /= sound.soft.size * (sound.soft.stereo + 1);
2292                         if (size > (bufSize << 10))
2293                                 size = bufSize << 10;
2294                 } else
2295                         size = bufSize << 10;
2296                 sq_setup(numBufs, size, sound_buffers);
2297                 sq.max_active = nbufs;
2298                 return 0;
2299 #endif
2300
2301         default:
2302                 return mixer_ioctl(inode, file, cmd, arg);
2303         }
2304         return -EINVAL;
2305 }
2306
2307
2308
2309 static struct file_operations sq_fops =
2310 {
2311         .owner =        THIS_MODULE,
2312         .llseek =       sound_lseek,
2313         .read =         sq_read,                        /* sq_read */
2314         .write =        sq_write,
2315         .ioctl =        sq_ioctl,
2316         .open =         sq_open,
2317         .release =      sq_release,
2318 };
2319
2320
2321 static void __init sq_init(void)
2322 {
2323         sq_unit = register_sound_dsp(&sq_fops, -1);
2324         if (sq_unit < 0)
2325                 return;
2326
2327         init_waitqueue_head(&sq.action_queue);
2328         init_waitqueue_head(&sq.open_queue);
2329         init_waitqueue_head(&sq.sync_queue);
2330         init_waitqueue_head(&read_sq.action_queue);
2331         init_waitqueue_head(&read_sq.open_queue);
2332         init_waitqueue_head(&read_sq.sync_queue);
2333
2334         sq.busy = 0;
2335         read_sq.busy = 0;
2336
2337         /* whatever you like as startup mode for /dev/dsp,
2338          * (/dev/audio hasn't got a startup mode). note that
2339          * once changed a new open() will *not* restore these!
2340          */
2341         sound.dsp.format = AFMT_S16_BE;
2342         sound.dsp.stereo = 1;
2343         sound.dsp.size = 16;
2344
2345         /* set minimum rate possible without expanding */
2346         sound.dsp.speed = 8000;
2347
2348         /* before the first open to /dev/dsp this wouldn't be set */
2349         sound.soft = sound.dsp;
2350         sound.hard = sound.dsp;
2351
2352         sound_silence();
2353 }
2354
2355 /*
2356  * /dev/sndstat
2357  */
2358
2359
2360 /* state.buf should not overflow! */
2361
2362 static int state_open(struct inode *inode, struct file *file)
2363 {
2364         char *buffer = state.buf, *mach = "", cs4218_buf[50];
2365         int len = 0;
2366
2367         if (state.busy)
2368                 return -EBUSY;
2369
2370         state.ptr = 0;
2371         state.busy = 1;
2372
2373         sprintf(cs4218_buf, "Crystal CS4218 on TDM, ");
2374         mach = cs4218_buf;
2375
2376         len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
2377
2378         len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
2379         switch (sound.soft.format) {
2380         case AFMT_MU_LAW:
2381                 len += sprintf(buffer+len, " (mu-law)");
2382                 break;
2383         case AFMT_A_LAW:
2384                 len += sprintf(buffer+len, " (A-law)");
2385                 break;
2386         case AFMT_U8:
2387                 len += sprintf(buffer+len, " (unsigned 8 bit)");
2388                 break;
2389         case AFMT_S8:
2390                 len += sprintf(buffer+len, " (signed 8 bit)");
2391                 break;
2392         case AFMT_S16_BE:
2393                 len += sprintf(buffer+len, " (signed 16 bit big)");
2394                 break;
2395         case AFMT_U16_BE:
2396                 len += sprintf(buffer+len, " (unsigned 16 bit big)");
2397                 break;
2398         case AFMT_S16_LE:
2399                 len += sprintf(buffer+len, " (signed 16 bit little)");
2400                 break;
2401         case AFMT_U16_LE:
2402                 len += sprintf(buffer+len, " (unsigned 16 bit little)");
2403                 break;
2404         }
2405         len += sprintf(buffer+len, "\n");
2406         len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
2407                        sound.soft.speed, sound.hard.speed);
2408         len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
2409                        sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
2410         len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d"
2411                        " sq.max_active = %d\n",
2412                        sq.block_size, sq.max_count, sq.max_active);
2413         len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
2414                        sq.rear_size);
2415         len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
2416                        sq.active, sq.syncing);
2417         state.len = len;
2418         return 0;
2419 }
2420
2421
2422 static int state_release(struct inode *inode, struct file *file)
2423 {
2424         state.busy = 0;
2425         return 0;
2426 }
2427
2428
2429 static ssize_t state_read(struct file *file, char *buf, size_t count,
2430                           loff_t *ppos)
2431 {
2432         int n = state.len - state.ptr;
2433         if (n > count)
2434                 n = count;
2435         if (n <= 0)
2436                 return 0;
2437         if (copy_to_user(buf, &state.buf[state.ptr], n))
2438                 return -EFAULT;
2439         state.ptr += n;
2440         return n;
2441 }
2442
2443
2444 static struct file_operations state_fops =
2445 {
2446         .owner =        THIS_MODULE,
2447         .llseek =       sound_lseek,
2448         .read =         state_read,
2449         .open =         state_open,
2450         .release =      state_release,
2451 };
2452
2453
2454 static void __init state_init(void)
2455 {
2456         state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
2457         if (state_unit < 0)
2458                 return;
2459         state.busy = 0;
2460 }
2461
2462
2463 /*** Common stuff ********************************************************/
2464
2465 static long long sound_lseek(struct file *file, long long offset, int orig)
2466 {
2467         return -ESPIPE;
2468 }
2469
2470
2471 /*** Config & Setup **********************************************************/
2472
2473
2474 int __init tdm8xx_sound_init(void)
2475 {
2476         int i, has_sound;
2477         uint                    dp_addr;
2478         volatile uint           *sirp;
2479         volatile cbd_t          *bdp;
2480         volatile cpm8xx_t       *cp;
2481         volatile smc_t          *sp;
2482         volatile smc_uart_t     *up;
2483         volatile immap_t        *immap;
2484
2485         has_sound = 0;
2486
2487         /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes.
2488         */
2489         cp = cpmp;      /* Get pointer to Communication Processor */
2490         immap = (immap_t *)IMAP_ADDR;   /* and to internal registers */
2491
2492         /* Set all TDMa control bits to zero.  This enables most features
2493          * we want.
2494          */
2495         cp->cp_simode &= ~0x00000fff;
2496
2497         /* Enable common receive/transmit clock pins, use IDL format.
2498          * Sync on falling edge, transmit rising clock, receive falling
2499          * clock, delay 1 bit on both Tx and Rx.  Common Tx/Rx clocks and
2500          * sync.
2501          * Connect SMC2 to TSA.
2502          */
2503         cp->cp_simode |= 0x80000141;
2504
2505         /* Configure port A pins for TDMa operation.
2506          * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used.
2507          */
2508         immap->im_ioport.iop_papar |= 0x01c0; /* Enable TDMa functions */
2509         immap->im_ioport.iop_padir |= 0x00c0; /* Enable TDMa Tx/Rx */
2510         immap->im_ioport.iop_padir &= ~0x0100; /* Enable L1RCLKa */
2511
2512         immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */
2513         immap->im_ioport.iop_pcdir &= ~0x0800;
2514
2515         /* Initialize the SI TDM routing table.  We use TDMa only.
2516          * The receive table and transmit table each have only one
2517          * entry, to capture/send four bytes after each frame pulse.
2518          * The 16-bit ram entry is 0000 0001 1000 1111. (SMC2)
2519          */
2520         cp->cp_sigmr = 0;
2521         sirp = (uint *)cp->cp_siram;
2522
2523         *sirp = 0x018f0000;             /* Receive entry */
2524         sirp += 64;
2525         *sirp = 0x018f0000;             /* Tramsmit entry */
2526
2527         /* Enable single TDMa routing.
2528         */
2529         cp->cp_sigmr = 0x04;
2530
2531         /* Initialize the SMC for transparent operation.
2532         */
2533         sp = &cpmp->cp_smc[1];
2534         up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
2535
2536         /* We need to allocate a transmit and receive buffer
2537          * descriptors from dual port ram.
2538          */
2539         dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs);
2540
2541         /* Set the physical address of the host memory
2542          * buffers in the buffer descriptors, and the
2543          * virtual address for us to work with.
2544          */
2545         bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2546         up->smc_rbase = dp_addr;
2547         rx_cur = rx_base = (cbd_t *)bdp;
2548
2549         for (i=0; i<(numReadBufs-1); i++) {
2550                 bdp->cbd_bufaddr = 0;
2551                 bdp->cbd_datlen = 0;
2552                 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
2553                 bdp++;
2554         }
2555         bdp->cbd_bufaddr = 0;
2556         bdp->cbd_datlen = 0;
2557         bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
2558
2559         /* Now, do the same for the transmit buffers.
2560         */
2561         dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs);
2562
2563         bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2564         up->smc_tbase = dp_addr;
2565         tx_cur = tx_base = (cbd_t *)bdp;
2566
2567         for (i=0; i<(numBufs-1); i++) {
2568                 bdp->cbd_bufaddr = 0;
2569                 bdp->cbd_datlen = 0;
2570                 bdp->cbd_sc = BD_SC_INTRPT;
2571                 bdp++;
2572         }
2573         bdp->cbd_bufaddr = 0;
2574         bdp->cbd_datlen = 0;
2575         bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
2576
2577         /* Set transparent SMC mode.
2578          * A few things are specific to our application.  The codec interface
2579          * is MSB first, hence the REVD selection.  The CD/CTS pulse are
2580          * used by the TSA to indicate the frame start to the SMC.
2581          */
2582         up->smc_rfcr = SCC_EB;
2583         up->smc_tfcr = SCC_EB;
2584         up->smc_mrblr = readbufSize * 1024;
2585
2586         /* Set 16-bit reversed data, transparent mode.
2587         */
2588         sp->smc_smcmr = smcr_mk_clen(15) |
2589                 SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS;
2590
2591         /* Enable and clear events.
2592          * Because of FIFO delays, all we need is the receive interrupt
2593          * and we can process both the current receive and current
2594          * transmit interrupt within a few microseconds of the transmit.
2595          */
2596         sp->smc_smce = 0xff;
2597         sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX;
2598
2599         /* Send the CPM an initialize command.
2600         */
2601         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2602                                 CPM_CR_INIT_TRX) | CPM_CR_FLG;
2603         while (cp->cp_cpcr & CPM_CR_FLG);
2604
2605         sound.mach = mach_cs4218;
2606         has_sound = 1;
2607
2608         /* Initialize beep stuff */
2609         orig_mksound = kd_mksound;
2610         kd_mksound = cs_mksound;
2611         beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
2612         if (beep_buf == NULL)
2613                 printk(KERN_WARNING "dmasound: no memory for "
2614                        "beep buffer\n");
2615
2616         if (!has_sound)
2617                 return -ENODEV;
2618
2619         /* Initialize the software SPI.
2620         */
2621         sw_spi_init();
2622
2623         /* Set up sound queue, /dev/audio and /dev/dsp. */
2624
2625         /* Set default settings. */
2626         sq_init();
2627
2628         /* Set up /dev/sndstat. */
2629         state_init();
2630
2631         /* Set up /dev/mixer. */
2632         mixer_init();
2633
2634         if (!sound.mach.irqinit()) {
2635                 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
2636                 return -ENODEV;
2637         }
2638 #ifdef MODULE
2639         irq_installed = 1;
2640 #endif
2641
2642         printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
2643                numBufs, bufSize);
2644
2645         return 0;
2646 }
2647
2648 /* Due to FIFOs and bit delays, the transmit interrupt occurs a few
2649  * microseconds ahead of the receive interrupt.
2650  * When we get an interrupt, we service the transmit first, then
2651  * check for a receive to prevent the overhead of returning through
2652  * the interrupt handler only to get back here right away during
2653  * full duplex operation.
2654  */
2655 static void
2656 cs4218_intr(void *dev_id, struct pt_regs *regs)
2657 {
2658         volatile smc_t  *sp;
2659         volatile cpm8xx_t       *cp;
2660
2661         sp = &cpmp->cp_smc[1];
2662
2663         if (sp->smc_smce & SCCM_TX) {
2664                 sp->smc_smce = SCCM_TX;
2665                 cs4218_tdm_tx_intr((void *)sp);
2666         }
2667
2668         if (sp->smc_smce & SCCM_RX) {
2669                 sp->smc_smce = SCCM_RX;
2670                 cs4218_tdm_rx_intr((void *)sp);
2671         }
2672
2673         if (sp->smc_smce & SCCM_TXE) {
2674                 /* Transmit underrun.  This happens with the application
2675                  * didn't keep up sending buffers.  We tell the SMC to
2676                  * restart, which will cause it to poll the current (next)
2677                  * BD.  If the user supplied data since this occurred,
2678                  * we just start running again.  If they didn't, the SMC
2679                  * will poll the descriptor until data is placed there.
2680                  */
2681                 sp->smc_smce = SCCM_TXE;
2682                 cp = cpmp;      /* Get pointer to Communication Processor */
2683                 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2684                                         CPM_CR_RESTART_TX) | CPM_CR_FLG;
2685                 while (cp->cp_cpcr & CPM_CR_FLG);
2686         }
2687 }
2688
2689
2690 #define MAXARGS         8       /* Should be sufficient for now */
2691
2692 void __init dmasound_setup(char *str, int *ints)
2693 {
2694         /* check the bootstrap parameter for "dmasound=" */
2695
2696         switch (ints[0]) {
2697         case 3:
2698                 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
2699                         printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
2700                 else
2701                         catchRadius = ints[3];
2702                 /* fall through */
2703         case 2:
2704                 if (ints[1] < MIN_BUFFERS)
2705                         printk("dmasound_setup: invalid number of buffers, using default = %d\n", numBufs);
2706                 else
2707                         numBufs = ints[1];
2708                 if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
2709                         printk("dmasound_setup: invalid buffer size, using default = %d\n", bufSize);
2710                 else
2711                         bufSize = ints[2];
2712                 break;
2713         case 0:
2714                 break;
2715         default:
2716                 printk("dmasound_setup: invalid number of arguments\n");
2717         }
2718 }
2719
2720 /* Software SPI functions.
2721  * These are on Port B.
2722  */
2723 #define PB_SPICLK       ((uint)0x00000002)
2724 #define PB_SPIMOSI      ((uint)0x00000004)
2725 #define PB_SPIMISO      ((uint)0x00000008)
2726
2727 static
2728 void    sw_spi_init(void)
2729 {
2730         volatile cpm8xx_t       *cp;
2731         volatile uint           *hcsr4;
2732
2733         hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2734         cp = cpmp;      /* Get pointer to Communication Processor */
2735
2736         *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2737
2738         /* Make these Port B signals general purpose I/O.
2739          * First, make sure the clock is low.
2740          */
2741         cp->cp_pbdat &= ~PB_SPICLK;
2742         cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO);
2743
2744         /* Clock and Master Output are outputs.
2745         */
2746         cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI);
2747
2748         /* Master Input.
2749         */
2750         cp->cp_pbdir &= ~PB_SPIMISO;
2751
2752 }
2753
2754 /* Write the CS4218 control word out the SPI port.  While the
2755  * the control word is going out, the status word is arriving.
2756  */
2757 static
2758 uint    cs4218_ctl_write(uint ctlreg)
2759 {
2760         uint    status;
2761
2762         sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4);
2763
2764         /* Shadow the control register.....I guess we could do
2765          * the same for the status, but for now we just return it
2766          * and let the caller decide.
2767          */
2768         cs4218_control = ctlreg;
2769         return status;
2770 }
2771
2772 static
2773 void    sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt)
2774 {
2775         int     bits, i;
2776         u_char  outbyte, inbyte;
2777         volatile cpm8xx_t       *cp;
2778         volatile uint           *hcsr4;
2779
2780         hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2781         cp = cpmp;      /* Get pointer to Communication Processor */
2782
2783         /* The timing on the bus is pretty slow.  Code inefficiency
2784          * and eieio() is our friend here :-).
2785          */
2786         cp->cp_pbdat &= ~PB_SPICLK;
2787         *hcsr4 |= HIOX_CSR4_AUDSPISEL;  /* Enable SPI select */
2788         eieio();
2789
2790         /* Clock in/out the bytes.  Data is valid on the falling edge
2791          * of the clock.  Data is MSB first.
2792          */
2793         for (i=0; i<bcnt; i++) {
2794                 outbyte = *obuf++;
2795                 inbyte = 0;
2796                 for (bits=0; bits<8; bits++) {
2797                         eieio();
2798                         cp->cp_pbdat |= PB_SPICLK;
2799                         eieio();
2800                         if (outbyte & 0x80)
2801                                 cp->cp_pbdat |= PB_SPIMOSI;
2802                         else
2803                                 cp->cp_pbdat &= ~PB_SPIMOSI;
2804                         eieio();
2805                         cp->cp_pbdat &= ~PB_SPICLK;
2806                         eieio();
2807                         outbyte <<= 1;
2808                         inbyte <<= 1;
2809                         if (cp->cp_pbdat & PB_SPIMISO)
2810                                 inbyte |= 1;
2811                 }
2812                 *ibuf++ = inbyte;
2813         }
2814
2815         *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2816         eieio();
2817 }
2818
2819 void cleanup_module(void)
2820 {
2821         if (irq_installed) {
2822                 sound_silence();
2823 #ifdef MODULE
2824                 sound.mach.irqcleanup();
2825 #endif
2826         }
2827
2828         sq_release_read_buffers();
2829         sq_release_buffers();
2830
2831         if (mixer_unit >= 0)
2832                 unregister_sound_mixer(mixer_unit);
2833         if (state_unit >= 0)
2834                 unregister_sound_special(state_unit);
2835         if (sq_unit >= 0)
2836                 unregister_sound_dsp(sq_unit);
2837 }
2838
2839 module_init(tdm8xx_sound_init);
2840 module_exit(cleanup_module);
2841