Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dmasound_atari.c
Go to the documentation of this file.
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 
34 extern void atari_microwire_cmd(int cmd);
35 
36 static int is_falcon;
37 static int write_sq_ignore_int; /* ++TeSche: used for Falcon */
38 
39 static int expand_bal; /* Balance factor for expanding (not volume!) */
40 static 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 
70 static ssize_t ata_ct_law(const u_char __user *userPtr, size_t userCount,
71  u_char frame[], ssize_t *frameUsed,
72  ssize_t frameLeft);
73 static ssize_t ata_ct_s8(const u_char __user *userPtr, size_t userCount,
74  u_char frame[], ssize_t *frameUsed,
75  ssize_t frameLeft);
76 static ssize_t ata_ct_u8(const u_char __user *userPtr, size_t userCount,
77  u_char frame[], ssize_t *frameUsed,
78  ssize_t frameLeft);
79 static ssize_t ata_ct_s16be(const u_char __user *userPtr, size_t userCount,
80  u_char frame[], ssize_t *frameUsed,
81  ssize_t frameLeft);
82 static ssize_t ata_ct_u16be(const u_char __user *userPtr, size_t userCount,
83  u_char frame[], ssize_t *frameUsed,
84  ssize_t frameLeft);
85 static ssize_t ata_ct_s16le(const u_char __user *userPtr, size_t userCount,
86  u_char frame[], ssize_t *frameUsed,
87  ssize_t frameLeft);
88 static ssize_t ata_ct_u16le(const u_char __user *userPtr, size_t userCount,
89  u_char frame[], ssize_t *frameUsed,
90  ssize_t frameLeft);
91 static ssize_t ata_ctx_law(const u_char __user *userPtr, size_t userCount,
92  u_char frame[], ssize_t *frameUsed,
93  ssize_t frameLeft);
94 static ssize_t ata_ctx_s8(const u_char __user *userPtr, size_t userCount,
95  u_char frame[], ssize_t *frameUsed,
96  ssize_t frameLeft);
97 static ssize_t ata_ctx_u8(const u_char __user *userPtr, size_t userCount,
98  u_char frame[], ssize_t *frameUsed,
99  ssize_t frameLeft);
100 static ssize_t ata_ctx_s16be(const u_char __user *userPtr, size_t userCount,
101  u_char frame[], ssize_t *frameUsed,
102  ssize_t frameLeft);
103 static ssize_t ata_ctx_u16be(const u_char __user *userPtr, size_t userCount,
104  u_char frame[], ssize_t *frameUsed,
105  ssize_t frameLeft);
106 static ssize_t ata_ctx_s16le(const u_char __user *userPtr, size_t userCount,
107  u_char frame[], ssize_t *frameUsed,
108  ssize_t frameLeft);
109 static 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 
117 static void *AtaAlloc(unsigned int size, gfp_t flags);
118 static void AtaFree(void *, unsigned int size);
119 static int AtaIrqInit(void);
120 #ifdef MODULE
121 static void AtaIrqCleanUp(void);
122 #endif /* MODULE */
123 static int AtaSetBass(int bass);
124 static int AtaSetTreble(int treble);
125 static void TTSilence(void);
126 static void TTInit(void);
127 static int TTSetFormat(int format);
128 static int TTSetVolume(int volume);
129 static int TTSetGain(int gain);
130 static void FalconSilence(void);
131 static void FalconInit(void);
132 static int FalconSetFormat(int format);
133 static int FalconSetVolume(int volume);
134 static void AtaPlayNextFrame(int index);
135 static void AtaPlay(void);
136 static irqreturn_t AtaInterrupt(int irq, void *dummy);
137 
138 /*** Mid level stuff *********************************************************/
139 
140 static void TTMixerInit(void);
141 static void FalconMixerInit(void);
142 static int AtaMixerIoctl(u_int cmd, u_long arg);
143 static int TTMixerIoctl(u_int cmd, u_long arg);
144 static int FalconMixerIoctl(u_int cmd, u_long arg);
145 static int AtaWriteSqSetup(void);
146 static int AtaSqOpen(fmode_t mode);
147 static int TTStateInfo(char *buffer, size_t space);
148 static int FalconStateInfo(char *buffer, size_t space);
149 
150 
151 /*** Translations ************************************************************/
152 
153 
154 static 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 
179 static 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 
197 static 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 
232 static 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 
264 static 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 
303 static 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 
344 static 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 
384 static 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 
446 static 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 
500 static 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 
556 static 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 
612 static 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 
670 static 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 
728 static 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 
786 static 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 
793 static 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 
800 static 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 
811 static 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 
831 static void *AtaAlloc(unsigned int size, gfp_t flags)
832 {
833  return atari_stram_alloc(size, "dmasound");
834 }
835 
836 static void AtaFree(void *obj, unsigned int size)
837 {
838  atari_stram_free( obj );
839 }
840 
841 static 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
863 static 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 
877 static int AtaSetBass(int bass)
878 {
879  dmasound.bass = TONE_VOXWARE_TO_DB(bass);
881  return TONE_DB_TO_VOXWARE(dmasound.bass);
882 }
883 
884 
885 static int AtaSetTreble(int treble)
886 {
887  dmasound.treble = TONE_VOXWARE_TO_DB(treble);
889  return TONE_DB_TO_VOXWARE(dmasound.treble);
890 }
891 
892 
893 
894 /*
895  * TT
896  */
897 
898 
899 static 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 
906 static 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 ?
950  DMASND_MODE_8BIT | mode;
951 
952  expand_bal = -dmasound.soft.speed;
953 }
954 
955 
956 static 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 
989 static int TTSetVolume(int volume)
990 {
991  dmasound.volume_left = VOLUME_VOXWARE_TO_DB(volume & 0xff);
993  dmasound.volume_right = VOLUME_VOXWARE_TO_DB((volume & 0xff00) >> 8);
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 
1004 static int TTSetGain(int gain)
1005 {
1006  dmasound.gain = GAIN_VOXWARE_TO_DB(gain);
1008  return GAIN_DB_TO_VOXWARE(dmasound.gain);
1009 }
1010 
1011 
1012 
1013 /*
1014  * Falcon
1015  */
1016 
1017 
1018 static void FalconSilence(void)
1019 {
1020  /* stop playback, set sample rate 50kHz for PSG sound */
1021  tt_dmasnd.ctrl = DMASND_CTRL_OFF;
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 
1032 static 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 ?
1104  ((dmasound.hard.size == 8) ?
1107 
1108  expand_bal = -dmasound.soft.speed;
1109 }
1110 
1111 
1112 static 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 
1158 static 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 
1168 static 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);
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++;
1186 }
1187 
1188 
1189 static 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 
1261 static irqreturn_t AtaInterrupt(int irq, void *dummy)
1262 {
1263 #if 0
1264  /* ++TeSche: if you should want to test this... */
1265  static int cnt;
1266  if (write_sq.active == 2)
1267  if (++cnt == 10) {
1268  /* simulate losing an interrupt */
1269  cnt = 0;
1270  return IRQ_HANDLED;
1271  }
1272 #endif
1273  spin_lock(&dmasound.lock);
1274  if (write_sq_ignore_int && is_falcon) {
1275  /* ++TeSche: Falcon only: ignore first irq because it comes
1276  * immediately after starting a frame. after that, irqs come
1277  * (almost) like on the TT.
1278  */
1279  write_sq_ignore_int = 0;
1280  goto out;
1281  }
1282 
1283  if (!write_sq.active) {
1284  /* playing was interrupted and sq_reset() has already cleared
1285  * the sq variables, so better don't do anything here.
1286  */
1287  WAKE_UP(write_sq.sync_queue);
1288  goto out;
1289  }
1290 
1291  /* Probably ;) one frame is finished. Well, in fact it may be that a
1292  * pre-programmed one is also finished because there has been a long
1293  * delay in interrupt delivery and we've completely lost one, but
1294  * there's no way to detect such a situation. In such a case the last
1295  * frame will be played more than once and the situation will recover
1296  * as soon as the irq gets through.
1297  */
1298  write_sq.count--;
1299  write_sq.active--;
1300 
1301  if (!write_sq.active) {
1302  tt_dmasnd.ctrl = DMASND_CTRL_OFF;
1303  write_sq_ignore_int = 1;
1304  }
1305 
1306  WAKE_UP(write_sq.action_queue);
1307  /* At least one block of the queue is free now
1308  so wake up a writing process blocked because
1309  of a full queue. */
1310 
1311  if ((write_sq.active != 1) || (write_sq.count != 1))
1312  /* We must be a bit carefully here: write_sq.count indicates the
1313  * number of buffers used and not the number of frames to be
1314  * played. If write_sq.count==1 and write_sq.active==1 that
1315  * means the only remaining frame was already programmed
1316  * earlier (and is currently running) so we mustn't call
1317  * AtaPlay() here, otherwise we'll play one frame too much.
1318  */
1319  AtaPlay();
1320 
1321  if (!write_sq.active) WAKE_UP(write_sq.sync_queue);
1322  /* We are not playing after AtaPlay(), so there
1323  is nothing to play any more. Wake up a process
1324  waiting for audio output to drain. */
1325 out:
1326  spin_unlock(&dmasound.lock);
1327  return IRQ_HANDLED;
1328 }
1329 
1330 
1331 /*** Mid level stuff *********************************************************/
1332 
1333 
1334 /*
1335  * /dev/mixer abstraction
1336  */
1337 
1338 #define RECLEVEL_VOXWARE_TO_GAIN(v) \
1339  ((v) < 0 ? 0 : (v) > 100 ? 15 : (v) * 3 / 20)
1340 #define RECLEVEL_GAIN_TO_VOXWARE(v) (((v) * 20 + 2) / 3)
1341 
1342 
1343 static void __init TTMixerInit(void)
1344 {
1346  dmasound.volume_left = 0;
1348  dmasound.volume_right = 0;
1352 }
1353 
1354 static void __init FalconMixerInit(void)
1355 {
1356  dmasound.volume_left = (tt_dmasnd.output_atten & 0xf00) >> 8;
1357  dmasound.volume_right = (tt_dmasnd.output_atten & 0xf0) >> 4;
1358 }
1359 
1360 static int AtaMixerIoctl(u_int cmd, u_long arg)
1361 {
1362  int data;
1363  unsigned long flags;
1364  switch (cmd) {
1366  if (is_falcon || MACH_IS_TT) {
1367  int porta;
1368  spin_lock_irqsave(&dmasound.lock, flags);
1369  sound_ym.rd_data_reg_sel = 14;
1370  porta = sound_ym.rd_data_reg_sel;
1371  spin_unlock_irqrestore(&dmasound.lock, flags);
1372  return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1373  }
1374  break;
1376  IOCTL_IN(arg, data);
1377  return IOCTL_OUT(arg, dmasound_set_volume(data));
1379  if (is_falcon || MACH_IS_TT) {
1380  int porta;
1381  IOCTL_IN(arg, data);
1382  spin_lock_irqsave(&dmasound.lock, flags);
1383  sound_ym.rd_data_reg_sel = 14;
1384  porta = (sound_ym.rd_data_reg_sel & ~0x40) |
1385  (data < 50 ? 0x40 : 0);
1386  sound_ym.wd_data = porta;
1387  spin_unlock_irqrestore(&dmasound.lock, flags);
1388  return IOCTL_OUT(arg, porta & 0x40 ? 0 : 100);
1389  }
1390  }
1391  return -EINVAL;
1392 }
1393 
1394 
1395 static int TTMixerIoctl(u_int cmd, u_long arg)
1396 {
1397  int data;
1398  switch (cmd) {
1400  return IOCTL_OUT(arg, 0);
1402  return IOCTL_OUT(arg,
1404  (MACH_IS_TT ? SOUND_MASK_SPEAKER : 0));
1406  return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
1408  return IOCTL_OUT(arg,
1409  VOLUME_DB_TO_VOXWARE(dmasound.volume_left) |
1410  (VOLUME_DB_TO_VOXWARE(dmasound.volume_right) << 8));
1411  case SOUND_MIXER_READ_BASS:
1412  return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.bass));
1414  return IOCTL_OUT(arg, TONE_DB_TO_VOXWARE(dmasound.treble));
1416  return IOCTL_OUT(arg, GAIN_DB_TO_VOXWARE(dmasound.gain));
1418  IOCTL_IN(arg, data);
1419  return IOCTL_OUT(arg, dmasound_set_bass(data));
1421  IOCTL_IN(arg, data);
1422  return IOCTL_OUT(arg, dmasound_set_treble(data));
1424  IOCTL_IN(arg, data);
1425  return IOCTL_OUT(arg, dmasound_set_gain(data));
1426  }
1427  return AtaMixerIoctl(cmd, arg);
1428 }
1429 
1430 static int FalconMixerIoctl(u_int cmd, u_long arg)
1431 {
1432  int data;
1433  switch (cmd) {
1435  return IOCTL_OUT(arg, SOUND_MASK_MIC);
1441  return IOCTL_OUT(arg,
1442  VOLUME_ATT_TO_VOXWARE(dmasound.volume_left) |
1443  VOLUME_ATT_TO_VOXWARE(dmasound.volume_right) << 8);
1444  case SOUND_MIXER_READ_CAPS:
1445  return IOCTL_OUT(arg, SOUND_CAP_EXCL_INPUT);
1446  case SOUND_MIXER_WRITE_MIC:
1447  IOCTL_IN(arg, data);
1448  tt_dmasnd.input_gain =
1449  RECLEVEL_VOXWARE_TO_GAIN(data & 0xff) << 4 |
1450  RECLEVEL_VOXWARE_TO_GAIN(data >> 8 & 0xff);
1451  /* fall thru, return set value */
1452  case SOUND_MIXER_READ_MIC:
1453  return IOCTL_OUT(arg,
1454  RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain >> 4 & 0xf) |
1455  RECLEVEL_GAIN_TO_VOXWARE(tt_dmasnd.input_gain & 0xf) << 8);
1456  }
1457  return AtaMixerIoctl(cmd, arg);
1458 }
1459 
1460 static int AtaWriteSqSetup(void)
1461 {
1462  write_sq_ignore_int = 0;
1463  return 0 ;
1464 }
1465 
1466 static int AtaSqOpen(fmode_t mode)
1467 {
1468  write_sq_ignore_int = 1;
1469  return 0 ;
1470 }
1471 
1472 static int TTStateInfo(char *buffer, size_t space)
1473 {
1474  int len = 0;
1475  len += sprintf(buffer+len, "\tvol left %ddB [-40... 0]\n",
1476  dmasound.volume_left);
1477  len += sprintf(buffer+len, "\tvol right %ddB [-40... 0]\n",
1478  dmasound.volume_right);
1479  len += sprintf(buffer+len, "\tbass %ddB [-12...+12]\n",
1480  dmasound.bass);
1481  len += sprintf(buffer+len, "\ttreble %ddB [-12...+12]\n",
1482  dmasound.treble);
1483  if (len >= space) {
1484  printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1485  len = space ;
1486  }
1487  return len;
1488 }
1489 
1490 static int FalconStateInfo(char *buffer, size_t space)
1491 {
1492  int len = 0;
1493  len += sprintf(buffer+len, "\tvol left %ddB [-22.5 ... 0]\n",
1494  dmasound.volume_left);
1495  len += sprintf(buffer+len, "\tvol right %ddB [-22.5 ... 0]\n",
1496  dmasound.volume_right);
1497  if (len >= space) {
1498  printk(KERN_ERR "dmasound_atari: overflowed state buffer alloc.\n") ;
1499  len = space ;
1500  }
1501  return len;
1502 }
1503 
1504 
1505 /*** Machine definitions *****************************************************/
1506 
1507 static SETTINGS def_hard_falcon = {
1508  .format = AFMT_S8,
1509  .stereo = 0,
1510  .size = 8,
1511  .speed = 8195
1512 } ;
1513 
1514 static SETTINGS def_hard_tt = {
1515  .format = AFMT_S8,
1516  .stereo = 0,
1517  .size = 8,
1518  .speed = 12517
1519 } ;
1520 
1521 static SETTINGS def_soft = {
1522  .format = AFMT_U8,
1523  .stereo = 0,
1524  .size = 8,
1525  .speed = 8000
1526 } ;
1527 
1528 static __initdata MACHINE machTT = {
1529  .name = "Atari",
1530  .name2 = "TT",
1531  .owner = THIS_MODULE,
1532  .dma_alloc = AtaAlloc,
1533  .dma_free = AtaFree,
1534  .irqinit = AtaIrqInit,
1535 #ifdef MODULE
1536  .irqcleanup = AtaIrqCleanUp,
1537 #endif /* MODULE */
1538  .init = TTInit,
1539  .silence = TTSilence,
1540  .setFormat = TTSetFormat,
1541  .setVolume = TTSetVolume,
1542  .setBass = AtaSetBass,
1543  .setTreble = AtaSetTreble,
1544  .setGain = TTSetGain,
1545  .play = AtaPlay,
1546  .mixer_init = TTMixerInit,
1547  .mixer_ioctl = TTMixerIoctl,
1548  .write_sq_setup = AtaWriteSqSetup,
1549  .sq_open = AtaSqOpen,
1550  .state_info = TTStateInfo,
1551  .min_dsp_speed = 6258,
1552  .version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1553  .hardware_afmts = AFMT_S8, /* h'ware-supported formats *only* here */
1554  .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
1555 };
1556 
1557 static __initdata MACHINE machFalcon = {
1558  .name = "Atari",
1559  .name2 = "FALCON",
1560  .dma_alloc = AtaAlloc,
1561  .dma_free = AtaFree,
1562  .irqinit = AtaIrqInit,
1563 #ifdef MODULE
1564  .irqcleanup = AtaIrqCleanUp,
1565 #endif /* MODULE */
1566  .init = FalconInit,
1567  .silence = FalconSilence,
1568  .setFormat = FalconSetFormat,
1569  .setVolume = FalconSetVolume,
1570  .setBass = AtaSetBass,
1571  .setTreble = AtaSetTreble,
1572  .play = AtaPlay,
1573  .mixer_init = FalconMixerInit,
1574  .mixer_ioctl = FalconMixerIoctl,
1575  .write_sq_setup = AtaWriteSqSetup,
1576  .sq_open = AtaSqOpen,
1577  .state_info = FalconStateInfo,
1578  .min_dsp_speed = 8195,
1579  .version = ((DMASOUND_ATARI_REVISION<<8) | DMASOUND_ATARI_EDITION),
1580  .hardware_afmts = (AFMT_S8 | AFMT_S16_BE), /* h'ware-supported formats *only* here */
1581  .capabilities = DSP_CAP_BATCH /* As per SNDCTL_DSP_GETCAPS */
1582 };
1583 
1584 
1585 /*** Config & Setup **********************************************************/
1586 
1587 
1588 static int __init dmasound_atari_init(void)
1589 {
1590  if (MACH_IS_ATARI && ATARIHW_PRESENT(PCM_8BIT)) {
1591  if (ATARIHW_PRESENT(CODEC)) {
1592  dmasound.mach = machFalcon;
1593  dmasound.mach.default_soft = def_soft ;
1594  dmasound.mach.default_hard = def_hard_falcon ;
1595  is_falcon = 1;
1596  } else if (ATARIHW_PRESENT(MICROWIRE)) {
1597  dmasound.mach = machTT;
1598  dmasound.mach.default_soft = def_soft ;
1599  dmasound.mach.default_hard = def_hard_tt ;
1600  is_falcon = 0;
1601  } else
1602  return -ENODEV;
1603  if ((st_mfp.int_en_a & st_mfp.int_mk_a & 0x20) == 0)
1604  return dmasound_init();
1605  else {
1606  printk("DMA sound driver: Timer A interrupt already in use\n");
1607  return -EBUSY;
1608  }
1609  }
1610  return -ENODEV;
1611 }
1612 
1613 static void __exit dmasound_atari_cleanup(void)
1614 {
1615  dmasound_deinit();
1616 }
1617 
1618 module_init(dmasound_atari_init);
1619 module_exit(dmasound_atari_cleanup);
1620 MODULE_LICENSE("GPL");