1 /*
2  *  linux/drivers/sound/dmasound/dmasound_atari.c
3  *
4  *  Atari TT and Falcon DMA Sound Driver
5  *
6  *  See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits
7  *  prior to 28/01/2001
8  *
9  *  28/01/2001 [0.1] Iain Sandoe
10  *		     - added versioning
11  *		     - put in and populated the hardware_afmts field.
12  *             [0.2] - put in SNDCTL_DSP_GETCAPS value.
13  *  01/02/2001 [0.3] - put in default hard/soft settings.
14  */
15 
16 
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/soundcard.h>
21 #include <linux/mm.h>
22 
23 #include <asm/pgalloc.h>
24 #include <asm/uaccess.h>
25 #include <asm/atariints.h>
26 #include <asm/atari_stram.h>
27 
28 #include "dmasound.h"
29 
30 #define DMASOUND_ATARI_REVISION 0
31 #define DMASOUND_ATARI_EDITION 3
32 
33 extern void atari_microwire_cmd(int cmd);
34 
35 static int is_falcon;
36 static int write_sq_ignore_int = 0;	/* ++TeSche: used for Falcon */
37 
38 static int expand_bal;	/* Balance factor for expanding (not volume!) */
39 static int expand_data;	/* Data for expanding */
40 
41 
42 /*** Translations ************************************************************/
43 
44 
45 /* ++TeSche: radically changed for new expanding purposes...
46  *
47  * These two routines now deal with copying/expanding/translating the samples
48  * from user space into our buffer at the right frequency. They take care about
49  * how much data there's actually to read, how much buffer space there is and
50  * to convert samples into the right frequency/encoding. They will only work on
51  * complete samples so it may happen they leave some bytes in the input stream
52  * if the user didn't write a multiple of the current sample size. They both
53  * return the number of bytes they've used from both streams so you may detect
54  * such a situation. Luckily all programs should be able to cope with that.
55  *
56  * I think I've optimized anything as far as one can do in plain C, all
57  * variables should fit in registers and the loops are really short. There's
58  * one loop for every possible situation. Writing a more generalized and thus
59  * parameterized loop would only produce slower code. Feel free to optimize
60  * this in assembler if you like. :)
61  *
62  * I think these routines belong here because they're not yet really hardware
63  * independent, especially the fact that the Falcon can play 16bit samples
64  * only in stereo is hardcoded in both of them!
65  *
66  * ++geert: split in even more functions (one per format)
67  */
68 
69 static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
70 			  u_char frame[], ssize_t *frameUsed,
71 			  ssize_t frameLeft);
72 static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
73 			 u_char frame[], ssize_t *frameUsed,
74 			 ssize_t frameLeft);
75 static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
76 			 u_char frame[], ssize_t *frameUsed,
77 			 ssize_t frameLeft);
78 static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
79 			    u_char frame[], ssize_t *frameUsed,
80 			    ssize_t frameLeft);
81 static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
82 			    u_char frame[], ssize_t *frameUsed,
83 			    ssize_t frameLeft);
84 static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
85 			    u_char frame[], ssize_t *frameUsed,
86 			    ssize_t frameLeft);
87 static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
88 			    u_char frame[], ssize_t *frameUsed,
89 			    ssize_t frameLeft);
90 static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
91 			   u_char frame[], ssize_t *frameUsed,
92 			   ssize_t frameLeft);
93 static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
94 			  u_char frame[], ssize_t *frameUsed,
95 			  ssize_t frameLeft);
96 static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
97 			  u_char frame[], ssize_t *frameUsed,
98 			  ssize_t frameLeft);
99 static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
100 			     u_char frame[], ssize_t *frameUsed,
101 			     ssize_t frameLeft);
102 static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
103 			     u_char frame[], ssize_t *frameUsed,
104 			     ssize_t frameLeft);
105 static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
106 			     u_char frame[], ssize_t *frameUsed,
107 			     ssize_t frameLeft);
108 static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
109 			     u_char frame[], ssize_t *frameUsed,
110 			     ssize_t frameLeft);
111 
112 
113 /*** Low level stuff *********************************************************/
114 
115 
116 static void AtaOpen(void);
117 static void AtaRelease(void);
118 static void *AtaAlloc(unsigned int size, int flags);
119 static void AtaFree(void *, unsigned int size);
120 static int AtaIrqInit(void);
121 #ifdef MODULE
122 static void AtaIrqCleanUp(void);
123 #endif /* MODULE */
124 static int AtaSetBass(int bass);
125 static int AtaSetTreble(int treble);
126 static void TTSilence(void);
127 static void TTInit(void);
128 static int TTSetFormat(int format);
129 static int TTSetVolume(int volume);
130 static int TTSetGain(int gain);
131 static void FalconSilence(void);
132 static void FalconInit(void);
133 static int FalconSetFormat(int format);
134 static int FalconSetVolume(int volume);
135 static void AtaPlayNextFrame(int index);
136 static void AtaPlay(void);
137 static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp);
138 
139 /*** Mid level stuff *********************************************************/
140 
141 static void TTMixerInit(void);
142 static void FalconMixerInit(void);
143 static int AtaMixerIoctl(u_int cmd, u_long arg);
144 static int TTMixerIoctl(u_int cmd, u_long arg);
145 static int FalconMixerIoctl(u_int cmd, u_long arg);
146 static int AtaWriteSqSetup(void);
147 static int AtaSqOpen(mode_t mode);
148 static int TTStateInfo(char *buffer, size_t space);
149 static int FalconStateInfo(char *buffer, size_t space);
150 
151 
152 /*** Translations ************************************************************/
153 
154 
ata_ct_law(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)155 static ssize_t ata_ct_law(const u_char *userPtr, size_t userCount,
156 			  u_char frame[], ssize_t *frameUsed,
157 			  ssize_t frameLeft)
158 {
159 	char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
160 							  : dmasound_alaw2dma8;
161 	ssize_t count, used;
162 	u_char *p = &frame[*frameUsed];
163 
164 	count = min_t(unsigned long, userCount, frameLeft);
165 	if (dmasound.soft.stereo)
166 		count &= ~1;
167 	used = count;
168 	while (count > 0) {
169 		u_char data;
170 		if (get_user(data, userPtr++))
171 			return -EFAULT;
172 		*p++ = table[data];
173 		count--;
174 	}
175 	*frameUsed += used;
176 	return used;
177 }
178 
179 
ata_ct_s8(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)180 static ssize_t ata_ct_s8(const u_char *userPtr, size_t userCount,
181 			 u_char frame[], ssize_t *frameUsed,
182 			 ssize_t frameLeft)
183 {
184 	ssize_t count, used;
185 	void *p = &frame[*frameUsed];
186 
187 	count = min_t(unsigned long, userCount, frameLeft);
188 	if (dmasound.soft.stereo)
189 		count &= ~1;
190 	used = count;
191 	if (copy_from_user(p, userPtr, count))
192 		return -EFAULT;
193 	*frameUsed += used;
194 	return used;
195 }
196 
197 
ata_ct_u8(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)198 static ssize_t ata_ct_u8(const u_char *userPtr, size_t userCount,
199 			 u_char frame[], ssize_t *frameUsed,
200 			 ssize_t frameLeft)
201 {
202 	ssize_t count, used;
203 
204 	if (!dmasound.soft.stereo) {
205 		u_char *p = &frame[*frameUsed];
206 		count = min_t(unsigned long, userCount, frameLeft);
207 		used = count;
208 		while (count > 0) {
209 			u_char data;
210 			if (get_user(data, userPtr++))
211 				return -EFAULT;
212 			*p++ = data ^ 0x80;
213 			count--;
214 		}
215 	} else {
216 		u_short *p = (u_short *)&frame[*frameUsed];
217 		count = min_t(unsigned long, userCount, frameLeft)>>1;
218 		used = count*2;
219 		while (count > 0) {
220 			u_short data;
221 			if (get_user(data, ((u_short *)userPtr)++))
222 				return -EFAULT;
223 			*p++ = data ^ 0x8080;
224 			count--;
225 		}
226 	}
227 	*frameUsed += used;
228 	return used;
229 }
230 
231 
ata_ct_s16be(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)232 static ssize_t ata_ct_s16be(const u_char *userPtr, size_t userCount,
233 			    u_char frame[], ssize_t *frameUsed,
234 			    ssize_t frameLeft)
235 {
236 	ssize_t count, used;
237 
238 	if (!dmasound.soft.stereo) {
239 		u_short *p = (u_short *)&frame[*frameUsed];
240 		count = min_t(unsigned long, userCount, frameLeft)>>1;
241 		used = count*2;
242 		while (count > 0) {
243 			u_short data;
244 			if (get_user(data, ((u_short *)userPtr)++))
245 				return -EFAULT;
246 			*p++ = data;
247 			*p++ = data;
248 			count--;
249 		}
250 		*frameUsed += used*2;
251 	} else {
252 		void *p = (u_short *)&frame[*frameUsed];
253 		count = min_t(unsigned long, userCount, frameLeft) & ~3;
254 		used = count;
255 		if (copy_from_user(p, userPtr, count))
256 			return -EFAULT;
257 		*frameUsed += used;
258 	}
259 	return used;
260 }
261 
262 
ata_ct_u16be(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)263 static ssize_t ata_ct_u16be(const u_char *userPtr, size_t userCount,
264 			    u_char frame[], ssize_t *frameUsed,
265 			    ssize_t frameLeft)
266 {
267 	ssize_t count, used;
268 
269 	if (!dmasound.soft.stereo) {
270 		u_short *p = (u_short *)&frame[*frameUsed];
271 		count = min_t(unsigned long, userCount, frameLeft)>>1;
272 		used = count*2;
273 		while (count > 0) {
274 			u_short data;
275 			if (get_user(data, ((u_short *)userPtr)++))
276 				return -EFAULT;
277 			data ^= 0x8000;
278 			*p++ = data;
279 			*p++ = data;
280 			count--;
281 		}
282 		*frameUsed += used*2;
283 	} else {
284 		u_long *p = (u_long *)&frame[*frameUsed];
285 		count = min_t(unsigned long, userCount, frameLeft)>>2;
286 		used = count*4;
287 		while (count > 0) {
288 			u_long data;
289 			if (get_user(data, ((u_int *)userPtr)++))
290 				return -EFAULT;
291 			*p++ = data ^ 0x80008000;
292 			count--;
293 		}
294 		*frameUsed += used;
295 	}
296 	return used;
297 }
298 
299 
ata_ct_s16le(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)300 static ssize_t ata_ct_s16le(const u_char *userPtr, size_t userCount,
301 			    u_char frame[], ssize_t *frameUsed,
302 			    ssize_t frameLeft)
303 {
304 	ssize_t count, used;
305 
306 	count = frameLeft;
307 	if (!dmasound.soft.stereo) {
308 		u_short *p = (u_short *)&frame[*frameUsed];
309 		count = min_t(unsigned long, userCount, frameLeft)>>1;
310 		used = count*2;
311 		while (count > 0) {
312 			u_short data;
313 			if (get_user(data, ((u_short *)userPtr)++))
314 				return -EFAULT;
315 			data = le2be16(data);
316 			*p++ = data;
317 			*p++ = data;
318 			count--;
319 		}
320 		*frameUsed += used*2;
321 	} else {
322 		u_long *p = (u_long *)&frame[*frameUsed];
323 		count = min_t(unsigned long, userCount, frameLeft)>>2;
324 		used = count*4;
325 		while (count > 0) {
326 			u_long data;
327 			if (get_user(data, ((u_int *)userPtr)++))
328 				return -EFAULT;
329 			data = le2be16dbl(data);
330 			*p++ = data;
331 			count--;
332 		}
333 		*frameUsed += used;
334 	}
335 	return used;
336 }
337 
338 
ata_ct_u16le(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)339 static ssize_t ata_ct_u16le(const u_char *userPtr, size_t userCount,
340 			    u_char frame[], ssize_t *frameUsed,
341 			    ssize_t frameLeft)
342 {
343 	ssize_t count, used;
344 
345 	count = frameLeft;
346 	if (!dmasound.soft.stereo) {
347 		u_short *p = (u_short *)&frame[*frameUsed];
348 		count = min_t(unsigned long, userCount, frameLeft)>>1;
349 		used = count*2;
350 		while (count > 0) {
351 			u_short data;
352 			if (get_user(data, ((u_short *)userPtr)++))
353 				return -EFAULT;
354 			data = le2be16(data) ^ 0x8000;
355 			*p++ = data;
356 			*p++ = data;
357 		}
358 		*frameUsed += used*2;
359 	} else {
360 		u_long *p = (u_long *)&frame[*frameUsed];
361 		count = min_t(unsigned long, userCount, frameLeft)>>2;
362 		used = count;
363 		while (count > 0) {
364 			u_long data;
365 			if (get_user(data, ((u_int *)userPtr)++))
366 				return -EFAULT;
367 			data = le2be16dbl(data) ^ 0x80008000;
368 			*p++ = data;
369 			count--;
370 		}
371 		*frameUsed += used;
372 	}
373 	return used;
374 }
375 
376 
ata_ctx_law(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)377 static ssize_t ata_ctx_law(const u_char *userPtr, size_t userCount,
378 			   u_char frame[], ssize_t *frameUsed,
379 			   ssize_t frameLeft)
380 {
381 	char *table = dmasound.soft.format == AFMT_MU_LAW ? dmasound_ulaw2dma8
382 							  : dmasound_alaw2dma8;
383 	/* this should help gcc to stuff everything into registers */
384 	long bal = expand_bal;
385 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
386 	ssize_t used, usedf;
387 
388 	used = userCount;
389 	usedf = frameLeft;
390 	if (!dmasound.soft.stereo) {
391 		u_char *p = &frame[*frameUsed];
392 		u_char data = expand_data;
393 		while (frameLeft) {
394 			u_char c;
395 			if (bal < 0) {
396 				if (!userCount)
397 					break;
398 				if (get_user(c, userPtr++))
399 					return -EFAULT;
400 				data = table[c];
401 				userCount--;
402 				bal += hSpeed;
403 			}
404 			*p++ = data;
405 			frameLeft--;
406 			bal -= sSpeed;
407 		}
408 		expand_data = data;
409 	} else {
410 		u_short *p = (u_short *)&frame[*frameUsed];
411 		u_short data = expand_data;
412 		while (frameLeft >= 2) {
413 			u_char c;
414 			if (bal < 0) {
415 				if (userCount < 2)
416 					break;
417 				if (get_user(c, userPtr++))
418 					return -EFAULT;
419 				data = table[c] << 8;
420 				if (get_user(c, userPtr++))
421 					return -EFAULT;
422 				data |= table[c];
423 				userCount -= 2;
424 				bal += hSpeed;
425 			}
426 			*p++ = data;
427 			frameLeft -= 2;
428 			bal -= sSpeed;
429 		}
430 		expand_data = data;
431 	}
432 	expand_bal = bal;
433 	used -= userCount;
434 	*frameUsed += usedf-frameLeft;
435 	return used;
436 }
437 
438 
ata_ctx_s8(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)439 static ssize_t ata_ctx_s8(const u_char *userPtr, size_t userCount,
440 			  u_char frame[], ssize_t *frameUsed,
441 			  ssize_t frameLeft)
442 {
443 	/* this should help gcc to stuff everything into registers */
444 	long bal = expand_bal;
445 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
446 	ssize_t used, usedf;
447 
448 	used = userCount;
449 	usedf = frameLeft;
450 	if (!dmasound.soft.stereo) {
451 		u_char *p = &frame[*frameUsed];
452 		u_char data = expand_data;
453 		while (frameLeft) {
454 			if (bal < 0) {
455 				if (!userCount)
456 					break;
457 				if (get_user(data, userPtr++))
458 					return -EFAULT;
459 				userCount--;
460 				bal += hSpeed;
461 			}
462 			*p++ = data;
463 			frameLeft--;
464 			bal -= sSpeed;
465 		}
466 		expand_data = data;
467 	} else {
468 		u_short *p = (u_short *)&frame[*frameUsed];
469 		u_short data = expand_data;
470 		while (frameLeft >= 2) {
471 			if (bal < 0) {
472 				if (userCount < 2)
473 					break;
474 				if (get_user(data, ((u_short *)userPtr)++))
475 					return -EFAULT;
476 				userCount -= 2;
477 				bal += hSpeed;
478 			}
479 			*p++ = data;
480 			frameLeft -= 2;
481 			bal -= sSpeed;
482 		}
483 		expand_data = data;
484 	}
485 	expand_bal = bal;
486 	used -= userCount;
487 	*frameUsed += usedf-frameLeft;
488 	return used;
489 }
490 
491 
ata_ctx_u8(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)492 static ssize_t ata_ctx_u8(const u_char *userPtr, size_t userCount,
493 			  u_char frame[], ssize_t *frameUsed,
494 			  ssize_t frameLeft)
495 {
496 	/* this should help gcc to stuff everything into registers */
497 	long bal = expand_bal;
498 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
499 	ssize_t used, usedf;
500 
501 	used = userCount;
502 	usedf = frameLeft;
503 	if (!dmasound.soft.stereo) {
504 		u_char *p = &frame[*frameUsed];
505 		u_char data = expand_data;
506 		while (frameLeft) {
507 			if (bal < 0) {
508 				if (!userCount)
509 					break;
510 				if (get_user(data, userPtr++))
511 					return -EFAULT;
512 				data ^= 0x80;
513 				userCount--;
514 				bal += hSpeed;
515 			}
516 			*p++ = data;
517 			frameLeft--;
518 			bal -= sSpeed;
519 		}
520 		expand_data = data;
521 	} else {
522 		u_short *p = (u_short *)&frame[*frameUsed];
523 		u_short data = expand_data;
524 		while (frameLeft >= 2) {
525 			if (bal < 0) {
526 				if (userCount < 2)
527 					break;
528 				if (get_user(data, ((u_short *)userPtr)++))
529 					return -EFAULT;
530 				data ^= 0x8080;
531 				userCount -= 2;
532 				bal += hSpeed;
533 			}
534 			*p++ = data;
535 			frameLeft -= 2;
536 			bal -= sSpeed;
537 		}
538 		expand_data = data;
539 	}
540 	expand_bal = bal;
541 	used -= userCount;
542 	*frameUsed += usedf-frameLeft;
543 	return used;
544 }
545 
546 
ata_ctx_s16be(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)547 static ssize_t ata_ctx_s16be(const u_char *userPtr, size_t userCount,
548 			     u_char frame[], ssize_t *frameUsed,
549 			     ssize_t frameLeft)
550 {
551 	/* this should help gcc to stuff everything into registers */
552 	long bal = expand_bal;
553 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
554 	ssize_t used, usedf;
555 
556 	used = userCount;
557 	usedf = frameLeft;
558 	if (!dmasound.soft.stereo) {
559 		u_short *p = (u_short *)&frame[*frameUsed];
560 		u_short data = expand_data;
561 		while (frameLeft >= 4) {
562 			if (bal < 0) {
563 				if (userCount < 2)
564 					break;
565 				if (get_user(data, ((u_short *)userPtr)++))
566 					return -EFAULT;
567 				userCount -= 2;
568 				bal += hSpeed;
569 			}
570 			*p++ = data;
571 			*p++ = data;
572 			frameLeft -= 4;
573 			bal -= sSpeed;
574 		}
575 		expand_data = data;
576 	} else {
577 		u_long *p = (u_long *)&frame[*frameUsed];
578 		u_long data = expand_data;
579 		while (frameLeft >= 4) {
580 			if (bal < 0) {
581 				if (userCount < 4)
582 					break;
583 				if (get_user(data, ((u_int *)userPtr)++))
584 					return -EFAULT;
585 				userCount -= 4;
586 				bal += hSpeed;
587 			}
588 			*p++ = data;
589 			frameLeft -= 4;
590 			bal -= sSpeed;
591 		}
592 		expand_data = data;
593 	}
594 	expand_bal = bal;
595 	used -= userCount;
596 	*frameUsed += usedf-frameLeft;
597 	return used;
598 }
599 
600 
ata_ctx_u16be(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)601 static ssize_t ata_ctx_u16be(const u_char *userPtr, size_t userCount,
602 			     u_char frame[], ssize_t *frameUsed,
603 			     ssize_t frameLeft)
604 {
605 	/* this should help gcc to stuff everything into registers */
606 	long bal = expand_bal;
607 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
608 	ssize_t used, usedf;
609 
610 	used = userCount;
611 	usedf = frameLeft;
612 	if (!dmasound.soft.stereo) {
613 		u_short *p = (u_short *)&frame[*frameUsed];
614 		u_short data = expand_data;
615 		while (frameLeft >= 4) {
616 			if (bal < 0) {
617 				if (userCount < 2)
618 					break;
619 				if (get_user(data, ((u_short *)userPtr)++))
620 					return -EFAULT;
621 				data ^= 0x8000;
622 				userCount -= 2;
623 				bal += hSpeed;
624 			}
625 			*p++ = data;
626 			*p++ = data;
627 			frameLeft -= 4;
628 			bal -= sSpeed;
629 		}
630 		expand_data = data;
631 	} else {
632 		u_long *p = (u_long *)&frame[*frameUsed];
633 		u_long data = expand_data;
634 		while (frameLeft >= 4) {
635 			if (bal < 0) {
636 				if (userCount < 4)
637 					break;
638 				if (get_user(data, ((u_int *)userPtr)++))
639 					return -EFAULT;
640 				data ^= 0x80008000;
641 				userCount -= 4;
642 				bal += hSpeed;
643 			}
644 			*p++ = data;
645 			frameLeft -= 4;
646 			bal -= sSpeed;
647 		}
648 		expand_data = data;
649 	}
650 	expand_bal = bal;
651 	used -= userCount;
652 	*frameUsed += usedf-frameLeft;
653 	return used;
654 }
655 
656 
ata_ctx_s16le(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)657 static ssize_t ata_ctx_s16le(const u_char *userPtr, size_t userCount,
658 			     u_char frame[], ssize_t *frameUsed,
659 			     ssize_t frameLeft)
660 {
661 	/* this should help gcc to stuff everything into registers */
662 	long bal = expand_bal;
663 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
664 	ssize_t used, usedf;
665 
666 	used = userCount;
667 	usedf = frameLeft;
668 	if (!dmasound.soft.stereo) {
669 		u_short *p = (u_short *)&frame[*frameUsed];
670 		u_short data = expand_data;
671 		while (frameLeft >= 4) {
672 			if (bal < 0) {
673 				if (userCount < 2)
674 					break;
675 				if (get_user(data, ((u_short *)userPtr)++))
676 					return -EFAULT;
677 				data = le2be16(data);
678 				userCount -= 2;
679 				bal += hSpeed;
680 			}
681 			*p++ = data;
682 			*p++ = data;
683 			frameLeft -= 4;
684 			bal -= sSpeed;
685 		}
686 		expand_data = data;
687 	} else {
688 		u_long *p = (u_long *)&frame[*frameUsed];
689 		u_long data = expand_data;
690 		while (frameLeft >= 4) {
691 			if (bal < 0) {
692 				if (userCount < 4)
693 					break;
694 				if (get_user(data, ((u_int *)userPtr)++))
695 					return -EFAULT;
696 				data = le2be16dbl(data);
697 				userCount -= 4;
698 				bal += hSpeed;
699 			}
700 			*p++ = data;
701 			frameLeft -= 4;
702 			bal -= sSpeed;
703 		}
704 		expand_data = data;
705 	}
706 	expand_bal = bal;
707 	used -= userCount;
708 	*frameUsed += usedf-frameLeft;
709 	return used;
710 }
711 
712 
ata_ctx_u16le(const u_char * userPtr,size_t userCount,u_char frame[],ssize_t * frameUsed,ssize_t frameLeft)713 static ssize_t ata_ctx_u16le(const u_char *userPtr, size_t userCount,
714 			     u_char frame[], ssize_t *frameUsed,
715 			     ssize_t frameLeft)
716 {
717 	/* this should help gcc to stuff everything into registers */
718 	long bal = expand_bal;
719 	long hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
720 	ssize_t used, usedf;
721 
722 	used = userCount;
723 	usedf = frameLeft;
724 	if (!dmasound.soft.stereo) {
725 		u_short *p = (u_short *)&frame[*frameUsed];
726 		u_short data = expand_data;
727 		while (frameLeft >= 4) {
728 			if (bal < 0) {
729 				if (userCount < 2)
730 					break;
731 				if (get_user(data, ((u_short *)userPtr)++))
732 					return -EFAULT;
733 				data = le2be16(data) ^ 0x8000;
734 				userCount -= 2;
735 				bal += hSpeed;
736 			}
737 			*p++ = data;
738 			*p++ = data;
739 			frameLeft -= 4;
740 			bal -= sSpeed;
741 		}
742 		expand_data = data;
743 	} else {
744 		u_long *p = (u_long *)&frame[*frameUsed];
745 		u_long data = expand_data;
746 		while (frameLeft >= 4) {
747 			if (bal < 0) {
748 				if (userCount < 4)
749 					break;
750 				if (get_user(data, ((u_int *)userPtr)++))
751 					return -EFAULT;
752 				data = le2be16dbl(data) ^ 0x80008000;
753 				userCount -= 4;
754 				bal += hSpeed;
755 			}
756 			*p++ = data;
757 			frameLeft -= 4;
758 			bal -= sSpeed;
759 		}
760 		expand_data = data;
761 	}
762 	expand_bal = bal;
763 	used -= userCount;
764 	*frameUsed += usedf-frameLeft;
765 	return used;
766 }
767 
768 
769 static TRANS transTTNormal = {
770 	ct_ulaw:	ata_ct_law,
771 	ct_alaw:	ata_ct_law,
772 	ct_s8:		ata_ct_s8,
773 	ct_u8:		ata_ct_u8,
774 };
775 
776 static TRANS transTTExpanding = {
777 	ct_ulaw:	ata_ctx_law,
778 	ct_alaw:	ata_ctx_law,
779 	ct_s8:		ata_ctx_s8,
780 	ct_u8:		ata_ctx_u8,
781 };
782 
783 static TRANS transFalconNormal = {
784 	ct_ulaw:	ata_ct_law,
785 	ct_alaw:	ata_ct_law,
786 	ct_s8:		ata_ct_s8,
787 	ct_u8:		ata_ct_u8,
788 	ct_s16be:	ata_ct_s16be,
789 	ct_u16be:	ata_ct_u16be,
790 	ct_s16le:	ata_ct_s16le,
791 	ct_u16le:	ata_ct_u16le
792 };
793 
794 static TRANS transFalconExpanding = {
795 	ct_ulaw:	ata_ctx_law,
796 	ct_alaw:	ata_ctx_law,
797 	ct_s8:		ata_ctx_s8,
798 	ct_u8:		ata_ctx_u8,
799 	ct_s16be:	ata_ctx_s16be,
800 	ct_u16be:	ata_ctx_u16be,
801 	ct_s16le:	ata_ctx_s16le,
802 	ct_u16le:	ata_ctx_u16le,
803 };
804 
805 
806 /*** Low level stuff *********************************************************/
807 
808 
809 
810 /*
811  * Atari (TT/Falcon)
812  */
813 
AtaOpen(void)814 static void AtaOpen(void)
815 {
816 	MOD_INC_USE_COUNT;
817 }
818 
AtaRelease(void)819 static void AtaRelease(void)
820 {
821 	MOD_DEC_USE_COUNT;
822 }
823 
AtaAlloc(unsigned int size,int flags)824 static void *AtaAlloc(unsigned int size, int flags)
825 {
826 	return atari_stram_alloc(size, "dmasound");
827 }
828 
AtaFree(void * obj,unsigned int size)829 static void AtaFree(void *obj, unsigned int size)
830 {
831 	atari_stram_free( obj );
832 }
833 
AtaIrqInit(void)834 static int __init AtaIrqInit(void)
835 {
836 	/* Set up timer A. Timer A
837 	   will receive a signal upon end of playing from the sound
838 	   hardware. Furthermore Timer A is able to count events
839 	   and will cause an interrupt after a programmed number
840 	   of events. So all we need to keep the music playing is
841 	   to provide the sound hardware with new data upon
842 	   an interrupt from timer A. */
843 	mfp.tim_ct_a = 0;	/* ++roman: Stop timer before programming! */
844 	mfp.tim_dt_a = 1;	/* Cause interrupt after first event. */
845 	mfp.tim_ct_a = 8;	/* Turn on event counting. */
846 	/* Register interrupt handler. */
847 	request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
848 		    AtaInterrupt);
849 	mfp.int_en_a |= 0x20;	/* Turn interrupt on. */
850 	mfp.int_mk_a |= 0x20;
851 	return 1;
852 }
853 
854 #ifdef MODULE
AtaIrqCleanUp(void)855 static void AtaIrqCleanUp(void)
856 {
857 	mfp.tim_ct_a = 0;	/* stop timer */
858 	mfp.int_en_a &= ~0x20;	/* turn interrupt off */
859 	free_irq(IRQ_MFP_TIMA, AtaInterrupt);
860 }
861 #endif /* MODULE */
862 
863 
864 #define TONE_VOXWARE_TO_DB(v) \
865 	(((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
866 #define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
867 
868 
AtaSetBass(int bass)869 static int AtaSetBass(int bass)
870 {
871 	dmasound.bass = TONE_VOXWARE_TO_DB(bass);
872 	atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
873 	return TONE_DB_TO_VOXWARE(dmasound.bass);
874 }
875 
876 
AtaSetTreble(int treble)877 static int AtaSetTreble(int treble)
878 {
879 	dmasound.treble = TONE_VOXWARE_TO_DB(treble);
880 	atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
881 	return TONE_DB_TO_VOXWARE(dmasound.treble);
882 }
883 
884 
885 
886 /*
887  * TT
888  */
889 
890 
TTSilence(void)891 static void TTSilence(void)
892 {
893 	tt_dmasnd.ctrl = DMASND_CTRL_OFF;
894 	atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
895 }
896 
897 
TTInit(void)898 static void TTInit(void)
899 {
900 	int mode, i, idx;
901 	const int freq[4] = {50066, 25033, 12517, 6258};
902 
903 	/* search a frequency that fits into the allowed error range */
904 
905 	idx = -1;
906 	for (i = 0; i < ARRAY_SIZE(freq); i++)
907 		/* this isn't as much useful for a TT than for a Falcon, but
908 		 * then it doesn't hurt very much to implement it for a TT too.
909 		 */
910 		if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
911 			idx = i;
912 	if (idx > -1) {
913 		dmasound.soft.speed = freq[idx];
914 		dmasound.trans_write = &transTTNormal;
915 	} else
916 		dmasound.trans_write = &transTTExpanding;
917 
918 	TTSilence();
919 	dmasound.hard = dmasound.soft;
920 
921 	if (dmasound.hard.speed > 50066) {
922 		/* we would need to squeeze the sound, but we won't do that */
923 		dmasound.hard.speed = 50066;
924 		mode = DMASND_MODE_50KHZ;
925 		dmasound.trans_write = &transTTNormal;
926 	} else if (dmasound.hard.speed > 25033) {
927 		dmasound.hard.speed = 50066;
928 		mode = DMASND_MODE_50KHZ;
929 	} else if (dmasound.hard.speed > 12517) {
930 		dmasound.hard.speed = 25033;
931 		mode = DMASND_MODE_25KHZ;
932 	} else if (dmasound.hard.speed > 6258) {
933 		dmasound.hard.speed = 12517;
934 		mode = DMASND_MODE_12KHZ;
935 	} else {
936 		dmasound.hard.speed = 6258;
937 		mode = DMASND_MODE_6KHZ;
938 	}
939 
940 	tt_dmasnd.mode = (dmasound.hard.stereo ?
941 			  DMASND_MODE_STEREO : DMASND_MODE_MONO) |
942 		DMASND_MODE_8BIT | mode;
943 
944 	expand_bal = -dmasound.soft.speed;
945 }
946 
947 
TTSetFormat(int format)948 static int TTSetFormat(int format)
949 {
950 	/* TT sound DMA supports only 8bit modes */
951 
952 	switch (format) {
953 	case AFMT_QUERY:
954 		return dmasound.soft.format;
955 	case AFMT_MU_LAW:
956 	case AFMT_A_LAW:
957 	case AFMT_S8:
958 	case AFMT_U8:
959 		break;
960 	default:
961 		format = AFMT_S8;
962 	}
963 
964 	dmasound.soft.format = format;
965 	dmasound.soft.size = 8;
966 	if (dmasound.minDev == SND_DEV_DSP) {
967 		dmasound.dsp.format = format;
968 		dmasound.dsp.size = 8;
969 	}
970 	TTInit();
971 
972 	return format;
973 }
974 
975 
976 #define VOLUME_VOXWARE_TO_DB(v) \
977 	(((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
978 #define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
979 
980 
TTSetVolume(int volume)981 static int TTSetVolume(int volume)
982 {
983 	dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
984 	atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
985 	dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
986 	atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
987 	return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
988 	       (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
989 }
990 
991 
992 #define GAIN_VOXWARE_TO_DB(v) \
993 	(((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
994 #define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
995 
TTSetGain(int gain)996 static int TTSetGain(int gain)
997 {
998 	dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
999 	atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
1000 	return GAIN_DB_TO_VOXWARE(dmasound.gain);
1001 }
1002 
1003 
1004 
1005 /*
1006  * Falcon
1007  */
1008 
1009 
FalconSilence(void)1010 static void FalconSilence(void)
1011 {
1012 	/* stop playback, set sample rate 50kHz for PSG sound */
1013 	tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1014 	tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1015 	tt_dmasnd.int_div = 0; /* STE compatible divider */
1016 	tt_dmasnd.int_ctrl = 0x0;
1017 	tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1018 	tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1019 	tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1020 	tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1021 }
1022 
1023 
FalconInit(void)1024 static void FalconInit(void)
1025 {
1026 	int divider, i, idx;
1027 	const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1028 
1029 	/* search a frequency that fits into the allowed error range */
1030 
1031 	idx = -1;
1032 	for (i = 0; i < ARRAY_SIZE(freq); i++)
1033 		/* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1034 		 * be playable without expanding, but that now a kernel runtime
1035 		 * option
1036 		 */
1037 		if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1038 			idx = i;
1039 	if (idx > -1) {
1040 		dmasound.soft.speed = freq[idx];
1041 		dmasound.trans_write = &transFalconNormal;
1042 	} else
1043 		dmasound.trans_write = &transFalconExpanding;
1044 
1045 	FalconSilence();
1046 	dmasound.hard = dmasound.soft;
1047 
1048 	if (dmasound.hard.size == 16) {
1049 		/* the Falcon can play 16bit samples only in stereo */
1050 		dmasound.hard.stereo = 1;
1051 	}
1052 
1053 	if (dmasound.hard.speed > 49170) {
1054 		/* we would need to squeeze the sound, but we won't do that */
1055 		dmasound.hard.speed = 49170;
1056 		divider = 1;
1057 		dmasound.trans_write = &transFalconNormal;
1058 	} else if (dmasound.hard.speed > 32780) {
1059 		dmasound.hard.speed = 49170;
1060 		divider = 1;
1061 	} else if (dmasound.hard.speed > 24585) {
1062 		dmasound.hard.speed = 32780;
1063 		divider = 2;
1064 	} else if (dmasound.hard.speed > 19668) {
1065 		dmasound.hard.speed = 24585;
1066 		divider = 3;
1067 	} else if (dmasound.hard.speed > 16390) {
1068 		dmasound.hard.speed = 19668;
1069 		divider = 4;
1070 	} else if (dmasound.hard.speed > 12292) {
1071 		dmasound.hard.speed = 16390;
1072 		divider = 5;
1073 	} else if (dmasound.hard.speed > 9834) {
1074 		dmasound.hard.speed = 12292;
1075 		divider = 7;
1076 	} else if (dmasound.hard.speed > 8195) {
1077 		dmasound.hard.speed = 9834;
1078 		divider = 9;
1079 	} else {
1080 		dmasound.hard.speed = 8195;
1081 		divider = 11;
1082 	}
1083 	tt_dmasnd.int_div = divider;
1084 
1085 	/* Setup Falcon sound DMA for playback */
1086 	tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1087 	tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1088 	tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1089 	tt_dmasnd.cbar_dst = 0x0000;
1090 	tt_dmasnd.rec_track_select = 0;
1091 	tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1092 	tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1093 
1094 	tt_dmasnd.mode = (dmasound.hard.stereo ?
1095 			  DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1096 		((dmasound.hard.size == 8) ?
1097 		 DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1098 		DMASND_MODE_6KHZ;
1099 
1100 	expand_bal = -dmasound.soft.speed;
1101 }
1102 
1103 
FalconSetFormat(int format)1104 static int FalconSetFormat(int format)
1105 {
1106 	int size;
1107 	/* Falcon sound DMA supports 8bit and 16bit modes */
1108 
1109 	switch (format) {
1110 	case AFMT_QUERY:
1111 		return dmasound.soft.format;
1112 	case AFMT_MU_LAW:
1113 	case AFMT_A_LAW:
1114 	case AFMT_U8:
1115 	case AFMT_S8:
1116 		size = 8;
1117 		break;
1118 	case AFMT_S16_BE:
1119 	case AFMT_U16_BE:
1120 	case AFMT_S16_LE:
1121 	case AFMT_U16_LE:
1122 		size = 16;
1123 		break;
1124 	default: /* :-) */
1125 		size = 8;
1126 		format = AFMT_S8;
1127 	}
1128 
1129 	dmasound.soft.format = format;
1130 	dmasound.soft.size = size;
1131 	if (dmasound.minDev == SND_DEV_DSP) {
1132 		dmasound.dsp.format = format;
1133 		dmasound.dsp.size = dmasound.soft.size;
1134 	}
1135 
1136 	FalconInit();
1137 
1138 	return format;
1139 }
1140 
1141 
1142 /* This is for the Falcon output *attenuation* in 1.5dB steps,
1143  * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1144  */
1145 #define VOLUME_VOXWARE_TO_ATT(v) \
1146 	((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1147 #define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1148 
1149 
FalconSetVolume(int volume)1150 static int FalconSetVolume(int volume)
1151 {
1152 	dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1153 	dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1154 	tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1155 	return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1156 	       VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1157 }
1158 
1159 
AtaPlayNextFrame(int index)1160 static void AtaPlayNextFrame(int index)
1161 {
1162 	char *start, *end;
1163 
1164 	/* used by AtaPlay() if all doubts whether there really is something
1165 	 * to be played are already wiped out.
1166 	 */
1167 	start = write_sq.buffers[write_sq.front];
1168 	end = start+((write_sq.count == index) ? write_sq.rear_size
1169 					       : write_sq.block_size);
1170 	/* end might not be a legal virtual address. */
1171 	DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1172 	DMASNDSetBase(virt_to_phys(start));
1173 	/* Since only an even number of samples per frame can
1174 	   be played, we might lose one byte here. (TO DO) */
1175 	write_sq.front = (write_sq.front+1) % write_sq.max_count;
1176 	write_sq.active++;
1177 	tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1178 }
1179 
1180 
AtaPlay(void)1181 static void AtaPlay(void)
1182 {
1183 	/* ++TeSche: Note that write_sq.active is no longer just a flag but
1184 	 * holds the number of frames the DMA is currently programmed for
1185 	 * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1186 	 *
1187 	 * Changes done to write_sq.count and write_sq.active are a bit more
1188 	 * subtle again so now I must admit I also prefer disabling the irq
1189 	 * here rather than considering all possible situations. But the point
1190 	 * is that disabling the irq doesn't have any bad influence on this
1191 	 * version of the driver as we benefit from having pre-programmed the
1192 	 * DMA wherever possible: There's no need to reload the DMA at the
1193 	 * exact time of an interrupt but only at some time while the
1194 	 * pre-programmed frame is playing!
1195 	 */
1196 	atari_disable_irq(IRQ_MFP_TIMA);
1197 
1198 	if (write_sq.active == 2 ||	/* DMA is 'full' */
1199 	    write_sq.count <= 0) {	/* nothing to do */
1200 		atari_enable_irq(IRQ_MFP_TIMA);
1201 		return;
1202 	}
1203 
1204 	if (write_sq.active == 0) {
1205 		/* looks like there's nothing 'in' the DMA yet, so try
1206 		 * to put two frames into it (at least one is available).
1207 		 */
1208 		if (write_sq.count == 1 &&
1209 		    write_sq.rear_size < write_sq.block_size &&
1210 		    !write_sq.syncing) {
1211 			/* hmmm, the only existing frame is not
1212 			 * yet filled and we're not syncing?
1213 			 */
1214 			atari_enable_irq(IRQ_MFP_TIMA);
1215 			return;
1216 		}
1217 		AtaPlayNextFrame(1);
1218 		if (write_sq.count == 1) {
1219 			/* no more frames */
1220 			atari_enable_irq(IRQ_MFP_TIMA);
1221 			return;
1222 		}
1223 		if (write_sq.count == 2 &&
1224 		    write_sq.rear_size < write_sq.block_size &&
1225 		    !write_sq.syncing) {
1226 			/* hmmm, there were two frames, but the second
1227 			 * one is not yet filled and we're not syncing?
1228 			 */
1229 			atari_enable_irq(IRQ_MFP_TIMA);
1230 			return;
1231 		}
1232 		AtaPlayNextFrame(2);
1233 	} else {
1234 		/* there's already a frame being played so we may only stuff
1235 		 * one new into the DMA, but even if this may be the last
1236 		 * frame existing the previous one is still on write_sq.count.
1237 		 */
1238 		if (write_sq.count == 2 &&
1239 		    write_sq.rear_size < write_sq.block_size &&
1240 		    !write_sq.syncing) {
1241 			/* hmmm, the only existing frame is not
1242 			 * yet filled and we're not syncing?
1243 			 */
1244 			atari_enable_irq(IRQ_MFP_TIMA);
1245 			return;
1246 		}
1247 		AtaPlayNextFrame(2);
1248 	}
1249 	atari_enable_irq(IRQ_MFP_TIMA);
1250 }
1251 
1252 
AtaInterrupt(int irq,void * dummy,struct pt_regs * fp)1253 static void AtaInterrupt(int irq, void *dummy, struct pt_regs *fp)
1254 {
1255 #if 0
1256 	/* ++TeSche: if you should want to test this... */
1257 	static int cnt = 0;
1258 	if (write_sq.active == 2)
1259 		if (++cnt == 10) {
1260 			/* simulate losing an interrupt */
1261 			cnt = 0;
1262 			return;
1263 		}
1264 #endif
1265 
1266 	if (write_sq_ignore_int && is_falcon) {
1267 		/* ++TeSche: Falcon only: ignore first irq because it comes
1268 		 * immediately after starting a frame. after that, irqs come
1269 		 * (almost) like on the TT.
1270 		 */
1271 		write_sq_ignore_int = 0;
1272 		return;
1273 	}
1274 
1275 	if (!write_sq.active) {
1276 		/* playing was interrupted and sq_reset() has already cleared
1277 		 * the sq variables, so better don't do anything here.
1278 		 */
1279 		WAKE_UP(write_sq.sync_queue);
1280 		return;
1281 	}
1282 
1283 	/* Probably ;) one frame is finished. Well, in fact it may be that a
1284 	 * pre-programmed one is also finished because there has been a long
1285 	 * delay in interrupt delivery and we've completely lost one, but
1286 	 * there's no way to detect such a situation. In such a case the last
1287 	 * frame will be played more than once and the situation will recover
1288 	 * as soon as the irq gets through.
1289 	 */
1290 	write_sq.count--;
1291 	write_sq.active--;
1292 
1293 	if (!write_sq.active) {
1294 		tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1295 		write_sq_ignore_int = 1;
1296 	}
1297 
1298 	WAKE_UP(write_sq.action_queue);
1299 	/* At least one block of the queue is free now
1300 	   so wake up a writing process blocked because
1301 	   of a full queue. */
1302 
1303 	if ((write_sq.active != 1) || (write_sq.count != 1))
1304 		/* We must be a bit carefully here: write_sq.count indicates the
1305 		 * number of buffers used and not the number of frames to be
1306 		 * played. If write_sq.count==1 and write_sq.active==1 that
1307 		 * means the only remaining frame was already programmed
1308 		 * earlier (and is currently running) so we mustn't call
1309 		 * AtaPlay() here, otherwise we'll play one frame too much.
1310 		 */
1311 		AtaPlay();
1312 
1313 	if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1314 	/* We are not playing after AtaPlay(), so there
1315 	   is nothing to play any more. Wake up a process
1316 	   waiting for audio output to drain. */
1317 }
1318 
1319 
1320 /*** Mid level stuff *********************************************************/
1321 
1322 
1323 /*
1324  * /dev/mixer abstraction
1325  */
1326 
1327 #define RECLEVEL_VOXWARE_TO_GAIN(v)	\
1328 	((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1329 #define RECLEVEL_GAIN_TO_VOXWARE(v)	(((v) * 20 + 2) / 3)
1330 
1331 
TTMixerInit(void)1332 static void __init TTMixerInit(void)
1333 {
1334 	atari_microwire_cmd(MW_LM1992_VOLUME(0));
1335 	dmasound.volume_left = 0;
1336 	atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1337 	dmasound.volume_right = 0;
1338 	atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1339 	atari_microwire_cmd(MW_LM1992_TREBLE(0));
1340 	atari_microwire_cmd(MW_LM1992_BASS(0));
1341 }
1342 
FalconMixerInit(void)1343 static void __init FalconMixerInit(void)
1344 {
1345 	dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1346 	dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1347 }
1348 
AtaMixerIoctl(u_int cmd,u_long arg)1349 static int AtaMixerIoctl(u_int cmd, u_long arg)
1350 {
1351 	int data;
1352 	switch (cmd) {
1353 	    case SOUND_MIXER_READ_SPEAKER:
1354 		    if (is_falcon || MACH_IS_TT) {
1355 			    int porta;
1356 			    cli();
1357 			    sound_ym.rd_data_reg_sel = 14;
1358 			    porta = sound_ym.rd_data_reg_sel;
1359 			    sti();
1360 			    return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1361 		    }
1362 		    break;
1363 	    case SOUND_MIXER_WRITE_VOLUME:
1364 		    IOCTL_IN(arg, data);
1365 		    return IOCTL_OUT(arg, dmasound_set_volume(data));
1366 	    case SOUND_MIXER_WRITE_SPEAKER:
1367 		    if (is_falcon || MACH_IS_TT) {
1368 			    int porta;
1369 			    IOCTL_IN(arg, data);
1370 			    cli();
1371 			    sound_ym.rd_data_reg_sel = 14;
1372 			    porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1373 				    (data < 50 ? 0x40 : 0);
1374 			    sound_ym.wd_data = porta;
1375 			    sti();
1376 			    return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1377 		    }
1378 	}
1379 	return -EINVAL;
1380 }
1381 
1382 
TTMixerIoctl(u_int cmd,u_long arg)1383 static int TTMixerIoctl(u_int cmd, u_long arg)
1384 {
1385 	int data;
1386 	switch (cmd) {
1387 	    case SOUND_MIXER_READ_RECMASK:
1388 		return IOCTL_OUT(arg, 0);
1389 	    case SOUND_MIXER_READ_DEVMASK:
1390 		return IOCTL_OUT(arg,
1391 				 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1392 				 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1393 	    case SOUND_MIXER_READ_STEREODEVS:
1394 		return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1395 	    case SOUND_MIXER_READ_VOLUME:
1396 		return IOCTL_OUT(arg,
1397 				 VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1398 				 (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1399 	    case SOUND_MIXER_READ_BASS:
1400 		return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1401 	    case SOUND_MIXER_READ_TREBLE:
1402 		return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1403 	    case SOUND_MIXER_READ_OGAIN:
1404 		return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1405 	    case SOUND_MIXER_WRITE_BASS:
1406 		IOCTL_IN(arg, data);
1407 		return IOCTL_OUT(arg, dmasound_set_bass(data));
1408 	    case SOUND_MIXER_WRITE_TREBLE:
1409 		IOCTL_IN(arg, data);
1410 		return IOCTL_OUT(arg, dmasound_set_treble(data));
1411 	    case SOUND_MIXER_WRITE_OGAIN:
1412 		IOCTL_IN(arg, data);
1413 		return IOCTL_OUT(arg, dmasound_set_gain(data));
1414 	}
1415 	return AtaMixerIoctl(cmd, arg);
1416 }
1417 
FalconMixerIoctl(u_int cmd,u_long arg)1418 static int FalconMixerIoctl(u_int cmd, u_long arg)
1419 {
1420 	int data;
1421 	switch (cmd) {
1422 	    case SOUND_MIXER_READ_RECMASK:
1423 		return IOCTL_OUT(arg, SOUND_MASK_MIC);
1424 	    case SOUND_MIXER_READ_DEVMASK:
1425 		return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1426 	    case SOUND_MIXER_READ_STEREODEVS:
1427 		return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1428 	    case SOUND_MIXER_READ_VOLUME:
1429 		return IOCTL_OUT(arg,
1430 			VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1431 			VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1432 	    case SOUND_MIXER_READ_CAPS:
1433 		return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1434 	    case SOUND_MIXER_WRITE_MIC:
1435 		IOCTL_IN(arg, data);
1436 		tt_dmasnd.input_gain =
1437 			RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1438 			RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1439 		/* fall thru, return set value */
1440 	    case SOUND_MIXER_READ_MIC:
1441 		return IOCTL_OUT(arg,
1442 			RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1443 			RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1444 	}
1445 	return AtaMixerIoctl(cmd, arg);
1446 }
1447 
AtaWriteSqSetup(void)1448 static int AtaWriteSqSetup(void)
1449 {
1450 	write_sq_ignore_int = 0;
1451 	return 0 ;
1452 }
1453 
AtaSqOpen(mode_t mode)1454 static int AtaSqOpen(mode_t mode)
1455 {
1456 	write_sq_ignore_int = 1;
1457 	return 0 ;
1458 }
1459 
TTStateInfo(char * buffer,size_t space)1460 static int TTStateInfo(char *buffer, size_t space)
1461 {
1462 	int len = 0;
1463 	len += sprintf(buffer+len, "\tvol left  %ddB [-40...  0]\n",
1464 		       dmasound.volume_left);
1465 	len += sprintf(buffer+len, "\tvol right %ddB [-40...  0]\n",
1466 		       dmasound.volume_right);
1467 	len += sprintf(buffer+len, "\tbass      %ddB [-12...+12]\n",
1468 		       dmasound.bass);
1469 	len += sprintf(buffer+len, "\ttreble    %ddB [-12...+12]\n",
1470 		       dmasound.treble);
1471 	if (len >= space) {
1472 		printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1473 		len = space ;
1474 	}
1475 	return len;
1476 }
1477 
FalconStateInfo(char * buffer,size_t space)1478 static int FalconStateInfo(char *buffer, size_t space)
1479 {
1480 	int len = 0;
1481 	len += sprintf(buffer+len, "\tvol left  %ddB [-22.5 ... 0]\n",
1482 		       dmasound.volume_left);
1483 	len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1484 		       dmasound.volume_right);
1485 	if (len >= space) {
1486 		printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1487 		len = space ;
1488 	}
1489 	return len;
1490 }
1491 
1492 
1493 /*** Machine definitions *****************************************************/
1494 
1495 static SETTINGS def_hard_falcon = {
1496 	format: AFMT_S8,
1497 	stereo: 0,
1498 	size: 8,
1499 	speed: 8195
1500 } ;
1501 
1502 static SETTINGS def_hard_tt = {
1503 	format: AFMT_S8,
1504 	stereo: 0,
1505 	size: 8,
1506 	speed: 12517
1507 } ;
1508 
1509 static SETTINGS def_soft = {
1510 	format: AFMT_U8,
1511 	stereo: 0,
1512 	size: 8,
1513 	speed: 8000
1514 } ;
1515 
1516 static MACHINE machTT = {
1517 	name:		"Atari",
1518 	name2:		"TT",
1519 	open:		AtaOpen,
1520 	release:	AtaRelease,
1521 	dma_alloc:	AtaAlloc,
1522 	dma_free:	AtaFree,
1523 	irqinit:	AtaIrqInit,
1524 #ifdef MODULE
1525 	irqcleanup:	AtaIrqCleanUp,
1526 #endif /* MODULE */
1527 	init:		TTInit,
1528 	silence:	TTSilence,
1529 	setFormat:	TTSetFormat,
1530 	setVolume:	TTSetVolume,
1531 	setBass:	AtaSetBass,
1532 	setTreble:	AtaSetTreble,
1533 	setGain:	TTSetGain,
1534 	play:		AtaPlay,
1535 	mixer_init:	TTMixerInit,
1536 	mixer_ioctl:	TTMixerIoctl,
1537 	write_sq_setup:	AtaWriteSqSetup,
1538 	sq_open:	AtaSqOpen,
1539 	state_info:	TTStateInfo,
1540 	min_dsp_speed:	6258,
1541 	version:	((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1542 	hardware_afmts:	AFMT_S8,  /* h'ware-supported formats *only* here */
1543 	capabilities:	 DSP_CAP_BATCH	/* As per SNDCTL_DSP_GETCAPS */
1544 };
1545 
1546 static MACHINE machFalcon = {
1547 	name:		"Atari",
1548 	name2:		"FALCON",
1549 	dma_alloc:	AtaAlloc,
1550 	dma_free:	AtaFree,
1551 	irqinit:	AtaIrqInit,
1552 #ifdef MODULE
1553 	irqcleanup:	AtaIrqCleanUp,
1554 #endif /* MODULE */
1555 	init:		FalconInit,
1556 	silence:	FalconSilence,
1557 	setFormat:	FalconSetFormat,
1558 	setVolume:	FalconSetVolume,
1559 	setBass:	AtaSetBass,
1560 	setTreble:	AtaSetTreble,
1561 	play:		AtaPlay,
1562 	mixer_init:	FalconMixerInit,
1563 	mixer_ioctl:	FalconMixerIoctl,
1564 	write_sq_setup:	AtaWriteSqSetup,
1565 	sq_open:	AtaSqOpen,
1566 	state_info:	FalconStateInfo,
1567 	min_dsp_speed:	8195,
1568 	version:	((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1569 	hardware_afmts:	(AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1570 	capabilities:	 DSP_CAP_BATCH	/* As per SNDCTL_DSP_GETCAPS */
1571 };
1572 
1573 
1574 /*** Config & Setup **********************************************************/
1575 
1576 
dmasound_atari_init(void)1577 static int __init dmasound_atari_init(void)
1578 {
1579 	if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1580 	    if (ATARIHW_PRESENT(CODEC)) {
1581 		dmasound.mach = machFalcon;
1582 		dmasound.mach.default_soft = def_soft ;
1583 		dmasound.mach.default_hard = def_hard_falcon ;
1584 		is_falcon = 1;
1585 	    } else if (ATARIHW_PRESENT(MICROWIRE)) {
1586 		dmasound.mach = machTT;
1587 		dmasound.mach.default_soft = def_soft ;
1588 		dmasound.mach.default_hard = def_hard_tt ;
1589 		is_falcon = 0;
1590 	    } else
1591 		return -ENODEV;
1592 	    if ((mfp.int_en_a & mfp.int_mk_a & 0x20) == 0)
1593 		return dmasound_init();
1594 	    else {
1595 		printk("DMA sound driver: Timer A interrupt already in use\n");
1596 		return -EBUSY;
1597 	    }
1598 	}
1599 	return -ENODEV;
1600 }
1601 
dmasound_atari_cleanup(void)1602 static void __exit dmasound_atari_cleanup(void)
1603 {
1604 	dmasound_deinit();
1605 }
1606 
1607 module_init(dmasound_atari_init);
1608 module_exit(dmasound_atari_cleanup);
1609 MODULE_LICENSE("GPL");
1610