This source file includes following definitions.
- sb_dsp_command
- sbintr
- sb_get_irq
- sb_free_irq
- sb_reset_dsp
- dsp_speaker
- dsp_speed
- dsp_set_stereo
- sb_dsp_output_block
- sb_dsp_start_input
- dsp_cleanup
- sb_dsp_prepare_for_input
- sb_dsp_prepare_for_output
- sb_dsp_halt_xfer
- verify_irq
- sb_dsp_open
- sb_dsp_close
- sb_dsp_ioctl
- sb_dsp_reset
- sb_dsp_detect
- sb_dsp_init
- sb_dsp_disable_midi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include "sound_config.h"
35
36 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
37
38 #include "sb.h"
39 #include "sb_mixer.h"
40 #undef SB_TEST_IRQ
41
42 int sbc_base = 0;
43 static int sbc_irq = 0;
44 static int open_mode = 0;
45
46
47
48
49
50
51
52
53
54 int sb_dsp_ok = 0;
55
56
57
58
59 static int midi_disabled = 0;
60 int sb_dsp_highspeed = 0;
61 int sbc_major = 1, sbc_minor = 0;
62
63
64
65 static int dsp_stereo = 0;
66 static int dsp_current_speed = DSP_DEFAULT_SPEED;
67 static int sb16 = 0;
68 static int irq_verified = 0;
69
70 int sb_midi_mode = NORMAL_MIDI;
71 int sb_midi_busy = 0;
72
73
74
75
76 int sb_dsp_busy = 0;
77
78 volatile int sb_irq_mode = IMODE_NONE;
79
80
81
82
83
84 static volatile int irq_ok = 0;
85
86 int sb_duplex_midi = 0;
87 static int my_dev = 0;
88
89 volatile int sb_intr_active = 0;
90
91 static int dsp_speed (int);
92 static int dsp_set_stereo (int mode);
93 int sb_dsp_command (unsigned char val);
94
95 #if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
96
97
98
99
100
101 int
102 sb_dsp_command (unsigned char val)
103 {
104 int i;
105 unsigned long limit;
106
107 limit = GET_TIME () + HZ / 10;
108
109
110
111
112
113
114
115
116
117
118
119 for (i = 0; i < 500000 && GET_TIME () < limit; i++)
120 {
121 if ((INB (DSP_STATUS) & 0x80) == 0)
122 {
123 OUTB (val, DSP_COMMAND);
124 return 1;
125 }
126 }
127
128 printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val);
129 printk ("IRQ conflict???\n");
130 return 0;
131 }
132
133 void
134 sbintr (int unit)
135 {
136 int status;
137
138 #ifndef EXCLUDE_SBPRO
139 if (sb16)
140 {
141 unsigned char src = sb_getmixer (IRQ_STAT);
142
143
144
145
146
147
148 #ifndef EXCLUDE_SB16
149 if (src & 3)
150 sb16_dsp_interrupt (unit);
151
152 #ifndef EXCLUDE_MIDI
153 if (src & 4)
154 sb16midiintr (unit);
155
156
157 #endif
158
159 #endif
160
161 if (!(src & 1))
162 return;
163
164
165 }
166 #endif
167
168 status = INB (DSP_DATA_AVAIL);
169
170
171
172 if (sb_intr_active)
173 switch (sb_irq_mode)
174 {
175 case IMODE_OUTPUT:
176 sb_intr_active = 0;
177 DMAbuf_outputintr (my_dev, 1);
178 break;
179
180 case IMODE_INPUT:
181 sb_intr_active = 0;
182 DMAbuf_inputintr (my_dev);
183
184
185
186 break;
187
188 case IMODE_INIT:
189 sb_intr_active = 0;
190 irq_ok = 1;
191 break;
192
193 case IMODE_MIDI:
194 #ifndef EXCLUDE_MIDI
195 sb_midi_interrupt (unit);
196 #endif
197 break;
198
199 default:
200 printk ("SoundBlaster: Unexpected interrupt\n");
201 }
202 }
203
204 static int sb_irq_usecount = 0;
205
206 int
207 sb_get_irq (void)
208 {
209 int ok;
210
211 if (!sb_irq_usecount)
212 if ((ok = snd_set_irq_handler (sbc_irq, sbintr)) < 0)
213 return ok;
214
215 sb_irq_usecount++;
216
217 return 0;
218 }
219
220 void
221 sb_free_irq (void)
222 {
223 if (!sb_irq_usecount)
224 return;
225
226 sb_irq_usecount--;
227
228 if (!sb_irq_usecount)
229 snd_release_irq (sbc_irq);
230 }
231
232 int
233 sb_reset_dsp (void)
234 {
235 int loopc;
236
237 OUTB (1, DSP_RESET);
238 tenmicrosec ();
239 OUTB (0, DSP_RESET);
240 tenmicrosec ();
241 tenmicrosec ();
242 tenmicrosec ();
243
244 for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);
245
246
247
248
249
250
251
252
253 if (INB (DSP_READ) != 0xAA)
254 return 0;
255
256
257
258 return 1;
259 }
260
261 #endif
262
263 #ifndef EXCLUDE_AUDIO
264
265 static void
266 dsp_speaker (char state)
267 {
268 if (state)
269 sb_dsp_command (DSP_CMD_SPKON);
270 else
271 sb_dsp_command (DSP_CMD_SPKOFF);
272 }
273
274 static int
275 dsp_speed (int speed)
276 {
277 unsigned char tconst;
278 unsigned long flags;
279 int max_speed = 44100;
280
281 if (speed < 4000)
282 speed = 4000;
283
284
285
286
287
288 if (sbc_major < 2 ||
289 (sbc_major == 2 && sbc_minor == 0))
290 max_speed = 22050;
291
292
293
294
295 if (open_mode != OPEN_WRITE)
296 if (sbc_major < 3)
297 if (sbc_major == 2 && sbc_minor > 0)
298 max_speed = 15000;
299 else
300 max_speed = 13000;
301
302 if (speed > max_speed)
303 speed = max_speed;
304
305
306
307 if (dsp_stereo && speed > 22050)
308 speed = 22050;
309
310
311
312
313 if ((speed > 22050) && sb_midi_busy)
314 {
315 printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
316 speed = 22050;
317 }
318
319 if (dsp_stereo)
320 speed *= 2;
321
322
323
324
325
326 if (speed > 22050)
327 {
328
329
330 int tmp;
331
332 tconst = (unsigned char) ((65536 -
333 ((256000000 + speed / 2) / speed)) >> 8);
334 sb_dsp_highspeed = 1;
335
336 DISABLE_INTR (flags);
337 if (sb_dsp_command (0x40))
338 sb_dsp_command (tconst);
339 RESTORE_INTR (flags);
340
341 tmp = 65536 - (tconst << 8);
342 speed = (256000000 + tmp / 2) / tmp;
343 }
344 else
345 {
346 int tmp;
347
348 sb_dsp_highspeed = 0;
349 tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
350
351 DISABLE_INTR (flags);
352 if (sb_dsp_command (0x40))
353
354
355 sb_dsp_command (tconst);
356 RESTORE_INTR (flags);
357
358 tmp = 256 - tconst;
359 speed = (1000000 + tmp / 2) / tmp;
360 }
361
362 if (dsp_stereo)
363 speed /= 2;
364
365 dsp_current_speed = speed;
366 return speed;
367 }
368
369 static int
370 dsp_set_stereo (int mode)
371 {
372 dsp_stereo = 0;
373
374 #ifdef EXCLUDE_SBPRO
375 return 0;
376 #else
377 if (sbc_major < 3 || sb16)
378 return 0;
379
380
381
382 if (mode && sb_midi_busy)
383 {
384 printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
385 return 0;
386 }
387
388 dsp_stereo = !!mode;
389 return dsp_stereo;
390 #endif
391 }
392
393 static void
394 sb_dsp_output_block (int dev, unsigned long buf, int count,
395 int intrflag, int restart_dma)
396 {
397 unsigned long flags;
398
399 if (!sb_irq_mode)
400 dsp_speaker (ON);
401
402 sb_irq_mode = IMODE_OUTPUT;
403 DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
404
405 if (audio_devs[dev]->dmachan > 3)
406 count >>= 1;
407 count--;
408
409 if (sb_dsp_highspeed)
410 {
411 DISABLE_INTR (flags);
412 if (sb_dsp_command (0x48))
413
414
415 {
416 sb_dsp_command ((unsigned char) (count & 0xff));
417 sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
418 sb_dsp_command (0x91);
419
420
421 }
422 else
423 printk ("SB Error: Unable to start (high speed) DAC\n");
424 RESTORE_INTR (flags);
425 }
426 else
427 {
428 DISABLE_INTR (flags);
429 if (sb_dsp_command (0x14))
430
431
432 {
433 sb_dsp_command ((unsigned char) (count & 0xff));
434 sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
435 }
436 else
437 printk ("SB Error: Unable to start DAC\n");
438 RESTORE_INTR (flags);
439 }
440 sb_intr_active = 1;
441 }
442
443 static void
444 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
445 int restart_dma)
446 {
447
448
449
450
451 unsigned long flags;
452
453 if (!sb_irq_mode)
454 dsp_speaker (OFF);
455
456 sb_irq_mode = IMODE_INPUT;
457 DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
458
459 if (audio_devs[dev]->dmachan > 3)
460 count >>= 1;
461 count--;
462
463 if (sb_dsp_highspeed)
464 {
465 DISABLE_INTR (flags);
466 if (sb_dsp_command (0x48))
467
468
469 {
470 sb_dsp_command ((unsigned char) (count & 0xff));
471 sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
472 sb_dsp_command (0x99);
473
474
475 }
476 else
477 printk ("SB Error: Unable to start (high speed) ADC\n");
478 RESTORE_INTR (flags);
479 }
480 else
481 {
482 DISABLE_INTR (flags);
483 if (sb_dsp_command (0x24))
484
485
486 {
487 sb_dsp_command ((unsigned char) (count & 0xff));
488 sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
489 }
490 else
491 printk ("SB Error: Unable to start ADC\n");
492 RESTORE_INTR (flags);
493 }
494
495 sb_intr_active = 1;
496 }
497
498 static void
499 dsp_cleanup (void)
500 {
501 sb_intr_active = 0;
502 }
503
504 static int
505 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
506 {
507 dsp_cleanup ();
508 dsp_speaker (OFF);
509
510 if (sbc_major == 3)
511
512
513 {
514 if (dsp_stereo)
515 sb_dsp_command (0xa8);
516 else
517 sb_dsp_command (0xa0);
518
519 dsp_speed (dsp_current_speed);
520
521
522
523 }
524 return 0;
525 }
526
527 static int
528 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
529 {
530 dsp_cleanup ();
531 dsp_speaker (ON);
532
533 #ifndef EXCLUDE_SBPRO
534 if (sbc_major == 3)
535
536
537 {
538 sb_mixer_set_stereo (dsp_stereo);
539 dsp_speed (dsp_current_speed);
540
541
542
543 }
544 #endif
545 return 0;
546 }
547
548 static void
549 sb_dsp_halt_xfer (int dev)
550 {
551 }
552
553 static int
554 verify_irq (void)
555 {
556 #if 0
557 DEFINE_WAIT_QUEUE (testq, testf);
558
559 irq_ok = 0;
560
561 if (sb_get_irq () == -1)
562 {
563 printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
564 return 0;
565 }
566
567
568 sb_irq_mode = IMODE_INIT;
569
570 sb_dsp_command (0xf2);
571
572
573
574 DO_SLEEP (testq, testf, HZ / 5);
575
576 sb_free_irq ();
577
578 if (!irq_ok)
579 {
580 printk ("SB Warning: IRQ%d test not passed!", sbc_irq);
581 irq_ok = 1;
582 }
583 #else
584 irq_ok = 1;
585 #endif
586 return irq_ok;
587 }
588
589 static int
590 sb_dsp_open (int dev, int mode)
591 {
592 int retval;
593
594 if (!sb_dsp_ok)
595 {
596 printk ("SB Error: SoundBlaster board not installed\n");
597 return RET_ERROR (ENXIO);
598 }
599
600 if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
601 {
602 printk ("SB: PCM not possible during MIDI input\n");
603 return RET_ERROR (EBUSY);
604 }
605
606 if (!irq_verified)
607 {
608 verify_irq ();
609 irq_verified = 1;
610 }
611 else if (!irq_ok)
612 printk ("SB Warning: Incorrect IRQ setting %d\n",
613 sbc_irq);
614
615 retval = sb_get_irq ();
616 if (retval)
617 return retval;
618
619 if (DMAbuf_open_dma (dev) < 0)
620 {
621 sb_free_irq ();
622 printk ("SB: DMA Busy\n");
623 return RET_ERROR (EBUSY);
624 }
625
626 sb_irq_mode = IMODE_NONE;
627
628 sb_dsp_busy = 1;
629 open_mode = mode;
630
631 return 0;
632 }
633
634 static void
635 sb_dsp_close (int dev)
636 {
637 DMAbuf_close_dma (dev);
638 sb_free_irq ();
639 dsp_cleanup ();
640 dsp_speaker (OFF);
641 sb_dsp_busy = 0;
642 sb_dsp_highspeed = 0;
643 open_mode = 0;
644 }
645
646 static int
647 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
648 {
649 switch (cmd)
650 {
651 case SOUND_PCM_WRITE_RATE:
652 if (local)
653 return dsp_speed (arg);
654 return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
655 break;
656
657 case SOUND_PCM_READ_RATE:
658 if (local)
659 return dsp_current_speed;
660 return IOCTL_OUT (arg, dsp_current_speed);
661 break;
662
663 case SOUND_PCM_WRITE_CHANNELS:
664 if (local)
665 return dsp_set_stereo (arg - 1) + 1;
666 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
667 break;
668
669 case SOUND_PCM_READ_CHANNELS:
670 if (local)
671 return dsp_stereo + 1;
672 return IOCTL_OUT (arg, dsp_stereo + 1);
673 break;
674
675 case SNDCTL_DSP_STEREO:
676 if (local)
677 return dsp_set_stereo (arg);
678 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
679 break;
680
681 case SOUND_PCM_WRITE_BITS:
682 case SOUND_PCM_READ_BITS:
683 if (local)
684 return 8;
685 return IOCTL_OUT (arg, 8);
686
687
688 break;
689
690 case SOUND_PCM_WRITE_FILTER:
691 case SOUND_PCM_READ_FILTER:
692 return RET_ERROR (EINVAL);
693 break;
694
695 default:
696 return RET_ERROR (EINVAL);
697 }
698
699 return RET_ERROR (EINVAL);
700 }
701
702 static void
703 sb_dsp_reset (int dev)
704 {
705 unsigned long flags;
706
707 DISABLE_INTR (flags);
708
709 sb_reset_dsp ();
710 dsp_speed (dsp_current_speed);
711 dsp_cleanup ();
712
713 RESTORE_INTR (flags);
714 }
715
716 #endif
717
718 int
719 sb_dsp_detect (struct address_info *hw_config)
720 {
721 sbc_base = hw_config->io_base;
722 sbc_irq = hw_config->irq;
723
724 if (sb_dsp_ok)
725 return 0;
726
727
728
729 if (!sb_reset_dsp ())
730 return 0;
731
732 return 1;
733
734
735 }
736
737 #ifndef EXCLUDE_AUDIO
738 static struct audio_operations sb_dsp_operations =
739 {
740 "SoundBlaster",
741 NOTHING_SPECIAL,
742 AFMT_U8,
743 NULL,
744 sb_dsp_open,
745 sb_dsp_close,
746 sb_dsp_output_block,
747 sb_dsp_start_input,
748 sb_dsp_ioctl,
749 sb_dsp_prepare_for_input,
750 sb_dsp_prepare_for_output,
751 sb_dsp_reset,
752 sb_dsp_halt_xfer,
753 NULL,
754 NULL
755 };
756
757 #endif
758
759 long
760 sb_dsp_init (long mem_start, struct address_info *hw_config)
761 {
762 int i;
763 int mixer_type = 0;
764
765 sbc_major = sbc_minor = 0;
766 sb_dsp_command (0xe1);
767
768
769
770 for (i = 1000; i; i--)
771 {
772 if (INB (DSP_DATA_AVAIL) & 0x80)
773 {
774
775
776 if (sbc_major == 0)
777 sbc_major = INB (DSP_READ);
778 else
779 {
780 sbc_minor = INB (DSP_READ);
781 break;
782 }
783 }
784 }
785
786 if (sbc_major == 2 || sbc_major == 3)
787 sb_duplex_midi = 1;
788
789 if (sbc_major == 4)
790 sb16 = 1;
791
792 #ifndef EXCLUDE_SBPRO
793 if (sbc_major >= 3)
794 mixer_type = sb_mixer_init (sbc_major);
795 #endif
796
797 #ifndef EXCLUDE_YM3812
798
799 if (sbc_major > 3 ||
800 (sbc_major == 3 && INB (0x388) == 0x00))
801 enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
802 #endif
803
804 if (sbc_major >= 3)
805 {
806 #ifndef SCO
807 # ifdef __SGNXPRO__
808 if (mixer_type == 2)
809 {
810 sprintf (sb_dsp_operations.name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor);
811 }
812 else
813 # endif
814 {
815 sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
816 }
817 #endif
818 }
819 else
820 {
821 #ifndef SCO
822 sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
823 #endif
824 }
825
826 printk (" <%s>", sb_dsp_operations.name);
827
828 #ifndef EXCLUDE_AUDIO
829 #if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
830 if (!sb16)
831
832
833 #endif
834 if (num_audiodevs < MAX_AUDIO_DEV)
835 {
836 audio_devs[my_dev = num_audiodevs++] = &sb_dsp_operations;
837 audio_devs[my_dev]->buffcount = DSP_BUFFCOUNT;
838 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
839 audio_devs[my_dev]->dmachan = hw_config->dma;
840 }
841 else
842 printk ("SB: Too many DSP devices available\n");
843 #endif
844
845 #ifndef EXCLUDE_MIDI
846 if (!midi_disabled && !sb16)
847
848
849
850 sb_midi_init (sbc_major);
851 #endif
852
853 sb_dsp_ok = 1;
854 return mem_start;
855 }
856
857 void
858 sb_dsp_disable_midi (void)
859 {
860 midi_disabled = 1;
861 }
862
863 #endif