patch-2_6_7-vs1_9_1_12
[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 MACHINE mach_cs4218 = {
1460         .owner =        THIS_MODULE,
1461         .name =         "HIOX CS4218",
1462         .name2 =        "Built-in Sound",
1463         .dma_alloc =    CS_Alloc,
1464         .dma_free =     CS_Free,
1465         .irqinit =      CS_IrqInit,
1466 #ifdef MODULE
1467         .irqcleanup =   CS_IrqCleanup,
1468 #endif /* MODULE */
1469         .init =         CS_Init,
1470         .silence =      CS_Silence,
1471         .setFormat =    CS_SetFormat,
1472         .setVolume =    CS_SetVolume,
1473         .play =         CS_Play
1474 };
1475
1476
1477 /*** Mid level stuff *********************************************************/
1478
1479
1480 static void sound_silence(void)
1481 {
1482         /* update hardware settings one more */
1483         (*sound.mach.init)();
1484
1485         (*sound.mach.silence)();
1486 }
1487
1488
1489 static void sound_init(void)
1490 {
1491         (*sound.mach.init)();
1492 }
1493
1494
1495 static int sound_set_format(int format)
1496 {
1497         return(*sound.mach.setFormat)(format);
1498 }
1499
1500
1501 static int sound_set_speed(int speed)
1502 {
1503         if (speed < 0)
1504                 return(sound.soft.speed);
1505
1506         sound.soft.speed = speed;
1507         (*sound.mach.init)();
1508         if (sound.minDev == SND_DEV_DSP)
1509                 sound.dsp.speed = sound.soft.speed;
1510
1511         return(sound.soft.speed);
1512 }
1513
1514
1515 static int sound_set_stereo(int stereo)
1516 {
1517         if (stereo < 0)
1518                 return(sound.soft.stereo);
1519
1520         stereo = !!stereo;    /* should be 0 or 1 now */
1521
1522         sound.soft.stereo = stereo;
1523         if (sound.minDev == SND_DEV_DSP)
1524                 sound.dsp.stereo = stereo;
1525         (*sound.mach.init)();
1526
1527         return(stereo);
1528 }
1529
1530
1531 static int sound_set_volume(int volume)
1532 {
1533         return(*sound.mach.setVolume)(volume);
1534 }
1535
1536 static ssize_t sound_copy_translate(const u_char *userPtr,
1537                                     size_t userCount,
1538                                     u_char frame[], ssize_t *frameUsed,
1539                                     ssize_t frameLeft)
1540 {
1541         ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1542
1543         switch (sound.soft.format) {
1544         case AFMT_MU_LAW:
1545                 ct_func = sound.trans_write->ct_ulaw;
1546                 break;
1547         case AFMT_A_LAW:
1548                 ct_func = sound.trans_write->ct_alaw;
1549                 break;
1550         case AFMT_S8:
1551                 ct_func = sound.trans_write->ct_s8;
1552                 break;
1553         case AFMT_U8:
1554                 ct_func = sound.trans_write->ct_u8;
1555                 break;
1556         case AFMT_S16_BE:
1557                 ct_func = sound.trans_write->ct_s16be;
1558                 break;
1559         case AFMT_U16_BE:
1560                 ct_func = sound.trans_write->ct_u16be;
1561                 break;
1562         case AFMT_S16_LE:
1563                 ct_func = sound.trans_write->ct_s16le;
1564                 break;
1565         case AFMT_U16_LE:
1566                 ct_func = sound.trans_write->ct_u16le;
1567                 break;
1568         }
1569         if (ct_func)
1570                 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1571         else
1572                 return 0;
1573 }
1574
1575 static ssize_t sound_copy_translate_read(const u_char *userPtr,
1576                                     size_t userCount,
1577                                     u_char frame[], ssize_t *frameUsed,
1578                                     ssize_t frameLeft)
1579 {
1580         ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1581
1582         switch (sound.soft.format) {
1583         case AFMT_MU_LAW:
1584                 ct_func = sound.trans_read->ct_ulaw;
1585                 break;
1586         case AFMT_A_LAW:
1587                 ct_func = sound.trans_read->ct_alaw;
1588                 break;
1589         case AFMT_S8:
1590                 ct_func = sound.trans_read->ct_s8;
1591                 break;
1592         case AFMT_U8:
1593                 ct_func = sound.trans_read->ct_u8;
1594                 break;
1595         case AFMT_S16_BE:
1596                 ct_func = sound.trans_read->ct_s16be;
1597                 break;
1598         case AFMT_U16_BE:
1599                 ct_func = sound.trans_read->ct_u16be;
1600                 break;
1601         case AFMT_S16_LE:
1602                 ct_func = sound.trans_read->ct_s16le;
1603                 break;
1604         case AFMT_U16_LE:
1605                 ct_func = sound.trans_read->ct_u16le;
1606                 break;
1607         }
1608         if (ct_func)
1609                 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1610         else
1611                 return 0;
1612 }
1613
1614
1615 /*
1616  * /dev/mixer abstraction
1617  */
1618
1619 static int mixer_open(struct inode *inode, struct file *file)
1620 {
1621         mixer.busy = 1;
1622         return 0;
1623 }
1624
1625
1626 static int mixer_release(struct inode *inode, struct file *file)
1627 {
1628         mixer.busy = 0;
1629         return 0;
1630 }
1631
1632
1633 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
1634                        u_long arg)
1635 {
1636         int data;
1637         uint tmpcs;
1638
1639         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
1640             mixer.modify_counter++;
1641         if (cmd == OSS_GETVERSION)
1642             return IOCTL_OUT(arg, SOUND_VERSION);
1643         switch (cmd) {
1644                 case SOUND_MIXER_INFO: {
1645                     mixer_info info;
1646                     strlcpy(info.id, "CS4218_TDM", sizeof(info.id));
1647                     strlcpy(info.name, "CS4218_TDM", sizeof(info.name));
1648                     info.name[sizeof(info.name)-1] = 0;
1649                     info.modify_counter = mixer.modify_counter;
1650                     if (copy_to_user((int *)arg, &info, sizeof(info)))
1651                                 return -EFAULT;
1652                     return 0;
1653                 }
1654                 case SOUND_MIXER_READ_DEVMASK:
1655                         data = SOUND_MASK_VOLUME | SOUND_MASK_LINE
1656                                 | SOUND_MASK_MIC | SOUND_MASK_RECLEV
1657                                 | SOUND_MASK_ALTPCM;
1658                         return IOCTL_OUT(arg, data);
1659                 case SOUND_MIXER_READ_RECMASK:
1660                         data = SOUND_MASK_LINE | SOUND_MASK_MIC;
1661                         return IOCTL_OUT(arg, data);
1662                 case SOUND_MIXER_READ_RECSRC:
1663                         if (cs4218_control & CS_DO1)
1664                                 data = SOUND_MASK_LINE;
1665                         else
1666                                 data = SOUND_MASK_MIC;
1667                         return IOCTL_OUT(arg, data);
1668                 case SOUND_MIXER_WRITE_RECSRC:
1669                         IOCTL_IN(arg, data);
1670                         data &= (SOUND_MASK_LINE | SOUND_MASK_MIC);
1671                         if (data & SOUND_MASK_LINE)
1672                                 tmpcs = cs4218_control |
1673                                                 (CS_ISL | CS_ISR | CS_DO1);
1674                         if (data & SOUND_MASK_MIC)
1675                                 tmpcs = cs4218_control &
1676                                                 ~(CS_ISL | CS_ISR | CS_DO1);
1677                         if (tmpcs != cs4218_control)
1678                                 cs4218_ctl_write(tmpcs);
1679                         return IOCTL_OUT(arg, data);
1680                 case SOUND_MIXER_READ_STEREODEVS:
1681                         data = SOUND_MASK_VOLUME | SOUND_MASK_RECLEV;
1682                         return IOCTL_OUT(arg, data);
1683                 case SOUND_MIXER_READ_CAPS:
1684                         return IOCTL_OUT(arg, 0);
1685                 case SOUND_MIXER_READ_VOLUME:
1686                         data = (cs4218_control & CS_MUTE)? 0:
1687                                 cs_get_volume(cs4218_control);
1688                         return IOCTL_OUT(arg, data);
1689                 case SOUND_MIXER_WRITE_VOLUME:
1690                         IOCTL_IN(arg, data);
1691                         return IOCTL_OUT(arg, sound_set_volume(data));
1692                 case SOUND_MIXER_WRITE_ALTPCM:  /* really bell volume */
1693                         IOCTL_IN(arg, data);
1694                         beep_volume = data & 0xff;
1695                         /* fall through */
1696                 case SOUND_MIXER_READ_ALTPCM:
1697                         return IOCTL_OUT(arg, beep_volume);
1698                 case SOUND_MIXER_WRITE_RECLEV:
1699                         IOCTL_IN(arg, data);
1700                         data = cs_set_gain(data);
1701                         return IOCTL_OUT(arg, data);
1702                 case SOUND_MIXER_READ_RECLEV:
1703                         data = cs_get_gain(cs4218_control);
1704                         return IOCTL_OUT(arg, data);
1705         }
1706
1707         return -EINVAL;
1708 }
1709
1710
1711 static struct file_operations mixer_fops =
1712 {
1713         .owner =        THIS_MODULE,
1714         .llseek =       sound_lseek,
1715         .ioctl =        mixer_ioctl,
1716         .open =         mixer_open,
1717         .release =      mixer_release,
1718 };
1719
1720
1721 static void __init mixer_init(void)
1722 {
1723         mixer_unit = register_sound_mixer(&mixer_fops, -1);
1724         if (mixer_unit < 0)
1725                 return;
1726
1727         mixer.busy = 0;
1728         sound.treble = 0;
1729         sound.bass = 0;
1730
1731         /* Set Line input, no gain, no attenuation.
1732         */
1733         cs4218_control = CS_ISL | CS_ISR | CS_DO1;
1734         cs4218_control |= CS_LGAIN_SET(0) | CS_RGAIN_SET(0);
1735         cs4218_control |= CS_LATTEN_SET(0) | CS_RATTEN_SET(0);
1736         cs4218_ctl_write(cs4218_control);
1737 }
1738
1739
1740 /*
1741  * Sound queue stuff, the heart of the driver
1742  */
1743
1744
1745 static int sq_allocate_buffers(void)
1746 {
1747         int i;
1748
1749         if (sound_buffers)
1750                 return 0;
1751         sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
1752         if (!sound_buffers)
1753                 return -ENOMEM;
1754         for (i = 0; i < numBufs; i++) {
1755                 sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
1756                 if (!sound_buffers[i]) {
1757                         while (i--)
1758                                 sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1759                         kfree (sound_buffers);
1760                         sound_buffers = 0;
1761                         return -ENOMEM;
1762                 }
1763         }
1764         return 0;
1765 }
1766
1767
1768 static void sq_release_buffers(void)
1769 {
1770         int i;
1771
1772         if (sound_buffers) {
1773                 for (i = 0; i < numBufs; i++)
1774                         sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1775                 kfree (sound_buffers);
1776                 sound_buffers = 0;
1777         }
1778 }
1779
1780
1781 static int sq_allocate_read_buffers(void)
1782 {
1783         int i;
1784
1785         if (sound_read_buffers)
1786                 return 0;
1787         sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL);
1788         if (!sound_read_buffers)
1789                 return -ENOMEM;
1790         for (i = 0; i < numBufs; i++) {
1791                 sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10,
1792                                                               GFP_KERNEL);
1793                 if (!sound_read_buffers[i]) {
1794                         while (i--)
1795                                 sound.mach.dma_free (sound_read_buffers[i],
1796                                                      readbufSize << 10);
1797                         kfree (sound_read_buffers);
1798                         sound_read_buffers = 0;
1799                         return -ENOMEM;
1800                 }
1801         }
1802         return 0;
1803 }
1804
1805 static void sq_release_read_buffers(void)
1806 {
1807         int i;
1808
1809         if (sound_read_buffers) {
1810                 cpmp->cp_smc[1].smc_smcmr &= ~SMCMR_REN;
1811                 for (i = 0; i < numReadBufs; i++)
1812                         sound.mach.dma_free (sound_read_buffers[i],
1813                                              bufSize << 10);
1814                 kfree (sound_read_buffers);
1815                 sound_read_buffers = 0;
1816         }
1817 }
1818
1819
1820 static void sq_setup(int numBufs, int bufSize, char **write_buffers)
1821 {
1822         int i;
1823         volatile cbd_t *bdp;
1824         volatile cpm8xx_t       *cp;
1825         volatile smc_t  *sp;
1826
1827         /* Make sure the SMC transmit is shut down.
1828         */
1829         cp = cpmp;
1830         sp = &cpmp->cp_smc[1];
1831         sp->smc_smcmr &= ~SMCMR_TEN;
1832
1833         sq.max_count = numBufs;
1834         sq.max_active = numBufs;
1835         sq.block_size = bufSize;
1836         sq.buffers = write_buffers;
1837
1838         sq.front = sq.count = 0;
1839         sq.rear = -1;
1840         sq.syncing = 0;
1841         sq.active = 0;
1842
1843         bdp = tx_base;
1844         for (i=0; i<numBufs; i++) {
1845                 bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]);
1846                 bdp++;
1847         }
1848
1849         /* This causes the SMC to sync up with the first buffer again.
1850         */
1851         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_TX) | CPM_CR_FLG;
1852         while (cp->cp_cpcr & CPM_CR_FLG);
1853 }
1854
1855 static void read_sq_setup(int numBufs, int bufSize, char **read_buffers)
1856 {
1857         int i;
1858         volatile cbd_t *bdp;
1859         volatile cpm8xx_t       *cp;
1860         volatile smc_t  *sp;
1861
1862         /* Make sure the SMC receive is shut down.
1863         */
1864         cp = cpmp;
1865         sp = &cpmp->cp_smc[1];
1866         sp->smc_smcmr &= ~SMCMR_REN;
1867
1868         read_sq.max_count = numBufs;
1869         read_sq.max_active = numBufs;
1870         read_sq.block_size = bufSize;
1871         read_sq.buffers = read_buffers;
1872
1873         read_sq.front = read_sq.count = 0;
1874         read_sq.rear = 0;
1875         read_sq.rear_size = 0;
1876         read_sq.syncing = 0;
1877         read_sq.active = 0;
1878
1879         bdp = rx_base;
1880         for (i=0; i<numReadBufs; i++) {
1881                 bdp->cbd_bufaddr = virt_to_bus(read_buffers[i]);
1882                 bdp->cbd_datlen = read_sq.block_size;
1883                 bdp++;
1884         }
1885
1886         /* This causes the SMC to sync up with the first buffer again.
1887         */
1888         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_RX) | CPM_CR_FLG;
1889         while (cp->cp_cpcr & CPM_CR_FLG);
1890 }
1891
1892
1893 static void sq_play(void)
1894 {
1895         (*sound.mach.play)();
1896 }
1897
1898
1899 /* ++TeSche: radically changed this one too */
1900
1901 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
1902                         loff_t *ppos)
1903 {
1904         ssize_t uWritten = 0;
1905         u_char *dest;
1906         ssize_t uUsed, bUsed, bLeft;
1907
1908         /* ++TeSche: Is something like this necessary?
1909          * Hey, that's an honest question! Or does any other part of the
1910          * filesystem already checks this situation? I really don't know.
1911          */
1912         if (uLeft == 0)
1913                 return 0;
1914
1915         /* The interrupt doesn't start to play the last, incomplete frame.
1916          * Thus we can append to it without disabling the interrupts! (Note
1917          * also that sq.rear isn't affected by the interrupt.)
1918          */
1919
1920         if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
1921                 dest = sq_block_address(sq.rear);
1922                 bUsed = sq.rear_size;
1923                 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1924                 if (uUsed <= 0)
1925                         return uUsed;
1926                 src += uUsed;
1927                 uWritten += uUsed;
1928                 uLeft -= uUsed;
1929                 sq.rear_size = bUsed;
1930         }
1931
1932         do {
1933                 while (sq.count == sq.max_active) {
1934                         sq_play();
1935                         if (NON_BLOCKING(sq.open_mode))
1936                                 return uWritten > 0 ? uWritten : -EAGAIN;
1937                         SLEEP(sq.action_queue);
1938                         if (SIGNAL_RECEIVED)
1939                                 return uWritten > 0 ? uWritten : -EINTR;
1940                 }
1941
1942                 /* Here, we can avoid disabling the interrupt by first
1943                  * copying and translating the data, and then updating
1944                  * the sq variables. Until this is done, the interrupt
1945                  * won't see the new frame and we can work on it
1946                  * undisturbed.
1947                  */
1948
1949                 dest = sq_block_address((sq.rear+1) % sq.max_count);
1950                 bUsed = 0;
1951                 bLeft = sq.block_size;
1952                 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1953                 if (uUsed <= 0)
1954                         break;
1955                 src += uUsed;
1956                 uWritten += uUsed;
1957                 uLeft -= uUsed;
1958                 if (bUsed) {
1959                         sq.rear = (sq.rear+1) % sq.max_count;
1960                         sq.rear_size = bUsed;
1961                         sq.count++;
1962                 }
1963         } while (bUsed);   /* uUsed may have been 0 */
1964
1965         sq_play();
1966
1967         return uUsed < 0? uUsed: uWritten;
1968 }
1969
1970
1971 /***********/
1972
1973 /* Here is how the values are used for reading.
1974  * The value 'active' simply indicates the DMA is running.  This is
1975  * done so the driver semantics are DMA starts when the first read is
1976  * posted.  The value 'front' indicates the buffer we should next
1977  * send to the user.  The value 'rear' indicates the buffer the DMA is
1978  * currently filling.  When 'front' == 'rear' the buffer "ring" is
1979  * empty (we always have an empty available).  The 'rear_size' is used
1980  * to track partial offsets into the current buffer.  Right now, I just keep
1981  * The DMA running.  If the reader can't keep up, the interrupt tosses
1982  * the oldest buffer.  We could also shut down the DMA in this case.
1983  */
1984 static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
1985                        loff_t *ppos)
1986 {
1987
1988         ssize_t uRead, bLeft, bUsed, uUsed;
1989
1990         if (uLeft == 0)
1991                 return 0;
1992
1993         if (!read_sq.active)
1994                 CS_Record();    /* Kick off the record process. */
1995
1996         uRead = 0;
1997
1998         /* Move what the user requests, depending upon other options.
1999         */
2000         while (uLeft > 0) {
2001
2002                 /* When front == rear, the DMA is not done yet.
2003                 */
2004                 while (read_sq.front == read_sq.rear) {
2005                         if (NON_BLOCKING(read_sq.open_mode)) {
2006                                return uRead > 0 ? uRead : -EAGAIN;
2007                         }
2008                         SLEEP(read_sq.action_queue);
2009                         if (SIGNAL_RECEIVED)
2010                                 return uRead > 0 ? uRead : -EINTR;
2011                 }
2012
2013                 /* The amount we move is either what is left in the
2014                  * current buffer or what the user wants.
2015                  */
2016                 bLeft = read_sq.block_size - read_sq.rear_size;
2017                 bUsed = read_sq.rear_size;
2018                 uUsed = sound_copy_translate_read(dst, uLeft,
2019                         read_sq.buffers[read_sq.front], &bUsed, bLeft);
2020                 if (uUsed <= 0)
2021                         return uUsed;
2022                 dst += uUsed;
2023                 uRead += uUsed;
2024                 uLeft -= uUsed;
2025                 read_sq.rear_size += bUsed;
2026                 if (read_sq.rear_size >= read_sq.block_size) {
2027                         read_sq.rear_size = 0;
2028                         read_sq.front++;
2029                         if (read_sq.front >= read_sq.max_active)
2030                                 read_sq.front = 0;
2031                 }
2032         }
2033         return uRead;
2034 }
2035
2036 static int sq_open(struct inode *inode, struct file *file)
2037 {
2038         int rc = 0;
2039
2040         if (file->f_mode & FMODE_WRITE) {
2041                 if (sq.busy) {
2042                         rc = -EBUSY;
2043                         if (NON_BLOCKING(file->f_flags))
2044                                 goto err_out;
2045                         rc = -EINTR;
2046                         while (sq.busy) {
2047                                 SLEEP(sq.open_queue);
2048                                 if (SIGNAL_RECEIVED)
2049                                         goto err_out;
2050                         }
2051                 }
2052                 sq.busy = 1; /* Let's play spot-the-race-condition */
2053
2054                 if (sq_allocate_buffers()) goto err_out_nobusy;
2055
2056                 sq_setup(numBufs, bufSize<<10,sound_buffers);
2057                 sq.open_mode = file->f_mode;
2058         }
2059
2060
2061         if (file->f_mode & FMODE_READ) {
2062                 if (read_sq.busy) {
2063                         rc = -EBUSY;
2064                         if (NON_BLOCKING(file->f_flags))
2065                                 goto err_out;
2066                         rc = -EINTR;
2067                         while (read_sq.busy) {
2068                                 SLEEP(read_sq.open_queue);
2069                                 if (SIGNAL_RECEIVED)
2070                                         goto err_out;
2071                         }
2072                         rc = 0;
2073                 }
2074                 read_sq.busy = 1;
2075                 if (sq_allocate_read_buffers()) goto err_out_nobusy;
2076
2077                 read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers);
2078                 read_sq.open_mode = file->f_mode;
2079         }
2080
2081         /* Start up the 4218 by:
2082          * Reset.
2083          * Enable, unreset.
2084          */
2085         *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_RSTAUDIO;
2086         eieio();
2087         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_ENAUDIO;
2088         mdelay(50);
2089         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2090
2091         /* We need to send the current control word in case someone
2092          * opened /dev/mixer and changed things while we were shut
2093          * down.  Chances are good the initialization that follows
2094          * would have done this, but it is still possible it wouldn't.
2095          */
2096         cs4218_ctl_write(cs4218_control);
2097
2098         sound.minDev = iminor(inode) & 0x0f;
2099         sound.soft = sound.dsp;
2100         sound.hard = sound.dsp;
2101         sound_init();
2102         if ((iminor(inode) & 0x0f) == SND_DEV_AUDIO) {
2103                 sound_set_speed(8000);
2104                 sound_set_stereo(0);
2105                 sound_set_format(AFMT_MU_LAW);
2106         }
2107
2108         return 0;
2109
2110 err_out_nobusy:
2111         if (file->f_mode & FMODE_WRITE) {
2112                 sq.busy = 0;
2113                 WAKE_UP(sq.open_queue);
2114         }
2115         if (file->f_mode & FMODE_READ) {
2116                 read_sq.busy = 0;
2117                 WAKE_UP(read_sq.open_queue);
2118         }
2119 err_out:
2120         return rc;
2121 }
2122
2123
2124 static void sq_reset(void)
2125 {
2126         sound_silence();
2127         sq.active = 0;
2128         sq.count = 0;
2129         sq.front = (sq.rear+1) % sq.max_count;
2130 #if 0
2131         init_tdm_buffers();
2132 #endif
2133 }
2134
2135
2136 static int sq_fsync(struct file *filp, struct dentry *dentry)
2137 {
2138         int rc = 0;
2139
2140         sq.syncing = 1;
2141         sq_play();      /* there may be an incomplete frame waiting */
2142
2143         while (sq.active) {
2144                 SLEEP(sq.sync_queue);
2145                 if (SIGNAL_RECEIVED) {
2146                         /* While waiting for audio output to drain, an
2147                          * interrupt occurred.  Stop audio output immediately
2148                          * and clear the queue. */
2149                         sq_reset();
2150                         rc = -EINTR;
2151                         break;
2152                 }
2153         }
2154
2155         sq.syncing = 0;
2156         return rc;
2157 }
2158
2159 static int sq_release(struct inode *inode, struct file *file)
2160 {
2161         int rc = 0;
2162
2163         if (sq.busy)
2164                 rc = sq_fsync(file, file->f_dentry);
2165         sound.soft = sound.dsp;
2166         sound.hard = sound.dsp;
2167         sound_silence();
2168
2169         sq_release_read_buffers();
2170         sq_release_buffers();
2171
2172         if (file->f_mode & FMODE_READ) {
2173                 read_sq.busy = 0;
2174                 WAKE_UP(read_sq.open_queue);
2175         }
2176
2177         if (file->f_mode & FMODE_WRITE) {
2178                 sq.busy = 0;
2179                 WAKE_UP(sq.open_queue);
2180         }
2181
2182         /* Shut down the SMC.
2183         */
2184         cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN);
2185
2186         /* Shut down the codec.
2187         */
2188         *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2189         eieio();
2190         *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO;
2191
2192         /* Wake up a process waiting for the queue being released.
2193          * Note: There may be several processes waiting for a call
2194          * to open() returning. */
2195
2196         return rc;
2197 }
2198
2199
2200 static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
2201                     u_long arg)
2202 {
2203         u_long fmt;
2204         int data;
2205 #if 0
2206         int size, nbufs;
2207 #else
2208         int size;
2209 #endif
2210
2211         switch (cmd) {
2212         case SNDCTL_DSP_RESET:
2213                 sq_reset();
2214                 return 0;
2215         case SNDCTL_DSP_POST:
2216         case SNDCTL_DSP_SYNC:
2217                 return sq_fsync(file, file->f_dentry);
2218
2219                 /* ++TeSche: before changing any of these it's
2220                  * probably wise to wait until sound playing has
2221                  * settled down. */
2222         case SNDCTL_DSP_SPEED:
2223                 sq_fsync(file, file->f_dentry);
2224                 IOCTL_IN(arg, data);
2225                 return IOCTL_OUT(arg, sound_set_speed(data));
2226         case SNDCTL_DSP_STEREO:
2227                 sq_fsync(file, file->f_dentry);
2228                 IOCTL_IN(arg, data);
2229                 return IOCTL_OUT(arg, sound_set_stereo(data));
2230         case SOUND_PCM_WRITE_CHANNELS:
2231                 sq_fsync(file, file->f_dentry);
2232                 IOCTL_IN(arg, data);
2233                 return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
2234         case SNDCTL_DSP_SETFMT:
2235                 sq_fsync(file, file->f_dentry);
2236                 IOCTL_IN(arg, data);
2237                 return IOCTL_OUT(arg, sound_set_format(data));
2238         case SNDCTL_DSP_GETFMTS:
2239                 fmt = 0;
2240                 if (sound.trans_write) {
2241                         if (sound.trans_write->ct_ulaw)
2242                                 fmt |= AFMT_MU_LAW;
2243                         if (sound.trans_write->ct_alaw)
2244                                 fmt |= AFMT_A_LAW;
2245                         if (sound.trans_write->ct_s8)
2246                                 fmt |= AFMT_S8;
2247                         if (sound.trans_write->ct_u8)
2248                                 fmt |= AFMT_U8;
2249                         if (sound.trans_write->ct_s16be)
2250                                 fmt |= AFMT_S16_BE;
2251                         if (sound.trans_write->ct_u16be)
2252                                 fmt |= AFMT_U16_BE;
2253                         if (sound.trans_write->ct_s16le)
2254                                 fmt |= AFMT_S16_LE;
2255                         if (sound.trans_write->ct_u16le)
2256                                 fmt |= AFMT_U16_LE;
2257                 }
2258                 return IOCTL_OUT(arg, fmt);
2259         case SNDCTL_DSP_GETBLKSIZE:
2260                 size = sq.block_size
2261                         * sound.soft.size * (sound.soft.stereo + 1)
2262                         / (sound.hard.size * (sound.hard.stereo + 1));
2263                 return IOCTL_OUT(arg, size);
2264         case SNDCTL_DSP_SUBDIVIDE:
2265                 break;
2266 #if 0   /* Sorry can't do this at the moment.  The CPM allocated buffers
2267          * long ago that can't be changed.
2268          */
2269         case SNDCTL_DSP_SETFRAGMENT:
2270                 if (sq.count || sq.active || sq.syncing)
2271                         return -EINVAL;
2272                 IOCTL_IN(arg, size);
2273                 nbufs = size >> 16;
2274                 if (nbufs < 2 || nbufs > numBufs)
2275                         nbufs = numBufs;
2276                 size &= 0xffff;
2277                 if (size >= 8 && size <= 30) {
2278                         size = 1 << size;
2279                         size *= sound.hard.size * (sound.hard.stereo + 1);
2280                         size /= sound.soft.size * (sound.soft.stereo + 1);
2281                         if (size > (bufSize << 10))
2282                                 size = bufSize << 10;
2283                 } else
2284                         size = bufSize << 10;
2285                 sq_setup(numBufs, size, sound_buffers);
2286                 sq.max_active = nbufs;
2287                 return 0;
2288 #endif
2289
2290         default:
2291                 return mixer_ioctl(inode, file, cmd, arg);
2292         }
2293         return -EINVAL;
2294 }
2295
2296
2297
2298 static struct file_operations sq_fops =
2299 {
2300         .owner =        THIS_MODULE,
2301         .llseek =       sound_lseek,
2302         .read =         sq_read,                        /* sq_read */
2303         .write =        sq_write,
2304         .ioctl =        sq_ioctl,
2305         .open =         sq_open,
2306         .release =      sq_release,
2307 };
2308
2309
2310 static void __init sq_init(void)
2311 {
2312         sq_unit = register_sound_dsp(&sq_fops, -1);
2313         if (sq_unit < 0)
2314                 return;
2315
2316         init_waitqueue_head(&sq.action_queue);
2317         init_waitqueue_head(&sq.open_queue);
2318         init_waitqueue_head(&sq.sync_queue);
2319         init_waitqueue_head(&read_sq.action_queue);
2320         init_waitqueue_head(&read_sq.open_queue);
2321         init_waitqueue_head(&read_sq.sync_queue);
2322
2323         sq.busy = 0;
2324         read_sq.busy = 0;
2325
2326         /* whatever you like as startup mode for /dev/dsp,
2327          * (/dev/audio hasn't got a startup mode). note that
2328          * once changed a new open() will *not* restore these!
2329          */
2330         sound.dsp.format = AFMT_S16_BE;
2331         sound.dsp.stereo = 1;
2332         sound.dsp.size = 16;
2333
2334         /* set minimum rate possible without expanding */
2335         sound.dsp.speed = 8000;
2336
2337         /* before the first open to /dev/dsp this wouldn't be set */
2338         sound.soft = sound.dsp;
2339         sound.hard = sound.dsp;
2340
2341         sound_silence();
2342 }
2343
2344 /*
2345  * /dev/sndstat
2346  */
2347
2348
2349 /* state.buf should not overflow! */
2350
2351 static int state_open(struct inode *inode, struct file *file)
2352 {
2353         char *buffer = state.buf, *mach = "", cs4218_buf[50];
2354         int len = 0;
2355
2356         if (state.busy)
2357                 return -EBUSY;
2358
2359         state.ptr = 0;
2360         state.busy = 1;
2361
2362         sprintf(cs4218_buf, "Crystal CS4218 on TDM, ");
2363         mach = cs4218_buf;
2364
2365         len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
2366
2367         len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
2368         switch (sound.soft.format) {
2369         case AFMT_MU_LAW:
2370                 len += sprintf(buffer+len, " (mu-law)");
2371                 break;
2372         case AFMT_A_LAW:
2373                 len += sprintf(buffer+len, " (A-law)");
2374                 break;
2375         case AFMT_U8:
2376                 len += sprintf(buffer+len, " (unsigned 8 bit)");
2377                 break;
2378         case AFMT_S8:
2379                 len += sprintf(buffer+len, " (signed 8 bit)");
2380                 break;
2381         case AFMT_S16_BE:
2382                 len += sprintf(buffer+len, " (signed 16 bit big)");
2383                 break;
2384         case AFMT_U16_BE:
2385                 len += sprintf(buffer+len, " (unsigned 16 bit big)");
2386                 break;
2387         case AFMT_S16_LE:
2388                 len += sprintf(buffer+len, " (signed 16 bit little)");
2389                 break;
2390         case AFMT_U16_LE:
2391                 len += sprintf(buffer+len, " (unsigned 16 bit little)");
2392                 break;
2393         }
2394         len += sprintf(buffer+len, "\n");
2395         len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
2396                        sound.soft.speed, sound.hard.speed);
2397         len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
2398                        sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
2399         len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d"
2400                        " sq.max_active = %d\n",
2401                        sq.block_size, sq.max_count, sq.max_active);
2402         len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
2403                        sq.rear_size);
2404         len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
2405                        sq.active, sq.syncing);
2406         state.len = len;
2407         return 0;
2408 }
2409
2410
2411 static int state_release(struct inode *inode, struct file *file)
2412 {
2413         state.busy = 0;
2414         return 0;
2415 }
2416
2417
2418 static ssize_t state_read(struct file *file, char *buf, size_t count,
2419                           loff_t *ppos)
2420 {
2421         int n = state.len - state.ptr;
2422         if (n > count)
2423                 n = count;
2424         if (n <= 0)
2425                 return 0;
2426         if (copy_to_user(buf, &state.buf[state.ptr], n))
2427                 return -EFAULT;
2428         state.ptr += n;
2429         return n;
2430 }
2431
2432
2433 static struct file_operations state_fops =
2434 {
2435         .owner =        THIS_MODULE,
2436         .llseek =       sound_lseek,
2437         .read =         state_read,
2438         .open =         state_open,
2439         .release =      state_release,
2440 };
2441
2442
2443 static void __init state_init(void)
2444 {
2445         state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
2446         if (state_unit < 0)
2447                 return;
2448         state.busy = 0;
2449 }
2450
2451
2452 /*** Common stuff ********************************************************/
2453
2454 static long long sound_lseek(struct file *file, long long offset, int orig)
2455 {
2456         return -ESPIPE;
2457 }
2458
2459
2460 /*** Config & Setup **********************************************************/
2461
2462
2463 int __init tdm8xx_sound_init(void)
2464 {
2465         int i, has_sound;
2466         uint                    dp_addr;
2467         volatile uint           *sirp;
2468         volatile cbd_t          *bdp;
2469         volatile cpm8xx_t       *cp;
2470         volatile smc_t          *sp;
2471         volatile smc_uart_t     *up;
2472         volatile immap_t        *immap;
2473
2474         has_sound = 0;
2475
2476         /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes.
2477         */
2478         cp = cpmp;      /* Get pointer to Communication Processor */
2479         immap = (immap_t *)IMAP_ADDR;   /* and to internal registers */
2480
2481         /* Set all TDMa control bits to zero.  This enables most features
2482          * we want.
2483          */
2484         cp->cp_simode &= ~0x00000fff;
2485
2486         /* Enable common receive/transmit clock pins, use IDL format.
2487          * Sync on falling edge, transmit rising clock, receive falling
2488          * clock, delay 1 bit on both Tx and Rx.  Common Tx/Rx clocks and
2489          * sync.
2490          * Connect SMC2 to TSA.
2491          */
2492         cp->cp_simode |= 0x80000141;
2493
2494         /* Configure port A pins for TDMa operation.
2495          * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used.
2496          */
2497         immap->im_ioport.iop_papar |= 0x01c0; /* Enable TDMa functions */
2498         immap->im_ioport.iop_padir |= 0x00c0; /* Enable TDMa Tx/Rx */
2499         immap->im_ioport.iop_padir &= ~0x0100; /* Enable L1RCLKa */
2500
2501         immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */
2502         immap->im_ioport.iop_pcdir &= ~0x0800;
2503
2504         /* Initialize the SI TDM routing table.  We use TDMa only.
2505          * The receive table and transmit table each have only one
2506          * entry, to capture/send four bytes after each frame pulse.
2507          * The 16-bit ram entry is 0000 0001 1000 1111. (SMC2)
2508          */
2509         cp->cp_sigmr = 0;
2510         sirp = (uint *)cp->cp_siram;
2511
2512         *sirp = 0x018f0000;             /* Receive entry */
2513         sirp += 64;
2514         *sirp = 0x018f0000;             /* Tramsmit entry */
2515
2516         /* Enable single TDMa routing.
2517         */
2518         cp->cp_sigmr = 0x04;
2519
2520         /* Initialize the SMC for transparent operation.
2521         */
2522         sp = &cpmp->cp_smc[1];
2523         up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
2524
2525         /* We need to allocate a transmit and receive buffer
2526          * descriptors from dual port ram.
2527          */
2528         dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numReadBufs);
2529
2530         /* Set the physical address of the host memory
2531          * buffers in the buffer descriptors, and the
2532          * virtual address for us to work with.
2533          */
2534         bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2535         up->smc_rbase = dp_addr;
2536         rx_cur = rx_base = (cbd_t *)bdp;
2537
2538         for (i=0; i<(numReadBufs-1); i++) {
2539                 bdp->cbd_bufaddr = 0;
2540                 bdp->cbd_datlen = 0;
2541                 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
2542                 bdp++;
2543         }
2544         bdp->cbd_bufaddr = 0;
2545         bdp->cbd_datlen = 0;
2546         bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
2547
2548         /* Now, do the same for the transmit buffers.
2549         */
2550         dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * numBufs);
2551
2552         bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2553         up->smc_tbase = dp_addr;
2554         tx_cur = tx_base = (cbd_t *)bdp;
2555
2556         for (i=0; i<(numBufs-1); i++) {
2557                 bdp->cbd_bufaddr = 0;
2558                 bdp->cbd_datlen = 0;
2559                 bdp->cbd_sc = BD_SC_INTRPT;
2560                 bdp++;
2561         }
2562         bdp->cbd_bufaddr = 0;
2563         bdp->cbd_datlen = 0;
2564         bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
2565
2566         /* Set transparent SMC mode.
2567          * A few things are specific to our application.  The codec interface
2568          * is MSB first, hence the REVD selection.  The CD/CTS pulse are
2569          * used by the TSA to indicate the frame start to the SMC.
2570          */
2571         up->smc_rfcr = SCC_EB;
2572         up->smc_tfcr = SCC_EB;
2573         up->smc_mrblr = readbufSize * 1024;
2574
2575         /* Set 16-bit reversed data, transparent mode.
2576         */
2577         sp->smc_smcmr = smcr_mk_clen(15) |
2578                 SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS;
2579
2580         /* Enable and clear events.
2581          * Because of FIFO delays, all we need is the receive interrupt
2582          * and we can process both the current receive and current
2583          * transmit interrupt within a few microseconds of the transmit.
2584          */
2585         sp->smc_smce = 0xff;
2586         sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX;
2587
2588         /* Send the CPM an initialize command.
2589         */
2590         cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2591                                 CPM_CR_INIT_TRX) | CPM_CR_FLG;
2592         while (cp->cp_cpcr & CPM_CR_FLG);
2593
2594         sound.mach = mach_cs4218;
2595         has_sound = 1;
2596
2597         /* Initialize beep stuff */
2598         orig_mksound = kd_mksound;
2599         kd_mksound = cs_mksound;
2600         beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
2601         if (beep_buf == NULL)
2602                 printk(KERN_WARNING "dmasound: no memory for "
2603                        "beep buffer\n");
2604
2605         if (!has_sound)
2606                 return -ENODEV;
2607
2608         /* Initialize the software SPI.
2609         */
2610         sw_spi_init();
2611
2612         /* Set up sound queue, /dev/audio and /dev/dsp. */
2613
2614         /* Set default settings. */
2615         sq_init();
2616
2617         /* Set up /dev/sndstat. */
2618         state_init();
2619
2620         /* Set up /dev/mixer. */
2621         mixer_init();
2622
2623         if (!sound.mach.irqinit()) {
2624                 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
2625                 return -ENODEV;
2626         }
2627 #ifdef MODULE
2628         irq_installed = 1;
2629 #endif
2630
2631         printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
2632                numBufs, bufSize);
2633
2634         return 0;
2635 }
2636
2637 /* Due to FIFOs and bit delays, the transmit interrupt occurs a few
2638  * microseconds ahead of the receive interrupt.
2639  * When we get an interrupt, we service the transmit first, then
2640  * check for a receive to prevent the overhead of returning through
2641  * the interrupt handler only to get back here right away during
2642  * full duplex operation.
2643  */
2644 static void
2645 cs4218_intr(void *dev_id, struct pt_regs *regs)
2646 {
2647         volatile smc_t  *sp;
2648         volatile cpm8xx_t       *cp;
2649
2650         sp = &cpmp->cp_smc[1];
2651
2652         if (sp->smc_smce & SCCM_TX) {
2653                 sp->smc_smce = SCCM_TX;
2654                 cs4218_tdm_tx_intr((void *)sp);
2655         }
2656
2657         if (sp->smc_smce & SCCM_RX) {
2658                 sp->smc_smce = SCCM_RX;
2659                 cs4218_tdm_rx_intr((void *)sp);
2660         }
2661
2662         if (sp->smc_smce & SCCM_TXE) {
2663                 /* Transmit underrun.  This happens with the application
2664                  * didn't keep up sending buffers.  We tell the SMC to
2665                  * restart, which will cause it to poll the current (next)
2666                  * BD.  If the user supplied data since this occurred,
2667                  * we just start running again.  If they didn't, the SMC
2668                  * will poll the descriptor until data is placed there.
2669                  */
2670                 sp->smc_smce = SCCM_TXE;
2671                 cp = cpmp;      /* Get pointer to Communication Processor */
2672                 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2673                                         CPM_CR_RESTART_TX) | CPM_CR_FLG;
2674                 while (cp->cp_cpcr & CPM_CR_FLG);
2675         }
2676 }
2677
2678
2679 #define MAXARGS         8       /* Should be sufficient for now */
2680
2681 void __init dmasound_setup(char *str, int *ints)
2682 {
2683         /* check the bootstrap parameter for "dmasound=" */
2684
2685         switch (ints[0]) {
2686         case 3:
2687                 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
2688                         printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
2689                 else
2690                         catchRadius = ints[3];
2691                 /* fall through */
2692         case 2:
2693                 if (ints[1] < MIN_BUFFERS)
2694                         printk("dmasound_setup: invalid number of buffers, using default = %d\n", numBufs);
2695                 else
2696                         numBufs = ints[1];
2697                 if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
2698                         printk("dmasound_setup: invalid buffer size, using default = %d\n", bufSize);
2699                 else
2700                         bufSize = ints[2];
2701                 break;
2702         case 0:
2703                 break;
2704         default:
2705                 printk("dmasound_setup: invalid number of arguments\n");
2706         }
2707 }
2708
2709 /* Software SPI functions.
2710  * These are on Port B.
2711  */
2712 #define PB_SPICLK       ((uint)0x00000002)
2713 #define PB_SPIMOSI      ((uint)0x00000004)
2714 #define PB_SPIMISO      ((uint)0x00000008)
2715
2716 static
2717 void    sw_spi_init(void)
2718 {
2719         volatile cpm8xx_t       *cp;
2720         volatile uint           *hcsr4;
2721
2722         hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2723         cp = cpmp;      /* Get pointer to Communication Processor */
2724
2725         *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2726
2727         /* Make these Port B signals general purpose I/O.
2728          * First, make sure the clock is low.
2729          */
2730         cp->cp_pbdat &= ~PB_SPICLK;
2731         cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO);
2732
2733         /* Clock and Master Output are outputs.
2734         */
2735         cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI);
2736
2737         /* Master Input.
2738         */
2739         cp->cp_pbdir &= ~PB_SPIMISO;
2740
2741 }
2742
2743 /* Write the CS4218 control word out the SPI port.  While the
2744  * the control word is going out, the status word is arriving.
2745  */
2746 static
2747 uint    cs4218_ctl_write(uint ctlreg)
2748 {
2749         uint    status;
2750
2751         sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4);
2752
2753         /* Shadow the control register.....I guess we could do
2754          * the same for the status, but for now we just return it
2755          * and let the caller decide.
2756          */
2757         cs4218_control = ctlreg;
2758         return status;
2759 }
2760
2761 static
2762 void    sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt)
2763 {
2764         int     bits, i;
2765         u_char  outbyte, inbyte;
2766         volatile cpm8xx_t       *cp;
2767         volatile uint           *hcsr4;
2768
2769         hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2770         cp = cpmp;      /* Get pointer to Communication Processor */
2771
2772         /* The timing on the bus is pretty slow.  Code inefficiency
2773          * and eieio() is our friend here :-).
2774          */
2775         cp->cp_pbdat &= ~PB_SPICLK;
2776         *hcsr4 |= HIOX_CSR4_AUDSPISEL;  /* Enable SPI select */
2777         eieio();
2778
2779         /* Clock in/out the bytes.  Data is valid on the falling edge
2780          * of the clock.  Data is MSB first.
2781          */
2782         for (i=0; i<bcnt; i++) {
2783                 outbyte = *obuf++;
2784                 inbyte = 0;
2785                 for (bits=0; bits<8; bits++) {
2786                         eieio();
2787                         cp->cp_pbdat |= PB_SPICLK;
2788                         eieio();
2789                         if (outbyte & 0x80)
2790                                 cp->cp_pbdat |= PB_SPIMOSI;
2791                         else
2792                                 cp->cp_pbdat &= ~PB_SPIMOSI;
2793                         eieio();
2794                         cp->cp_pbdat &= ~PB_SPICLK;
2795                         eieio();
2796                         outbyte <<= 1;
2797                         inbyte <<= 1;
2798                         if (cp->cp_pbdat & PB_SPIMISO)
2799                                 inbyte |= 1;
2800                 }
2801                 *ibuf++ = inbyte;
2802         }
2803
2804         *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2805         eieio();
2806 }
2807
2808 void cleanup_module(void)
2809 {
2810         if (irq_installed) {
2811                 sound_silence();
2812 #ifdef MODULE
2813                 sound.mach.irqcleanup();
2814 #endif
2815         }
2816
2817         sq_release_read_buffers();
2818         sq_release_buffers();
2819
2820         if (mixer_unit >= 0)
2821                 unregister_sound_mixer(mixer_unit);
2822         if (state_unit >= 0)
2823                 unregister_sound_special(state_unit);
2824         if (sq_unit >= 0)
2825                 unregister_sound_dsp(sq_unit);
2826 }
2827
2828 module_init(tdm8xx_sound_init);
2829 module_exit(cleanup_module);
2830