Import 2.3.18pre1
[davej-history.git] / drivers / sound / sscape.c
blob25bfaf3a7e19b47e631bd398047b706a50a4277c
1 /*
2 * sound/sscape.c
4 * Low level driver for Ensoniq SoundScape
5 */
7 /*
8 * Copyright (C) by Hannu Savolainen 1993-1997
10 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
11 * Version 2 (June 1991). See the "COPYING" file distributed with this software
12 * for more info.
16 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
19 #include <linux/config.h>
20 #include <linux/module.h>
22 #include "sound_config.h"
23 #include "soundmodule.h"
25 #ifdef CONFIG_SSCAPE
27 #include "coproc.h"
30 * I/O ports
32 #define MIDI_DATA 0
33 #define MIDI_CTRL 1
34 #define HOST_CTRL 2
35 #define TX_READY 0x02
36 #define RX_READY 0x01
37 #define HOST_DATA 3
38 #define ODIE_ADDR 4
39 #define ODIE_DATA 5
42 * Indirect registers
45 #define GA_INTSTAT_REG 0
46 #define GA_INTENA_REG 1
47 #define GA_DMAA_REG 2
48 #define GA_DMAB_REG 3
49 #define GA_INTCFG_REG 4
50 #define GA_DMACFG_REG 5
51 #define GA_CDCFG_REG 6
52 #define GA_SMCFGA_REG 7
53 #define GA_SMCFGB_REG 8
54 #define GA_HMCTL_REG 9
57 * DMA channel identifiers (A and B)
60 #define SSCAPE_DMA_A 0
61 #define SSCAPE_DMA_B 1
63 #define PORT(name) (devc->base+name)
66 * Host commands recognized by the OBP microcode
69 #define CMD_GEN_HOST_ACK 0x80
70 #define CMD_GEN_MPU_ACK 0x81
71 #define CMD_GET_BOARD_TYPE 0x82
72 #define CMD_SET_CONTROL 0x88 /* Old firmware only */
73 #define CMD_GET_CONTROL 0x89 /* Old firmware only */
74 #define CTL_MASTER_VOL 0
75 #define CTL_MIC_MODE 2
76 #define CTL_SYNTH_VOL 4
77 #define CTL_WAVE_VOL 7
78 #define CMD_SET_EXTMIDI 0x8a
79 #define CMD_GET_EXTMIDI 0x8b
80 #define CMD_SET_MT32 0x8c
81 #define CMD_GET_MT32 0x8d
83 #define CMD_ACK 0x80
85 typedef struct sscape_info
87 int base, irq, dma;
88 int ok; /* Properly detected */
89 int failed;
90 int dma_allocated;
91 int codec_audiodev;
92 int opened;
93 int *osp;
94 int my_audiodev;
95 } sscape_info;
97 static struct sscape_info adev_info = {
101 static struct sscape_info *devc = &adev_info;
102 static int sscape_mididev = -1;
104 /* Some older cards have assigned interrupt bits differently than new ones */
105 static char valid_interrupts_old[] = {
106 9, 7, 5, 15
109 static char valid_interrupts_new[] = {
110 9, 5, 7, 10
113 static char *valid_interrupts = valid_interrupts_new;
116 * See the bottom of the driver. This can be set by spea =0/1.
119 #ifdef REVEAL_SPEA
120 static char old_hardware = 1;
121 #else
122 static char old_hardware = 0;
123 #endif
125 static void sleep(unsigned howlong)
127 current->state = TASK_INTERRUPTIBLE;
128 schedule_timeout(1);
131 static unsigned char sscape_read(struct sscape_info *devc, int reg)
133 unsigned long flags;
134 unsigned char val;
136 save_flags(flags);
137 cli();
138 outb(reg, PORT(ODIE_ADDR));
139 val = inb(PORT(ODIE_DATA));
140 restore_flags(flags);
141 return val;
144 static void sscape_write(struct sscape_info *devc, int reg, int data)
146 unsigned long flags;
148 save_flags(flags);
149 cli();
150 outb(reg, PORT(ODIE_ADDR));
151 outb(data, PORT(ODIE_DATA));
152 restore_flags(flags);
155 static void host_open(struct sscape_info *devc)
157 outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */
160 static void host_close(struct sscape_info *devc)
162 outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */
165 static int host_write(struct sscape_info *devc, unsigned char *data, int count)
167 unsigned long flags;
168 int i, timeout_val;
170 save_flags(flags);
171 cli();
174 * Send the command and data bytes
177 for (i = 0; i < count; i++)
179 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
180 if (inb(PORT(HOST_CTRL)) & TX_READY)
181 break;
183 if (timeout_val <= 0)
185 restore_flags(flags);
186 return 0;
188 outb(data[i], PORT(HOST_DATA));
190 restore_flags(flags);
191 return 1;
194 static int host_read(struct sscape_info *devc)
196 unsigned long flags;
197 int timeout_val;
198 unsigned char data;
200 save_flags(flags);
201 cli();
204 * Read a byte
207 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
208 if (inb(PORT(HOST_CTRL)) & RX_READY)
209 break;
211 if (timeout_val <= 0)
213 restore_flags(flags);
214 return -1;
216 data = inb(PORT(HOST_DATA));
217 restore_flags(flags);
218 return data;
222 static int host_command2(struct sscape_info *devc, int cmd, int parm1)
224 unsigned char buf[10];
226 buf[0] = (unsigned char) (cmd & 0xff);
227 buf[1] = (unsigned char) (parm1 & 0xff);
229 return host_write(devc, buf, 2);
232 static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
234 unsigned char buf[10];
236 buf[0] = (unsigned char) (cmd & 0xff);
237 buf[1] = (unsigned char) (parm1 & 0xff);
238 buf[2] = (unsigned char) (parm2 & 0xff);
239 return host_write(devc, buf, 3);
242 static void set_mt32(struct sscape_info *devc, int value)
244 host_open(devc);
245 host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
246 if (host_read(devc) != CMD_ACK)
248 /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
250 host_close(devc);
253 static void set_control(struct sscape_info *devc, int ctrl, int value)
255 host_open(devc);
256 host_command3(devc, CMD_SET_CONTROL, ctrl, value);
257 if (host_read(devc) != CMD_ACK)
259 /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
261 host_close(devc);
264 static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
266 unsigned char temp;
268 if (dma_chan != SSCAPE_DMA_A)
270 printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
271 return;
273 audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
274 DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
275 audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
277 temp = devc->dma << 4; /* Setup DMA channel select bits */
278 if (devc->dma <= 3)
279 temp |= 0x80; /* 8 bit DMA channel */
281 temp |= 1; /* Trigger DMA */
282 sscape_write(devc, GA_DMAA_REG, temp);
283 temp &= 0xfe; /* Clear DMA trigger */
284 sscape_write(devc, GA_DMAA_REG, temp);
287 static int verify_mpu(struct sscape_info *devc)
290 * The SoundScape board could be in three modes (MPU, 8250 and host).
291 * If the card is not in the MPU mode, enabling the MPU driver will
292 * cause infinite loop (the driver believes that there is always some
293 * received data in the buffer.
295 * Detect this by looking if there are more than 10 received MIDI bytes
296 * (0x00) in the buffer.
299 int i;
301 for (i = 0; i < 10; i++)
303 if (inb(devc->base + HOST_CTRL) & 0x80)
304 return 1;
306 if (inb(devc->base) != 0x00)
307 return 1;
309 printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
310 return 0;
313 static int sscape_coproc_open(void *dev_info, int sub_device)
315 if (sub_device == COPR_MIDI)
317 set_mt32(devc, 0);
318 if (!verify_mpu(devc))
319 return -EIO;
321 return 0;
324 static void sscape_coproc_close(void *dev_info, int sub_device)
326 struct sscape_info *devc = dev_info;
327 unsigned long flags;
329 save_flags(flags);
330 cli();
331 if (devc->dma_allocated)
333 sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
334 devc->dma_allocated = 0;
336 restore_flags(flags);
337 return;
340 static void sscape_coproc_reset(void *dev_info)
344 static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
346 unsigned long flags;
347 unsigned char temp;
348 volatile int done, timeout_val;
349 static unsigned char codec_dma_bits = 0;
351 if (flag & CPF_FIRST)
354 * First block. Have to allocate DMA and to reset the board
355 * before continuing.
358 save_flags(flags);
359 cli();
360 codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
362 if (devc->dma_allocated == 0)
363 devc->dma_allocated = 1;
365 restore_flags(flags);
367 sscape_write(devc, GA_HMCTL_REG,
368 (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
370 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
371 sscape_read(devc, GA_HMCTL_REG); /* Delay */
373 /* Take board out of reset */
374 sscape_write(devc, GA_HMCTL_REG,
375 (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
378 * Transfer one code block using DMA
380 if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
382 printk(KERN_WARNING "soundscape: DMA buffer not available\n");
383 return 0;
385 memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
387 save_flags(flags);
388 cli();
390 /******** INTERRUPTS DISABLED NOW ********/
392 do_dma(devc, SSCAPE_DMA_A,
393 audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
394 size, DMA_MODE_WRITE);
397 * Wait until transfer completes.
400 done = 0;
401 timeout_val = 30;
402 while (!done && timeout_val-- > 0)
404 int resid;
406 if (HZ / 50)
407 sleep(HZ / 50);
408 clear_dma_ff(devc->dma);
409 if ((resid = get_dma_residue(devc->dma)) == 0)
410 done = 1;
413 restore_flags(flags);
414 if (!done)
415 return 0;
417 if (flag & CPF_LAST)
420 * Take the board out of reset
422 outb((0x00), PORT(HOST_CTRL));
423 outb((0x00), PORT(MIDI_CTRL));
425 temp = sscape_read(devc, GA_HMCTL_REG);
426 temp |= 0x40;
427 sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
430 * Wait until the ODB wakes up
433 save_flags(flags);
434 cli();
435 done = 0;
436 timeout_val = 5 * HZ;
437 while (!done && timeout_val-- > 0)
439 unsigned char x;
441 sleep(1);
442 x = inb(PORT(HOST_DATA));
443 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
445 DDB(printk("Soundscape: Acknowledge = %x\n", x));
446 done = 1;
449 sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
451 restore_flags(flags);
452 if (!done)
454 printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
455 return 0;
457 save_flags(flags);
458 cli();
459 done = 0;
460 timeout_val = 5 * HZ;
461 while (!done && timeout_val-- > 0)
463 sleep(1);
464 if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
465 done = 1;
467 restore_flags(flags);
468 if (!done)
470 printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
471 return 0;
473 printk(KERN_INFO "SoundScape board initialized OK\n");
474 set_control(devc, CTL_MASTER_VOL, 100);
475 set_control(devc, CTL_SYNTH_VOL, 100);
477 #ifdef SSCAPE_DEBUG3
479 * Temporary debugging aid. Print contents of the registers after
480 * downloading the code.
483 int i;
485 for (i = 0; i < 13; i++)
486 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
488 #endif
491 return 1;
494 static int download_boot_block(void *dev_info, copr_buffer * buf)
496 if (buf->len <= 0 || buf->len > sizeof(buf->data))
497 return -EINVAL;
499 if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
501 printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
502 return -EIO;
504 return 0;
507 static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
509 copr_buffer *buf;
510 int err;
512 switch (cmd)
514 case SNDCTL_COPR_RESET:
515 sscape_coproc_reset(dev_info);
516 return 0;
518 case SNDCTL_COPR_LOAD:
519 buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
520 if (buf == NULL)
521 return -ENOSPC;
522 if (copy_from_user(buf, arg, sizeof(copr_buffer)))
524 vfree(buf);
525 return -EFAULT;
527 err = download_boot_block(dev_info, buf);
528 vfree(buf);
529 return err;
531 default:
532 return -EINVAL;
536 static coproc_operations sscape_coproc_operations =
538 "SoundScape M68K",
539 sscape_coproc_open,
540 sscape_coproc_close,
541 sscape_coproc_ioctl,
542 sscape_coproc_reset,
543 &adev_info
546 static int sscape_detected = 0;
548 void attach_sscape(struct address_info *hw_config)
550 #ifndef SSCAPE_REGS
552 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
553 * These values are card
554 * dependent. If you have another SoundScape based card, you have to
555 * find the correct values. Do the following:
556 * - Compile this driver with SSCAPE_DEBUG1 defined.
557 * - Shut down and power off your machine.
558 * - Boot with DOS so that the SSINIT.EXE program is run.
559 * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
560 * when detecting the SoundScape.
561 * - Modify the following list to use the values printed during boot.
562 * Undefine the SSCAPE_DEBUG1
564 #define SSCAPE_REGS { \
565 /* I0 */ 0x00, \
566 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
567 0x20, /* Note! Ignored. Set always to 0x20 */ \
568 0x20, /* Note! Ignored. Set always to 0x20 */ \
569 0xf5, /* Ignored */ \
570 0x10, \
571 0x00, \
572 0x2e, /* I7 MEM config A. Likely to vary between models */ \
573 0x00, /* I8 MEM config B. Likely to vary between models */ \
574 /* I9 */ 0x40 /* Ignored */ \
576 #endif
578 unsigned long flags;
579 static unsigned char regs[10] = SSCAPE_REGS;
581 int i, irq_bits = 0xff;
583 if (sscape_detected != hw_config->io_base)
584 return;
586 request_region(devc->base + 2, 6, "SoundScape");
587 if (old_hardware)
589 valid_interrupts = valid_interrupts_old;
590 conf_printf("Ensoniq SoundScape (old)", hw_config);
592 else
593 conf_printf("Ensoniq SoundScape", hw_config);
595 for (i = 0; i < sizeof(valid_interrupts); i++)
597 if (hw_config->irq == valid_interrupts[i])
599 irq_bits = i;
600 break;
603 if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
605 printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
606 return;
608 save_flags(flags);
609 cli();
611 for (i = 1; i < 10; i++)
613 switch (i)
615 case 1: /* Host interrupt enable */
616 sscape_write(devc, i, 0xf0); /* All interrupts enabled */
617 break;
619 case 2: /* DMA A status/trigger register */
620 case 3: /* DMA B status/trigger register */
621 sscape_write(devc, i, 0x20); /* DMA channel disabled */
622 break;
624 case 4: /* Host interrupt config reg */
625 sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
626 break;
628 case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
629 sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
630 break;
632 case 6: /* CD-ROM config (WSS codec actually) */
633 sscape_write(devc, i, regs[i]);
634 break;
636 case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
637 sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
638 break;
640 default:
641 sscape_write(devc, i, regs[i]);
644 restore_flags(flags);
646 #ifdef SSCAPE_DEBUG2
648 * Temporary debugging aid. Print contents of the registers after
649 * changing them.
652 int i;
654 for (i = 0; i < 13; i++)
655 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
657 #endif
659 #if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
660 if (probe_mpu401(hw_config))
661 hw_config->always_detect = 1;
662 hw_config->name = "SoundScape";
664 hw_config->irq *= -1; /* Negative value signals IRQ sharing */
665 attach_mpu401(hw_config);
666 hw_config->irq *= -1; /* Restore it */
668 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
670 sscape_mididev = hw_config->slots[1];
671 midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
673 #endif
674 sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
675 devc->ok = 1;
676 devc->failed = 0;
679 static int detect_ga(sscape_info * devc)
681 unsigned char save;
683 DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
685 if (check_region(devc->base, 8))
686 return 0;
689 * First check that the address register of "ODIE" is
690 * there and that it has exactly 4 writable bits.
691 * First 4 bits
694 if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
696 DDB(printk("soundscape: Detect error A\n"));
697 return 0;
699 outb((0x00), PORT(ODIE_ADDR));
700 if (inb(PORT(ODIE_ADDR)) != 0x00)
702 DDB(printk("soundscape: Detect error B\n"));
703 return 0;
705 outb((0xff), PORT(ODIE_ADDR));
706 if (inb(PORT(ODIE_ADDR)) != 0x0f)
708 DDB(printk("soundscape: Detect error C\n"));
709 return 0;
711 outb((save), PORT(ODIE_ADDR));
714 * Now verify that some indirect registers return zero on some bits.
715 * This may break the driver with some future revisions of "ODIE" but...
718 if (sscape_read(devc, 0) & 0x0c)
720 DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
721 return 0;
723 if (sscape_read(devc, 1) & 0x0f)
725 DDB(printk("soundscape: Detect error E\n"));
726 return 0;
728 if (sscape_read(devc, 5) & 0x0f)
730 DDB(printk("soundscape: Detect error F\n"));
731 return 0;
733 return 1;
736 int probe_sscape(struct address_info *hw_config)
739 if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
740 return 0;
742 devc->base = hw_config->io_base;
743 devc->irq = hw_config->irq;
744 devc->dma = hw_config->dma;
745 devc->osp = hw_config->osp;
747 #ifdef SSCAPE_DEBUG1
749 * Temporary debugging aid. Print contents of the registers before
750 * changing them.
753 int i;
755 for (i = 0; i < 13; i++)
756 printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
758 #endif
759 devc->failed = 1;
761 if (!detect_ga(devc))
762 return 0;
764 if (old_hardware) /* Check that it's really an old Spea/Reveal card. */
766 unsigned char tmp;
767 int cc;
769 if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
771 sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
772 for (cc = 0; cc < 200000; ++cc)
773 inb(devc->base + ODIE_ADDR);
776 sscape_detected = hw_config->io_base;
777 return 1;
780 int probe_ss_ms_sound(struct address_info *hw_config)
782 int i, irq_bits = 0xff;
783 int ad_flags = 0;
785 if (devc->failed)
787 printk(KERN_ERR "soundscape: Card not detected\n");
788 return 0;
790 if (devc->ok == 0)
792 printk(KERN_ERR "soundscape: Invalid initialization order.\n");
793 return 0;
795 for (i = 0; i < sizeof(valid_interrupts); i++)
797 if (hw_config->irq == valid_interrupts[i])
799 irq_bits = i;
800 break;
803 if (hw_config->irq > 15 || irq_bits == 0xff)
805 printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
806 return 0;
808 if (old_hardware)
809 ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
810 return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
813 void attach_ss_ms_sound(struct address_info *hw_config)
816 * This routine configures the SoundScape card for use with the
817 * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
818 * config registers of the "ODIE".
821 int i, irq_bits = 0xff;
823 hw_config->dma = devc->dma; /* Share the DMA with the ODIE/OPUS chip */
826 * Setup the DMA polarity.
829 sscape_write(devc, GA_DMACFG_REG, 0x50);
832 * Take the gate-array off of the DMA channel.
835 sscape_write(devc, GA_DMAB_REG, 0x20);
838 * Init the AD1848 (CD-ROM) config reg.
841 for (i = 0; i < sizeof(valid_interrupts); i++)
843 if (hw_config->irq == valid_interrupts[i])
845 irq_bits = i;
846 break;
849 sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
851 if (hw_config->irq == devc->irq)
852 printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
854 hw_config->slots[0] = ad1848_init("SoundScape", hw_config->io_base,
855 hw_config->irq,
856 hw_config->dma,
857 hw_config->dma,
859 devc->osp);
861 if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */
863 audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
864 devc->codec_audiodev = hw_config->slots[0];
865 devc->my_audiodev = hw_config->slots[0];
867 /* Set proper routings here (what are they) */
868 AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
870 #ifdef SSCAPE_DEBUG5
872 * Temporary debugging aid. Print contents of the registers
873 * after the AD1848 device has been initialized.
876 int i;
878 for (i = 0; i < 13; i++)
879 printk("I%d = %02x\n", i, sscape_read(devc, i));
881 #endif
885 void unload_sscape(struct address_info *hw_config)
887 release_region(devc->base + 2, 6);
888 #if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI)
889 unload_mpu401(hw_config);
890 #endif
893 void unload_ss_ms_sound(struct address_info *hw_config)
895 ad1848_unload(hw_config->io_base,
896 hw_config->irq,
897 devc->dma,
898 devc->dma,
900 sound_unload_audiodev(hw_config->slots[0]);
903 #ifdef MODULE
905 int dma = -1;
906 int irq = -1;
907 int io = -1;
909 int mpu_irq = -1;
910 int mpu_io = -1;
912 int spea = -1;
914 static int mss = 0;
916 MODULE_PARM(dma, "i");
917 MODULE_PARM(irq, "i");
918 MODULE_PARM(io, "i");
919 MODULE_PARM(spea, "i"); /* spea=0/1 set the old_hardware */
920 MODULE_PARM(mpu_irq, "i");
921 MODULE_PARM(mpu_io, "i");
922 MODULE_PARM(mss, "i");
924 struct address_info config;
925 struct address_info mpu_config;
927 int init_module(void)
929 printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
930 if (dma == -1 || irq == -1 || io == -1)
932 printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
933 return -EINVAL;
935 if (mpu_irq == -1 && mpu_io != -1)
937 printk(KERN_ERR "CONFIG_MPU_IRQ must be specified if CONFIG_MPU_IO is set.\n");
938 return -EINVAL;
940 config.irq = irq;
941 config.dma = dma;
942 config.io_base = io;
944 mpu_config.irq = mpu_irq;
945 mpu_config.io_base = mpu_io;
946 /* WEH - Try to get right dma channel */
947 mpu_config.dma = dma;
949 if(spea != -1)
951 old_hardware = spea;
952 printk(KERN_INFO "Forcing %s hardware support.\n",
953 spea?"new":"old");
955 if (probe_sscape(&mpu_config) == 0)
956 return -ENODEV;
958 attach_sscape(&mpu_config);
960 mss = probe_ss_ms_sound(&config);
962 if (mss)
963 attach_ss_ms_sound(&config);
964 SOUND_LOCK;
965 return 0;
968 void cleanup_module(void)
970 if (mss)
971 unload_ss_ms_sound(&config);
972 SOUND_LOCK_END;
973 unload_sscape(&mpu_config);
976 #endif
977 #endif