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