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