[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / arch / ppc / 8xx_io / cs4218_tdm.c
blob89fe0ceeaa40294dfacdffc15590af7f5623e299
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 :-).
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)
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>
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>
32 /* Should probably do something different with this path name.....
33 * Actually, I should just stop using it...
35 #include "cs4218.h"
36 #include <linux/soundcard.h>
38 #include <asm/mpc8xx.h>
39 #include <asm/8xx_immap.h>
40 #include <asm/commproc.h>
42 #define DMASND_CS4218 5
44 #define MAX_CATCH_RADIUS 10
45 #define MIN_BUFFERS 4
46 #define MIN_BUFSIZE 4
47 #define MAX_BUFSIZE 128
49 #define HAS_8BIT_TABLES
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;
58 static DEFINE_SPINLOCK(cs4218_lock);
60 /* Local copies of things we put in the control register. Output
61 * volume, like most codecs is really attenuation.
63 static int cs4218_rate_index;
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.
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,
105 #define BEEP_SPEED 5 /* 22050 Hz sample rate */
106 #define BEEP_BUFLEN 512
107 #define BEEP_VOLUME 15 /* 0 - 100 */
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);
115 /* This is found someplace else......I guess in the keyboard driver
116 * we don't include.
118 static void (*kd_mksound)(unsigned int, unsigned int);
120 static int catchRadius = 0;
121 static int numBufs = 4, bufSize = 32;
122 static int numReadBufs = 4, readbufSize = 32;
125 /* TDM/Serial transmit and receive buffer descriptors.
127 static volatile cbd_t *rx_base, *rx_cur, *tx_base, *tx_cur;
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");
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))
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)
145 /* CS4218 serial port control in mode 4.
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)
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)
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)
167 /* The control register is effectively write only. We have to keep a copy
168 * of what we write.
170 static uint cs4218_control;
172 /* A place to store expanding information.
174 static int expand_bal;
175 static int expand_data;
177 /* Since I can't make the microcode patch work for the SPI, I just
178 * clock the bits using software.
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);
184 /*** Some low level helpers **************************************************/
186 /* 16 bit mu-law */
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,
223 /* 16 bit A-law */
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,
261 /*** Translations ************************************************************/
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);
302 /*** Low level stuff *********************************************************/
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 */
319 static struct cs_sound_settings sound;
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);
343 /*** Mid level stuff *********************************************************/
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);
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);
364 * /dev/mixer abstraction
367 struct sound_mixer {
368 int busy;
369 int modify_counter;
372 static struct sound_mixer mixer;
374 static struct sound_queue sq;
375 static struct sound_queue read_sq;
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
384 * /dev/sndstat
387 struct sound_state {
388 int busy;
389 char buf[512];
390 int len, ptr;
393 static struct sound_state state;
395 /*** Common stuff ********************************************************/
397 static long long sound_lseek(struct file *file, long long offset, int orig);
399 /*** Config & Setup **********************************************************/
401 void dmasound_setup(char *str, int *ints);
403 /*** Translations ************************************************************/
406 /* ++TeSche: radically changed for new expanding purposes...
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.
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. :)
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!
427 * ++geert: split in even more functions (one per format)
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)
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;
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];
454 *p++ = val;
455 count--;
457 *frameUsed += used * 4;
458 return stereo? used * 2: used;
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)
466 ssize_t count, used;
467 short *p = (short *) &frame[*frameUsed];
468 int val, stereo = sound.soft.stereo;
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;
485 *p++ = val;
486 count--;
488 *frameUsed += used * 4;
489 return stereo? used * 2: used;
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)
497 ssize_t count, used;
498 short *p = (short *) &frame[*frameUsed];
499 int val, stereo = sound.soft.stereo;
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;
516 *p++ = val;
517 count--;
519 *frameUsed += used * 4;
520 return stereo? used * 2: used;
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.
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)
533 ssize_t count, used;
534 int stereo = sound.soft.stereo;
535 short *fp = (short *) &frame[*frameUsed];
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--;
550 } else {
551 if (copy_from_user(fp, userPtr, count * 4))
552 return -EFAULT;
554 *frameUsed += used * 4;
555 return stereo? used * 4: used * 2;
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)
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;
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;
582 *fp++ = data;
583 count--;
585 *frameUsed += used * 4;
586 return stereo? used * 4: used * 2;
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)
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;
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;
625 *p++ = data;
626 frameLeft--;
627 bal -= sSpeed;
629 expand_bal = bal;
630 expand_data = data;
631 *frameUsed += (ftotal - frameLeft) * 4;
632 utotal -= userCount;
633 return stereo? utotal * 2: utotal;
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)
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;
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;
670 *p++ = data;
671 frameLeft--;
672 bal -= sSpeed;
674 expand_bal = bal;
675 expand_data = data;
676 *frameUsed += (ftotal - frameLeft) * 4;
677 utotal -= userCount;
678 return stereo? utotal * 2: utotal;
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)
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;
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;
715 *p++ = data;
716 frameLeft--;
717 bal -= sSpeed;
719 expand_bal = bal;
720 expand_data = data;
721 *frameUsed += (ftotal - frameLeft) * 4;
722 utotal -= userCount;
723 return stereo? utotal * 2: utotal;
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)
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;
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;
759 *p++ = data;
760 frameLeft--;
761 bal -= sSpeed;
763 expand_bal = bal;
764 expand_data = data;
765 *frameUsed += (ftotal - frameLeft) * 4;
766 utotal -= userCount;
767 return stereo? utotal * 4: utotal * 2;
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)
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;
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;
805 *p++ = data;
806 frameLeft--;
807 bal -= sSpeed;
809 expand_bal = bal;
810 expand_data = data;
811 *frameUsed += (ftotal - frameLeft) * 4;
812 utotal -= userCount;
813 return stereo? utotal * 4: utotal * 2;
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)
820 ssize_t count, used;
821 short *p = (short *) &frame[*frameUsed];
822 int val, stereo = sound.soft.stereo;
824 frameLeft >>= 2;
825 if (stereo)
826 userCount >>= 1;
827 used = count = min(userCount, frameLeft);
828 while (count > 0) {
829 u_char data;
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;
841 p++;
842 count--;
844 *frameUsed += used * 4;
845 return stereo? used * 2: used;
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)
853 ssize_t count, used;
854 short *p = (short *) &frame[*frameUsed];
855 int val, stereo = sound.soft.stereo;
857 frameLeft >>= 2;
858 if (stereo)
859 userCount >>= 1;
860 used = count = min(userCount, frameLeft);
861 while (count > 0) {
862 u_char data;
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;
874 p++;
875 count--;
877 *frameUsed += used * 4;
878 return stereo? used * 2: used;
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)
886 ssize_t count, used;
887 int stereo = sound.soft.stereo;
888 short *fp = (short *) &frame[*frameUsed];
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--;
903 } else {
904 if (copy_to_user((u_char *)userPtr, fp, count * 4))
905 return -EFAULT;
907 *frameUsed += used * 4;
908 return stereo? used * 4: used * 2;
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)
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;
921 frameLeft >>= 2;
922 userCount >>= (stereo? 2: 1);
923 used = count = min(userCount, frameLeft);
924 while (count > 0) {
925 int data;
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;
937 fp++;
938 count--;
940 *frameUsed += used * 4;
941 return stereo? used * 4: used * 2;
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
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
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
960 /*** Low level stuff *********************************************************/
962 static void *CS_Alloc(unsigned int size, int flags)
964 int order;
966 size >>= 13;
967 for (order=0; order < 5; order++) {
968 if (size == 0)
969 break;
970 size >>= 1;
972 return (void *)__get_free_pages(flags, order);
975 static void CS_Free(void *ptr, unsigned int size)
977 int order;
979 size >>= 13;
980 for (order=0; order < 5; order++) {
981 if (size == 0)
982 break;
983 size >>= 1;
985 free_pages((ulong)ptr, order);
988 static int __init CS_IrqInit(void)
990 cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL);
991 return 1;
994 #ifdef MODULE
995 static void CS_IrqCleanup(void)
997 volatile smc_t *sp;
998 volatile cpm8xx_t *cp;
1000 /* First disable transmitter and receiver.
1002 sp = &cpmp->cp_smc[1];
1003 sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
1005 /* And now shut down the SMC.
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);
1012 /* Release the interrupt handler.
1014 cpm_free_handler(CPMVEC_SMC2);
1016 if (beep_buf)
1017 kfree(beep_buf);
1018 kd_mksound = orig_mksound;
1020 #endif /* MODULE */
1022 static void CS_Silence(void)
1024 volatile smc_t *sp;
1026 /* Disable transmitter.
1028 sp = &cpmp->cp_smc[1];
1029 sp->smc_smcmr &= ~SMCMR_TEN;
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.
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
1048 static void CS_Init(void)
1050 int i, tolerance;
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;
1061 sound.hard.stereo = 1;
1062 sound.hard.size = 16;
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.
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;
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.
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);
1092 expand_bal = -sound.soft.speed;
1095 static int CS_SetFormat(int format)
1097 int size;
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;
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;
1128 CS_Init();
1130 return format;
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".
1136 #define CS_VOLUME_TO_MASK(x) (31 - ((((x) - 1) * 31) / 99))
1137 #define CS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 31))
1139 static int cs_get_volume(uint reg)
1141 int volume;
1143 volume = CS_MASK_TO_VOLUME(CS_LATTEN_GET(reg));
1144 volume |= CS_MASK_TO_VOLUME(CS_RATTEN_GET(reg)) << 8;
1145 return volume;
1148 static int cs_volume_setter(int volume, int mute)
1150 uint tempctl;
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);
1161 if (tempctl != cs4218_control) {
1162 cs4218_ctl_write(tempctl);
1164 return volume;
1168 /* Gain has 16 steps from 0 to 15. These are in 1.5dB increments from
1169 * 0 (no gain) to 22.5 dB.
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)
1175 static int cs_get_gain(uint reg)
1177 int gain;
1179 gain = CS_GAIN_TO_RECLEVEL(CS_LGAIN_GET(reg));
1180 gain |= CS_GAIN_TO_RECLEVEL(CS_RGAIN_GET(reg)) << 8;
1181 return gain;
1184 static int cs_set_gain(int gain)
1186 uint tempctl;
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);
1193 if (tempctl != cs4218_control) {
1194 cs4218_ctl_write(tempctl);
1196 return gain;
1199 static int CS_SetVolume(int volume)
1201 return cs_volume_setter(volume, CS_MUTE);
1204 static void CS_Play(void)
1206 int i, count;
1207 unsigned long flags;
1208 volatile cbd_t *bdp;
1209 volatile cpm8xx_t *cp;
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])));
1223 beep_playing = 0;
1224 awacs_beep_state = 0;
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;
1236 bdp = &tx_base[i];
1237 bdp->cbd_datlen = count;
1239 flush_dcache_range((ulong)sound_buffers[i],
1240 (ulong)(sound_buffers[i] + count));
1242 if (++i >= sq.max_count)
1243 i = 0;
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.
1252 bdp->cbd_datlen -= 2;
1254 /* Start up the SMC Transmitter.
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);
1263 /* Buffer is ready now.
1265 bdp->cbd_sc |= BD_SC_READY;
1267 ++sq.active;
1269 spin_unlock_irqrestore(&cs4218_lock, flags);
1273 static void CS_Record(void)
1275 unsigned long flags;
1276 volatile smc_t *sp;
1278 if (read_sq.active)
1279 return;
1281 /* Protect buffer */
1282 spin_lock_irqsave(&cs4218_lock, flags);
1284 /* This is all we have to do......Just start it up.
1286 sp = &cpmp->cp_smc[1];
1287 sp->smc_smcmr |= SMCMR_REN;
1289 read_sq.active = 1;
1291 spin_unlock_irqrestore(&cs4218_lock, flags);
1295 static void
1296 cs4218_tdm_tx_intr(void *devid)
1298 int i = sq.front;
1299 volatile cbd_t *bdp;
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;
1310 if (i != sq.front)
1311 WAKE_UP(sq.action_queue);
1312 sq.front = i;
1314 CS_Play();
1316 if (!sq.active)
1317 WAKE_UP(sq.sync_queue);
1321 static void
1322 cs4218_tdm_rx_intr(void *devid)
1325 /* We want to blow 'em off when shutting down.
1327 if (read_sq.active == 0)
1328 return;
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.
1334 while ((rx_base[read_sq.rear].cbd_sc & BD_SC_EMPTY) == 0) {
1336 /* Invalidate the data cache range for this buffer.
1338 invalidate_dcache_range(
1339 (uint)(sound_read_buffers[read_sq.rear]),
1340 (uint)(sound_read_buffers[read_sq.rear] + read_sq.block_size));
1342 /* Make buffer available again and move on.
1344 rx_base[read_sq.rear].cbd_sc |= BD_SC_EMPTY;
1345 read_sq.rear++;
1347 /* Wrap the buffer ring.
1349 if (read_sq.rear >= read_sq.max_active)
1350 read_sq.rear = 0;
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.
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;
1365 WAKE_UP(read_sq.action_queue);
1368 static void cs_nosound(unsigned long xx)
1370 unsigned long flags;
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;
1380 spin_unlock_irqrestore(&cs4218_lock, flags);
1383 static struct timer_list beep_timer = TIMER_INITIALIZER(cs_nosound, 0, 0);
1386 static void cs_mksound(unsigned int hz, unsigned int ticks)
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;
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
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);
1416 if (beep_playing || sq.active || beep_buf == NULL) {
1417 spin_unlock_irqrestore(&cs4218_lock, flags);
1418 return; /* too hard, sorry :-( */
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);
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;
1439 beep_hz_cache = hz;
1440 beep_volume_cache = beep_volume;
1441 beep_nsamples_cache = nsamples;
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;
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));
1461 spin_unlock_irqrestore(&cs4218_lock, flags);
1462 #endif
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
1483 /*** Mid level stuff *********************************************************/
1486 static void sound_silence(void)
1488 /* update hardware settings one more */
1489 (*sound.mach.init)();
1491 (*sound.mach.silence)();
1495 static void sound_init(void)
1497 (*sound.mach.init)();
1501 static int sound_set_format(int format)
1503 return(*sound.mach.setFormat)(format);
1507 static int sound_set_speed(int speed)
1509 if (speed < 0)
1510 return(sound.soft.speed);
1512 sound.soft.speed = speed;
1513 (*sound.mach.init)();
1514 if (sound.minDev == SND_DEV_DSP)
1515 sound.dsp.speed = sound.soft.speed;
1517 return(sound.soft.speed);
1521 static int sound_set_stereo(int stereo)
1523 if (stereo < 0)
1524 return(sound.soft.stereo);
1526 stereo = !!stereo; /* should be 0 or 1 now */
1528 sound.soft.stereo = stereo;
1529 if (sound.minDev == SND_DEV_DSP)
1530 sound.dsp.stereo = stereo;
1531 (*sound.mach.init)();
1533 return(stereo);
1537 static int sound_set_volume(int volume)
1539 return(*sound.mach.setVolume)(volume);
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)
1547 ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
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;
1575 if (ct_func)
1576 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1577 else
1578 return 0;
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)
1586 ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
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;
1614 if (ct_func)
1615 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1616 else
1617 return 0;
1622 * /dev/mixer abstraction
1625 static int mixer_open(struct inode *inode, struct file *file)
1627 mixer.busy = 1;
1628 return nonseekable_open(inode, file);
1632 static int mixer_release(struct inode *inode, struct file *file)
1634 mixer.busy = 0;
1635 return 0;
1639 static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
1640 u_long arg)
1642 int data;
1643 uint tmpcs;
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;
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);
1713 return -EINVAL;
1717 static struct file_operations mixer_fops =
1719 .owner = THIS_MODULE,
1720 .llseek = sound_lseek,
1721 .ioctl = mixer_ioctl,
1722 .open = mixer_open,
1723 .release = mixer_release,
1727 static void __init mixer_init(void)
1729 mixer_unit = register_sound_mixer(&mixer_fops, -1);
1730 if (mixer_unit < 0)
1731 return;
1733 mixer.busy = 0;
1734 sound.treble = 0;
1735 sound.bass = 0;
1737 /* Set Line input, no gain, no attenuation.
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);
1747 * Sound queue stuff, the heart of the driver
1751 static int sq_allocate_buffers(void)
1753 int i;
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;
1770 return 0;
1774 static void sq_release_buffers(void)
1776 int i;
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;
1787 static int sq_allocate_read_buffers(void)
1789 int i;
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;
1808 return 0;
1811 static void sq_release_read_buffers(void)
1813 int i;
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;
1826 static void sq_setup(int numBufs, int bufSize, char **write_buffers)
1828 int i;
1829 volatile cbd_t *bdp;
1830 volatile cpm8xx_t *cp;
1831 volatile smc_t *sp;
1833 /* Make sure the SMC transmit is shut down.
1835 cp = cpmp;
1836 sp = &cpmp->cp_smc[1];
1837 sp->smc_smcmr &= ~SMCMR_TEN;
1839 sq.max_count = numBufs;
1840 sq.max_active = numBufs;
1841 sq.block_size = bufSize;
1842 sq.buffers = write_buffers;
1844 sq.front = sq.count = 0;
1845 sq.rear = -1;
1846 sq.syncing = 0;
1847 sq.active = 0;
1849 bdp = tx_base;
1850 for (i=0; i<numBufs; i++) {
1851 bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]);
1852 bdp++;
1855 /* This causes the SMC to sync up with the first buffer again.
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);
1861 static void read_sq_setup(int numBufs, int bufSize, char **read_buffers)
1863 int i;
1864 volatile cbd_t *bdp;
1865 volatile cpm8xx_t *cp;
1866 volatile smc_t *sp;
1868 /* Make sure the SMC receive is shut down.
1870 cp = cpmp;
1871 sp = &cpmp->cp_smc[1];
1872 sp->smc_smcmr &= ~SMCMR_REN;
1874 read_sq.max_count = numBufs;
1875 read_sq.max_active = numBufs;
1876 read_sq.block_size = bufSize;
1877 read_sq.buffers = read_buffers;
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;
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++;
1892 /* This causes the SMC to sync up with the first buffer again.
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);
1899 static void sq_play(void)
1901 (*sound.mach.play)();
1905 /* ++TeSche: radically changed this one too */
1907 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
1908 loff_t *ppos)
1910 ssize_t uWritten = 0;
1911 u_char *dest;
1912 ssize_t uUsed, bUsed, bLeft;
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.
1918 if (uLeft == 0)
1919 return 0;
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.)
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;
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;
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.
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++;
1969 } while (bUsed); /* uUsed may have been 0 */
1971 sq_play();
1973 return uUsed < 0? uUsed: uWritten;
1977 /***********/
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.
1990 static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
1991 loff_t *ppos)
1994 ssize_t uRead, bLeft, bUsed, uUsed;
1996 if (uLeft == 0)
1997 return 0;
1999 if (!read_sq.active)
2000 CS_Record(); /* Kick off the record process. */
2002 uRead = 0;
2004 /* Move what the user requests, depending upon other options.
2006 while (uLeft > 0) {
2008 /* When front == rear, the DMA is not done yet.
2010 while (read_sq.front == read_sq.rear) {
2011 if (NON_BLOCKING(read_sq.open_mode)) {
2012 return uRead > 0 ? uRead : -EAGAIN;
2014 SLEEP(read_sq.action_queue);
2015 if (SIGNAL_RECEIVED)
2016 return uRead > 0 ? uRead : -EINTR;
2019 /* The amount we move is either what is left in the
2020 * current buffer or what the user wants.
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;
2039 return uRead;
2042 static int sq_open(struct inode *inode, struct file *file)
2044 int rc = 0;
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;
2058 sq.busy = 1; /* Let's play spot-the-race-condition */
2060 if (sq_allocate_buffers()) goto err_out_nobusy;
2062 sq_setup(numBufs, bufSize<<10,sound_buffers);
2063 sq.open_mode = file->f_mode;
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;
2078 rc = 0;
2080 read_sq.busy = 1;
2081 if (sq_allocate_read_buffers()) goto err_out_nobusy;
2083 read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers);
2084 read_sq.open_mode = file->f_mode;
2087 /* Start up the 4218 by:
2088 * Reset.
2089 * Enable, unreset.
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;
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.
2102 cs4218_ctl_write(cs4218_control);
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);
2114 return nonseekable_open(inode, file);
2116 err_out_nobusy:
2117 if (file->f_mode & FMODE_WRITE) {
2118 sq.busy = 0;
2119 WAKE_UP(sq.open_queue);
2121 if (file->f_mode & FMODE_READ) {
2122 read_sq.busy = 0;
2123 WAKE_UP(read_sq.open_queue);
2125 err_out:
2126 return rc;
2130 static void sq_reset(void)
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
2142 static int sq_fsync(struct file *filp, struct dentry *dentry)
2144 int rc = 0;
2146 sq.syncing = 1;
2147 sq_play(); /* there may be an incomplete frame waiting */
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;
2161 sq.syncing = 0;
2162 return rc;
2165 static int sq_release(struct inode *inode, struct file *file)
2167 int rc = 0;
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();
2175 sq_release_read_buffers();
2176 sq_release_buffers();
2178 if (file->f_mode & FMODE_READ) {
2179 read_sq.busy = 0;
2180 WAKE_UP(read_sq.open_queue);
2183 if (file->f_mode & FMODE_WRITE) {
2184 sq.busy = 0;
2185 WAKE_UP(sq.open_queue);
2188 /* Shut down the SMC.
2190 cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN);
2192 /* Shut down the codec.
2194 *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2195 eieio();
2196 *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO;
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. */
2202 return rc;
2206 static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
2207 u_long arg)
2209 u_long fmt;
2210 int data;
2211 #if 0
2212 int size, nbufs;
2213 #else
2214 int size;
2215 #endif
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);
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;
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.
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
2296 default:
2297 return mixer_ioctl(inode, file, cmd, arg);
2299 return -EINVAL;
2304 static struct file_operations sq_fops =
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,
2316 static void __init sq_init(void)
2318 sq_unit = register_sound_dsp(&sq_fops, -1);
2319 if (sq_unit < 0)
2320 return;
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);
2329 sq.busy = 0;
2330 read_sq.busy = 0;
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!
2336 sound.dsp.format = AFMT_S16_BE;
2337 sound.dsp.stereo = 1;
2338 sound.dsp.size = 16;
2340 /* set minimum rate possible without expanding */
2341 sound.dsp.speed = 8000;
2343 /* before the first open to /dev/dsp this wouldn't be set */
2344 sound.soft = sound.dsp;
2345 sound.hard = sound.dsp;
2347 sound_silence();
2351 * /dev/sndstat
2355 /* state.buf should not overflow! */
2357 static int state_open(struct inode *inode, struct file *file)
2359 char *buffer = state.buf, *mach = "", cs4218_buf[50];
2360 int len = 0;
2362 if (state.busy)
2363 return -EBUSY;
2365 state.ptr = 0;
2366 state.busy = 1;
2368 sprintf(cs4218_buf, "Crystal CS4218 on TDM, ");
2369 mach = cs4218_buf;
2371 len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
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;
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);
2417 static int state_release(struct inode *inode, struct file *file)
2419 state.busy = 0;
2420 return 0;
2424 static ssize_t state_read(struct file *file, char *buf, size_t count,
2425 loff_t *ppos)
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;
2439 static struct file_operations state_fops =
2441 .owner = THIS_MODULE,
2442 .llseek = sound_lseek,
2443 .read = state_read,
2444 .open = state_open,
2445 .release = state_release,
2449 static void __init state_init(void)
2451 state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
2452 if (state_unit < 0)
2453 return;
2454 state.busy = 0;
2458 /*** Common stuff ********************************************************/
2460 static long long sound_lseek(struct file *file, long long offset, int orig)
2462 return -ESPIPE;
2466 /*** Config & Setup **********************************************************/
2469 int __init tdm8xx_sound_init(void)
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;
2480 has_sound = 0;
2482 /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes.
2484 cp = cpmp; /* Get pointer to Communication Processor */
2485 immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
2487 /* Set all TDMa control bits to zero. This enables most features
2488 * we want.
2490 cp->cp_simode &= ~0x00000fff;
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.
2498 cp->cp_simode |= 0x80000141;
2500 /* Configure port A pins for TDMa operation.
2501 * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used.
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 */
2507 immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */
2508 immap->im_ioport.iop_pcdir &= ~0x0800;
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)
2515 cp->cp_sigmr = 0;
2516 sirp = (uint *)cp->cp_siram;
2518 *sirp = 0x018f0000; /* Receive entry */
2519 sirp += 64;
2520 *sirp = 0x018f0000; /* Tramsmit entry */
2522 /* Enable single TDMa routing.
2524 cp->cp_sigmr = 0x04;
2526 /* Initialize the SMC for transparent operation.
2528 sp = &cpmp->cp_smc[1];
2529 up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
2531 /* We need to allocate a transmit and receive buffer
2532 * descriptors from dual port ram.
2534 dp_addr = cpm_dpalloc(sizeof(cbd_t) * numReadBufs, 8);
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.
2540 bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2541 up->smc_rbase = dp_offset;
2542 rx_cur = rx_base = (cbd_t *)bdp;
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++;
2550 bdp->cbd_bufaddr = 0;
2551 bdp->cbd_datlen = 0;
2552 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
2554 /* Now, do the same for the transmit buffers.
2556 dp_offset = cpm_dpalloc(sizeof(cbd_t) * numBufs, 8);
2558 bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2559 up->smc_tbase = dp_offset;
2560 tx_cur = tx_base = (cbd_t *)bdp;
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++;
2568 bdp->cbd_bufaddr = 0;
2569 bdp->cbd_datlen = 0;
2570 bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
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.
2577 up->smc_rfcr = SCC_EB;
2578 up->smc_tfcr = SCC_EB;
2579 up->smc_mrblr = readbufSize * 1024;
2581 /* Set 16-bit reversed data, transparent mode.
2583 sp->smc_smcmr = smcr_mk_clen(15) |
2584 SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS;
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.
2591 sp->smc_smce = 0xff;
2592 sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX;
2594 /* Send the CPM an initialize command.
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);
2600 sound.mach = mach_cs4218;
2601 has_sound = 1;
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");
2611 if (!has_sound)
2612 return -ENODEV;
2614 /* Initialize the software SPI.
2616 sw_spi_init();
2618 /* Set up sound queue, /dev/audio and /dev/dsp. */
2620 /* Set default settings. */
2621 sq_init();
2623 /* Set up /dev/sndstat. */
2624 state_init();
2626 /* Set up /dev/mixer. */
2627 mixer_init();
2629 if (!sound.mach.irqinit()) {
2630 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
2631 return -ENODEV;
2633 #ifdef MODULE
2634 irq_installed = 1;
2635 #endif
2637 printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
2638 numBufs, bufSize);
2640 return 0;
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.
2650 static void
2651 cs4218_intr(void *dev_id, struct pt_regs *regs)
2653 volatile smc_t *sp;
2654 volatile cpm8xx_t *cp;
2656 sp = &cpmp->cp_smc[1];
2658 if (sp->smc_smce & SCCM_TX) {
2659 sp->smc_smce = SCCM_TX;
2660 cs4218_tdm_tx_intr((void *)sp);
2663 if (sp->smc_smce & SCCM_RX) {
2664 sp->smc_smce = SCCM_RX;
2665 cs4218_tdm_rx_intr((void *)sp);
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.
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);
2685 #define MAXARGS 8 /* Should be sufficient for now */
2687 void __init dmasound_setup(char *str, int *ints)
2689 /* check the bootstrap parameter for "dmasound=" */
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");
2715 /* Software SPI functions.
2716 * These are on Port B.
2718 #define PB_SPICLK ((uint)0x00000002)
2719 #define PB_SPIMOSI ((uint)0x00000004)
2720 #define PB_SPIMISO ((uint)0x00000008)
2722 static
2723 void sw_spi_init(void)
2725 volatile cpm8xx_t *cp;
2726 volatile uint *hcsr4;
2728 hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2729 cp = cpmp; /* Get pointer to Communication Processor */
2731 *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2733 /* Make these Port B signals general purpose I/O.
2734 * First, make sure the clock is low.
2736 cp->cp_pbdat &= ~PB_SPICLK;
2737 cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO);
2739 /* Clock and Master Output are outputs.
2741 cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI);
2743 /* Master Input.
2745 cp->cp_pbdir &= ~PB_SPIMISO;
2749 /* Write the CS4218 control word out the SPI port. While the
2750 * the control word is going out, the status word is arriving.
2752 static
2753 uint cs4218_ctl_write(uint ctlreg)
2755 uint status;
2757 sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4);
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.
2763 cs4218_control = ctlreg;
2764 return status;
2767 static
2768 void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt)
2770 int bits, i;
2771 u_char outbyte, inbyte;
2772 volatile cpm8xx_t *cp;
2773 volatile uint *hcsr4;
2775 hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2776 cp = cpmp; /* Get pointer to Communication Processor */
2778 /* The timing on the bus is pretty slow. Code inefficiency
2779 * and eieio() is our friend here :-).
2781 cp->cp_pbdat &= ~PB_SPICLK;
2782 *hcsr4 |= HIOX_CSR4_AUDSPISEL; /* Enable SPI select */
2783 eieio();
2785 /* Clock in/out the bytes. Data is valid on the falling edge
2786 * of the clock. Data is MSB first.
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;
2807 *ibuf++ = inbyte;
2810 *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2811 eieio();
2814 void cleanup_module(void)
2816 if (irq_installed) {
2817 sound_silence();
2818 #ifdef MODULE
2819 sound.mach.irqcleanup();
2820 #endif
2823 sq_release_read_buffers();
2824 sq_release_buffers();
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);
2834 module_init(tdm8xx_sound_init);
2835 module_exit(cleanup_module);