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