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