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