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