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