This source file includes following definitions.
- dsp_command
- sbintr
- set_dsp_irq
- 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
- sb_dsp_open
- sb_dsp_close
- sb_dsp_ioctl
- sb_dsp_reset
- sb_dsp_detect
- setmixer
- getmixer
- detect_mixer
- init_mixer
- set_filter
- mixer_output
- sbp_mixer_set
- mixer_input
- sbp_mixer_get
- mixer_set_levels
- mixer_set_params
- mixer_get_levels
- mixer_get_params
- sb_mixer_ioctl
- sb_midi_open
- sb_midi_close
- sb_midi_out
- sb_midi_start_read
- sb_midi_end_read
- sb_midi_ioctl
- verify_irq
- 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 #include "sound_config.h"
33
34 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
35
36 #undef SB_TEST_IRQ
37
38 #define DSP_RESET (sbc_base + 0x6)
39 #define DSP_READ (sbc_base + 0xA)
40 #define DSP_WRITE (sbc_base + 0xC)
41 #define DSP_COMMAND (sbc_base + 0xC)
42 #define DSP_STATUS (sbc_base + 0xC)
43 #define DSP_DATA_AVAIL (sbc_base + 0xE)
44 #define MIXER_ADDR (sbc_base + 0x4)
45 #define MIXER_DATA (sbc_base + 0x5)
46 #define OPL3_LEFT (sbc_base + 0x0)
47 #define OPL3_RIGHT (sbc_base + 0x2)
48 #define OPL3_BOTH (sbc_base + 0x8)
49
50 static int sbc_base = 0;
51 static int sbc_irq = 0;
52
53 #define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
54
55 #define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
56 SOUND_MASK_CD | SOUND_MASK_VOLUME)
57
58
59
60
61
62
63
64 #define VOC_VOL 0x04
65 #define MIC_VOL 0x0A
66 #define MIC_MIX 0x0A
67 #define RECORD_SRC 0x0C
68 #define IN_FILTER 0x0C
69 #define OUT_FILTER 0x0E
70 #define MASTER_VOL 0x22
71 #define FM_VOL 0x26
72 #define CD_VOL 0x28
73 #define LINE_VOL 0x2E
74
75 #define FREQ_HI (1 << 3)
76 #define FREQ_LOW 0
77 #define FILT_ON 0
78 #define FILT_OFF (1 << 5)
79
80
81 #define B1(x) ((x) & 0x01)
82 #define B2(x) ((x) & 0x03)
83 #define B3(x) ((x) & 0x07)
84 #define B4(x) ((x) & 0x0f)
85 #define B5(x) ((x) & 0x1f)
86 #define B6(x) ((x) & 0x3f)
87 #define B7(x) ((x) & 0x7f)
88 #define B8(x) ((x) & 0xff)
89 #define F(x) (!!(x))
90
91 #define MONO_DAC 0x00
92 #define STEREO_DAC 0x02
93
94
95
96 #define DSP_CMD_SPKON 0xD1
97 #define DSP_CMD_SPKOFF 0xD3
98
99
100
101
102
103
104
105
106
107 #define IMODE_NONE 0
108 #define IMODE_OUTPUT 1
109 #define IMODE_INPUT 2
110 #define IMODE_INIT 3
111 #define IMODE_MIDI 4
112
113 #define NORMAL_MIDI 0
114 #define UART_MIDI 1
115
116 static int sb_dsp_ok = 0;
117 static int midi_disabled = 0;
118 static int dsp_highspeed = 0, dsp_stereo = 0;
119 static int dsp_current_speed = DSP_DEFAULT_SPEED;
120 static int sb16 = 0;
121
122 #ifndef EXCLUDE_SBPRO
123 static int rec_devices = SOUND_MASK_MIC;
124 static int hi_filter = 0, filter_in = 0, filter_out = 0;
125
126 #endif
127
128 static int midi_mode = NORMAL_MIDI;
129 static int midi_busy = 0;
130 static int dsp_busy = 0;
131
132 static volatile int irq_mode = IMODE_NONE;
133
134 static volatile int irq_ok = 0;
135
136 static int dsp_model = 1;
137 static int duplex_midi = 0;
138 static int my_dev = 0;
139
140 static volatile int intr_active = 0;
141
142 static int dsp_speed (int);
143 static int dsp_set_stereo (int mode);
144 static int dsp_command (unsigned char val);
145
146 #ifndef EXCLUDE_SBPRO
147 static void setmixer (unsigned char port, unsigned char value);
148 static int getmixer (unsigned char port);
149 static void init_mixer (void);
150 static int detect_mixer (void);
151
152 #endif
153
154 #if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
155
156
157
158 static int
159 dsp_command (unsigned char val)
160 {
161 int i, limit;
162
163 limit = GET_TIME () + 10;
164
165
166
167
168
169
170
171
172
173 for (i = 0; i < 5000000 && GET_TIME () < limit; i++)
174 {
175 if ((INB (DSP_STATUS) & 0x80) == 0)
176 {
177 OUTB (val, DSP_COMMAND);
178 return 1;
179 }
180 }
181
182 printk ("SoundBlaster: DSP Command(%02x) Timeout.\n", val);
183 printk ("IRQ conflict???\n");
184 return 0;
185 }
186
187 void
188 sbintr (int unused)
189 {
190 int status, data;
191
192 #ifndef EXCLUDE_SBPRO
193 if (sb16)
194 {
195 unsigned char src = getmixer (0x82);
196
197 if (!(src & 1))
198 return;
199 }
200 #endif
201
202 status = INB (DSP_DATA_AVAIL);
203
204 if (intr_active)
205 switch (irq_mode)
206 {
207 case IMODE_OUTPUT:
208 intr_active = 0;
209 DMAbuf_outputintr (my_dev);
210 break;
211
212 case IMODE_INPUT:
213 intr_active = 0;
214 DMAbuf_inputintr (my_dev);
215
216 break;
217
218 case IMODE_INIT:
219 intr_active = 0;
220 irq_ok = 1;
221 break;
222
223 case IMODE_MIDI:
224 printk ("+");
225 data = INB (DSP_READ);
226 printk ("%02x", data);
227
228 break;
229
230 default:
231 printk ("SoundBlaster: Unexpected interrupt\n");
232 }
233 }
234
235 static int
236 set_dsp_irq (int interrupt_level)
237 {
238 int retcode;
239
240 #ifdef linux
241 struct sigaction sa;
242
243 sa.sa_handler = sbintr;
244
245 #ifdef SND_SA_INTERRUPT
246 sa.sa_flags = SA_INTERRUPT;
247 #else
248 sa.sa_flags = 0;
249 #endif
250
251 sa.sa_mask = 0;
252 sa.sa_restorer = NULL;
253
254 retcode = irqaction (interrupt_level, &sa);
255
256 if (retcode < 0)
257 {
258 printk ("SoundBlaster: IRQ%d already in use\n", interrupt_level);
259 }
260
261 #else
262
263 #endif
264 return retcode;
265 }
266
267 static int
268 reset_dsp (void)
269 {
270 int loopc;
271
272 OUTB (1, DSP_RESET);
273 tenmicrosec ();
274 OUTB (0, DSP_RESET);
275 tenmicrosec ();
276 tenmicrosec ();
277 tenmicrosec ();
278
279 for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);
280
281
282 if (INB (DSP_READ) != 0xAA)
283 return 0;
284
285 return 1;
286 }
287
288 #endif
289
290 #ifndef EXCLUDE_AUDIO
291
292 static void
293 dsp_speaker (char state)
294 {
295 if (state)
296 dsp_command (DSP_CMD_SPKON);
297 else
298 dsp_command (DSP_CMD_SPKOFF);
299 }
300
301 static int
302 dsp_speed (int speed)
303 {
304 unsigned char tconst;
305 unsigned long flags;
306
307
308 if (speed < 4000)
309 speed = 4000;
310
311 if (speed > 44100)
312 speed = 44100;
313
314 if (dsp_model == 1 && speed > 22050)
315 speed = 22050;
316
317
318
319 if (dsp_stereo && speed > 22050)
320 speed = 22050;
321
322
323 if ((speed > 22050) && midi_busy)
324 {
325 printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
326 speed = 22050;
327 }
328
329 if (dsp_stereo)
330 speed <<= 1;
331
332
333
334 if (speed > 22050)
335 {
336 tconst = (unsigned char) ((65536 - (256000000 / speed)) >> 8);
337 dsp_highspeed = 1;
338
339 DISABLE_INTR (flags);
340 if (dsp_command (0x40))
341 dsp_command (tconst);
342 RESTORE_INTR (flags);
343
344 speed = (256000000 / (65536 - (tconst << 8)));
345 }
346 else
347 {
348 dsp_highspeed = 0;
349 tconst = (256 - (1000000 / speed)) & 0xff;
350
351 DISABLE_INTR (flags);
352 if (dsp_command (0x40))
353 dsp_command (tconst);
354 RESTORE_INTR (flags);
355
356 speed = 1000000 / (256 - tconst);
357 }
358
359 if (dsp_stereo)
360 speed >>= 1;
361
362 dsp_current_speed = speed;
363 return speed;
364 }
365
366 static int
367 dsp_set_stereo (int mode)
368 {
369 dsp_stereo = 0;
370
371 if (dsp_model == 1 || sb16)
372 return 0;
373
374 if (mode && midi_busy)
375 {
376 printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
377 return 0;
378 }
379
380 dsp_stereo = !!mode;
381
382 #ifndef EXCLUDE_SBPRO
383 setmixer (OUT_FILTER, ((getmixer (OUT_FILTER) & ~STEREO_DAC)
384 | (mode ? STEREO_DAC : MONO_DAC)));
385 #endif
386 dsp_speed (dsp_current_speed);
387
388 return mode;
389 }
390
391 static void
392 sb_dsp_output_block (int dev, unsigned long buf, int count, int intrflag)
393 {
394 unsigned long flags;
395
396 if (!irq_mode)
397 dsp_speaker (ON);
398
399 irq_mode = IMODE_OUTPUT;
400 DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
401
402 if (sound_dsp_dmachan[dev] > 3)
403 count >>= 1;
404 count--;
405
406 if (dsp_highspeed)
407 {
408 DISABLE_INTR (flags);
409 if (dsp_command (0x48))
410 {
411 dsp_command (count & 0xff);
412 dsp_command ((count >> 8) & 0xff);
413 dsp_command (0x91);
414 }
415 else
416 printk ("SB Error: Unable to start (high speed) DAC\n");
417 RESTORE_INTR (flags);
418 }
419 else
420 {
421 DISABLE_INTR (flags);
422 if (dsp_command (0x14))
423 {
424 dsp_command (count & 0xff);
425 dsp_command ((count >> 8) & 0xff);
426 }
427 else
428 printk ("SB Error: Unable to start DAC\n");
429 RESTORE_INTR (flags);
430 }
431 intr_active = 1;
432 }
433
434 static void
435 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag)
436 {
437
438
439 unsigned long flags;
440
441 if (!irq_mode)
442 dsp_speaker (OFF);
443
444 irq_mode = IMODE_INPUT;
445 DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
446
447 if (sound_dsp_dmachan[dev] > 3)
448 count >>= 1;
449 count--;
450
451 if (dsp_highspeed)
452 {
453 DISABLE_INTR (flags);
454 if (dsp_command (0x48))
455 {
456 dsp_command (count & 0xff);
457 dsp_command ((count >> 8) & 0xff);
458 dsp_command (0x99);
459 }
460 else
461 printk ("SB Error: Unable to start (high speed) ADC\n");
462 RESTORE_INTR (flags);
463 }
464 else
465 {
466 DISABLE_INTR (flags);
467 if (dsp_command (0x24))
468 {
469 dsp_command (count & 0xff);
470 dsp_command ((count >> 8) & 0xff);
471 }
472 else
473 printk ("SB Error: Unable to start ADC\n");
474 RESTORE_INTR (flags);
475 }
476
477 intr_active = 1;
478 }
479
480 static void
481 dsp_cleanup (void)
482 {
483 intr_active = 0;
484 }
485
486 static int
487 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
488 {
489 dsp_cleanup ();
490 dsp_speaker (OFF);
491 return 0;
492 }
493
494 static int
495 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
496 {
497 dsp_cleanup ();
498 dsp_speaker (ON);
499 return 0;
500 }
501
502 static void
503 sb_dsp_halt_xfer (int dev)
504 {
505 }
506
507 static int
508 sb_dsp_open (int dev, int mode)
509 {
510 int retval;
511
512 if (!sb_dsp_ok)
513 {
514 printk ("SB Error: SoundBlaster board not installed\n");
515 return RET_ERROR (ENXIO);
516 }
517
518 if (!irq_ok)
519 {
520 printk ("SB Error: Incorrect IRQ setting (%d)\n", sbc_irq);
521 return RET_ERROR (ENXIO);
522 }
523
524 if (intr_active || (midi_busy && midi_mode == UART_MIDI))
525 {
526 printk ("SB: PCM not possible during MIDI input\n");
527 return RET_ERROR (EBUSY);
528 }
529
530 if (mode != OPEN_READ && mode != OPEN_WRITE)
531 {
532 printk ("SoundBlaster error: DAC and ACD not possible simultaneously\n");
533 return RET_ERROR (EINVAL);
534 }
535
536 retval = set_dsp_irq (sbc_irq);
537 if (retval)
538 return retval;
539
540 if (!DMAbuf_open_dma (dev))
541 {
542 RELEASE_IRQ (sbc_irq);
543 printk ("SB: DMA Busy\n");
544 return RET_ERROR (EBUSY);
545 }
546
547 dsp_set_stereo (OFF);
548 dsp_speed (DSP_DEFAULT_SPEED);
549 irq_mode = IMODE_NONE;
550
551 dsp_busy = 1;
552
553 return 0;
554 }
555
556 static void
557 sb_dsp_close (int dev)
558 {
559 DMAbuf_close_dma (dev);
560 RELEASE_IRQ (sbc_irq);
561 dsp_cleanup ();
562 dsp_speed (DSP_DEFAULT_SPEED);
563 dsp_set_stereo (OFF);
564 dsp_speaker (OFF);
565 dsp_busy = 0;
566 }
567
568 static int
569 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
570 {
571 switch (cmd)
572 {
573 case SOUND_PCM_WRITE_RATE:
574 if (local)
575 return dsp_speed (arg);
576 return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
577 break;
578
579 case SOUND_PCM_READ_RATE:
580 if (local)
581 return dsp_current_speed;
582 return IOCTL_OUT (arg, dsp_current_speed);
583 break;
584
585 case SOUND_PCM_WRITE_CHANNELS:
586 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
587 break;
588
589 case SOUND_PCM_READ_CHANNELS:
590 if (local)
591 return dsp_stereo + 1;
592 return IOCTL_OUT (arg, dsp_stereo + 1);
593 break;
594
595 case SNDCTL_DSP_STEREO:
596 if (local)
597 return dsp_set_stereo (arg);
598 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
599 break;
600
601 case SOUND_PCM_WRITE_BITS:
602 case SOUND_PCM_READ_BITS:
603 if (local)
604 return 8;
605 return IOCTL_OUT (arg, 8);
606 break;
607
608 case SOUND_PCM_WRITE_FILTER:
609 case SOUND_PCM_READ_FILTER:
610 return RET_ERROR (EINVAL);
611 break;
612
613 default:
614 return RET_ERROR (EINVAL);
615 }
616
617 return RET_ERROR (EINVAL);
618 }
619
620 static void
621 sb_dsp_reset (int dev)
622 {
623 unsigned long flags;
624
625 DISABLE_INTR (flags);
626
627 reset_dsp ();
628 dsp_cleanup ();
629
630 RESTORE_INTR (flags);
631 }
632
633 #endif
634
635 int
636 sb_dsp_detect (struct address_info *hw_config)
637 {
638 sbc_base = hw_config->io_base;
639 sbc_irq = hw_config->irq;
640
641 if (sb_dsp_ok)
642 return 0;
643
644 if (!reset_dsp ())
645 return 0;
646
647 return 1;
648 }
649
650 #ifndef EXCLUDE_SBPRO
651
652 static void
653 setmixer (unsigned char port, unsigned char value)
654 {
655 OUTB (port, MIXER_ADDR);
656 tenmicrosec ();
657 OUTB (value, MIXER_DATA);
658 tenmicrosec ();
659 }
660
661 static int
662 getmixer (unsigned char port)
663 {
664 int val;
665
666 OUTB (port, MIXER_ADDR);
667 tenmicrosec ();
668 val = INB (MIXER_DATA);
669 tenmicrosec ();
670
671 return val;
672 }
673
674 static int
675 detect_mixer (void)
676 {
677
678
679
680
681
682 setmixer (FM_VOL, 0xff);
683 setmixer (VOC_VOL, 0x33);
684
685 if (getmixer (FM_VOL) != 0xff)
686 return 0;
687 if (getmixer (VOC_VOL) != 0x33)
688 return 0;
689
690 return 1;
691 }
692
693 static void
694 init_mixer (void)
695 {
696 setmixer (MASTER_VOL, 0xbb);
697 setmixer (VOC_VOL, 0x99);
698 setmixer (LINE_VOL, 0xbb);
699 setmixer (FM_VOL, 0x99);
700 setmixer (CD_VOL, 0x11);
701 setmixer (MIC_MIX, 0x11);
702 setmixer (RECORD_SRC, 0x31);
703 setmixer (OUT_FILTER, 0x31);
704 }
705
706 static void
707 set_filter (int record_source, int hifreq_filter, int filter_input, int filter_output)
708 {
709 setmixer (RECORD_SRC, (record_source
710 | (hifreq_filter ? FREQ_HI : FREQ_LOW)
711 | (filter_input ? FILT_ON : FILT_OFF)));
712
713 setmixer (OUT_FILTER, ((dsp_stereo ? STEREO_DAC : MONO_DAC)
714 | (filter_output ? FILT_ON : FILT_OFF)));
715
716 hi_filter = hifreq_filter;
717 filter_in = filter_input;
718 filter_out = filter_output;
719 }
720
721 static int
722 mixer_output (int right_vol, int left_vol, int div, int device)
723 {
724 int left = ((left_vol * div) + 50) / 100;
725 int right = ((right_vol * div) + 50) / 100;
726
727 setmixer (device, ((left & 0xf) << 4) | (right & 0xf));
728
729 return (left_vol | (right_vol << 8));
730 }
731
732 static int
733 sbp_mixer_set (int whichDev, unsigned int level)
734 {
735 int left, right, devmask;
736
737 left = level & 0x7f;
738 right = (level & 0x7f00) >> 8;
739
740 switch (whichDev)
741 {
742 case SOUND_MIXER_VOLUME:
743 return mixer_output (right, left, 15, MASTER_VOL);
744 break;
745 case SOUND_MIXER_SYNTH:
746 return mixer_output (right, left, 15, FM_VOL);
747 break;
748 case SOUND_MIXER_PCM:
749 return mixer_output (right, left, 15, VOC_VOL);
750 break;
751 case SOUND_MIXER_LINE:
752 return mixer_output (right, left, 15, LINE_VOL);
753 break;
754 case SOUND_MIXER_CD:
755 return mixer_output (right, left, 15, CD_VOL);
756 break;
757 case SOUND_MIXER_MIC:
758 return mixer_output (right, left, 7, MIC_VOL);
759 break;
760
761 case SOUND_MIXER_RECSRC:
762 devmask = level & POSSIBLE_RECORDING_DEVICES;
763
764 if (devmask != SOUND_MASK_MIC &&
765 devmask != SOUND_MASK_LINE &&
766 devmask != SOUND_MASK_CD)
767 {
768
769 devmask &= ~rec_devices;
770 }
771
772 if (devmask != SOUND_MASK_MIC &&
773 devmask != SOUND_MASK_LINE &&
774 devmask != SOUND_MASK_CD)
775 {
776
777 devmask = SOUND_MASK_MIC;
778 }
779
780 if (devmask ^ rec_devices)
781 {
782 switch (devmask)
783 {
784
785 case SOUND_MASK_MIC:
786 set_filter (SRC_MIC, hi_filter, filter_in, filter_out);
787 break;
788
789 case SOUND_MASK_LINE:
790 set_filter (SRC_LINE, hi_filter, filter_in, filter_out);
791 break;
792
793 case SOUND_MASK_CD:
794 set_filter (SRC_CD, hi_filter, filter_in, filter_out);
795 break;
796
797 default:
798 set_filter (SRC_MIC, hi_filter, filter_in, filter_out);
799 }
800 }
801
802 rec_devices = devmask;
803
804 return rec_devices;
805 break;
806
807 default:
808 return RET_ERROR (EINVAL);
809 }
810
811 }
812
813 static int
814 mixer_input (int div, int device)
815 {
816 int level, left, right, half;
817
818 level = getmixer (device);
819 half = div / 2;
820
821 left = ((((level & 0xf0) >> 4) * 100) + half) / div;
822 right = (((level & 0x0f) * 100) + half) / div;
823
824 return (right << 8) | left;
825 }
826
827 static int
828 sbp_mixer_get (int whichDev)
829 {
830
831 switch (whichDev)
832 {
833 case SOUND_MIXER_VOLUME:
834 return mixer_input (15, MASTER_VOL);
835 break;
836 case SOUND_MIXER_SYNTH:
837 return mixer_input (15, FM_VOL);
838 break;
839 case SOUND_MIXER_PCM:
840 return mixer_input (15, VOC_VOL);
841 break;
842 case SOUND_MIXER_LINE:
843 return mixer_input (15, LINE_VOL);
844 break;
845 case SOUND_MIXER_CD:
846 return mixer_input (15, CD_VOL);
847 break;
848 case SOUND_MIXER_MIC:
849 return mixer_input (7, MIC_VOL);
850 break;
851
852 default:
853 return RET_ERROR (EINVAL);
854 }
855
856 }
857
858
859
860
861
862
863
864
865 static int
866 mixer_set_levels (struct sb_mixer_levels *user_l)
867 {
868 struct sb_mixer_levels l;
869
870 IOCTL_FROM_USER ((char *) &l, ((char *) user_l), 0, sizeof (l));
871
872 if (l.master.l & ~0xF || l.master.r & ~0xF
873 || l.line.l & ~0xF || l.line.r & ~0xF
874 || l.voc.l & ~0xF || l.voc.r & ~0xF
875 || l.fm.l & ~0xF || l.fm.r & ~0xF
876 || l.cd.l & ~0xF || l.cd.r & ~0xF
877 || l.mic & ~0x7)
878 return (RET_ERROR (EINVAL));
879
880 setmixer (MASTER_VOL, (l.master.l << 4) | l.master.r);
881 setmixer (LINE_VOL, (l.line.l << 4) | l.line.r);
882 setmixer (VOC_VOL, (l.voc.l << 4) | l.voc.r);
883 setmixer (FM_VOL, (l.fm.l << 4) | l.fm.r);
884 setmixer (CD_VOL, (l.cd.l << 4) | l.cd.r);
885 setmixer (MIC_VOL, l.mic);
886 return (0);
887 }
888
889
890
891
892
893
894 static int
895 mixer_set_params (struct sb_mixer_params *user_p)
896 {
897 struct sb_mixer_params p;
898
899 IOCTL_FROM_USER ((char *) &p, (char *) user_p, 0, sizeof (p));
900
901 if (p.record_source != SRC_MIC
902 && p.record_source != SRC_CD
903 && p.record_source != SRC_LINE)
904 return (EINVAL);
905
906
907
908
909
910
911
912 dsp_stereo = !!p.dsp_stereo;
913
914 set_filter (p.record_source, p.hifreq_filter, p.filter_input, p.filter_output);
915
916 switch (p.record_source)
917 {
918
919 case SRC_MIC:
920 rec_devices = SOUND_MASK_MIC;
921 break;
922
923 case SRC_LINE:
924 rec_devices = SOUND_MASK_LINE;
925 break;
926
927 case SRC_CD:
928 rec_devices = SOUND_MASK_CD;
929 }
930
931 return (0);
932 }
933
934
935 static int
936 mixer_get_levels (struct sb_mixer_levels *user_l)
937 {
938 S_BYTE val;
939 struct sb_mixer_levels l;
940
941 val = getmixer (MASTER_VOL);
942 l.master.l = B4 (val >> 4);
943 l.master.r = B4 (val);
944
945 val = getmixer (LINE_VOL);
946 l.line.l = B4 (val >> 4);
947 l.line.r = B4 (val);
948
949 val = getmixer (VOC_VOL);
950 l.voc.l = B4 (val >> 4);
951 l.voc.r = B4 (val);
952
953 val = getmixer (FM_VOL);
954 l.fm.l = B4 (val >> 4);
955 l.fm.r = B4 (val);
956
957 val = getmixer (CD_VOL);
958 l.cd.l = B4 (val >> 4);
959 l.cd.r = B4 (val);
960
961 val = getmixer (MIC_VOL);
962 l.mic = B3 (val);
963
964 IOCTL_TO_USER ((char *) user_l, 0, (char *) &l, sizeof (l));
965
966 return (0);
967 }
968
969
970 static int
971 mixer_get_params (struct sb_mixer_params *user_params)
972 {
973 S_BYTE val;
974 struct sb_mixer_params params;
975
976 val = getmixer (RECORD_SRC);
977 params.record_source = val & 0x07;
978 params.hifreq_filter = !!(val & FREQ_HI);
979 params.filter_input = (val & FILT_OFF) ? OFF : ON;
980 params.filter_output = (getmixer (OUT_FILTER) & FILT_OFF) ? OFF : ON;
981 params.dsp_stereo = dsp_stereo;
982
983 IOCTL_TO_USER ((char *) user_params, 0, (char *) ¶ms, sizeof (params));
984 return (0);
985 }
986
987 static int
988 sb_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
989 {
990 if (((cmd >> 8) & 0xff) == 'M')
991 {
992 if (cmd & IOC_IN)
993 return IOCTL_OUT (arg, sbp_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
994 else
995 {
996
997 switch (cmd & 0xff)
998 {
999
1000 case SOUND_MIXER_RECSRC:
1001 return IOCTL_OUT (arg, rec_devices);
1002 break;
1003
1004 case SOUND_MIXER_DEVMASK:
1005 return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES);
1006 break;
1007
1008 case SOUND_MIXER_STEREODEVS:
1009 return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES & ~SOUND_MASK_MIC);
1010 break;
1011
1012 case SOUND_MIXER_RECMASK:
1013 return IOCTL_OUT (arg, POSSIBLE_RECORDING_DEVICES);
1014 break;
1015
1016 case SOUND_MIXER_CAPS:
1017 return IOCTL_OUT (arg, SOUND_CAP_EXCL_INPUT);
1018 break;
1019
1020 default:
1021 return IOCTL_OUT (arg, sbp_mixer_get (cmd & 0xff));
1022 }
1023 }
1024 }
1025 else
1026 {
1027 switch (cmd)
1028 {
1029 case MIXER_IOCTL_SET_LEVELS:
1030 return (mixer_set_levels ((struct sb_mixer_levels *) arg));
1031 case MIXER_IOCTL_SET_PARAMS:
1032 return (mixer_set_params ((struct sb_mixer_params *) arg));
1033 case MIXER_IOCTL_READ_LEVELS:
1034 return (mixer_get_levels ((struct sb_mixer_levels *) arg));
1035 case MIXER_IOCTL_READ_PARAMS:
1036 return (mixer_get_params ((struct sb_mixer_params *) arg));
1037 case MIXER_IOCTL_RESET:
1038 init_mixer ();
1039 return (0);
1040 default:
1041 return RET_ERROR (EINVAL);
1042 }
1043 }
1044 }
1045
1046
1047 #endif
1048
1049 #ifndef EXCLUDE_MIDI
1050
1051
1052
1053 static int
1054 sb_midi_open (int dev, int mode,
1055 void (*input) (int dev, unsigned char data),
1056 void (*output) (int dev)
1057 )
1058 {
1059 int ret;
1060
1061 if (!sb_dsp_ok)
1062 {
1063 printk ("SB Error: MIDI hardware not installed\n");
1064 return RET_ERROR (ENXIO);
1065 }
1066
1067 if (mode != OPEN_WRITE && !duplex_midi)
1068 {
1069 if (num_midis == 1)
1070 printk ("SoundBlaster: Midi input not currently supported\n");
1071 return RET_ERROR (EPERM);
1072 }
1073
1074 midi_mode = NORMAL_MIDI;
1075 if (mode != OPEN_WRITE)
1076 {
1077 if (dsp_busy || intr_active)
1078 return RET_ERROR (EBUSY);
1079 midi_mode = UART_MIDI;
1080 }
1081
1082 if (dsp_highspeed || dsp_stereo)
1083 {
1084 printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
1085 return RET_ERROR (EBUSY);
1086 }
1087
1088 if (midi_mode == UART_MIDI)
1089 {
1090 irq_mode = IMODE_MIDI;
1091
1092 reset_dsp ();
1093 dsp_speaker (OFF);
1094
1095 if (!dsp_command (0x35))
1096 return RET_ERROR (EIO);
1097 intr_active = 1;
1098
1099 if ((ret = set_dsp_irq (sbc_irq)) < 0)
1100 {
1101 reset_dsp ();
1102 return 0;
1103 }
1104 }
1105
1106 midi_busy = 1;
1107
1108 return 0;
1109 }
1110
1111 static void
1112 sb_midi_close (int dev)
1113 {
1114 if (midi_mode == UART_MIDI)
1115 {
1116 reset_dsp ();
1117 RELEASE_IRQ (sbc_irq);
1118 }
1119 intr_active = 0;
1120 midi_busy = 0;
1121 }
1122
1123 static int
1124 sb_midi_out (int dev, unsigned char midi_byte)
1125 {
1126 unsigned long flags;
1127
1128 midi_busy = 1;
1129
1130 if (midi_mode == NORMAL_MIDI)
1131 {
1132 DISABLE_INTR (flags);
1133 if (dsp_command (0x38))
1134 dsp_command (midi_byte);
1135 else
1136 printk ("SB Error: Unable to send a MIDI byte\n");
1137 RESTORE_INTR (flags);
1138 }
1139 else
1140 dsp_command (midi_byte);
1141
1142 return 1;
1143 }
1144
1145 static int
1146 sb_midi_start_read (int dev)
1147 {
1148 if (midi_mode != UART_MIDI)
1149 {
1150 printk ("SoundBlaster: MIDI input not implemented.\n");
1151 return RET_ERROR (EPERM);
1152 }
1153 return 0;
1154 }
1155
1156 static int
1157 sb_midi_end_read (int dev)
1158 {
1159 if (midi_mode == UART_MIDI)
1160 {
1161 reset_dsp ();
1162 intr_active = 0;
1163 }
1164 return 0;
1165 }
1166
1167 static int
1168 sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
1169 {
1170 return RET_ERROR (EPERM);
1171 }
1172
1173
1174 #endif
1175
1176 #ifndef EXCLUDE_AUDIO
1177 static struct audio_operations sb_dsp_operations =
1178 {
1179 "SoundBlaster",
1180 sb_dsp_open,
1181 sb_dsp_close,
1182 sb_dsp_output_block,
1183 sb_dsp_start_input,
1184 sb_dsp_ioctl,
1185 sb_dsp_prepare_for_input,
1186 sb_dsp_prepare_for_output,
1187 sb_dsp_reset,
1188 sb_dsp_halt_xfer,
1189 NULL,
1190 NULL
1191 };
1192
1193 #endif
1194
1195 #ifndef EXCLUDE_SBPRO
1196 static struct mixer_operations sb_mixer_operations =
1197 {
1198 sb_mixer_ioctl
1199 };
1200
1201 #endif
1202
1203 #ifndef EXCLUDE_MIDI
1204 static struct midi_operations sb_midi_operations =
1205 {
1206 {"SoundBlaster", 0},
1207 sb_midi_open,
1208 sb_midi_close,
1209 sb_midi_ioctl,
1210 sb_midi_out,
1211 sb_midi_start_read,
1212 sb_midi_end_read,
1213 NULL,
1214 NULL,
1215 NULL
1216 };
1217
1218 #endif
1219
1220 static int
1221 verify_irq (void)
1222 {
1223 #if 0
1224 unsigned long loop;
1225
1226 irq_ok = 0;
1227
1228 if (set_dsp_irq (sbc_irq) == -1)
1229 {
1230 printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
1231 return 0;
1232 }
1233
1234
1235 irq_mode = IMODE_INIT;
1236
1237 dsp_command (0xf2);
1238
1239 for (loop = 100000; loop > 0 && !irq_ok; loop--);
1240
1241 RELEASE_IRQ (sbc_irq);
1242
1243 if (!irq_ok)
1244 {
1245 printk ("SB Warning: IRQ test not passed!");
1246 irq_ok = 1;
1247 }
1248 #else
1249 irq_ok = 1;
1250 #endif
1251 return irq_ok;
1252 }
1253
1254 long
1255 sb_dsp_init (long mem_start, struct address_info *hw_config)
1256 {
1257 int i, major, minor;
1258
1259 major = minor = 0;
1260 dsp_command (0xe1);
1261
1262 for (i = 1000; i; i--)
1263 {
1264 if (inb (DSP_DATA_AVAIL) & 0x80)
1265 {
1266 if (major == 0)
1267 major = inb (DSP_READ);
1268 else
1269 {
1270 minor = inb (DSP_READ);
1271 break;
1272 }
1273 }
1274 }
1275
1276 #ifndef EXCLUDE_SBPRO
1277 if (detect_mixer ())
1278 {
1279 #ifndef SCO
1280 sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);
1281 #endif
1282 init_mixer ();
1283 mixer_devs[num_mixers++] = &sb_mixer_operations;
1284
1285 if (major == 2 || major == 3)
1286 duplex_midi = 1;
1287
1288 if (major == 4)
1289 sb16 = 1;
1290
1291 if (major >= 3)
1292 dsp_model = 2;
1293
1294 #ifndef EXCLUDE_YM8312
1295 if (major > 3 || (major == 3 && minor > 0))
1296 {
1297 enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
1298 }
1299 #endif
1300 }
1301 else
1302 #endif
1303
1304 #ifndef SCO
1305 sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);
1306 #endif
1307
1308 printk (" <%s>", sb_dsp_operations.name);
1309
1310 if (!verify_irq ())
1311 return mem_start;
1312
1313 #ifndef EXCLUDE_AUDIO
1314 if (num_dspdevs < MAX_DSP_DEV)
1315 {
1316 dsp_devs[my_dev = num_dspdevs++] = &sb_dsp_operations;
1317 sound_buffcounts[my_dev] = DSP_BUFFCOUNT;
1318 sound_buffsizes[my_dev] = DSP_BUFFSIZE;
1319 sound_dsp_dmachan[my_dev] = hw_config->dma;
1320 sound_dma_automode[my_dev] = 0;
1321 }
1322 else
1323 printk ("SB: Too many DSP devices available\n");
1324 #endif
1325
1326 #ifndef EXCLUDE_MIDI
1327 if (!midi_disabled)
1328
1329 midi_devs[num_midis++] = &sb_midi_operations;
1330 #endif
1331
1332 sb_dsp_ok = 1;
1333 return mem_start;
1334 }
1335
1336 void
1337 sb_dsp_disable_midi (void)
1338 {
1339 midi_disabled = 1;
1340 }
1341
1342 #endif