blob: 49eb2a7e65c0711a8ee2585b0ec2221210796c5a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001
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
51static int sq_unit = -1;
52static int mixer_unit = -1;
53static int state_unit = -1;
54static int irq_installed = 0;
55static char **sound_buffers = NULL;
56static char **sound_read_buffers = NULL;
57
58static 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 */
63static 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 */
70static 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
109static int beep_volume = BEEP_VOLUME;
110static int beep_playing = 0;
111static int beep_state = 0;
112static short *beep_buf;
113static 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 */
118static void (*kd_mksound)(unsigned int, unsigned int);
119
120static int catchRadius = 0;
121static int numBufs = 4, bufSize = 32;
122static int numReadBufs = 4, readbufSize = 32;
123
124
125/* TDM/Serial transmit and receive buffer descriptors.
126*/
127static volatile cbd_t *rx_base, *rx_cur, *tx_base, *tx_cur;
128
129MODULE_PARM(catchRadius, "i");
130MODULE_PARM(numBufs, "i");
131MODULE_PARM(bufSize, "i");
132MODULE_PARM(numreadBufs, "i");
133MODULE_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 */
170static uint cs4218_control;
171
172/* A place to store expanding information.
173*/
174static int expand_bal;
175static 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 */
180static void sw_spi_init(void);
181static void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt);
182static uint cs4218_ctl_write(uint ctlreg);
183
184/*** Some low level helpers **************************************************/
185
186/* 16 bit mu-law */
187
188static 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
225static 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
264static ssize_t cs4218_ct_law(const u_char *userPtr, size_t userCount,
265 u_char frame[], ssize_t *frameUsed,
266 ssize_t frameLeft);
267static ssize_t cs4218_ct_s8(const u_char *userPtr, size_t userCount,
268 u_char frame[], ssize_t *frameUsed,
269 ssize_t frameLeft);
270static ssize_t cs4218_ct_u8(const u_char *userPtr, size_t userCount,
271 u_char frame[], ssize_t *frameUsed,
272 ssize_t frameLeft);
273static ssize_t cs4218_ct_s16(const u_char *userPtr, size_t userCount,
274 u_char frame[], ssize_t *frameUsed,
275 ssize_t frameLeft);
276static ssize_t cs4218_ct_u16(const u_char *userPtr, size_t userCount,
277 u_char frame[], ssize_t *frameUsed,
278 ssize_t frameLeft);
279static ssize_t cs4218_ctx_law(const u_char *userPtr, size_t userCount,
280 u_char frame[], ssize_t *frameUsed,
281 ssize_t frameLeft);
282static ssize_t cs4218_ctx_s8(const u_char *userPtr, size_t userCount,
283 u_char frame[], ssize_t *frameUsed,
284 ssize_t frameLeft);
285static ssize_t cs4218_ctx_u8(const u_char *userPtr, size_t userCount,
286 u_char frame[], ssize_t *frameUsed,
287 ssize_t frameLeft);
288static ssize_t cs4218_ctx_s16(const u_char *userPtr, size_t userCount,
289 u_char frame[], ssize_t *frameUsed,
290 ssize_t frameLeft);
291static ssize_t cs4218_ctx_u16(const u_char *userPtr, size_t userCount,
292 u_char frame[], ssize_t *frameUsed,
293 ssize_t frameLeft);
294static ssize_t cs4218_ct_s16_read(const u_char *userPtr, size_t userCount,
295 u_char frame[], ssize_t *frameUsed,
296 ssize_t frameLeft);
297static 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
304struct 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
319static struct cs_sound_settings sound;
320
Al Viro1ef64e62005-10-21 03:22:18 -0400321static void *CS_Alloc(unsigned int size, gfp_t flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322static void CS_Free(void *ptr, unsigned int size);
323static int CS_IrqInit(void);
324#ifdef MODULE
325static void CS_IrqCleanup(void);
326#endif /* MODULE */
327static void CS_Silence(void);
328static void CS_Init(void);
329static void CS_Play(void);
330static void CS_Record(void);
331static int CS_SetFormat(int format);
332static int CS_SetVolume(int volume);
333static void cs4218_tdm_tx_intr(void *devid);
334static void cs4218_tdm_rx_intr(void *devid);
335static void cs4218_intr(void *devid, struct pt_regs *regs);
336static int cs_get_volume(uint reg);
337static int cs_volume_setter(int volume, int mute);
338static int cs_get_gain(uint reg);
339static int cs_set_gain(int gain);
340static void cs_mksound(unsigned int hz, unsigned int ticks);
341static void cs_nosound(unsigned long xx);
342
343/*** Mid level stuff *********************************************************/
344
345
346static void sound_silence(void);
347static void sound_init(void);
348static int sound_set_format(int format);
349static int sound_set_speed(int speed);
350static int sound_set_stereo(int stereo);
351static int sound_set_volume(int volume);
352
353static ssize_t sound_copy_translate(const u_char *userPtr,
354 size_t userCount,
355 u_char frame[], ssize_t *frameUsed,
356 ssize_t frameLeft);
357static 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
367struct sound_mixer {
368 int busy;
369 int modify_counter;
370};
371
372static struct sound_mixer mixer;
373
374static struct sound_queue sq;
375static 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
387struct sound_state {
388 int busy;
389 char buf[512];
390 int len, ptr;
391};
392
393static struct sound_state state;
394
395/*** Common stuff ********************************************************/
396
397static long long sound_lseek(struct file *file, long long offset, int orig);
398
399/*** Config & Setup **********************************************************/
400
401void 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
430static 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
462static 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
493static 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 */
529static 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
558static 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
590static 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
637static 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
682static 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
727static 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
771static 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
816static 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
849static 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
882static 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
911static 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
944static 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
949static 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
954static 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
Al Viro1ef64e62005-10-21 03:22:18 -0400962static void *CS_Alloc(unsigned int size, gfp_t flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963{
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
975static 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
988static int __init CS_IrqInit(void)
989{
990 cpm_install_handler(CPMVEC_SMC2, cs4218_intr, NULL);
991 return 1;
992}
993
994#ifdef MODULE
995static 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
Jesper Juhlb2325fe2005-11-07 01:01:35 -08001016 kfree(beep_buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 kd_mksound = orig_mksound;
1018}
1019#endif /* MODULE */
1020
1021static void CS_Silence(void)
1022{
1023 volatile smc_t *sp;
1024
1025 /* Disable transmitter.
1026 */
1027 sp = &cpmp->cp_smc[1];
1028 sp->smc_smcmr &= ~SMCMR_TEN;
1029}
1030
1031/* Frequencies depend upon external oscillator. There are two
1032 * choices, 12.288 and 11.2896 MHz. The RPCG audio supports both through
1033 * and external control register selection bit.
1034 */
1035static int cs4218_freqs[] = {
1036 /* 12.288 11.2896 */
1037 48000, 44100,
1038 32000, 29400,
1039 24000, 22050,
1040 19200, 17640,
1041 16000, 14700,
1042 12000, 11025,
1043 9600, 8820,
1044 8000, 7350
1045};
1046
1047static void CS_Init(void)
1048{
1049 int i, tolerance;
1050
1051 switch (sound.soft.format) {
1052 case AFMT_S16_LE:
1053 case AFMT_U16_LE:
1054 sound.hard.format = AFMT_S16_LE;
1055 break;
1056 default:
1057 sound.hard.format = AFMT_S16_BE;
1058 break;
1059 }
1060 sound.hard.stereo = 1;
1061 sound.hard.size = 16;
1062
1063 /*
1064 * If we have a sample rate which is within catchRadius percent
1065 * of the requested value, we don't have to expand the samples.
1066 * Otherwise choose the next higher rate.
1067 */
1068 i = (sizeof(cs4218_freqs) / sizeof(int));
1069 do {
1070 tolerance = catchRadius * cs4218_freqs[--i] / 100;
1071 } while (sound.soft.speed > cs4218_freqs[i] + tolerance && i > 0);
1072 if (sound.soft.speed >= cs4218_freqs[i] - tolerance)
1073 sound.trans_write = &transCSNormal;
1074 else
1075 sound.trans_write = &transCSExpand;
1076 sound.trans_read = &transCSNormalRead;
1077 sound.hard.speed = cs4218_freqs[i];
1078 cs4218_rate_index = i;
1079
1080 /* The CS4218 has seven selectable clock dividers for the sample
1081 * clock. The HIOX then provides one of two external rates.
1082 * An even numbered frequency table index uses the high external
1083 * clock rate.
1084 */
1085 *(uint *)HIOX_CSR4_ADDR &= ~(HIOX_CSR4_AUDCLKHI | HIOX_CSR4_AUDCLKSEL);
1086 if ((i & 1) == 0)
1087 *(uint *)HIOX_CSR4_ADDR |= HIOX_CSR4_AUDCLKHI;
1088 i >>= 1;
1089 *(uint *)HIOX_CSR4_ADDR |= (i & HIOX_CSR4_AUDCLKSEL);
1090
1091 expand_bal = -sound.soft.speed;
1092}
1093
1094static int CS_SetFormat(int format)
1095{
1096 int size;
1097
1098 switch (format) {
1099 case AFMT_QUERY:
1100 return sound.soft.format;
1101 case AFMT_MU_LAW:
1102 case AFMT_A_LAW:
1103 case AFMT_U8:
1104 case AFMT_S8:
1105 size = 8;
1106 break;
1107 case AFMT_S16_BE:
1108 case AFMT_U16_BE:
1109 case AFMT_S16_LE:
1110 case AFMT_U16_LE:
1111 size = 16;
1112 break;
1113 default: /* :-) */
1114 printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n",
1115 format);
1116 size = 8;
1117 format = AFMT_U8;
1118 }
1119
1120 sound.soft.format = format;
1121 sound.soft.size = size;
1122 if (sound.minDev == SND_DEV_DSP) {
1123 sound.dsp.format = format;
1124 sound.dsp.size = size;
1125 }
1126
1127 CS_Init();
1128
1129 return format;
1130}
1131
1132/* Volume is the amount of attenuation we tell the codec to impose
1133 * on the outputs. There are 32 levels, with 0 the "loudest".
1134 */
1135#define CS_VOLUME_TO_MASK(x) (31 - ((((x) - 1) * 31) / 99))
1136#define CS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 31))
1137
1138static int cs_get_volume(uint reg)
1139{
1140 int volume;
1141
1142 volume = CS_MASK_TO_VOLUME(CS_LATTEN_GET(reg));
1143 volume |= CS_MASK_TO_VOLUME(CS_RATTEN_GET(reg)) << 8;
1144 return volume;
1145}
1146
1147static int cs_volume_setter(int volume, int mute)
1148{
1149 uint tempctl;
1150
1151 if (mute && volume == 0) {
1152 tempctl = cs4218_control | CS_MUTE;
1153 } else {
1154 tempctl = cs4218_control & ~CS_MUTE;
1155 tempctl = tempctl & ~(CS_LATTEN | CS_RATTEN);
1156 tempctl |= CS_LATTEN_SET(CS_VOLUME_TO_MASK(volume & 0xff));
1157 tempctl |= CS_RATTEN_SET(CS_VOLUME_TO_MASK((volume >> 8) & 0xff));
1158 volume = cs_get_volume(tempctl);
1159 }
1160 if (tempctl != cs4218_control) {
1161 cs4218_ctl_write(tempctl);
1162 }
1163 return volume;
1164}
1165
1166
1167/* Gain has 16 steps from 0 to 15. These are in 1.5dB increments from
1168 * 0 (no gain) to 22.5 dB.
1169 */
1170#define CS_RECLEVEL_TO_GAIN(v) \
1171 ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1172#define CS_GAIN_TO_RECLEVEL(v) (((v) * 20 + 2) / 3)
1173
1174static int cs_get_gain(uint reg)
1175{
1176 int gain;
1177
1178 gain = CS_GAIN_TO_RECLEVEL(CS_LGAIN_GET(reg));
1179 gain |= CS_GAIN_TO_RECLEVEL(CS_RGAIN_GET(reg)) << 8;
1180 return gain;
1181}
1182
1183static int cs_set_gain(int gain)
1184{
1185 uint tempctl;
1186
1187 tempctl = cs4218_control & ~(CS_LGAIN | CS_RGAIN);
1188 tempctl |= CS_LGAIN_SET(CS_RECLEVEL_TO_GAIN(gain & 0xff));
1189 tempctl |= CS_RGAIN_SET(CS_RECLEVEL_TO_GAIN((gain >> 8) & 0xff));
1190 gain = cs_get_gain(tempctl);
1191
1192 if (tempctl != cs4218_control) {
1193 cs4218_ctl_write(tempctl);
1194 }
1195 return gain;
1196}
1197
1198static int CS_SetVolume(int volume)
1199{
1200 return cs_volume_setter(volume, CS_MUTE);
1201}
1202
1203static void CS_Play(void)
1204{
1205 int i, count;
1206 unsigned long flags;
1207 volatile cbd_t *bdp;
1208 volatile cpm8xx_t *cp;
1209
1210 /* Protect buffer */
1211 spin_lock_irqsave(&cs4218_lock, flags);
1212#if 0
1213 if (awacs_beep_state) {
1214 /* sound takes precedence over beeps */
1215 out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
1216 out_le32(&awacs->control,
1217 (in_le32(&awacs->control) & ~0x1f00)
1218 | (awacs_rate_index << 8));
1219 out_le32(&awacs->byteswap, sound.hard.format != AFMT_S16_BE);
1220 out_le32(&awacs_txdma->cmdptr, virt_to_bus(&(awacs_tx_cmds[(sq.front+sq.active) % sq.max_count])));
1221
1222 beep_playing = 0;
1223 awacs_beep_state = 0;
1224 }
1225#endif
1226 i = sq.front + sq.active;
1227 if (i >= sq.max_count)
1228 i -= sq.max_count;
1229 while (sq.active < 2 && sq.active < sq.count) {
1230 count = (sq.count == sq.active + 1)?sq.rear_size:sq.block_size;
1231 if (count < sq.block_size && !sq.syncing)
1232 /* last block not yet filled, and we're not syncing. */
1233 break;
1234
1235 bdp = &tx_base[i];
1236 bdp->cbd_datlen = count;
1237
1238 flush_dcache_range((ulong)sound_buffers[i],
1239 (ulong)(sound_buffers[i] + count));
1240
1241 if (++i >= sq.max_count)
1242 i = 0;
1243
1244 if (sq.active == 0) {
1245 /* The SMC does not load its fifo until the first
1246 * TDM frame pulse, so the transmit data gets shifted
1247 * by one word. To compensate for this, we incorrectly
1248 * transmit the first buffer and shorten it by one
1249 * word. Subsequent buffers are then aligned properly.
1250 */
1251 bdp->cbd_datlen -= 2;
1252
1253 /* Start up the SMC Transmitter.
1254 */
1255 cp = cpmp;
1256 cp->cp_smc[1].smc_smcmr |= SMCMR_TEN;
1257 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
1258 CPM_CR_RESTART_TX) | CPM_CR_FLG;
1259 while (cp->cp_cpcr & CPM_CR_FLG);
1260 }
1261
1262 /* Buffer is ready now.
1263 */
1264 bdp->cbd_sc |= BD_SC_READY;
1265
1266 ++sq.active;
1267 }
1268 spin_unlock_irqrestore(&cs4218_lock, flags);
1269}
1270
1271
1272static void CS_Record(void)
1273{
1274 unsigned long flags;
1275 volatile smc_t *sp;
1276
1277 if (read_sq.active)
1278 return;
1279
1280 /* Protect buffer */
1281 spin_lock_irqsave(&cs4218_lock, flags);
1282
1283 /* This is all we have to do......Just start it up.
1284 */
1285 sp = &cpmp->cp_smc[1];
1286 sp->smc_smcmr |= SMCMR_REN;
1287
1288 read_sq.active = 1;
1289
1290 spin_unlock_irqrestore(&cs4218_lock, flags);
1291}
1292
1293
1294static void
1295cs4218_tdm_tx_intr(void *devid)
1296{
1297 int i = sq.front;
1298 volatile cbd_t *bdp;
1299
1300 while (sq.active > 0) {
1301 bdp = &tx_base[i];
1302 if (bdp->cbd_sc & BD_SC_READY)
1303 break; /* this frame is still going */
1304 --sq.count;
1305 --sq.active;
1306 if (++i >= sq.max_count)
1307 i = 0;
1308 }
1309 if (i != sq.front)
1310 WAKE_UP(sq.action_queue);
1311 sq.front = i;
1312
1313 CS_Play();
1314
1315 if (!sq.active)
1316 WAKE_UP(sq.sync_queue);
1317}
1318
1319
1320static void
1321cs4218_tdm_rx_intr(void *devid)
1322{
1323
1324 /* We want to blow 'em off when shutting down.
1325 */
1326 if (read_sq.active == 0)
1327 return;
1328
1329 /* Check multiple buffers in case we were held off from
1330 * interrupt processing for a long time. Geeze, I really hope
1331 * this doesn't happen.
1332 */
1333 while ((rx_base[read_sq.rear].cbd_sc & BD_SC_EMPTY) == 0) {
1334
1335 /* Invalidate the data cache range for this buffer.
1336 */
1337 invalidate_dcache_range(
1338 (uint)(sound_read_buffers[read_sq.rear]),
1339 (uint)(sound_read_buffers[read_sq.rear] + read_sq.block_size));
1340
1341 /* Make buffer available again and move on.
1342 */
1343 rx_base[read_sq.rear].cbd_sc |= BD_SC_EMPTY;
1344 read_sq.rear++;
1345
1346 /* Wrap the buffer ring.
1347 */
1348 if (read_sq.rear >= read_sq.max_active)
1349 read_sq.rear = 0;
1350
1351 /* If we have caught up to the front buffer, bump it.
1352 * This will cause weird (but not fatal) results if the
1353 * read loop is currently using this buffer. The user is
1354 * behind in this case anyway, so weird things are going
1355 * to happen.
1356 */
1357 if (read_sq.rear == read_sq.front) {
1358 read_sq.front++;
1359 if (read_sq.front >= read_sq.max_active)
1360 read_sq.front = 0;
1361 }
1362 }
1363
1364 WAKE_UP(read_sq.action_queue);
1365}
1366
1367static void cs_nosound(unsigned long xx)
1368{
1369 unsigned long flags;
1370
1371 /* not sure if this is needed, since hardware command is #if 0'd */
1372 spin_lock_irqsave(&cs4218_lock, flags);
1373 if (beep_playing) {
1374#if 0
1375 st_le16(&beep_dbdma_cmd->command, DBDMA_STOP);
1376#endif
1377 beep_playing = 0;
1378 }
1379 spin_unlock_irqrestore(&cs4218_lock, flags);
1380}
1381
Ingo Molnar8d06afa2005-09-09 13:10:40 -07001382static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383};
1384
1385static void cs_mksound(unsigned int hz, unsigned int ticks)
1386{
1387 unsigned long flags;
1388 int beep_speed = BEEP_SPEED;
1389 int srate = cs4218_freqs[beep_speed];
1390 int period, ncycles, nsamples;
1391 int i, j, f;
1392 short *p;
1393 static int beep_hz_cache;
1394 static int beep_nsamples_cache;
1395 static int beep_volume_cache;
1396
1397 if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) {
1398#if 1
1399 /* this is a hack for broken X server code */
1400 hz = 750;
1401 ticks = 12;
1402#else
1403 /* cancel beep currently playing */
1404 awacs_nosound(0);
1405 return;
1406#endif
1407 }
1408 /* lock while modifying beep_timer */
1409 spin_lock_irqsave(&cs4218_lock, flags);
1410 del_timer(&beep_timer);
1411 if (ticks) {
1412 beep_timer.expires = jiffies + ticks;
1413 add_timer(&beep_timer);
1414 }
1415 if (beep_playing || sq.active || beep_buf == NULL) {
1416 spin_unlock_irqrestore(&cs4218_lock, flags);
1417 return; /* too hard, sorry :-( */
1418 }
1419 beep_playing = 1;
1420#if 0
1421 st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS);
1422#endif
1423 spin_unlock_irqrestore(&cs4218_lock, flags);
1424
1425 if (hz == beep_hz_cache && beep_volume == beep_volume_cache) {
1426 nsamples = beep_nsamples_cache;
1427 } else {
1428 period = srate * 256 / hz; /* fixed point */
1429 ncycles = BEEP_BUFLEN * 256 / period;
1430 nsamples = (period * ncycles) >> 8;
1431 f = ncycles * 65536 / nsamples;
1432 j = 0;
1433 p = beep_buf;
1434 for (i = 0; i < nsamples; ++i, p += 2) {
1435 p[0] = p[1] = beep_wform[j >> 8] * beep_volume;
1436 j = (j + f) & 0xffff;
1437 }
1438 beep_hz_cache = hz;
1439 beep_volume_cache = beep_volume;
1440 beep_nsamples_cache = nsamples;
1441 }
1442
1443#if 0
1444 st_le16(&beep_dbdma_cmd->req_count, nsamples*4);
1445 st_le16(&beep_dbdma_cmd->xfer_status, 0);
1446 st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd));
1447 st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf));
1448 awacs_beep_state = 1;
1449
1450 spin_lock_irqsave(&cs4218_lock, flags);
1451 if (beep_playing) { /* i.e. haven't been terminated already */
1452 out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
1453 out_le32(&awacs->control,
1454 (in_le32(&awacs->control) & ~0x1f00)
1455 | (beep_speed << 8));
1456 out_le32(&awacs->byteswap, 0);
1457 out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
1458 out_le32(&awacs_txdma->control, RUN | (RUN << 16));
1459 }
1460 spin_unlock_irqrestore(&cs4218_lock, flags);
1461#endif
1462}
1463
1464static MACHINE mach_cs4218 = {
1465 .owner = THIS_MODULE,
1466 .name = "HIOX CS4218",
1467 .name2 = "Built-in Sound",
1468 .dma_alloc = CS_Alloc,
1469 .dma_free = CS_Free,
1470 .irqinit = CS_IrqInit,
1471#ifdef MODULE
1472 .irqcleanup = CS_IrqCleanup,
1473#endif /* MODULE */
1474 .init = CS_Init,
1475 .silence = CS_Silence,
1476 .setFormat = CS_SetFormat,
1477 .setVolume = CS_SetVolume,
1478 .play = CS_Play
1479};
1480
1481
1482/*** Mid level stuff *********************************************************/
1483
1484
1485static void sound_silence(void)
1486{
1487 /* update hardware settings one more */
1488 (*sound.mach.init)();
1489
1490 (*sound.mach.silence)();
1491}
1492
1493
1494static void sound_init(void)
1495{
1496 (*sound.mach.init)();
1497}
1498
1499
1500static int sound_set_format(int format)
1501{
1502 return(*sound.mach.setFormat)(format);
1503}
1504
1505
1506static int sound_set_speed(int speed)
1507{
1508 if (speed < 0)
1509 return(sound.soft.speed);
1510
1511 sound.soft.speed = speed;
1512 (*sound.mach.init)();
1513 if (sound.minDev == SND_DEV_DSP)
1514 sound.dsp.speed = sound.soft.speed;
1515
1516 return(sound.soft.speed);
1517}
1518
1519
1520static int sound_set_stereo(int stereo)
1521{
1522 if (stereo < 0)
1523 return(sound.soft.stereo);
1524
1525 stereo = !!stereo; /* should be 0 or 1 now */
1526
1527 sound.soft.stereo = stereo;
1528 if (sound.minDev == SND_DEV_DSP)
1529 sound.dsp.stereo = stereo;
1530 (*sound.mach.init)();
1531
1532 return(stereo);
1533}
1534
1535
1536static int sound_set_volume(int volume)
1537{
1538 return(*sound.mach.setVolume)(volume);
1539}
1540
1541static ssize_t sound_copy_translate(const u_char *userPtr,
1542 size_t userCount,
1543 u_char frame[], ssize_t *frameUsed,
1544 ssize_t frameLeft)
1545{
1546 ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1547
1548 switch (sound.soft.format) {
1549 case AFMT_MU_LAW:
1550 ct_func = sound.trans_write->ct_ulaw;
1551 break;
1552 case AFMT_A_LAW:
1553 ct_func = sound.trans_write->ct_alaw;
1554 break;
1555 case AFMT_S8:
1556 ct_func = sound.trans_write->ct_s8;
1557 break;
1558 case AFMT_U8:
1559 ct_func = sound.trans_write->ct_u8;
1560 break;
1561 case AFMT_S16_BE:
1562 ct_func = sound.trans_write->ct_s16be;
1563 break;
1564 case AFMT_U16_BE:
1565 ct_func = sound.trans_write->ct_u16be;
1566 break;
1567 case AFMT_S16_LE:
1568 ct_func = sound.trans_write->ct_s16le;
1569 break;
1570 case AFMT_U16_LE:
1571 ct_func = sound.trans_write->ct_u16le;
1572 break;
1573 }
1574 if (ct_func)
1575 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1576 else
1577 return 0;
1578}
1579
1580static ssize_t sound_copy_translate_read(const u_char *userPtr,
1581 size_t userCount,
1582 u_char frame[], ssize_t *frameUsed,
1583 ssize_t frameLeft)
1584{
1585 ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
1586
1587 switch (sound.soft.format) {
1588 case AFMT_MU_LAW:
1589 ct_func = sound.trans_read->ct_ulaw;
1590 break;
1591 case AFMT_A_LAW:
1592 ct_func = sound.trans_read->ct_alaw;
1593 break;
1594 case AFMT_S8:
1595 ct_func = sound.trans_read->ct_s8;
1596 break;
1597 case AFMT_U8:
1598 ct_func = sound.trans_read->ct_u8;
1599 break;
1600 case AFMT_S16_BE:
1601 ct_func = sound.trans_read->ct_s16be;
1602 break;
1603 case AFMT_U16_BE:
1604 ct_func = sound.trans_read->ct_u16be;
1605 break;
1606 case AFMT_S16_LE:
1607 ct_func = sound.trans_read->ct_s16le;
1608 break;
1609 case AFMT_U16_LE:
1610 ct_func = sound.trans_read->ct_u16le;
1611 break;
1612 }
1613 if (ct_func)
1614 return ct_func(userPtr, userCount, frame, frameUsed, frameLeft);
1615 else
1616 return 0;
1617}
1618
1619
1620/*
1621 * /dev/mixer abstraction
1622 */
1623
1624static int mixer_open(struct inode *inode, struct file *file)
1625{
1626 mixer.busy = 1;
1627 return nonseekable_open(inode, file);
1628}
1629
1630
1631static int mixer_release(struct inode *inode, struct file *file)
1632{
1633 mixer.busy = 0;
1634 return 0;
1635}
1636
1637
1638static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
1639 u_long arg)
1640{
1641 int data;
1642 uint tmpcs;
1643
1644 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
1645 mixer.modify_counter++;
1646 if (cmd == OSS_GETVERSION)
1647 return IOCTL_OUT(arg, SOUND_VERSION);
1648 switch (cmd) {
1649 case SOUND_MIXER_INFO: {
1650 mixer_info info;
1651 strlcpy(info.id, "CS4218_TDM", sizeof(info.id));
1652 strlcpy(info.name, "CS4218_TDM", sizeof(info.name));
1653 info.name[sizeof(info.name)-1] = 0;
1654 info.modify_counter = mixer.modify_counter;
1655 if (copy_to_user((int *)arg, &info, sizeof(info)))
1656 return -EFAULT;
1657 return 0;
1658 }
1659 case SOUND_MIXER_READ_DEVMASK:
1660 data = SOUND_MASK_VOLUME | SOUND_MASK_LINE
1661 | SOUND_MASK_MIC | SOUND_MASK_RECLEV
1662 | SOUND_MASK_ALTPCM;
1663 return IOCTL_OUT(arg, data);
1664 case SOUND_MIXER_READ_RECMASK:
1665 data = SOUND_MASK_LINE | SOUND_MASK_MIC;
1666 return IOCTL_OUT(arg, data);
1667 case SOUND_MIXER_READ_RECSRC:
1668 if (cs4218_control & CS_DO1)
1669 data = SOUND_MASK_LINE;
1670 else
1671 data = SOUND_MASK_MIC;
1672 return IOCTL_OUT(arg, data);
1673 case SOUND_MIXER_WRITE_RECSRC:
1674 IOCTL_IN(arg, data);
1675 data &= (SOUND_MASK_LINE | SOUND_MASK_MIC);
1676 if (data & SOUND_MASK_LINE)
1677 tmpcs = cs4218_control |
1678 (CS_ISL | CS_ISR | CS_DO1);
1679 if (data & SOUND_MASK_MIC)
1680 tmpcs = cs4218_control &
1681 ~(CS_ISL | CS_ISR | CS_DO1);
1682 if (tmpcs != cs4218_control)
1683 cs4218_ctl_write(tmpcs);
1684 return IOCTL_OUT(arg, data);
1685 case SOUND_MIXER_READ_STEREODEVS:
1686 data = SOUND_MASK_VOLUME | SOUND_MASK_RECLEV;
1687 return IOCTL_OUT(arg, data);
1688 case SOUND_MIXER_READ_CAPS:
1689 return IOCTL_OUT(arg, 0);
1690 case SOUND_MIXER_READ_VOLUME:
1691 data = (cs4218_control & CS_MUTE)? 0:
1692 cs_get_volume(cs4218_control);
1693 return IOCTL_OUT(arg, data);
1694 case SOUND_MIXER_WRITE_VOLUME:
1695 IOCTL_IN(arg, data);
1696 return IOCTL_OUT(arg, sound_set_volume(data));
1697 case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
1698 IOCTL_IN(arg, data);
1699 beep_volume = data & 0xff;
1700 /* fall through */
1701 case SOUND_MIXER_READ_ALTPCM:
1702 return IOCTL_OUT(arg, beep_volume);
1703 case SOUND_MIXER_WRITE_RECLEV:
1704 IOCTL_IN(arg, data);
1705 data = cs_set_gain(data);
1706 return IOCTL_OUT(arg, data);
1707 case SOUND_MIXER_READ_RECLEV:
1708 data = cs_get_gain(cs4218_control);
1709 return IOCTL_OUT(arg, data);
1710 }
1711
1712 return -EINVAL;
1713}
1714
1715
1716static struct file_operations mixer_fops =
1717{
1718 .owner = THIS_MODULE,
1719 .llseek = sound_lseek,
1720 .ioctl = mixer_ioctl,
1721 .open = mixer_open,
1722 .release = mixer_release,
1723};
1724
1725
1726static void __init mixer_init(void)
1727{
1728 mixer_unit = register_sound_mixer(&mixer_fops, -1);
1729 if (mixer_unit < 0)
1730 return;
1731
1732 mixer.busy = 0;
1733 sound.treble = 0;
1734 sound.bass = 0;
1735
1736 /* Set Line input, no gain, no attenuation.
1737 */
1738 cs4218_control = CS_ISL | CS_ISR | CS_DO1;
1739 cs4218_control |= CS_LGAIN_SET(0) | CS_RGAIN_SET(0);
1740 cs4218_control |= CS_LATTEN_SET(0) | CS_RATTEN_SET(0);
1741 cs4218_ctl_write(cs4218_control);
1742}
1743
1744
1745/*
1746 * Sound queue stuff, the heart of the driver
1747 */
1748
1749
1750static int sq_allocate_buffers(void)
1751{
1752 int i;
1753
1754 if (sound_buffers)
1755 return 0;
1756 sound_buffers = kmalloc (numBufs * sizeof(char *), GFP_KERNEL);
1757 if (!sound_buffers)
1758 return -ENOMEM;
1759 for (i = 0; i < numBufs; i++) {
1760 sound_buffers[i] = sound.mach.dma_alloc (bufSize << 10, GFP_KERNEL);
1761 if (!sound_buffers[i]) {
1762 while (i--)
1763 sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1764 kfree (sound_buffers);
1765 sound_buffers = 0;
1766 return -ENOMEM;
1767 }
1768 }
1769 return 0;
1770}
1771
1772
1773static void sq_release_buffers(void)
1774{
1775 int i;
1776
1777 if (sound_buffers) {
1778 for (i = 0; i < numBufs; i++)
1779 sound.mach.dma_free (sound_buffers[i], bufSize << 10);
1780 kfree (sound_buffers);
1781 sound_buffers = 0;
1782 }
1783}
1784
1785
1786static int sq_allocate_read_buffers(void)
1787{
1788 int i;
1789
1790 if (sound_read_buffers)
1791 return 0;
1792 sound_read_buffers = kmalloc(numReadBufs * sizeof(char *), GFP_KERNEL);
1793 if (!sound_read_buffers)
1794 return -ENOMEM;
1795 for (i = 0; i < numBufs; i++) {
1796 sound_read_buffers[i] = sound.mach.dma_alloc (readbufSize<<10,
1797 GFP_KERNEL);
1798 if (!sound_read_buffers[i]) {
1799 while (i--)
1800 sound.mach.dma_free (sound_read_buffers[i],
1801 readbufSize << 10);
1802 kfree (sound_read_buffers);
1803 sound_read_buffers = 0;
1804 return -ENOMEM;
1805 }
1806 }
1807 return 0;
1808}
1809
1810static void sq_release_read_buffers(void)
1811{
1812 int i;
1813
1814 if (sound_read_buffers) {
1815 cpmp->cp_smc[1].smc_smcmr &= ~SMCMR_REN;
1816 for (i = 0; i < numReadBufs; i++)
1817 sound.mach.dma_free (sound_read_buffers[i],
1818 bufSize << 10);
1819 kfree (sound_read_buffers);
1820 sound_read_buffers = 0;
1821 }
1822}
1823
1824
1825static void sq_setup(int numBufs, int bufSize, char **write_buffers)
1826{
1827 int i;
1828 volatile cbd_t *bdp;
1829 volatile cpm8xx_t *cp;
1830 volatile smc_t *sp;
1831
1832 /* Make sure the SMC transmit is shut down.
1833 */
1834 cp = cpmp;
1835 sp = &cpmp->cp_smc[1];
1836 sp->smc_smcmr &= ~SMCMR_TEN;
1837
1838 sq.max_count = numBufs;
1839 sq.max_active = numBufs;
1840 sq.block_size = bufSize;
1841 sq.buffers = write_buffers;
1842
1843 sq.front = sq.count = 0;
1844 sq.rear = -1;
1845 sq.syncing = 0;
1846 sq.active = 0;
1847
1848 bdp = tx_base;
1849 for (i=0; i<numBufs; i++) {
1850 bdp->cbd_bufaddr = virt_to_bus(write_buffers[i]);
1851 bdp++;
1852 }
1853
1854 /* This causes the SMC to sync up with the first buffer again.
1855 */
1856 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_TX) | CPM_CR_FLG;
1857 while (cp->cp_cpcr & CPM_CR_FLG);
1858}
1859
1860static void read_sq_setup(int numBufs, int bufSize, char **read_buffers)
1861{
1862 int i;
1863 volatile cbd_t *bdp;
1864 volatile cpm8xx_t *cp;
1865 volatile smc_t *sp;
1866
1867 /* Make sure the SMC receive is shut down.
1868 */
1869 cp = cpmp;
1870 sp = &cpmp->cp_smc[1];
1871 sp->smc_smcmr &= ~SMCMR_REN;
1872
1873 read_sq.max_count = numBufs;
1874 read_sq.max_active = numBufs;
1875 read_sq.block_size = bufSize;
1876 read_sq.buffers = read_buffers;
1877
1878 read_sq.front = read_sq.count = 0;
1879 read_sq.rear = 0;
1880 read_sq.rear_size = 0;
1881 read_sq.syncing = 0;
1882 read_sq.active = 0;
1883
1884 bdp = rx_base;
1885 for (i=0; i<numReadBufs; i++) {
1886 bdp->cbd_bufaddr = virt_to_bus(read_buffers[i]);
1887 bdp->cbd_datlen = read_sq.block_size;
1888 bdp++;
1889 }
1890
1891 /* This causes the SMC to sync up with the first buffer again.
1892 */
1893 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2, CPM_CR_INIT_RX) | CPM_CR_FLG;
1894 while (cp->cp_cpcr & CPM_CR_FLG);
1895}
1896
1897
1898static void sq_play(void)
1899{
1900 (*sound.mach.play)();
1901}
1902
1903
1904/* ++TeSche: radically changed this one too */
1905
1906static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
1907 loff_t *ppos)
1908{
1909 ssize_t uWritten = 0;
1910 u_char *dest;
1911 ssize_t uUsed, bUsed, bLeft;
1912
1913 /* ++TeSche: Is something like this necessary?
1914 * Hey, that's an honest question! Or does any other part of the
1915 * filesystem already checks this situation? I really don't know.
1916 */
1917 if (uLeft == 0)
1918 return 0;
1919
1920 /* The interrupt doesn't start to play the last, incomplete frame.
1921 * Thus we can append to it without disabling the interrupts! (Note
1922 * also that sq.rear isn't affected by the interrupt.)
1923 */
1924
1925 if (sq.count > 0 && (bLeft = sq.block_size-sq.rear_size) > 0) {
1926 dest = sq_block_address(sq.rear);
1927 bUsed = sq.rear_size;
1928 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1929 if (uUsed <= 0)
1930 return uUsed;
1931 src += uUsed;
1932 uWritten += uUsed;
1933 uLeft -= uUsed;
1934 sq.rear_size = bUsed;
1935 }
1936
1937 do {
1938 while (sq.count == sq.max_active) {
1939 sq_play();
1940 if (NON_BLOCKING(sq.open_mode))
1941 return uWritten > 0 ? uWritten : -EAGAIN;
1942 SLEEP(sq.action_queue);
1943 if (SIGNAL_RECEIVED)
1944 return uWritten > 0 ? uWritten : -EINTR;
1945 }
1946
1947 /* Here, we can avoid disabling the interrupt by first
1948 * copying and translating the data, and then updating
1949 * the sq variables. Until this is done, the interrupt
1950 * won't see the new frame and we can work on it
1951 * undisturbed.
1952 */
1953
1954 dest = sq_block_address((sq.rear+1) % sq.max_count);
1955 bUsed = 0;
1956 bLeft = sq.block_size;
1957 uUsed = sound_copy_translate(src, uLeft, dest, &bUsed, bLeft);
1958 if (uUsed <= 0)
1959 break;
1960 src += uUsed;
1961 uWritten += uUsed;
1962 uLeft -= uUsed;
1963 if (bUsed) {
1964 sq.rear = (sq.rear+1) % sq.max_count;
1965 sq.rear_size = bUsed;
1966 sq.count++;
1967 }
1968 } while (bUsed); /* uUsed may have been 0 */
1969
1970 sq_play();
1971
1972 return uUsed < 0? uUsed: uWritten;
1973}
1974
1975
1976/***********/
1977
1978/* Here is how the values are used for reading.
1979 * The value 'active' simply indicates the DMA is running. This is
1980 * done so the driver semantics are DMA starts when the first read is
1981 * posted. The value 'front' indicates the buffer we should next
1982 * send to the user. The value 'rear' indicates the buffer the DMA is
1983 * currently filling. When 'front' == 'rear' the buffer "ring" is
1984 * empty (we always have an empty available). The 'rear_size' is used
1985 * to track partial offsets into the current buffer. Right now, I just keep
1986 * The DMA running. If the reader can't keep up, the interrupt tosses
1987 * the oldest buffer. We could also shut down the DMA in this case.
1988 */
1989static ssize_t sq_read(struct file *file, char *dst, size_t uLeft,
1990 loff_t *ppos)
1991{
1992
1993 ssize_t uRead, bLeft, bUsed, uUsed;
1994
1995 if (uLeft == 0)
1996 return 0;
1997
1998 if (!read_sq.active)
1999 CS_Record(); /* Kick off the record process. */
2000
2001 uRead = 0;
2002
2003 /* Move what the user requests, depending upon other options.
2004 */
2005 while (uLeft > 0) {
2006
2007 /* When front == rear, the DMA is not done yet.
2008 */
2009 while (read_sq.front == read_sq.rear) {
2010 if (NON_BLOCKING(read_sq.open_mode)) {
2011 return uRead > 0 ? uRead : -EAGAIN;
2012 }
2013 SLEEP(read_sq.action_queue);
2014 if (SIGNAL_RECEIVED)
2015 return uRead > 0 ? uRead : -EINTR;
2016 }
2017
2018 /* The amount we move is either what is left in the
2019 * current buffer or what the user wants.
2020 */
2021 bLeft = read_sq.block_size - read_sq.rear_size;
2022 bUsed = read_sq.rear_size;
2023 uUsed = sound_copy_translate_read(dst, uLeft,
2024 read_sq.buffers[read_sq.front], &bUsed, bLeft);
2025 if (uUsed <= 0)
2026 return uUsed;
2027 dst += uUsed;
2028 uRead += uUsed;
2029 uLeft -= uUsed;
2030 read_sq.rear_size += bUsed;
2031 if (read_sq.rear_size >= read_sq.block_size) {
2032 read_sq.rear_size = 0;
2033 read_sq.front++;
2034 if (read_sq.front >= read_sq.max_active)
2035 read_sq.front = 0;
2036 }
2037 }
2038 return uRead;
2039}
2040
2041static int sq_open(struct inode *inode, struct file *file)
2042{
2043 int rc = 0;
2044
2045 if (file->f_mode & FMODE_WRITE) {
2046 if (sq.busy) {
2047 rc = -EBUSY;
2048 if (NON_BLOCKING(file->f_flags))
2049 goto err_out;
2050 rc = -EINTR;
2051 while (sq.busy) {
2052 SLEEP(sq.open_queue);
2053 if (SIGNAL_RECEIVED)
2054 goto err_out;
2055 }
2056 }
2057 sq.busy = 1; /* Let's play spot-the-race-condition */
2058
2059 if (sq_allocate_buffers()) goto err_out_nobusy;
2060
2061 sq_setup(numBufs, bufSize<<10,sound_buffers);
2062 sq.open_mode = file->f_mode;
2063 }
2064
2065
2066 if (file->f_mode & FMODE_READ) {
2067 if (read_sq.busy) {
2068 rc = -EBUSY;
2069 if (NON_BLOCKING(file->f_flags))
2070 goto err_out;
2071 rc = -EINTR;
2072 while (read_sq.busy) {
2073 SLEEP(read_sq.open_queue);
2074 if (SIGNAL_RECEIVED)
2075 goto err_out;
2076 }
2077 rc = 0;
2078 }
2079 read_sq.busy = 1;
2080 if (sq_allocate_read_buffers()) goto err_out_nobusy;
2081
2082 read_sq_setup(numReadBufs,readbufSize<<10, sound_read_buffers);
2083 read_sq.open_mode = file->f_mode;
2084 }
2085
2086 /* Start up the 4218 by:
2087 * Reset.
2088 * Enable, unreset.
2089 */
2090 *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_RSTAUDIO;
2091 eieio();
2092 *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_ENAUDIO;
2093 mdelay(50);
2094 *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2095
2096 /* We need to send the current control word in case someone
2097 * opened /dev/mixer and changed things while we were shut
2098 * down. Chances are good the initialization that follows
2099 * would have done this, but it is still possible it wouldn't.
2100 */
2101 cs4218_ctl_write(cs4218_control);
2102
2103 sound.minDev = iminor(inode) & 0x0f;
2104 sound.soft = sound.dsp;
2105 sound.hard = sound.dsp;
2106 sound_init();
2107 if ((iminor(inode) & 0x0f) == SND_DEV_AUDIO) {
2108 sound_set_speed(8000);
2109 sound_set_stereo(0);
2110 sound_set_format(AFMT_MU_LAW);
2111 }
2112
2113 return nonseekable_open(inode, file);
2114
2115err_out_nobusy:
2116 if (file->f_mode & FMODE_WRITE) {
2117 sq.busy = 0;
2118 WAKE_UP(sq.open_queue);
2119 }
2120 if (file->f_mode & FMODE_READ) {
2121 read_sq.busy = 0;
2122 WAKE_UP(read_sq.open_queue);
2123 }
2124err_out:
2125 return rc;
2126}
2127
2128
2129static void sq_reset(void)
2130{
2131 sound_silence();
2132 sq.active = 0;
2133 sq.count = 0;
2134 sq.front = (sq.rear+1) % sq.max_count;
2135#if 0
2136 init_tdm_buffers();
2137#endif
2138}
2139
2140
2141static int sq_fsync(struct file *filp, struct dentry *dentry)
2142{
2143 int rc = 0;
2144
2145 sq.syncing = 1;
2146 sq_play(); /* there may be an incomplete frame waiting */
2147
2148 while (sq.active) {
2149 SLEEP(sq.sync_queue);
2150 if (SIGNAL_RECEIVED) {
2151 /* While waiting for audio output to drain, an
2152 * interrupt occurred. Stop audio output immediately
2153 * and clear the queue. */
2154 sq_reset();
2155 rc = -EINTR;
2156 break;
2157 }
2158 }
2159
2160 sq.syncing = 0;
2161 return rc;
2162}
2163
2164static int sq_release(struct inode *inode, struct file *file)
2165{
2166 int rc = 0;
2167
2168 if (sq.busy)
2169 rc = sq_fsync(file, file->f_dentry);
2170 sound.soft = sound.dsp;
2171 sound.hard = sound.dsp;
2172 sound_silence();
2173
2174 sq_release_read_buffers();
2175 sq_release_buffers();
2176
2177 if (file->f_mode & FMODE_READ) {
2178 read_sq.busy = 0;
2179 WAKE_UP(read_sq.open_queue);
2180 }
2181
2182 if (file->f_mode & FMODE_WRITE) {
2183 sq.busy = 0;
2184 WAKE_UP(sq.open_queue);
2185 }
2186
2187 /* Shut down the SMC.
2188 */
2189 cpmp->cp_smc[1].smc_smcmr &= ~(SMCMR_TEN | SMCMR_REN);
2190
2191 /* Shut down the codec.
2192 */
2193 *((volatile uint *)HIOX_CSR4_ADDR) |= HIOX_CSR4_RSTAUDIO;
2194 eieio();
2195 *((volatile uint *)HIOX_CSR4_ADDR) &= ~HIOX_CSR4_ENAUDIO;
2196
2197 /* Wake up a process waiting for the queue being released.
2198 * Note: There may be several processes waiting for a call
2199 * to open() returning. */
2200
2201 return rc;
2202}
2203
2204
2205static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
2206 u_long arg)
2207{
2208 u_long fmt;
2209 int data;
2210#if 0
2211 int size, nbufs;
2212#else
2213 int size;
2214#endif
2215
2216 switch (cmd) {
2217 case SNDCTL_DSP_RESET:
2218 sq_reset();
2219 return 0;
2220 case SNDCTL_DSP_POST:
2221 case SNDCTL_DSP_SYNC:
2222 return sq_fsync(file, file->f_dentry);
2223
2224 /* ++TeSche: before changing any of these it's
2225 * probably wise to wait until sound playing has
2226 * settled down. */
2227 case SNDCTL_DSP_SPEED:
2228 sq_fsync(file, file->f_dentry);
2229 IOCTL_IN(arg, data);
2230 return IOCTL_OUT(arg, sound_set_speed(data));
2231 case SNDCTL_DSP_STEREO:
2232 sq_fsync(file, file->f_dentry);
2233 IOCTL_IN(arg, data);
2234 return IOCTL_OUT(arg, sound_set_stereo(data));
2235 case SOUND_PCM_WRITE_CHANNELS:
2236 sq_fsync(file, file->f_dentry);
2237 IOCTL_IN(arg, data);
2238 return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
2239 case SNDCTL_DSP_SETFMT:
2240 sq_fsync(file, file->f_dentry);
2241 IOCTL_IN(arg, data);
2242 return IOCTL_OUT(arg, sound_set_format(data));
2243 case SNDCTL_DSP_GETFMTS:
2244 fmt = 0;
2245 if (sound.trans_write) {
2246 if (sound.trans_write->ct_ulaw)
2247 fmt |= AFMT_MU_LAW;
2248 if (sound.trans_write->ct_alaw)
2249 fmt |= AFMT_A_LAW;
2250 if (sound.trans_write->ct_s8)
2251 fmt |= AFMT_S8;
2252 if (sound.trans_write->ct_u8)
2253 fmt |= AFMT_U8;
2254 if (sound.trans_write->ct_s16be)
2255 fmt |= AFMT_S16_BE;
2256 if (sound.trans_write->ct_u16be)
2257 fmt |= AFMT_U16_BE;
2258 if (sound.trans_write->ct_s16le)
2259 fmt |= AFMT_S16_LE;
2260 if (sound.trans_write->ct_u16le)
2261 fmt |= AFMT_U16_LE;
2262 }
2263 return IOCTL_OUT(arg, fmt);
2264 case SNDCTL_DSP_GETBLKSIZE:
2265 size = sq.block_size
2266 * sound.soft.size * (sound.soft.stereo + 1)
2267 / (sound.hard.size * (sound.hard.stereo + 1));
2268 return IOCTL_OUT(arg, size);
2269 case SNDCTL_DSP_SUBDIVIDE:
2270 break;
2271#if 0 /* Sorry can't do this at the moment. The CPM allocated buffers
2272 * long ago that can't be changed.
2273 */
2274 case SNDCTL_DSP_SETFRAGMENT:
2275 if (sq.count || sq.active || sq.syncing)
2276 return -EINVAL;
2277 IOCTL_IN(arg, size);
2278 nbufs = size >> 16;
2279 if (nbufs < 2 || nbufs > numBufs)
2280 nbufs = numBufs;
2281 size &= 0xffff;
2282 if (size >= 8 && size <= 30) {
2283 size = 1 << size;
2284 size *= sound.hard.size * (sound.hard.stereo + 1);
2285 size /= sound.soft.size * (sound.soft.stereo + 1);
2286 if (size > (bufSize << 10))
2287 size = bufSize << 10;
2288 } else
2289 size = bufSize << 10;
2290 sq_setup(numBufs, size, sound_buffers);
2291 sq.max_active = nbufs;
2292 return 0;
2293#endif
2294
2295 default:
2296 return mixer_ioctl(inode, file, cmd, arg);
2297 }
2298 return -EINVAL;
2299}
2300
2301
2302
2303static struct file_operations sq_fops =
2304{
2305 .owner = THIS_MODULE,
2306 .llseek = sound_lseek,
2307 .read = sq_read, /* sq_read */
2308 .write = sq_write,
2309 .ioctl = sq_ioctl,
2310 .open = sq_open,
2311 .release = sq_release,
2312};
2313
2314
2315static void __init sq_init(void)
2316{
2317 sq_unit = register_sound_dsp(&sq_fops, -1);
2318 if (sq_unit < 0)
2319 return;
2320
2321 init_waitqueue_head(&sq.action_queue);
2322 init_waitqueue_head(&sq.open_queue);
2323 init_waitqueue_head(&sq.sync_queue);
2324 init_waitqueue_head(&read_sq.action_queue);
2325 init_waitqueue_head(&read_sq.open_queue);
2326 init_waitqueue_head(&read_sq.sync_queue);
2327
2328 sq.busy = 0;
2329 read_sq.busy = 0;
2330
2331 /* whatever you like as startup mode for /dev/dsp,
2332 * (/dev/audio hasn't got a startup mode). note that
2333 * once changed a new open() will *not* restore these!
2334 */
2335 sound.dsp.format = AFMT_S16_BE;
2336 sound.dsp.stereo = 1;
2337 sound.dsp.size = 16;
2338
2339 /* set minimum rate possible without expanding */
2340 sound.dsp.speed = 8000;
2341
2342 /* before the first open to /dev/dsp this wouldn't be set */
2343 sound.soft = sound.dsp;
2344 sound.hard = sound.dsp;
2345
2346 sound_silence();
2347}
2348
2349/*
2350 * /dev/sndstat
2351 */
2352
2353
2354/* state.buf should not overflow! */
2355
2356static int state_open(struct inode *inode, struct file *file)
2357{
2358 char *buffer = state.buf, *mach = "", cs4218_buf[50];
2359 int len = 0;
2360
2361 if (state.busy)
2362 return -EBUSY;
2363
2364 state.ptr = 0;
2365 state.busy = 1;
2366
2367 sprintf(cs4218_buf, "Crystal CS4218 on TDM, ");
2368 mach = cs4218_buf;
2369
2370 len += sprintf(buffer+len, "%sDMA sound driver:\n", mach);
2371
2372 len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
2373 switch (sound.soft.format) {
2374 case AFMT_MU_LAW:
2375 len += sprintf(buffer+len, " (mu-law)");
2376 break;
2377 case AFMT_A_LAW:
2378 len += sprintf(buffer+len, " (A-law)");
2379 break;
2380 case AFMT_U8:
2381 len += sprintf(buffer+len, " (unsigned 8 bit)");
2382 break;
2383 case AFMT_S8:
2384 len += sprintf(buffer+len, " (signed 8 bit)");
2385 break;
2386 case AFMT_S16_BE:
2387 len += sprintf(buffer+len, " (signed 16 bit big)");
2388 break;
2389 case AFMT_U16_BE:
2390 len += sprintf(buffer+len, " (unsigned 16 bit big)");
2391 break;
2392 case AFMT_S16_LE:
2393 len += sprintf(buffer+len, " (signed 16 bit little)");
2394 break;
2395 case AFMT_U16_LE:
2396 len += sprintf(buffer+len, " (unsigned 16 bit little)");
2397 break;
2398 }
2399 len += sprintf(buffer+len, "\n");
2400 len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
2401 sound.soft.speed, sound.hard.speed);
2402 len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
2403 sound.soft.stereo, sound.soft.stereo ? "stereo" : "mono");
2404 len += sprintf(buffer+len, "\tsq.block_size = %d sq.max_count = %d"
2405 " sq.max_active = %d\n",
2406 sq.block_size, sq.max_count, sq.max_active);
2407 len += sprintf(buffer+len, "\tsq.count = %d sq.rear_size = %d\n", sq.count,
2408 sq.rear_size);
2409 len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n",
2410 sq.active, sq.syncing);
2411 state.len = len;
2412 return nonseekable_open(inode, file);
2413}
2414
2415
2416static int state_release(struct inode *inode, struct file *file)
2417{
2418 state.busy = 0;
2419 return 0;
2420}
2421
2422
2423static ssize_t state_read(struct file *file, char *buf, size_t count,
2424 loff_t *ppos)
2425{
2426 int n = state.len - state.ptr;
2427 if (n > count)
2428 n = count;
2429 if (n <= 0)
2430 return 0;
2431 if (copy_to_user(buf, &state.buf[state.ptr], n))
2432 return -EFAULT;
2433 state.ptr += n;
2434 return n;
2435}
2436
2437
2438static struct file_operations state_fops =
2439{
2440 .owner = THIS_MODULE,
2441 .llseek = sound_lseek,
2442 .read = state_read,
2443 .open = state_open,
2444 .release = state_release,
2445};
2446
2447
2448static void __init state_init(void)
2449{
2450 state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
2451 if (state_unit < 0)
2452 return;
2453 state.busy = 0;
2454}
2455
2456
2457/*** Common stuff ********************************************************/
2458
2459static long long sound_lseek(struct file *file, long long offset, int orig)
2460{
2461 return -ESPIPE;
2462}
2463
2464
2465/*** Config & Setup **********************************************************/
2466
2467
2468int __init tdm8xx_sound_init(void)
2469{
2470 int i, has_sound;
2471 uint dp_offset;
2472 volatile uint *sirp;
2473 volatile cbd_t *bdp;
2474 volatile cpm8xx_t *cp;
2475 volatile smc_t *sp;
2476 volatile smc_uart_t *up;
2477 volatile immap_t *immap;
2478
2479 has_sound = 0;
2480
2481 /* Program the SI/TSA to use TDMa, connected to SMC2, for 4 bytes.
2482 */
2483 cp = cpmp; /* Get pointer to Communication Processor */
2484 immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
2485
2486 /* Set all TDMa control bits to zero. This enables most features
2487 * we want.
2488 */
2489 cp->cp_simode &= ~0x00000fff;
2490
2491 /* Enable common receive/transmit clock pins, use IDL format.
2492 * Sync on falling edge, transmit rising clock, receive falling
2493 * clock, delay 1 bit on both Tx and Rx. Common Tx/Rx clocks and
2494 * sync.
2495 * Connect SMC2 to TSA.
2496 */
2497 cp->cp_simode |= 0x80000141;
2498
2499 /* Configure port A pins for TDMa operation.
2500 * The RPX-Lite (MPC850/823) loses SMC2 when TDM is used.
2501 */
2502 immap->im_ioport.iop_papar |= 0x01c0; /* Enable TDMa functions */
2503 immap->im_ioport.iop_padir |= 0x00c0; /* Enable TDMa Tx/Rx */
2504 immap->im_ioport.iop_padir &= ~0x0100; /* Enable L1RCLKa */
2505
2506 immap->im_ioport.iop_pcpar |= 0x0800; /* Enable L1RSYNCa */
2507 immap->im_ioport.iop_pcdir &= ~0x0800;
2508
2509 /* Initialize the SI TDM routing table. We use TDMa only.
2510 * The receive table and transmit table each have only one
2511 * entry, to capture/send four bytes after each frame pulse.
2512 * The 16-bit ram entry is 0000 0001 1000 1111. (SMC2)
2513 */
2514 cp->cp_sigmr = 0;
2515 sirp = (uint *)cp->cp_siram;
2516
2517 *sirp = 0x018f0000; /* Receive entry */
2518 sirp += 64;
2519 *sirp = 0x018f0000; /* Tramsmit entry */
2520
2521 /* Enable single TDMa routing.
2522 */
2523 cp->cp_sigmr = 0x04;
2524
2525 /* Initialize the SMC for transparent operation.
2526 */
2527 sp = &cpmp->cp_smc[1];
2528 up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
2529
2530 /* We need to allocate a transmit and receive buffer
2531 * descriptors from dual port ram.
2532 */
2533 dp_addr = cpm_dpalloc(sizeof(cbd_t) * numReadBufs, 8);
2534
2535 /* Set the physical address of the host memory
2536 * buffers in the buffer descriptors, and the
2537 * virtual address for us to work with.
2538 */
2539 bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2540 up->smc_rbase = dp_offset;
2541 rx_cur = rx_base = (cbd_t *)bdp;
2542
2543 for (i=0; i<(numReadBufs-1); i++) {
2544 bdp->cbd_bufaddr = 0;
2545 bdp->cbd_datlen = 0;
2546 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
2547 bdp++;
2548 }
2549 bdp->cbd_bufaddr = 0;
2550 bdp->cbd_datlen = 0;
2551 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
2552
2553 /* Now, do the same for the transmit buffers.
2554 */
2555 dp_offset = cpm_dpalloc(sizeof(cbd_t) * numBufs, 8);
2556
2557 bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
2558 up->smc_tbase = dp_offset;
2559 tx_cur = tx_base = (cbd_t *)bdp;
2560
2561 for (i=0; i<(numBufs-1); i++) {
2562 bdp->cbd_bufaddr = 0;
2563 bdp->cbd_datlen = 0;
2564 bdp->cbd_sc = BD_SC_INTRPT;
2565 bdp++;
2566 }
2567 bdp->cbd_bufaddr = 0;
2568 bdp->cbd_datlen = 0;
2569 bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
2570
2571 /* Set transparent SMC mode.
2572 * A few things are specific to our application. The codec interface
2573 * is MSB first, hence the REVD selection. The CD/CTS pulse are
2574 * used by the TSA to indicate the frame start to the SMC.
2575 */
2576 up->smc_rfcr = SCC_EB;
2577 up->smc_tfcr = SCC_EB;
2578 up->smc_mrblr = readbufSize * 1024;
2579
2580 /* Set 16-bit reversed data, transparent mode.
2581 */
2582 sp->smc_smcmr = smcr_mk_clen(15) |
2583 SMCMR_SM_TRANS | SMCMR_REVD | SMCMR_BS;
2584
2585 /* Enable and clear events.
2586 * Because of FIFO delays, all we need is the receive interrupt
2587 * and we can process both the current receive and current
2588 * transmit interrupt within a few microseconds of the transmit.
2589 */
2590 sp->smc_smce = 0xff;
2591 sp->smc_smcm = SMCM_TXE | SMCM_TX | SMCM_RX;
2592
2593 /* Send the CPM an initialize command.
2594 */
2595 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2596 CPM_CR_INIT_TRX) | CPM_CR_FLG;
2597 while (cp->cp_cpcr & CPM_CR_FLG);
2598
2599 sound.mach = mach_cs4218;
2600 has_sound = 1;
2601
2602 /* Initialize beep stuff */
2603 orig_mksound = kd_mksound;
2604 kd_mksound = cs_mksound;
2605 beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
2606 if (beep_buf == NULL)
2607 printk(KERN_WARNING "dmasound: no memory for "
2608 "beep buffer\n");
2609
2610 if (!has_sound)
2611 return -ENODEV;
2612
2613 /* Initialize the software SPI.
2614 */
2615 sw_spi_init();
2616
2617 /* Set up sound queue, /dev/audio and /dev/dsp. */
2618
2619 /* Set default settings. */
2620 sq_init();
2621
2622 /* Set up /dev/sndstat. */
2623 state_init();
2624
2625 /* Set up /dev/mixer. */
2626 mixer_init();
2627
2628 if (!sound.mach.irqinit()) {
2629 printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n");
2630 return -ENODEV;
2631 }
2632#ifdef MODULE
2633 irq_installed = 1;
2634#endif
2635
2636 printk(KERN_INFO "DMA sound driver installed, using %d buffers of %dk.\n",
2637 numBufs, bufSize);
2638
2639 return 0;
2640}
2641
2642/* Due to FIFOs and bit delays, the transmit interrupt occurs a few
2643 * microseconds ahead of the receive interrupt.
2644 * When we get an interrupt, we service the transmit first, then
2645 * check for a receive to prevent the overhead of returning through
2646 * the interrupt handler only to get back here right away during
2647 * full duplex operation.
2648 */
2649static void
2650cs4218_intr(void *dev_id, struct pt_regs *regs)
2651{
2652 volatile smc_t *sp;
2653 volatile cpm8xx_t *cp;
2654
2655 sp = &cpmp->cp_smc[1];
2656
2657 if (sp->smc_smce & SCCM_TX) {
2658 sp->smc_smce = SCCM_TX;
2659 cs4218_tdm_tx_intr((void *)sp);
2660 }
2661
2662 if (sp->smc_smce & SCCM_RX) {
2663 sp->smc_smce = SCCM_RX;
2664 cs4218_tdm_rx_intr((void *)sp);
2665 }
2666
2667 if (sp->smc_smce & SCCM_TXE) {
2668 /* Transmit underrun. This happens with the application
2669 * didn't keep up sending buffers. We tell the SMC to
2670 * restart, which will cause it to poll the current (next)
2671 * BD. If the user supplied data since this occurred,
2672 * we just start running again. If they didn't, the SMC
2673 * will poll the descriptor until data is placed there.
2674 */
2675 sp->smc_smce = SCCM_TXE;
2676 cp = cpmp; /* Get pointer to Communication Processor */
2677 cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC2,
2678 CPM_CR_RESTART_TX) | CPM_CR_FLG;
2679 while (cp->cp_cpcr & CPM_CR_FLG);
2680 }
2681}
2682
2683
2684#define MAXARGS 8 /* Should be sufficient for now */
2685
2686void __init dmasound_setup(char *str, int *ints)
2687{
2688 /* check the bootstrap parameter for "dmasound=" */
2689
2690 switch (ints[0]) {
2691 case 3:
2692 if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS))
2693 printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius);
2694 else
2695 catchRadius = ints[3];
2696 /* fall through */
2697 case 2:
2698 if (ints[1] < MIN_BUFFERS)
2699 printk("dmasound_setup: invalid number of buffers, using default = %d\n", numBufs);
2700 else
2701 numBufs = ints[1];
2702 if (ints[2] < MIN_BUFSIZE || ints[2] > MAX_BUFSIZE)
2703 printk("dmasound_setup: invalid buffer size, using default = %d\n", bufSize);
2704 else
2705 bufSize = ints[2];
2706 break;
2707 case 0:
2708 break;
2709 default:
2710 printk("dmasound_setup: invalid number of arguments\n");
2711 }
2712}
2713
2714/* Software SPI functions.
2715 * These are on Port B.
2716 */
2717#define PB_SPICLK ((uint)0x00000002)
2718#define PB_SPIMOSI ((uint)0x00000004)
2719#define PB_SPIMISO ((uint)0x00000008)
2720
2721static
2722void sw_spi_init(void)
2723{
2724 volatile cpm8xx_t *cp;
2725 volatile uint *hcsr4;
2726
2727 hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2728 cp = cpmp; /* Get pointer to Communication Processor */
2729
2730 *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2731
2732 /* Make these Port B signals general purpose I/O.
2733 * First, make sure the clock is low.
2734 */
2735 cp->cp_pbdat &= ~PB_SPICLK;
2736 cp->cp_pbpar &= ~(PB_SPICLK | PB_SPIMOSI | PB_SPIMISO);
2737
2738 /* Clock and Master Output are outputs.
2739 */
2740 cp->cp_pbdir |= (PB_SPICLK | PB_SPIMOSI);
2741
2742 /* Master Input.
2743 */
2744 cp->cp_pbdir &= ~PB_SPIMISO;
2745
2746}
2747
2748/* Write the CS4218 control word out the SPI port. While the
2749 * the control word is going out, the status word is arriving.
2750 */
2751static
2752uint cs4218_ctl_write(uint ctlreg)
2753{
2754 uint status;
2755
2756 sw_spi_io((u_char *)&ctlreg, (u_char *)&status, 4);
2757
2758 /* Shadow the control register.....I guess we could do
2759 * the same for the status, but for now we just return it
2760 * and let the caller decide.
2761 */
2762 cs4218_control = ctlreg;
2763 return status;
2764}
2765
2766static
2767void sw_spi_io(u_char *obuf, u_char *ibuf, uint bcnt)
2768{
2769 int bits, i;
2770 u_char outbyte, inbyte;
2771 volatile cpm8xx_t *cp;
2772 volatile uint *hcsr4;
2773
2774 hcsr4 = (volatile uint *)HIOX_CSR4_ADDR;
2775 cp = cpmp; /* Get pointer to Communication Processor */
2776
2777 /* The timing on the bus is pretty slow. Code inefficiency
2778 * and eieio() is our friend here :-).
2779 */
2780 cp->cp_pbdat &= ~PB_SPICLK;
2781 *hcsr4 |= HIOX_CSR4_AUDSPISEL; /* Enable SPI select */
2782 eieio();
2783
2784 /* Clock in/out the bytes. Data is valid on the falling edge
2785 * of the clock. Data is MSB first.
2786 */
2787 for (i=0; i<bcnt; i++) {
2788 outbyte = *obuf++;
2789 inbyte = 0;
2790 for (bits=0; bits<8; bits++) {
2791 eieio();
2792 cp->cp_pbdat |= PB_SPICLK;
2793 eieio();
2794 if (outbyte & 0x80)
2795 cp->cp_pbdat |= PB_SPIMOSI;
2796 else
2797 cp->cp_pbdat &= ~PB_SPIMOSI;
2798 eieio();
2799 cp->cp_pbdat &= ~PB_SPICLK;
2800 eieio();
2801 outbyte <<= 1;
2802 inbyte <<= 1;
2803 if (cp->cp_pbdat & PB_SPIMISO)
2804 inbyte |= 1;
2805 }
2806 *ibuf++ = inbyte;
2807 }
2808
2809 *hcsr4 &= ~HIOX_CSR4_AUDSPISEL; /* Disable SPI select */
2810 eieio();
2811}
2812
2813void cleanup_module(void)
2814{
2815 if (irq_installed) {
2816 sound_silence();
2817#ifdef MODULE
2818 sound.mach.irqcleanup();
2819#endif
2820 }
2821
2822 sq_release_read_buffers();
2823 sq_release_buffers();
2824
2825 if (mixer_unit >= 0)
2826 unregister_sound_mixer(mixer_unit);
2827 if (state_unit >= 0)
2828 unregister_sound_special(state_unit);
2829 if (sq_unit >= 0)
2830 unregister_sound_dsp(sq_unit);
2831}
2832
2833module_init(tdm8xx_sound_init);
2834module_exit(cleanup_module);
2835