• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/oss/dmasound/
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 __user *userPtr, size_t userCount,
71			  u_char frame[], ssize_t *frameUsed,
72			  ssize_t frameLeft);
73static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
74			 u_char frame[], ssize_t *frameUsed,
75			 ssize_t frameLeft);
76static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
77			 u_char frame[], ssize_t *frameUsed,
78			 ssize_t frameLeft);
79static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
80			    u_char frame[], ssize_t *frameUsed,
81			    ssize_t frameLeft);
82static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
83			    u_char frame[], ssize_t *frameUsed,
84			    ssize_t frameLeft);
85static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
86			    u_char frame[], ssize_t *frameUsed,
87			    ssize_t frameLeft);
88static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
89			    u_char frame[], ssize_t *frameUsed,
90			    ssize_t frameLeft);
91static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
92			   u_char frame[], ssize_t *frameUsed,
93			   ssize_t frameLeft);
94static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
95			  u_char frame[], ssize_t *frameUsed,
96			  ssize_t frameLeft);
97static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
98			  u_char frame[], ssize_t *frameUsed,
99			  ssize_t frameLeft);
100static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
101			     u_char frame[], ssize_t *frameUsed,
102			     ssize_t frameLeft);
103static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
104			     u_char frame[], ssize_t *frameUsed,
105			     ssize_t frameLeft);
106static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
107			     u_char frame[], ssize_t *frameUsed,
108			     ssize_t frameLeft);
109static ssize_t ata_ctx_u16le(const u_char __user *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);
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(fmode_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 __user *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 __user *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 __user *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 __user *)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 __user *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 __user *)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 __user *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 __user *)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_int data;
291			if (get_user(data, (u_int __user *)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 __user *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 __user *)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 __user *)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 __user *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 __user *)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 __user *)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 __user *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 __user *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 __user *)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 __user *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 __user *)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 __user *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 __user *)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 __user *)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 __user *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 __user *)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 __user *)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 __user *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 __user *)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 __user *)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 __user *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 __user *)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 __user *)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	st_mfp.tim_ct_a = 0;	/* ++roman: Stop timer before programming! */
851	st_mfp.tim_dt_a = 1;	/* Cause interrupt after first event. */
852	st_mfp.tim_ct_a = 8;	/* Turn on event counting. */
853	/* Register interrupt handler. */
854	if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
855			AtaInterrupt))
856		return 0;
857	st_mfp.int_en_a |= 0x20;	/* Turn interrupt on. */
858	st_mfp.int_mk_a |= 0x20;
859	return 1;
860}
861
862#ifdef MODULE
863static void AtaIrqCleanUp(void)
864{
865	st_mfp.tim_ct_a = 0;		/* stop timer */
866	st_mfp.int_en_a &= ~0x20;	/* turn interrupt off */
867	free_irq(IRQ_MFP_TIMA, AtaInterrupt);
868}
869#endif /* MODULE */
870
871
872#define TONE_VOXWARE_TO_DB(v) \
873	(((v) < 0) ? -12 : ((v) > 100) ? 12 : ((v) - 50) * 6 / 25)
874#define TONE_DB_TO_VOXWARE(v) (((v) * 25 + ((v) > 0 ? 5 : -5)) / 6 + 50)
875
876
877static int AtaSetBass(int bass)
878{
879	dmasound.bass = TONE_VOXWARE_TO_DB(bass);
880	atari_microwire_cmd(MW_LM1992_BASS(dmasound.bass));
881	return TONE_DB_TO_VOXWARE(dmasound.bass);
882}
883
884
885static int AtaSetTreble(int treble)
886{
887	dmasound.treble = TONE_VOXWARE_TO_DB(treble);
888	atari_microwire_cmd(MW_LM1992_TREBLE(dmasound.treble));
889	return TONE_DB_TO_VOXWARE(dmasound.treble);
890}
891
892
893
894/*
895 * TT
896 */
897
898
899static void TTSilence(void)
900{
901	tt_dmasnd.ctrl = DMASND_CTRL_OFF;
902	atari_microwire_cmd(MW_LM1992_PSG_HIGH); /* mix in PSG signal 1:1 */
903}
904
905
906static void TTInit(void)
907{
908	int mode, i, idx;
909	const int freq[4] = {50066, 25033, 12517, 6258};
910
911	/* search a frequency that fits into the allowed error range */
912
913	idx = -1;
914	for (i = 0; i < ARRAY_SIZE(freq); i++)
915		/* this isn't as much useful for a TT than for a Falcon, but
916		 * then it doesn't hurt very much to implement it for a TT too.
917		 */
918		if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
919			idx = i;
920	if (idx > -1) {
921		dmasound.soft.speed = freq[idx];
922		dmasound.trans_write = &transTTNormal;
923	} else
924		dmasound.trans_write = &transTTExpanding;
925
926	TTSilence();
927	dmasound.hard = dmasound.soft;
928
929	if (dmasound.hard.speed > 50066) {
930		/* we would need to squeeze the sound, but we won't do that */
931		dmasound.hard.speed = 50066;
932		mode = DMASND_MODE_50KHZ;
933		dmasound.trans_write = &transTTNormal;
934	} else if (dmasound.hard.speed > 25033) {
935		dmasound.hard.speed = 50066;
936		mode = DMASND_MODE_50KHZ;
937	} else if (dmasound.hard.speed > 12517) {
938		dmasound.hard.speed = 25033;
939		mode = DMASND_MODE_25KHZ;
940	} else if (dmasound.hard.speed > 6258) {
941		dmasound.hard.speed = 12517;
942		mode = DMASND_MODE_12KHZ;
943	} else {
944		dmasound.hard.speed = 6258;
945		mode = DMASND_MODE_6KHZ;
946	}
947
948	tt_dmasnd.mode = (dmasound.hard.stereo ?
949			  DMASND_MODE_STEREO : DMASND_MODE_MONO) |
950		DMASND_MODE_8BIT | mode;
951
952	expand_bal = -dmasound.soft.speed;
953}
954
955
956static int TTSetFormat(int format)
957{
958	/* TT sound DMA supports only 8bit modes */
959
960	switch (format) {
961	case AFMT_QUERY:
962		return dmasound.soft.format;
963	case AFMT_MU_LAW:
964	case AFMT_A_LAW:
965	case AFMT_S8:
966	case AFMT_U8:
967		break;
968	default:
969		format = AFMT_S8;
970	}
971
972	dmasound.soft.format = format;
973	dmasound.soft.size = 8;
974	if (dmasound.minDev == SND_DEV_DSP) {
975		dmasound.dsp.format = format;
976		dmasound.dsp.size = 8;
977	}
978	TTInit();
979
980	return format;
981}
982
983
984#define VOLUME_VOXWARE_TO_DB(v) \
985	(((v) < 0) ? -40 : ((v) > 100) ? 0 : ((v) * 2) / 5 - 40)
986#define VOLUME_DB_TO_VOXWARE(v) ((((v) + 40) * 5 + 1) / 2)
987
988
989static int TTSetVolume(int volume)
990{
991	dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
992	atari_microwire_cmd(MW_LM1992_BALLEFT(dmasound.volume_left));
993	dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
994	atari_microwire_cmd(MW_LM1992_BALRIGHT(dmasound.volume_right));
995	return VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
996	       (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8);
997}
998
999
1000#define GAIN_VOXWARE_TO_DB(v) \
1001	(((v) < 0) ? -80 : ((v) > 100) ? 0 : ((v) * 4) / 5 - 80)
1002#define GAIN_DB_TO_VOXWARE(v) ((((v) + 80) * 5 + 1) / 4)
1003
1004static int TTSetGain(int gain)
1005{
1006	dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
1007	atari_microwire_cmd(MW_LM1992_VOLUME(dmasound.gain));
1008	return GAIN_DB_TO_VOXWARE(dmasound.gain);
1009}
1010
1011
1012
1013/*
1014 * Falcon
1015 */
1016
1017
1018static void FalconSilence(void)
1019{
1020	/* stop playback, set sample rate 50kHz for PSG sound */
1021	tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1022	tt_dmasnd.mode = DMASND_MODE_50KHZ | DMASND_MODE_STEREO | DMASND_MODE_8BIT;
1023	tt_dmasnd.int_div = 0; /* STE compatible divider */
1024	tt_dmasnd.int_ctrl = 0x0;
1025	tt_dmasnd.cbar_src = 0x0000; /* no matrix inputs */
1026	tt_dmasnd.cbar_dst = 0x0000; /* no matrix outputs */
1027	tt_dmasnd.dac_src = 1; /* connect ADC to DAC, disconnect matrix */
1028	tt_dmasnd.adc_src = 3; /* ADC Input = PSG */
1029}
1030
1031
1032static void FalconInit(void)
1033{
1034	int divider, i, idx;
1035	const int freq[8] = {49170, 32780, 24585, 19668, 16390, 12292, 9834, 8195};
1036
1037	/* search a frequency that fits into the allowed error range */
1038
1039	idx = -1;
1040	for (i = 0; i < ARRAY_SIZE(freq); i++)
1041		/* if we will tolerate 3% error 8000Hz->8195Hz (2.38%) would
1042		 * be playable without expanding, but that now a kernel runtime
1043		 * option
1044		 */
1045		if ((100 * abs(dmasound.soft.speed - freq[i]) / freq[i]) < catchRadius)
1046			idx = i;
1047	if (idx > -1) {
1048		dmasound.soft.speed = freq[idx];
1049		dmasound.trans_write = &transFalconNormal;
1050	} else
1051		dmasound.trans_write = &transFalconExpanding;
1052
1053	FalconSilence();
1054	dmasound.hard = dmasound.soft;
1055
1056	if (dmasound.hard.size == 16) {
1057		/* the Falcon can play 16bit samples only in stereo */
1058		dmasound.hard.stereo = 1;
1059	}
1060
1061	if (dmasound.hard.speed > 49170) {
1062		/* we would need to squeeze the sound, but we won't do that */
1063		dmasound.hard.speed = 49170;
1064		divider = 1;
1065		dmasound.trans_write = &transFalconNormal;
1066	} else if (dmasound.hard.speed > 32780) {
1067		dmasound.hard.speed = 49170;
1068		divider = 1;
1069	} else if (dmasound.hard.speed > 24585) {
1070		dmasound.hard.speed = 32780;
1071		divider = 2;
1072	} else if (dmasound.hard.speed > 19668) {
1073		dmasound.hard.speed = 24585;
1074		divider = 3;
1075	} else if (dmasound.hard.speed > 16390) {
1076		dmasound.hard.speed = 19668;
1077		divider = 4;
1078	} else if (dmasound.hard.speed > 12292) {
1079		dmasound.hard.speed = 16390;
1080		divider = 5;
1081	} else if (dmasound.hard.speed > 9834) {
1082		dmasound.hard.speed = 12292;
1083		divider = 7;
1084	} else if (dmasound.hard.speed > 8195) {
1085		dmasound.hard.speed = 9834;
1086		divider = 9;
1087	} else {
1088		dmasound.hard.speed = 8195;
1089		divider = 11;
1090	}
1091	tt_dmasnd.int_div = divider;
1092
1093	/* Setup Falcon sound DMA for playback */
1094	tt_dmasnd.int_ctrl = 0x4; /* Timer A int at play end */
1095	tt_dmasnd.track_select = 0x0; /* play 1 track, track 1 */
1096	tt_dmasnd.cbar_src = 0x0001; /* DMA(25MHz) --> DAC */
1097	tt_dmasnd.cbar_dst = 0x0000;
1098	tt_dmasnd.rec_track_select = 0;
1099	tt_dmasnd.dac_src = 2; /* connect matrix to DAC */
1100	tt_dmasnd.adc_src = 0; /* ADC Input = Mic */
1101
1102	tt_dmasnd.mode = (dmasound.hard.stereo ?
1103			  DMASND_MODE_STEREO : DMASND_MODE_MONO) |
1104		((dmasound.hard.size == 8) ?
1105		 DMASND_MODE_8BIT : DMASND_MODE_16BIT) |
1106		DMASND_MODE_6KHZ;
1107
1108	expand_bal = -dmasound.soft.speed;
1109}
1110
1111
1112static int FalconSetFormat(int format)
1113{
1114	int size;
1115	/* Falcon sound DMA supports 8bit and 16bit modes */
1116
1117	switch (format) {
1118	case AFMT_QUERY:
1119		return dmasound.soft.format;
1120	case AFMT_MU_LAW:
1121	case AFMT_A_LAW:
1122	case AFMT_U8:
1123	case AFMT_S8:
1124		size = 8;
1125		break;
1126	case AFMT_S16_BE:
1127	case AFMT_U16_BE:
1128	case AFMT_S16_LE:
1129	case AFMT_U16_LE:
1130		size = 16;
1131		break;
1132	default: /* :-) */
1133		size = 8;
1134		format = AFMT_S8;
1135	}
1136
1137	dmasound.soft.format = format;
1138	dmasound.soft.size = size;
1139	if (dmasound.minDev == SND_DEV_DSP) {
1140		dmasound.dsp.format = format;
1141		dmasound.dsp.size = dmasound.soft.size;
1142	}
1143
1144	FalconInit();
1145
1146	return format;
1147}
1148
1149
1150/* This is for the Falcon output *attenuation* in 1.5dB steps,
1151 * i.e. output level from 0 to -22.5dB in -1.5dB steps.
1152 */
1153#define VOLUME_VOXWARE_TO_ATT(v) \
1154	((v) < 0 ? 15 : (v) > 100 ? 0 : 15 - (v) * 3 / 20)
1155#define VOLUME_ATT_TO_VOXWARE(v) (100 - (v) * 20 / 3)
1156
1157
1158static int FalconSetVolume(int volume)
1159{
1160	dmasound.volume_left = VOLUME_VOXWARE_TO_ATT(volume & 0xff);
1161	dmasound.volume_right = VOLUME_VOXWARE_TO_ATT((volume & 0xff00) >> 8);
1162	tt_dmasnd.output_atten = dmasound.volume_left << 8 | dmasound.volume_right << 4;
1163	return VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1164	       VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8;
1165}
1166
1167
1168static void AtaPlayNextFrame(int index)
1169{
1170	char *start, *end;
1171
1172	/* used by AtaPlay() if all doubts whether there really is something
1173	 * to be played are already wiped out.
1174	 */
1175	start = write_sq.buffers[write_sq.front];
1176	end = start+((write_sq.count == index) ? write_sq.rear_size
1177					       : write_sq.block_size);
1178	/* end might not be a legal virtual address. */
1179	DMASNDSetEnd(virt_to_phys(end - 1) + 1);
1180	DMASNDSetBase(virt_to_phys(start));
1181	/* Since only an even number of samples per frame can
1182	   be played, we might lose one byte here. (TO DO) */
1183	write_sq.front = (write_sq.front+1) % write_sq.max_count;
1184	write_sq.active++;
1185	tt_dmasnd.ctrl = DMASND_CTRL_ON | DMASND_CTRL_REPEAT;
1186}
1187
1188
1189static void AtaPlay(void)
1190{
1191	/* ++TeSche: Note that write_sq.active is no longer just a flag but
1192	 * holds the number of frames the DMA is currently programmed for
1193	 * instead, may be 0, 1 (currently being played) or 2 (pre-programmed).
1194	 *
1195	 * Changes done to write_sq.count and write_sq.active are a bit more
1196	 * subtle again so now I must admit I also prefer disabling the irq
1197	 * here rather than considering all possible situations. But the point
1198	 * is that disabling the irq doesn't have any bad influence on this
1199	 * version of the driver as we benefit from having pre-programmed the
1200	 * DMA wherever possible: There's no need to reload the DMA at the
1201	 * exact time of an interrupt but only at some time while the
1202	 * pre-programmed frame is playing!
1203	 */
1204	atari_disable_irq(IRQ_MFP_TIMA);
1205
1206	if (write_sq.active == 2 ||	/* DMA is 'full' */
1207	    write_sq.count <= 0) {	/* nothing to do */
1208		atari_enable_irq(IRQ_MFP_TIMA);
1209		return;
1210	}
1211
1212	if (write_sq.active == 0) {
1213		/* looks like there's nothing 'in' the DMA yet, so try
1214		 * to put two frames into it (at least one is available).
1215		 */
1216		if (write_sq.count == 1 &&
1217		    write_sq.rear_size < write_sq.block_size &&
1218		    !write_sq.syncing) {
1219			/* hmmm, the only existing frame is not
1220			 * yet filled and we're not syncing?
1221			 */
1222			atari_enable_irq(IRQ_MFP_TIMA);
1223			return;
1224		}
1225		AtaPlayNextFrame(1);
1226		if (write_sq.count == 1) {
1227			/* no more frames */
1228			atari_enable_irq(IRQ_MFP_TIMA);
1229			return;
1230		}
1231		if (write_sq.count == 2 &&
1232		    write_sq.rear_size < write_sq.block_size &&
1233		    !write_sq.syncing) {
1234			/* hmmm, there were two frames, but the second
1235			 * one is not yet filled and we're not syncing?
1236			 */
1237			atari_enable_irq(IRQ_MFP_TIMA);
1238			return;
1239		}
1240		AtaPlayNextFrame(2);
1241	} else {
1242		/* there's already a frame being played so we may only stuff
1243		 * one new into the DMA, but even if this may be the last
1244		 * frame existing the previous one is still on write_sq.count.
1245		 */
1246		if (write_sq.count == 2 &&
1247		    write_sq.rear_size < write_sq.block_size &&
1248		    !write_sq.syncing) {
1249			/* hmmm, the only existing frame is not
1250			 * yet filled and we're not syncing?
1251			 */
1252			atari_enable_irq(IRQ_MFP_TIMA);
1253			return;
1254		}
1255		AtaPlayNextFrame(2);
1256	}
1257	atari_enable_irq(IRQ_MFP_TIMA);
1258}
1259
1260
1261static irqreturn_t AtaInterrupt(int irq, void *dummy)
1262{
1263	spin_lock(&dmasound.lock);
1264	if (write_sq_ignore_int && is_falcon) {
1265		/* ++TeSche: Falcon only: ignore first irq because it comes
1266		 * immediately after starting a frame. after that, irqs come
1267		 * (almost) like on the TT.
1268		 */
1269		write_sq_ignore_int = 0;
1270		goto out;
1271	}
1272
1273	if (!write_sq.active) {
1274		/* playing was interrupted and sq_reset() has already cleared
1275		 * the sq variables, so better don't do anything here.
1276		 */
1277		WAKE_UP(write_sq.sync_queue);
1278		goto out;
1279	}
1280
1281	/* Probably ;) one frame is finished. Well, in fact it may be that a
1282	 * pre-programmed one is also finished because there has been a long
1283	 * delay in interrupt delivery and we've completely lost one, but
1284	 * there's no way to detect such a situation. In such a case the last
1285	 * frame will be played more than once and the situation will recover
1286	 * as soon as the irq gets through.
1287	 */
1288	write_sq.count--;
1289	write_sq.active--;
1290
1291	if (!write_sq.active) {
1292		tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1293		write_sq_ignore_int = 1;
1294	}
1295
1296	WAKE_UP(write_sq.action_queue);
1297	/* At least one block of the queue is free now
1298	   so wake up a writing process blocked because
1299	   of a full queue. */
1300
1301	if ((write_sq.active != 1) || (write_sq.count != 1))
1302		/* We must be a bit carefully here: write_sq.count indicates the
1303		 * number of buffers used and not the number of frames to be
1304		 * played. If write_sq.count==1 and write_sq.active==1 that
1305		 * means the only remaining frame was already programmed
1306		 * earlier (and is currently running) so we mustn't call
1307		 * AtaPlay() here, otherwise we'll play one frame too much.
1308		 */
1309		AtaPlay();
1310
1311	if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1312	/* We are not playing after AtaPlay(), so there
1313	   is nothing to play any more. Wake up a process
1314	   waiting for audio output to drain. */
1315out:
1316	spin_unlock(&dmasound.lock);
1317	return IRQ_HANDLED;
1318}
1319
1320
1321/*** Mid level stuff *********************************************************/
1322
1323
1324/*
1325 * /dev/mixer abstraction
1326 */
1327
1328#define RECLEVEL_VOXWARE_TO_GAIN(v)	\
1329	((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1330#define RECLEVEL_GAIN_TO_VOXWARE(v)	(((v) * 20 + 2) / 3)
1331
1332
1333static void __init TTMixerInit(void)
1334{
1335	atari_microwire_cmd(MW_LM1992_VOLUME(0));
1336	dmasound.volume_left = 0;
1337	atari_microwire_cmd(MW_LM1992_BALLEFT(0));
1338	dmasound.volume_right = 0;
1339	atari_microwire_cmd(MW_LM1992_BALRIGHT(0));
1340	atari_microwire_cmd(MW_LM1992_TREBLE(0));
1341	atari_microwire_cmd(MW_LM1992_BASS(0));
1342}
1343
1344static void __init FalconMixerInit(void)
1345{
1346	dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1347	dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1348}
1349
1350static int AtaMixerIoctl(u_int cmd, u_long arg)
1351{
1352	int data;
1353	unsigned long flags;
1354	switch (cmd) {
1355	    case SOUND_MIXER_READ_SPEAKER:
1356		    if (is_falcon || MACH_IS_TT) {
1357			    int porta;
1358			    spin_lock_irqsave(&dmasound.lock, flags);
1359			    sound_ym.rd_data_reg_sel = 14;
1360			    porta = sound_ym.rd_data_reg_sel;
1361			    spin_unlock_irqrestore(&dmasound.lock, flags);
1362			    return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1363		    }
1364		    break;
1365	    case SOUND_MIXER_WRITE_VOLUME:
1366		    IOCTL_IN(arg, data);
1367		    return IOCTL_OUT(arg, dmasound_set_volume(data));
1368	    case SOUND_MIXER_WRITE_SPEAKER:
1369		    if (is_falcon || MACH_IS_TT) {
1370			    int porta;
1371			    IOCTL_IN(arg, data);
1372			    spin_lock_irqsave(&dmasound.lock, flags);
1373			    sound_ym.rd_data_reg_sel = 14;
1374			    porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1375				    (data < 50 ? 0x40 : 0);
1376			    sound_ym.wd_data = porta;
1377			    spin_unlock_irqrestore(&dmasound.lock, flags);
1378			    return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1379		    }
1380	}
1381	return -EINVAL;
1382}
1383
1384
1385static int TTMixerIoctl(u_int cmd, u_long arg)
1386{
1387	int data;
1388	switch (cmd) {
1389	    case SOUND_MIXER_READ_RECMASK:
1390		return IOCTL_OUT(arg, 0);
1391	    case SOUND_MIXER_READ_DEVMASK:
1392		return IOCTL_OUT(arg,
1393				 SOUND_MASK_VOLUME | SOUND_MASK_TREBLE | SOUND_MASK_BASS |
1394				 (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1395	    case SOUND_MIXER_READ_STEREODEVS:
1396		return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1397	    case SOUND_MIXER_READ_VOLUME:
1398		return IOCTL_OUT(arg,
1399				 VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1400				 (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1401	    case SOUND_MIXER_READ_BASS:
1402		return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1403	    case SOUND_MIXER_READ_TREBLE:
1404		return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1405	    case SOUND_MIXER_READ_OGAIN:
1406		return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1407	    case SOUND_MIXER_WRITE_BASS:
1408		IOCTL_IN(arg, data);
1409		return IOCTL_OUT(arg, dmasound_set_bass(data));
1410	    case SOUND_MIXER_WRITE_TREBLE:
1411		IOCTL_IN(arg, data);
1412		return IOCTL_OUT(arg, dmasound_set_treble(data));
1413	    case SOUND_MIXER_WRITE_OGAIN:
1414		IOCTL_IN(arg, data);
1415		return IOCTL_OUT(arg, dmasound_set_gain(data));
1416	}
1417	return AtaMixerIoctl(cmd, arg);
1418}
1419
1420static int FalconMixerIoctl(u_int cmd, u_long arg)
1421{
1422	int data;
1423	switch (cmd) {
1424	    case SOUND_MIXER_READ_RECMASK:
1425		return IOCTL_OUT(arg, SOUND_MASK_MIC);
1426	    case SOUND_MIXER_READ_DEVMASK:
1427		return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_SPEAKER);
1428	    case SOUND_MIXER_READ_STEREODEVS:
1429		return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC);
1430	    case SOUND_MIXER_READ_VOLUME:
1431		return IOCTL_OUT(arg,
1432			VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1433			VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1434	    case SOUND_MIXER_READ_CAPS:
1435		return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1436	    case SOUND_MIXER_WRITE_MIC:
1437		IOCTL_IN(arg, data);
1438		tt_dmasnd.input_gain =
1439			RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1440			RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1441		/* fall thru, return set value */
1442	    case SOUND_MIXER_READ_MIC:
1443		return IOCTL_OUT(arg,
1444			RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1445			RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1446	}
1447	return AtaMixerIoctl(cmd, arg);
1448}
1449
1450static int AtaWriteSqSetup(void)
1451{
1452	write_sq_ignore_int = 0;
1453	return 0 ;
1454}
1455
1456static int AtaSqOpen(fmode_t mode)
1457{
1458	write_sq_ignore_int = 1;
1459	return 0 ;
1460}
1461
1462static int TTStateInfo(char *buffer, size_t space)
1463{
1464	int len = 0;
1465	len += sprintf(buffer+len, "\tvol left  %ddB [-40...  0]\n",
1466		       dmasound.volume_left);
1467	len += sprintf(buffer+len, "\tvol right %ddB [-40...  0]\n",
1468		       dmasound.volume_right);
1469	len += sprintf(buffer+len, "\tbass      %ddB [-12...+12]\n",
1470		       dmasound.bass);
1471	len += sprintf(buffer+len, "\ttreble    %ddB [-12...+12]\n",
1472		       dmasound.treble);
1473	if (len >= space) {
1474		printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1475		len = space ;
1476	}
1477	return len;
1478}
1479
1480static int FalconStateInfo(char *buffer, size_t space)
1481{
1482	int len = 0;
1483	len += sprintf(buffer+len, "\tvol left  %ddB [-22.5 ... 0]\n",
1484		       dmasound.volume_left);
1485	len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1486		       dmasound.volume_right);
1487	if (len >= space) {
1488		printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1489		len = space ;
1490	}
1491	return len;
1492}
1493
1494
1495/*** Machine definitions *****************************************************/
1496
1497static SETTINGS def_hard_falcon = {
1498	.format		= AFMT_S8,
1499	.stereo		= 0,
1500	.size		= 8,
1501	.speed		= 8195
1502} ;
1503
1504static SETTINGS def_hard_tt = {
1505	.format	= AFMT_S8,
1506	.stereo	= 0,
1507	.size	= 8,
1508	.speed	= 12517
1509} ;
1510
1511static SETTINGS def_soft = {
1512	.format	= AFMT_U8,
1513	.stereo	= 0,
1514	.size	= 8,
1515	.speed	= 8000
1516} ;
1517
1518static __initdata MACHINE machTT = {
1519	.name		= "Atari",
1520	.name2		= "TT",
1521	.owner		= THIS_MODULE,
1522	.dma_alloc	= AtaAlloc,
1523	.dma_free	= AtaFree,
1524	.irqinit	= AtaIrqInit,
1525#ifdef MODULE
1526	.irqcleanup	= AtaIrqCleanUp,
1527#endif /* MODULE */
1528	.init		= TTInit,
1529	.silence	= TTSilence,
1530	.setFormat	= TTSetFormat,
1531	.setVolume	= TTSetVolume,
1532	.setBass	= AtaSetBass,
1533	.setTreble	= AtaSetTreble,
1534	.setGain	= TTSetGain,
1535	.play		= AtaPlay,
1536	.mixer_init	= TTMixerInit,
1537	.mixer_ioctl	= TTMixerIoctl,
1538	.write_sq_setup	= AtaWriteSqSetup,
1539	.sq_open	= AtaSqOpen,
1540	.state_info	= TTStateInfo,
1541	.min_dsp_speed	= 6258,
1542	.version	= ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1543	.hardware_afmts	= AFMT_S8,  /* h'ware-supported formats *only* here */
1544	.capabilities	=  DSP_CAP_BATCH	/* As per SNDCTL_DSP_GETCAPS */
1545};
1546
1547static __initdata MACHINE machFalcon = {
1548	.name		= "Atari",
1549	.name2		= "FALCON",
1550	.dma_alloc	= AtaAlloc,
1551	.dma_free	= AtaFree,
1552	.irqinit	= AtaIrqInit,
1553#ifdef MODULE
1554	.irqcleanup	= AtaIrqCleanUp,
1555#endif /* MODULE */
1556	.init		= FalconInit,
1557	.silence	= FalconSilence,
1558	.setFormat	= FalconSetFormat,
1559	.setVolume	= FalconSetVolume,
1560	.setBass	= AtaSetBass,
1561	.setTreble	= AtaSetTreble,
1562	.play		= AtaPlay,
1563	.mixer_init	= FalconMixerInit,
1564	.mixer_ioctl	= FalconMixerIoctl,
1565	.write_sq_setup	= AtaWriteSqSetup,
1566	.sq_open	= AtaSqOpen,
1567	.state_info	= FalconStateInfo,
1568	.min_dsp_speed	= 8195,
1569	.version	= ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1570	.hardware_afmts	= (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1571	.capabilities	=  DSP_CAP_BATCH	/* As per SNDCTL_DSP_GETCAPS */
1572};
1573
1574
1575/*** Config & Setup **********************************************************/
1576
1577
1578static int __init dmasound_atari_init(void)
1579{
1580	if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1581	    if (ATARIHW_PRESENT(CODEC)) {
1582		dmasound.mach = machFalcon;
1583		dmasound.mach.default_soft = def_soft ;
1584		dmasound.mach.default_hard = def_hard_falcon ;
1585		is_falcon = 1;
1586	    } else if (ATARIHW_PRESENT(MICROWIRE)) {
1587		dmasound.mach = machTT;
1588		dmasound.mach.default_soft = def_soft ;
1589		dmasound.mach.default_hard = def_hard_tt ;
1590		is_falcon = 0;
1591	    } else
1592		return -ENODEV;
1593	    if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0)
1594		return dmasound_init();
1595	    else {
1596		printk("DMA sound driver: Timer A interrupt already in use\n");
1597		return -EBUSY;
1598	    }
1599	}
1600	return -ENODEV;
1601}
1602
1603static void __exit dmasound_atari_cleanup(void)
1604{
1605	dmasound_deinit();
1606}
1607
1608module_init(dmasound_atari_init);
1609module_exit(dmasound_atari_cleanup);
1610MODULE_LICENSE("GPL");
1611