This source file includes following definitions.
- sscape_read
- sscape_write
- host_open
- host_close
- host_write
- host_read
- host_command1
- host_command2
- host_command3
- set_mt32
- get_board_type
- sscapeintr
- sscape_enable_intr
- sscape_disable_intr
- do_dma
- verify_mpu
- sscape_coproc_open
- sscape_coproc_close
- sscape_coproc_reset
- sscape_download_boot
- download_boot_block
- sscape_coproc_ioctl
- sscape_audio_open
- sscape_audio_close
- set_speed
- set_channels
- set_format
- sscape_audio_ioctl
- sscape_audio_output_block
- sscape_audio_start_input
- sscape_audio_prepare_for_input
- sscape_audio_prepare_for_output
- sscape_audio_halt
- sscape_audio_reset
- attach_sscape
- probe_sscape
- probe_ss_ms_sound
- attach_ss_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 #include "sound_config.h"
31
32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SSCAPE)
33
34 #include "coproc.h"
35
36
37
38
39 #define MIDI_DATA 0
40 #define MIDI_CTRL 1
41 #define HOST_CTRL 2
42 #define TX_READY 0x02
43 #define RX_READY 0x01
44 #define HOST_DATA 3
45 #define ODIE_ADDR 4
46 #define ODIE_DATA 5
47
48
49
50
51 #define GA_INTSTAT_REG 0
52 #define GA_INTENA_REG 1
53 #define GA_DMAA_REG 2
54 #define GA_DMAB_REG 3
55 #define GA_INTCFG_REG 4
56 #define GA_DMACFG_REG 5
57 #define GA_CDCFG_REG 6
58 #define GA_SMCFGA_REG 7
59 #define GA_SMCFGB_REG 8
60 #define GA_HMCTL_REG 9
61
62
63
64
65 #define SSCAPE_DMA_A 0
66 #define SSCAPE_DMA_B 1
67
68 #define PORT(name) (devc->base+name)
69
70
71
72
73 #define CMD_GEN_HOST_ACK 0x80
74 #define CMD_GEN_MPU_ACK 0x81
75 #define CMD_GET_BOARD_TYPE 0x82
76 #define CMD_SET_CONTROL 0x88
77 #define CMD_GET_CONTROL 0x89
78 #define CMD_SET_MT32 0x96
79 #define CMD_GET_MT32 0x97
80 #define CMD_SET_EXTMIDI 0x9b
81 #define CMD_GET_EXTMIDI 0x9c
82
83 #define CMD_ACK 0x80
84
85 typedef struct sscape_info
86 {
87 int base, irq, dma;
88 int ok;
89 int dma_allocated;
90 int my_audiodev;
91 int opened;
92 }
93
94 sscape_info;
95 static struct sscape_info dev_info =
96 {0};
97 static struct sscape_info *devc = &dev_info;
98
99 DEFINE_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
100
101
102 static char valid_interrupts_old[] =
103 {9, 7, 5, 15};
104
105 static char valid_interrupts_new[] =
106 {9, 5, 7, 10};
107
108 static char *valid_interrupts = valid_interrupts_new;
109
110 #ifdef REVEAL_SPEA
111 static char old_hardware = 1;
112
113 #else
114 static char old_hardware = 0;
115
116 #endif
117
118 static unsigned char
119 sscape_read (struct sscape_info *devc, int reg)
120 {
121 unsigned long flags;
122 unsigned char val;
123
124 DISABLE_INTR (flags);
125 OUTB (reg, PORT (ODIE_ADDR));
126 val = INB (PORT (ODIE_DATA));
127 RESTORE_INTR (flags);
128 return val;
129 }
130
131 static void
132 sscape_write (struct sscape_info *devc, int reg, int data)
133 {
134 unsigned long flags;
135
136 DISABLE_INTR (flags);
137 OUTB (reg, PORT (ODIE_ADDR));
138 OUTB (data, PORT (ODIE_DATA));
139 RESTORE_INTR (flags);
140 }
141
142 static void
143 host_open (struct sscape_info *devc)
144 {
145 OUTB (0x00, PORT (HOST_CTRL));
146 }
147
148 static void
149 host_close (struct sscape_info *devc)
150 {
151 OUTB (0x03, PORT (HOST_CTRL));
152 }
153
154 static int
155 host_write (struct sscape_info *devc, unsigned char *data, int count)
156 {
157 unsigned long flags;
158 int i, timeout;
159
160 DISABLE_INTR (flags);
161
162
163
164
165
166 for (i = 0; i < count; i++)
167 {
168 for (timeout = 10000; timeout > 0; timeout--)
169 if (INB (PORT (HOST_CTRL)) & TX_READY)
170 break;
171
172 if (timeout <= 0)
173 {
174 RESTORE_INTR (flags);
175 return 0;
176 }
177
178 OUTB (data[i], PORT (HOST_DATA));
179 }
180
181
182 RESTORE_INTR (flags);
183
184 return 1;
185 }
186
187 static int
188 host_read (struct sscape_info *devc)
189 {
190 unsigned long flags;
191 int timeout;
192 unsigned char data;
193
194 DISABLE_INTR (flags);
195
196
197
198
199
200 for (timeout = 10000; timeout > 0; timeout--)
201 if (INB (PORT (HOST_CTRL)) & RX_READY)
202 break;
203
204 if (timeout <= 0)
205 {
206 RESTORE_INTR (flags);
207 return -1;
208 }
209
210 data = INB (PORT (HOST_DATA));
211
212 RESTORE_INTR (flags);
213
214 return data;
215 }
216
217 static int
218 host_command1 (struct sscape_info *devc, int cmd)
219 {
220 unsigned char buf[10];
221
222 buf[0] = (unsigned char) (cmd & 0xff);
223
224 return host_write (devc, buf, 1);
225 }
226
227 static int
228 host_command2 (struct sscape_info *devc, int cmd, int parm1)
229 {
230 unsigned char buf[10];
231
232 buf[0] = (unsigned char) (cmd & 0xff);
233 buf[1] = (unsigned char) (parm1 & 0xff);
234
235 return host_write (devc, buf, 2);
236 }
237
238 static int
239 host_command3 (struct sscape_info *devc, int cmd, int parm1, int parm2)
240 {
241 unsigned char buf[10];
242
243 buf[0] = (unsigned char) (cmd & 0xff);
244 buf[1] = (unsigned char) (parm1 & 0xff);
245 buf[2] = (unsigned char) (parm2 & 0xff);
246
247 return host_write (devc, buf, 3);
248 }
249
250 static void
251 set_mt32 (struct sscape_info *devc, int value)
252 {
253 host_open (devc);
254 host_command2 (devc, CMD_SET_MT32,
255 value ? 1 : 0);
256 if (host_read (devc) != CMD_ACK)
257 {
258 printk ("SNDSCAPE: Setting MT32 mode failed\n");
259 }
260 host_close (devc);
261 }
262
263 static int
264 get_board_type (struct sscape_info *devc)
265 {
266 int tmp;
267
268 host_open (devc);
269 if (!host_command1 (devc, CMD_GET_BOARD_TYPE))
270 tmp = -1;
271 else
272 tmp = host_read (devc);
273 host_close (devc);
274 return tmp;
275 }
276
277 void
278 sscapeintr (INT_HANDLER_PARMS (irq, dummy))
279 {
280 unsigned char bits, tmp;
281 static int debug = 0;
282
283 printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
284 if (SOMEONE_WAITING (sscape_sleeper, sscape_sleep_flag))
285 {
286 WAKE_UP (sscape_sleeper, sscape_sleep_flag);
287 }
288
289 if (bits & 0x02)
290 {
291 printk ("SSCAPE: Host interrupt, data=%02x\n", host_read (devc));
292 }
293
294 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
295 if (bits & 0x01)
296 {
297 mpuintr (INT_HANDLER_CALL (irq));
298 if (debug++ > 10)
299 {
300 sscape_write (devc, GA_INTENA_REG, 0x00);
301 }
302 }
303 #endif
304
305
306
307
308
309 tmp = sscape_read (devc, GA_INTENA_REG);
310 sscape_write (devc, GA_INTENA_REG, (~bits & 0x0e) | (tmp & 0xf1));
311
312 }
313
314 static void
315 sscape_enable_intr (struct sscape_info *devc, unsigned intr_bits)
316 {
317 unsigned char temp, orig;
318
319 temp = orig = sscape_read (devc, GA_INTENA_REG);
320 temp |= intr_bits;
321 temp |= 0x80;
322
323 if (temp == orig)
324 return;
325
326 sscape_write (devc, GA_INTENA_REG, temp);
327 }
328
329 static void
330 sscape_disable_intr (struct sscape_info *devc, unsigned intr_bits)
331 {
332 unsigned char temp, orig;
333
334 temp = orig = sscape_read (devc, GA_INTENA_REG);
335 temp &= ~intr_bits;
336 if ((temp & ~0x80) == 0x00)
337 temp = 0x00;
338 if (temp == orig)
339 return;
340
341 sscape_write (devc, GA_INTENA_REG, temp);
342 }
343
344 static void
345 do_dma (struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
346 {
347 unsigned char temp;
348
349 if (dma_chan != SSCAPE_DMA_A)
350 {
351 printk ("SSCAPE: Tried to use DMA channel != A. Why?\n");
352 return;
353 }
354
355 DMAbuf_start_dma (devc->my_audiodev,
356 buf,
357 blk_size, mode);
358
359 temp = devc->dma << 4;
360 if (devc->dma <= 3)
361 temp |= 0x80;
362
363 temp |= 1;
364 sscape_write (devc, GA_DMAA_REG, temp);
365 temp &= 0xfe;
366 sscape_write (devc, GA_DMAA_REG, temp);
367 }
368
369 static int
370 verify_mpu (struct sscape_info *devc)
371 {
372
373
374
375
376
377
378
379
380
381
382 int i;
383
384 for (i = 0; i < 10; i++)
385 {
386 if (INB (devc->base + HOST_CTRL) & 0x80)
387 return 1;
388
389 if (INB (devc->base) != 0x00)
390 return 1;
391 }
392
393 printk ("SoundScape: The device is not in the MPU-401 mode\n");
394 return 0;
395 }
396
397 static int
398 sscape_coproc_open (void *dev_info, int sub_device)
399 {
400 if (sub_device == COPR_MIDI)
401 {
402 set_mt32 (devc, 0);
403 if (!verify_mpu (devc))
404 return RET_ERROR (EIO);
405 }
406
407 return 0;
408 }
409
410 static void
411 sscape_coproc_close (void *dev_info, int sub_device)
412 {
413 struct sscape_info *devc = dev_info;
414 unsigned long flags;
415
416 DISABLE_INTR (flags);
417 if (devc->dma_allocated)
418 {
419 sscape_write (devc, GA_DMAA_REG, 0x20);
420 #ifndef EXCLUDE_NATIVE_PCM
421 DMAbuf_close_dma (devc->my_audiodev);
422 #endif
423 devc->dma_allocated = 0;
424 }
425 RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
426 RESTORE_INTR (flags);
427
428 return;
429 }
430
431 static void
432 sscape_coproc_reset (void *dev_info)
433 {
434 }
435
436 static int
437 sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag)
438 {
439 unsigned long flags;
440 unsigned char temp;
441 int done, timeout;
442
443 if (flag & CPF_FIRST)
444 {
445
446
447
448
449
450 DISABLE_INTR (flags);
451 if (devc->dma_allocated == 0)
452 {
453 #ifndef EXCLUDE_NATIVE_PCM
454 if (DMAbuf_open_dma (devc->my_audiodev) < 0)
455 {
456 RESTORE_INTR (flags);
457 return 0;
458 }
459 #endif
460
461 devc->dma_allocated = 1;
462 }
463 RESTORE_INTR (flags);
464
465 sscape_write (devc, GA_HMCTL_REG,
466 (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f);
467
468 for (timeout = 10000; timeout > 0; timeout--)
469 sscape_read (devc, GA_HMCTL_REG);
470
471
472 sscape_write (devc, GA_HMCTL_REG,
473 (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80);
474 }
475
476
477
478
479 memcpy (audio_devs[devc->my_audiodev]->dmap->raw_buf[0], block, size);
480
481 DISABLE_INTR (flags);
482
483 do_dma (devc, SSCAPE_DMA_A,
484 audio_devs[devc->my_audiodev]->dmap->raw_buf_phys[0],
485 size, DMA_MODE_WRITE);
486
487
488
489
490 RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
491 done = 0;
492 timeout = 100;
493 while (!done && timeout-- > 0)
494 {
495 int resid;
496
497 DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
498 clear_dma_ff (devc->dma);
499 if ((resid = get_dma_residue (devc->dma)) == 0)
500 done = 1;
501 }
502
503 RESTORE_INTR (flags);
504 if (!done)
505 return 0;
506
507 if (flag & CPF_LAST)
508 {
509
510
511
512 OUTB (0x00, PORT (HOST_CTRL));
513 OUTB (0x00, PORT (MIDI_CTRL));
514
515 temp = sscape_read (devc, GA_HMCTL_REG);
516 temp |= 0x40;
517 sscape_write (devc, GA_HMCTL_REG, temp);
518
519
520
521
522
523 DISABLE_INTR (flags);
524 done = 0;
525 timeout = 5 * HZ;
526 while (!done && timeout-- > 0)
527 {
528 DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
529 if (INB (PORT (HOST_DATA)) == 0xff)
530 done = 1;
531 }
532 RESTORE_INTR (flags);
533 if (!done)
534 {
535 printk ("SoundScape: The OBP didn't respond after code download\n");
536 return 0;
537 }
538
539 DISABLE_INTR (flags);
540 done = 0;
541 timeout = 5 * HZ;
542 while (!done && timeout-- > 0)
543 {
544 DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
545 if (INB (PORT (HOST_DATA)) == 0xfe)
546 done = 1;
547 }
548 RESTORE_INTR (flags);
549 if (!done)
550 {
551 printk ("SoundScape: OBP Initialization failed.\n");
552 return 0;
553 }
554
555 printk ("SoundScape board of type %d initialized OK\n",
556 get_board_type (devc));
557
558 #ifdef SSCAPE_DEBUG3
559
560
561
562
563 {
564 int i;
565
566 for (i = 0; i < 13; i++)
567 printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
568 }
569 #endif
570
571 }
572
573 return 1;
574 }
575
576 static int
577 download_boot_block (void *dev_info, copr_buffer * buf)
578 {
579 if (buf->len <= 0 || buf->len > sizeof (buf->data))
580 return RET_ERROR (EINVAL);
581
582 if (!sscape_download_boot (devc, buf->data, buf->len, buf->flags))
583 {
584 printk ("SSCAPE: Unable to load microcode block to the OBP.\n");
585 return RET_ERROR (EIO);
586 }
587
588 return 0;
589 }
590
591 static int
592 sscape_coproc_ioctl (void *dev_info, unsigned int cmd, unsigned int arg, int local)
593 {
594
595 switch (cmd)
596 {
597 case SNDCTL_COPR_RESET:
598 sscape_coproc_reset (dev_info);
599 return 0;
600 break;
601
602 case SNDCTL_COPR_LOAD:
603 {
604 copr_buffer *buf;
605 int err;
606
607 buf = (copr_buffer *) KERNEL_MALLOC (sizeof (copr_buffer));
608 IOCTL_FROM_USER ((char *) buf, (char *) arg, 0, sizeof (*buf));
609 err = download_boot_block (dev_info, buf);
610 KERNEL_FREE (buf);
611 return err;
612 }
613 break;
614
615 default:
616 return RET_ERROR (EINVAL);
617 }
618
619 return RET_ERROR (EINVAL);
620 }
621
622 static coproc_operations sscape_coproc_operations =
623 {
624 "SoundScape M68K",
625 sscape_coproc_open,
626 sscape_coproc_close,
627 sscape_coproc_ioctl,
628 sscape_coproc_reset,
629 &dev_info
630 };
631
632 static int
633 sscape_audio_open (int dev, int mode)
634 {
635 unsigned long flags;
636 sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
637
638 DISABLE_INTR (flags);
639 if (devc->opened)
640 {
641 RESTORE_INTR (flags);
642 return RET_ERROR (EBUSY);
643 }
644
645 if (devc->dma_allocated == 0)
646 {
647 int err;
648
649 if ((err = DMAbuf_open_dma (devc->my_audiodev)) < 0)
650 {
651 RESTORE_INTR (flags);
652 return err;
653 }
654
655 devc->dma_allocated = 1;
656 }
657
658 devc->opened = 1;
659 RESTORE_INTR (flags);
660 #ifdef SSCAPE_DEBUG4
661
662
663
664
665 {
666 int i;
667
668 for (i = 0; i < 13; i++)
669 printk ("I%d = %02x\n", i, sscape_read (devc, i));
670 }
671 #endif
672
673 return 0;
674 }
675
676 static void
677 sscape_audio_close (int dev)
678 {
679 unsigned long flags;
680 sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
681
682 DEB (printk ("sscape_audio_close(void)\n"));
683
684 DISABLE_INTR (flags);
685
686 if (devc->dma_allocated)
687 {
688 sscape_write (devc, GA_DMAA_REG, 0x20);
689 DMAbuf_close_dma (dev);
690 devc->dma_allocated = 0;
691 }
692 devc->opened = 0;
693
694 RESTORE_INTR (flags);
695 }
696
697 static int
698 set_speed (sscape_info * devc, int arg)
699 {
700 return 8000;
701 }
702
703 static int
704 set_channels (sscape_info * devc, int arg)
705 {
706 return 1;
707 }
708
709 static int
710 set_format (sscape_info * devc, int arg)
711 {
712 return AFMT_U8;
713 }
714
715 static int
716 sscape_audio_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
717 {
718 sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
719
720 switch (cmd)
721 {
722 case SOUND_PCM_WRITE_RATE:
723 if (local)
724 return set_speed (devc, arg);
725 return IOCTL_OUT (arg, set_speed (devc, IOCTL_IN (arg)));
726
727 case SOUND_PCM_READ_RATE:
728 if (local)
729 return 8000;
730 return IOCTL_OUT (arg, 8000);
731
732 case SNDCTL_DSP_STEREO:
733 if (local)
734 return set_channels (devc, arg + 1) - 1;
735 return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg) + 1) - 1);
736
737 case SOUND_PCM_WRITE_CHANNELS:
738 if (local)
739 return set_channels (devc, arg);
740 return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg)));
741
742 case SOUND_PCM_READ_CHANNELS:
743 if (local)
744 return 1;
745 return IOCTL_OUT (arg, 1);
746
747 case SNDCTL_DSP_SAMPLESIZE:
748 if (local)
749 return set_format (devc, arg);
750 return IOCTL_OUT (arg, set_format (devc, IOCTL_IN (arg)));
751
752 case SOUND_PCM_READ_BITS:
753 if (local)
754 return 8;
755 return IOCTL_OUT (arg, 8);
756
757 default:;
758 }
759 return RET_ERROR (EINVAL);
760 }
761
762 static void
763 sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
764 {
765 }
766
767 static void
768 sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
769 {
770 }
771
772 static int
773 sscape_audio_prepare_for_input (int dev, int bsize, int bcount)
774 {
775 return 0;
776 }
777
778 static int
779 sscape_audio_prepare_for_output (int dev, int bsize, int bcount)
780 {
781 return 0;
782 }
783
784 static void
785 sscape_audio_halt (int dev)
786 {
787 }
788
789 static void
790 sscape_audio_reset (int dev)
791 {
792 sscape_audio_halt (dev);
793 }
794
795 static struct audio_operations sscape_audio_operations =
796 {
797 "Not functional",
798 0,
799 AFMT_U8 | AFMT_S16_LE,
800 NULL,
801 sscape_audio_open,
802 sscape_audio_close,
803 sscape_audio_output_block,
804 sscape_audio_start_input,
805 sscape_audio_ioctl,
806 sscape_audio_prepare_for_input,
807 sscape_audio_prepare_for_output,
808 sscape_audio_reset,
809 sscape_audio_halt,
810 NULL,
811 NULL
812 };
813
814 long
815 attach_sscape (long mem_start, struct address_info *hw_config)
816 {
817 int my_dev;
818
819 #ifndef SSCAPE_REGS
820
821
822
823
824
825
826
827
828
829
830
831
832
833 #define SSCAPE_REGS { \
834 0x00, \
835 0xf0, \
836 0x20, \
837 0x20, \
838 0xf5, \
839 0x10, \
840 0x00, \
841 0x2e, \
842 0x00, \
843 0x40 \
844 }
845 #endif
846
847 unsigned long flags;
848 static unsigned char regs[10] = SSCAPE_REGS;
849
850 int i, irq_bits = 0xff;
851
852 if (!probe_sscape (hw_config))
853 return mem_start;
854
855 if (old_hardware)
856 {
857 valid_interrupts = valid_interrupts_old;
858 printk (" <Ensoniq Soundscape (old)>");
859 }
860 else
861 printk (" <Ensoniq Soundscape>");
862
863 for (i = 0; i < sizeof (valid_interrupts); i++)
864 if (hw_config->irq == valid_interrupts[i])
865 {
866 irq_bits = i;
867 break;
868 }
869
870 if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
871 {
872 printk ("Invalid IRQ%d\n", hw_config->irq);
873 return mem_start;
874 }
875
876 DISABLE_INTR (flags);
877
878 for (i = 1; i < 10; i++)
879 switch (i)
880 {
881 case 1:
882 sscape_write (devc, i, 0xf0);
883 break;
884
885 case 2:
886 case 3:
887 sscape_write (devc, i, 0x20);
888 break;
889
890 case 4:
891 sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
892 break;
893
894 case 5:
895 sscape_write (devc, i, (regs[i] & 0x3f) |
896 (sscape_read (devc, i) & 0xc0));
897 break;
898
899 case 6:
900 break;
901
902 case 9:
903 sscape_write (devc, i,
904 (sscape_read (devc, i) & 0xf0) | 0x00);
905 break;
906
907 default:
908 sscape_write (devc, i, regs[i]);
909 }
910
911 RESTORE_INTR (flags);
912
913 #ifdef SSCAPE_DEBUG2
914
915
916
917
918 {
919 int i;
920
921 for (i = 0; i < 13; i++)
922 printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
923 }
924 #endif
925
926 #if !defined(EXCLUDE_MIDI) && !defined(EXCLUDE_MPU_EMU)
927 hw_config->always_detect = 1;
928 if (probe_mpu401 (hw_config))
929 {
930 int prev_devs;
931
932 prev_devs = num_midis;
933 mem_start = attach_mpu401 (mem_start, hw_config);
934
935 if (num_midis == (prev_devs + 1))
936 midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
937 }
938 #endif
939
940 #ifndef EXCLUDE_NATIVE_PCM
941
942
943 #ifndef EXCLUDE_AUDIO
944 if (num_audiodevs < MAX_AUDIO_DEV)
945 {
946 audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
947 audio_devs[my_dev]->dmachan = hw_config->dma;
948 audio_devs[my_dev]->buffcount = 1;
949 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
950 audio_devs[my_dev]->devc = devc;
951 devc->my_audiodev = my_dev;
952 devc->opened = 0;
953 audio_devs[my_dev]->coproc = &sscape_coproc_operations;
954 if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape") < 0)
955 printk ("Error: Can't allocate IRQ for SoundScape\n");
956
957 sscape_write (devc, GA_INTENA_REG, 0x80);
958 }
959 else
960 printk ("SoundScape: More than enough audio devices detected\n");
961 #endif
962 #endif
963 devc->ok = 1;
964 return mem_start;
965 }
966
967 int
968 probe_sscape (struct address_info *hw_config)
969 {
970 unsigned char save;
971
972 devc->base = hw_config->io_base;
973 devc->irq = hw_config->irq;
974 devc->dma = hw_config->dma;
975
976
977
978
979
980
981 if ((save = INB (PORT (ODIE_ADDR))) & 0xf0)
982 return 0;
983
984 OUTB (0x00, PORT (ODIE_ADDR));
985 if (INB (PORT (ODIE_ADDR)) != 0x00)
986 return 0;
987
988 OUTB (0xff, PORT (ODIE_ADDR));
989 if (INB (PORT (ODIE_ADDR)) != 0x0f)
990 return 0;
991
992 OUTB (save, PORT (ODIE_ADDR));
993
994
995
996
997
998
999 if (sscape_read (devc, 0) & 0x0c)
1000 return 0;
1001
1002 if (sscape_read (devc, 1) & 0x0f)
1003 return 0;
1004
1005 if (sscape_read (devc, 5) & 0x0f)
1006 return 0;
1007
1008 #ifdef SSCAPE_DEBUG1
1009
1010
1011
1012
1013 {
1014 int i;
1015
1016 for (i = 0; i < 13; i++)
1017 printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i));
1018 }
1019 #endif
1020
1021 if (old_hardware)
1022 {
1023 int tmp, status = 0;
1024 int cc;
1025
1026 if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0))
1027 {
1028 sscape_write (devc, GA_HMCTL_REG, tmp | 0x80);
1029 for (cc = 0; cc < 200000; ++cc)
1030 INB (devc->base + ODIE_ADDR);
1031 }
1032 else
1033 old_hardware = 0;
1034 }
1035
1036
1037 return 1;
1038 }
1039
1040 int
1041 probe_ss_ms_sound (struct address_info *hw_config)
1042 {
1043 int i, irq_bits = 0xff;
1044
1045 if (devc->ok == 0)
1046 {
1047 printk ("SoundScape: Invalid initialization order.\n");
1048 return 0;
1049 }
1050
1051 for (i = 0; i < sizeof (valid_interrupts); i++)
1052 if (hw_config->irq == valid_interrupts[i])
1053 {
1054 irq_bits = i;
1055 break;
1056 }
1057 if (hw_config->irq > 15 || irq_bits == 0xff)
1058 {
1059 printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
1060 return 0;
1061 }
1062
1063 return ad1848_detect (hw_config->io_base);
1064 }
1065
1066 long
1067 attach_ss_ms_sound (long mem_start, struct address_info *hw_config)
1068 {
1069
1070
1071
1072
1073
1074
1075 int i, irq_bits = 0xff;
1076
1077 #ifdef EXCLUDE_NATIVE_PCM
1078 int prev_devs = num_audiodevs;
1079
1080 #endif
1081
1082
1083
1084
1085 sscape_write (devc, GA_DMACFG_REG, 0x50);
1086
1087
1088
1089
1090 sscape_write (devc, GA_DMAB_REG, 0x20);
1091
1092
1093
1094
1095
1096 for (i = 0; i < sizeof (valid_interrupts); i++)
1097 if (hw_config->irq == valid_interrupts[i])
1098 {
1099 irq_bits = i;
1100 break;
1101 }
1102
1103 sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
1104 (irq_bits << 1));
1105
1106 if (hw_config->irq == devc->irq)
1107 printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
1108
1109 ad1848_init ("SoundScape", hw_config->io_base,
1110 hw_config->irq,
1111 hw_config->dma,
1112 hw_config->dma);
1113
1114 #ifdef EXCLUDE_NATIVE_PCM
1115 if (num_audiodevs == (prev_devs + 1))
1116 audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
1117 #endif
1118 #ifdef SSCAPE_DEBUG5
1119
1120
1121
1122
1123 {
1124 int i;
1125
1126 for (i = 0; i < 13; i++)
1127 printk ("I%d = %02x\n", i, sscape_read (devc, i));
1128 }
1129 #endif
1130
1131 return mem_start;
1132 }
1133
1134 #endif