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