This source file includes following definitions.
- ad_read
- ad_write
- ad_set_MCE
- wait_for_calibration
- ad1848_open
- ad1848_close
- set_speed
- set_channels
- set_format
- ad1848_ioctl
- ad1848_output_block
- ad1848_start_input
- ad1848_prepare_for_IO
- ad1848_reset
- ad1848_halt
- ad1848_detect
- ad1848_init
- ad1848_interrupt
- probe_ms_sound
- attach_ms_sound
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 #define DEB(x)
35 #define DEB1(x)
36 #include "sound_config.h"
37
38 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AD1848)
39
40 #define IMODE_NONE 0
41 #define IMODE_OUTPUT 1
42 #define IMODE_INPUT 2
43 #define IMODE_INIT 3
44 #define IMODE_MIDI 4
45
46 typedef struct
47 {
48 int base;
49 int irq;
50 int dma_capture, dma_playback;
51 unsigned char MCE_bit;
52
53 int speed;
54 unsigned char speed_bits;
55 int channels;
56 int audio_format;
57 unsigned char format_bits;
58
59 int xfer_count;
60 int irq_mode;
61 int intr_active;
62 int opened;
63 char *chip_name;
64 int mode;
65 }
66
67 ad1848_info;
68
69 static int nr_ad1848_devs = 0;
70 static char irq2dev[16] =
71 {-1, -1, -1, -1, -1, -1, -1, -1,
72 -1, -1, -1, -1, -1, -1, -1, -1};
73
74 static int ad_format_mask[2 ] =
75 {
76 AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
77 AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_U16_LE | AFMT_IMA_ADPCM
78 };
79
80 static ad1848_info dev_info[MAX_AUDIO_DEV];
81
82 #define io_Index_Addr(d) ((d)->base)
83 #define io_Indexed_Data(d) ((d)->base+1)
84 #define io_Status(d) ((d)->base+2)
85 #define io_Polled_IO(d) ((d)->base+3)
86
87 static int ad1848_open (int dev, int mode);
88 static void ad1848_close (int dev);
89 static int ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local);
90 static void ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
91 static void ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
92 static int ad1848_prepare_for_IO (int dev, int bsize, int bcount);
93 static void ad1848_reset (int dev);
94 static void ad1848_halt (int dev);
95 void ad1848_interrupt (int dev);
96
97 static int
98 ad_read (ad1848_info * devc, int reg)
99 {
100 unsigned long flags;
101 int x;
102
103 DISABLE_INTR (flags);
104 OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc));
105 x = INB (io_Indexed_Data (devc));
106
107 RESTORE_INTR (flags);
108
109 return x;
110 }
111
112 static void
113 ad_write (ad1848_info * devc, int reg, int data)
114 {
115 unsigned long flags;
116
117 DISABLE_INTR (flags);
118 OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc));
119 OUTB ((unsigned char) (data & 0xff), io_Indexed_Data (devc));
120
121 RESTORE_INTR (flags);
122 }
123
124 static void
125 ad_set_MCE (ad1848_info * devc, int state)
126 {
127 unsigned long flags;
128
129 DISABLE_INTR (flags);
130 if (state)
131 devc->MCE_bit = 0x40;
132 else
133 devc->MCE_bit = 0x00;
134 OUTB (devc->MCE_bit, io_Index_Addr (devc));
135 RESTORE_INTR (flags);
136 }
137
138 static void
139 wait_for_calibration (ad1848_info * devc)
140 {
141 int timeout = 0;
142
143
144
145
146
147
148
149
150 timeout = 100000;
151 while (timeout > 0 && INB (devc->base) == 0x80)
152 timeout--;
153 if (INB (devc->base) == 0x80)
154 printk ("ad1848: Auto calibration timed out(1).\n");
155
156 timeout = 100000;
157 while (timeout > 0 && !(ad_read (devc, 11) & 0x20))
158 timeout--;
159 if (!(ad_read (devc, 11) & 0x20))
160 printk ("ad1848: Auto calibration timed out(2).\n");
161
162 timeout = 100000;
163 while (timeout > 0 && ad_read (devc, 11) & 0x20)
164 timeout--;
165 if (ad_read (devc, 11) & 0x20)
166 printk ("ad1848: Auto calibration timed out(3).\n");
167 }
168
169 static struct audio_operations ad1848_pcm_operations[MAX_AUDIO_DEV] =
170 {
171 {
172 "Generic AD1848 codec",
173 DMA_AUTOMODE,
174 AFMT_U8,
175 NULL,
176 ad1848_open,
177 ad1848_close,
178 ad1848_output_block,
179 ad1848_start_input,
180 ad1848_ioctl,
181 ad1848_prepare_for_IO,
182 ad1848_prepare_for_IO,
183 ad1848_reset,
184 ad1848_halt,
185 NULL,
186 NULL
187 }};
188
189 static int
190 ad1848_open (int dev, int mode)
191 {
192 int err;
193 ad1848_info *devc = NULL;
194 unsigned long flags;
195
196 DEB (printk ("ad1848_open(int mode = %X)\n", mode));
197
198 if (dev < 0 || dev >= num_audiodevs)
199 return RET_ERROR (ENXIO);
200
201 devc = (ad1848_info *) audio_devs[dev]->devc;
202
203 DISABLE_INTR (flags);
204 if (devc->opened)
205 {
206 RESTORE_INTR (flags);
207 printk ("ad1848: Already opened\n");
208 return RET_ERROR (EBUSY);
209 }
210
211 if (devc->irq)
212 if ((err = snd_set_irq_handler (devc->irq, ad1848_interrupt)) < 0)
213 {
214 printk ("ad1848: IRQ in use\n");
215 RESTORE_INTR (flags);
216 return err;
217 }
218
219 if (DMAbuf_open_dma (dev) < 0)
220 {
221 RESTORE_INTR (flags);
222 printk ("ad1848: DMA in use\n");
223 return RET_ERROR (EBUSY);
224 }
225
226 devc->intr_active = 0;
227 devc->opened = 1;
228 RESTORE_INTR (flags);
229
230 return 0;
231 }
232
233 static void
234 ad1848_close (int dev)
235 {
236 unsigned long flags;
237 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
238
239 DEB (printk ("ad1848_close(void)\n"));
240
241 DISABLE_INTR (flags);
242
243 devc->intr_active = 0;
244 if (devc->irq)
245 snd_release_irq (devc->irq);
246 ad1848_reset (dev);
247 DMAbuf_close_dma (dev);
248 devc->opened = 0;
249
250 RESTORE_INTR (flags);
251 }
252
253 static int
254 set_speed (ad1848_info * devc, int arg)
255 {
256
257
258
259
260
261
262
263
264 typedef struct
265 {
266 int speed;
267 unsigned char bits;
268 }
269 speed_struct;
270
271 static speed_struct speed_table[] =
272 {
273 {5510, (0 << 1) | 1},
274 {5510, (0 << 1) | 1},
275 {6620, (7 << 1) | 1},
276 {8000, (0 << 1) | 0},
277 {9600, (7 << 1) | 0},
278 {11025, (1 << 1) | 1},
279 {16000, (1 << 1) | 0},
280 {18900, (2 << 1) | 1},
281 {22050, (3 << 1) | 1},
282 {27420, (2 << 1) | 0},
283 {32000, (3 << 1) | 0},
284 {33075, (6 << 1) | 1},
285 {37800, (4 << 1) | 1},
286 {44100, (5 << 1) | 1},
287 {48000, (6 << 1) | 0}
288 };
289
290 int i, n, selected = -1;
291
292 n = sizeof (speed_table) / sizeof (speed_struct);
293
294 if (arg < speed_table[0].speed)
295 selected = 0;
296 if (arg > speed_table[n - 1].speed)
297 selected = n - 1;
298
299 for (i = 1 ; selected == -1 && i < n; i++)
300 if (speed_table[i].speed == arg)
301 selected = i;
302 else if (speed_table[i].speed > arg)
303 {
304 int diff1, diff2;
305
306 diff1 = arg - speed_table[i - 1].speed;
307 diff2 = speed_table[i].speed - arg;
308
309 if (diff1 < diff2)
310 selected = i - 1;
311 else
312 selected = i;
313 }
314
315 if (selected == -1)
316 {
317 printk ("ad1848: Can't find speed???\n");
318 selected = 3;
319 }
320
321 devc->speed = speed_table[selected].speed;
322 devc->speed_bits = speed_table[selected].bits;
323 return devc->speed;
324 }
325
326 static int
327 set_channels (ad1848_info * devc, int arg)
328 {
329 if (arg != 1 && arg != 2)
330 return devc->channels;
331
332 devc->channels = arg;
333 return arg;
334 }
335
336 static int
337 set_format (ad1848_info * devc, int arg)
338 {
339
340 static struct format_tbl
341 {
342 int format;
343 unsigned char bits;
344 }
345 format2bits [] =
346 {
347 {
348 0, 0
349 }
350 ,
351 {
352 AFMT_MU_LAW, 1
353 }
354 ,
355 {
356 AFMT_A_LAW, 3
357 }
358 ,
359 {
360 AFMT_IMA_ADPCM, 5
361 }
362 ,
363 {
364 AFMT_U8, 0
365 }
366 ,
367 {
368 AFMT_S16_LE, 2
369 }
370 ,
371 {
372 AFMT_S16_BE, 6
373 }
374 ,
375 {
376 AFMT_S8, 0
377 }
378 ,
379 {
380 AFMT_U16_LE, 0
381 }
382 ,
383 {
384 AFMT_U16_BE, 0
385 }
386 };
387 int i, n = sizeof (format2bits) / sizeof (struct format_tbl);
388
389 if (!(arg & ad_format_mask[devc->mode]))
390 arg = AFMT_U8;
391
392 devc->audio_format = arg;
393
394 for (i = 0; i < n; i++)
395 if (format2bits[i].format == arg)
396 {
397 if ((devc->format_bits = format2bits[i].bits) == 0)
398 return devc->audio_format = AFMT_U8;
399
400 return arg;
401 }
402
403
404 devc->format_bits = 0;
405 return devc->audio_format = AFMT_U8;
406 }
407
408 static int
409 ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
410 {
411 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
412
413 switch (cmd)
414 {
415 case SOUND_PCM_WRITE_RATE:
416 if (local)
417 return set_speed (devc, arg);
418 return IOCTL_OUT (arg, set_speed (devc, IOCTL_IN (arg)));
419
420 case SOUND_PCM_READ_RATE:
421 if (local)
422 return devc->speed;
423 return IOCTL_OUT (arg, devc->speed);
424
425 case SNDCTL_DSP_STEREO:
426 if (local)
427 return set_channels (devc, arg + 1) - 1;
428 return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg) + 1) - 1);
429
430 case SOUND_PCM_WRITE_CHANNELS:
431 if (local)
432 return set_channels (devc, arg);
433 return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg)));
434
435 case SOUND_PCM_READ_CHANNELS:
436 if (local)
437 return devc->channels;
438 return IOCTL_OUT (arg, devc->channels);
439
440 case SNDCTL_DSP_SAMPLESIZE:
441 if (local)
442 return set_format (devc, arg);
443 return IOCTL_OUT (arg, set_format (devc, IOCTL_IN (arg)));
444
445 case SOUND_PCM_READ_BITS:
446 if (local)
447 return devc->audio_format;
448 return IOCTL_OUT (arg, devc->audio_format);
449
450 default:;
451 }
452 return RET_ERROR (EINVAL);
453 }
454
455 static void
456 ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
457 {
458 unsigned long flags, cnt;
459 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
460
461 cnt = count;
462
463 if (devc->audio_format == AFMT_IMA_ADPCM)
464 {
465 cnt /= 4;
466 }
467 else
468 {
469 if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
470 cnt >>= 1;
471 }
472 if (devc->channels > 1)
473 cnt >>= 1;
474 cnt--;
475
476 if (audio_devs[dev]->flags & DMA_AUTOMODE &&
477 intrflag &&
478 cnt == devc->xfer_count)
479 {
480 devc->irq_mode = IMODE_OUTPUT;
481 devc->intr_active = 1;
482 return;
483
484
485 }
486 DISABLE_INTR (flags);
487
488 if (dma_restart)
489 {
490 ad1848_halt (dev);
491 DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
492 }
493
494 ad_set_MCE (devc, 1);
495
496 ad_write (devc, 15, (unsigned char) (cnt & 0xff));
497 ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
498
499
500 ad_write (devc, 9, 0x0d);
501
502
503
504
505 ad_set_MCE (devc, 0);
506
507
508
509 wait_for_calibration (devc);
510
511 devc->xfer_count = cnt;
512 devc->irq_mode = IMODE_OUTPUT;
513 devc->intr_active = 1;
514 RESTORE_INTR (flags);
515 }
516
517 static void
518 ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
519 {
520 unsigned long flags, cnt;
521 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
522
523
524
525 cnt = count;
526 if (devc->audio_format == AFMT_IMA_ADPCM)
527 {
528 cnt /= 4;
529 }
530 else
531 {
532 if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
533 cnt >>= 1;
534 }
535 if (devc->channels > 1)
536 cnt >>= 1;
537 cnt--;
538
539 if (audio_devs[dev]->flags & DMA_AUTOMODE &&
540 intrflag &&
541 cnt == devc->xfer_count)
542 {
543 devc->irq_mode = IMODE_INPUT;
544 devc->intr_active = 1;
545 return;
546
547
548 }
549 DISABLE_INTR (flags);
550
551 if (dma_restart)
552 {
553 ad1848_halt (dev);
554 DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
555 }
556
557 ad_set_MCE (devc, 1);
558 #if 0
559 ad_write (devc, count_reg + 1, (unsigned char) (cnt & 0xff));
560 ad_write (devc, count_reg, (unsigned char) ((cnt >> 8) & 0xff));
561 #else
562 ad_write (devc, 15, (unsigned char) (cnt & 0xff));
563 ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
564 if (devc->mode == 2)
565 {
566 ad_write (devc, 31, (unsigned char) (cnt & 0xff));
567 ad_write (devc, 32, (unsigned char) ((cnt >> 8) & 0xff));
568 }
569 #endif
570
571 ad_write (devc, 9, 0x0e);
572
573
574
575
576 ad_set_MCE (devc, 0);
577
578
579
580 wait_for_calibration (devc);
581
582 devc->xfer_count = cnt;
583 devc->irq_mode = IMODE_INPUT;
584 devc->intr_active = 1;
585 RESTORE_INTR (flags);
586 }
587
588 static int
589 ad1848_prepare_for_IO (int dev, int bsize, int bcount)
590 {
591 int timeout;
592 unsigned char fs;
593 unsigned long flags;
594 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
595
596 DISABLE_INTR (flags);
597 ad_set_MCE (devc, 1);
598 fs = devc->speed_bits | (devc->format_bits << 5);
599
600 if (devc->channels > 1)
601 fs |= 0x10;
602
603 ad_write (devc, 8, fs);
604
605
606
607 timeout = 10000;
608 while (timeout > 0 && INB (devc->base) == 0x80)
609 timeout--;
610
611 ad_set_MCE (devc, 0);
612
613
614
615 wait_for_calibration (devc);
616 RESTORE_INTR (flags);
617
618
619
620
621 if (devc->mode == 2)
622 {
623 ad_set_MCE (devc, 1);
624 ad_write (devc, 28, fs);
625
626
627
628
629 timeout = 10000;
630 while (timeout > 0 && INB (devc->base) == 0x80)
631 timeout--;
632
633 ad_set_MCE (devc, 0);
634
635
636
637 wait_for_calibration (devc);
638 RESTORE_INTR (flags);
639 }
640 devc->xfer_count = 0;
641 return 0;
642 }
643
644 static void
645 ad1848_reset (int dev)
646 {
647 ad1848_halt (dev);
648 }
649
650 static void
651 ad1848_halt (int dev)
652 {
653 ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
654
655 ad_write (devc, 9, 0);
656 OUTB (0, io_Status (devc));
657 }
658
659 int
660 ad1848_detect (int io_base)
661 {
662
663 #define DDB(x) x
664
665 unsigned char tmp;
666 int i;
667 ad1848_info *devc = &dev_info[nr_ad1848_devs];
668 unsigned char tmp1 = 0xff, tmp2 = 0xff;
669
670 if (nr_ad1848_devs >= MAX_AUDIO_DEV)
671 return 0;
672
673 devc->base = io_base;
674 devc->MCE_bit = 0x40;
675 devc->irq = 0;
676 devc->dma_capture = 0;
677 devc->dma_playback = 0;
678 devc->opened = 0;
679 devc->chip_name = "AD1848";
680 devc->mode = 1;
681
682
683
684
685
686
687
688
689
690
691
692 if ((INB (devc->base) & 0x80) != 0x00)
693 {
694 DDB (printk ("ad_detect_A\n"));
695 return 0;
696 }
697
698
699
700
701
702
703
704 ad_write (devc, 0, 0xaa);
705 ad_write (devc, 1, 0x45);
706
707 if ((tmp1 = ad_read (devc, 0)) != 0xaa || (tmp2 = ad_read (devc, 1)) != 0x45)
708 {
709 DDB (printk ("ad_detect_B (%x/%x)\n", tmp1, tmp2));
710 return 0;
711 }
712
713 ad_write (devc, 0, 0x45);
714 ad_write (devc, 1, 0xaa);
715
716 if ((tmp1 = ad_read (devc, 0)) != 0x45 || (tmp2 = ad_read (devc, 1)) != 0xaa)
717 {
718 DDB (printk ("ad_detect_C (%x/%x)\n", tmp1, tmp2));
719 return 0;
720 }
721
722
723
724
725
726
727 tmp = ad_read (devc, 12);
728 ad_write (devc, 12, (~tmp) & 0x0f);
729
730 if ((tmp & 0x0f) != ((tmp1 = ad_read (devc, 12)) & 0x0f))
731 {
732 DDB (printk ("ad_detect_D (%x)\n", tmp1));
733 return 0;
734 }
735
736
737
738
739
740
741
742
743
744
745
746
747
748 ad_write (devc, 12, 0);
749
750 for (i = 0; i < 16; i++)
751 if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16)))
752 {
753 DDB (printk ("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2));
754 return 0;
755 }
756
757
758
759
760
761
762 ad_write (devc, 12, 0x40);
763
764 tmp1 = ad_read (devc, 12);
765 if (tmp1 & 0x80)
766 devc->chip_name = "CS4248";
767
768 if ((tmp1 & 0xc0) == (0x80 | 0x40))
769 {
770
771
772
773
774
775 ad_write (devc, 16, 0);
776
777 ad_write (devc, 0, 0x45);
778 if ((tmp1 = ad_read (devc, 16)) != 0x45)
779 {
780
781 ad_write (devc, 0, 0xaa);
782 if ((tmp1 = ad_read (devc, 16)) == 0xaa)
783 {
784 DDB (printk ("ad_detect_H(%x)\n", tmp1));
785 return 0;
786 }
787
788
789
790
791
792 devc->chip_name = "CS4231";
793 devc->mode = 2;
794 }
795 }
796
797 return 1;
798 }
799
800 void
801 ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture)
802 {
803
804
805
806
807
808
809
810
811
812 static int init_values[] =
813 {
814 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
815 0x00, 0x08, 0x02, 0x00, 0xca, 0x00, 0x00, 0x00
816 };
817 int i, my_dev;
818 ad1848_info *devc = &dev_info[nr_ad1848_devs];
819
820 if (!ad1848_detect (io_base))
821 return;
822
823 devc->irq = (irq > 0) ? irq : 0;
824 devc->dma_capture = dma_playback;
825 devc->dma_playback = dma_capture;
826 devc->opened = 0;
827
828 if (nr_ad1848_devs != 0)
829 {
830 memcpy ((char *) &ad1848_pcm_operations[nr_ad1848_devs],
831 (char *) &ad1848_pcm_operations[0],
832 sizeof (struct audio_operations));
833 }
834
835 for (i = 0; i < 16; i++)
836 ad_write (devc, i, init_values[i]);
837
838 OUTB (0, io_Status (devc));
839
840 #ifndef SCO
841 sprintf (ad1848_pcm_operations[nr_ad1848_devs].name,
842 "%s (%s)", name, devc->chip_name);
843 #endif
844
845 if (irq > 0)
846 printk (" <%s>", ad1848_pcm_operations[nr_ad1848_devs].name);
847
848 if (num_audiodevs < MAX_AUDIO_DEV)
849 {
850 audio_devs[my_dev = num_audiodevs++] = &ad1848_pcm_operations[nr_ad1848_devs];
851 if (irq > 0)
852 irq2dev[irq] = my_dev;
853 else if (irq < 0)
854 irq2dev[-irq] = my_dev;
855
856 audio_devs[my_dev]->dmachan = dma_playback;
857 audio_devs[my_dev]->buffcount = 1;
858 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE * 2;
859 audio_devs[my_dev]->devc = devc;
860 audio_devs[my_dev]->format_mask = ad_format_mask[devc->mode];
861 nr_ad1848_devs++;
862 }
863 else
864 printk ("AD1848: Too many PCM devices available\n");
865 }
866
867 void
868 ad1848_interrupt (int irq)
869 {
870 unsigned char status;
871 ad1848_info *devc;
872 int dev;
873
874 if (irq < 0 || irq > 15)
875 return;
876 dev = irq2dev[irq];
877 if (dev < 0 || dev >= num_audiodevs)
878 return;
879
880 devc = (ad1848_info *) audio_devs[dev]->devc;
881 status = INB (io_Status (devc));
882
883 if (status & 0x01)
884 {
885 if (devc->opened && devc->irq_mode == IMODE_OUTPUT)
886 {
887 DMAbuf_outputintr (dev, 1);
888 }
889
890 if (devc->opened && devc->irq_mode == IMODE_INPUT)
891 DMAbuf_inputintr (dev);
892 }
893
894 OUTB (0, io_Status (devc));
895 }
896
897 #endif
898
899
900
901 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MSS)
902
903 int
904 probe_ms_sound (struct address_info *hw_config)
905 {
906 if ((INB (hw_config->io_base + 3) & 0x04) == 0)
907 return 0;
908
909 if (hw_config->irq > 11)
910 return 0;
911
912 if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
913 return 0;
914
915 return ad1848_detect (hw_config->io_base + 4);
916 }
917
918 long
919 attach_ms_sound (long mem_start, struct address_info *hw_config)
920 {
921 static unsigned char interrupt_bits[12] =
922 {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20};
923 char bits;
924
925 static unsigned char dma_bits[4] = {1, 2, 0, 3};
926
927 int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
928
929 if (!ad1848_detect (hw_config->io_base + 4))
930 return mem_start;
931
932
933
934
935
936 bits = interrupt_bits[hw_config->irq];
937 if (bits == -1)
938 return mem_start;
939
940 OUTB (bits | 0x40, config_port);
941 if ((INB (version_port) & 0x40) == 0)
942 printk ("[IRQ?]");
943
944 OUTB (bits | dma_bits[hw_config->dma], config_port);
945
946 ad1848_init ("MS Sound System", hw_config->io_base + 4,
947 hw_config->irq,
948 hw_config->dma,
949 hw_config->dma);
950 return mem_start;
951 }
952
953 #endif