1 /*
2 * sound/sscape.c
3 *
4 * Low level driver for Ensoniq SoundScape
5 *
6 *
7 * Copyright (C) by Hannu Savolainen 1993-1997
8 *
9 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
10 * Version 2 (June 1991). See the "COPYING" file distributed with this software
11 * for more info.
12 *
13 *
14 * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
15 * Sergey Smitienko : ensoniq p'n'p support
16 * Christoph Hellwig : adapted to module_init/module_exit
17 * Bartlomiej Zolnierkiewicz : added __init to attach_sscape()
18 */
19
20 #include <linux/init.h>
21 #include <linux/module.h>
22
23 #include "sound_config.h"
24 #include "sound_firmware.h"
25
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/signal.h>
29 #include <linux/fcntl.h>
30 #include <linux/ctype.h>
31 #include <linux/stddef.h>
32 #include <linux/kmod.h>
33 #include <asm/dma.h>
34 #include <asm/io.h>
35 #include <asm/segment.h>
36 #include <linux/wait.h>
37 #include <linux/malloc.h>
38 #include <linux/ioport.h>
39 #include <linux/delay.h>
40 #include <linux/proc_fs.h>
41 #include <linux/wrapper.h>
42
43 #include "coproc.h"
44
45 #include "ad1848.h"
46 #include "mpu401.h"
47
48 /*
49 * I/O ports
50 */
51 #define MIDI_DATA 0
52 #define MIDI_CTRL 1
53 #define HOST_CTRL 2
54 #define TX_READY 0x02
55 #define RX_READY 0x01
56 #define HOST_DATA 3
57 #define ODIE_ADDR 4
58 #define ODIE_DATA 5
59
60 /*
61 * Indirect registers
62 */
63
64 #define GA_INTSTAT_REG 0
65 #define GA_INTENA_REG 1
66 #define GA_DMAA_REG 2
67 #define GA_DMAB_REG 3
68 #define GA_INTCFG_REG 4
69 #define GA_DMACFG_REG 5
70 #define GA_CDCFG_REG 6
71 #define GA_SMCFGA_REG 7
72 #define GA_SMCFGB_REG 8
73 #define GA_HMCTL_REG 9
74
75 /*
76 * DMA channel identifiers (A and B)
77 */
78
79 #define SSCAPE_DMA_A 0
80 #define SSCAPE_DMA_B 1
81
82 #define PORT(name) (devc->base+name)
83
84 /*
85 * Host commands recognized by the OBP microcode
86 */
87
88 #define CMD_GEN_HOST_ACK 0x80
89 #define CMD_GEN_MPU_ACK 0x81
90 #define CMD_GET_BOARD_TYPE 0x82
91 #define CMD_SET_CONTROL 0x88 /* Old firmware only */
92 #define CMD_GET_CONTROL 0x89 /* Old firmware only */
93 #define CTL_MASTER_VOL 0
94 #define CTL_MIC_MODE 2
95 #define CTL_SYNTH_VOL 4
96 #define CTL_WAVE_VOL 7
97 #define CMD_SET_EXTMIDI 0x8a
98 #define CMD_GET_EXTMIDI 0x8b
99 #define CMD_SET_MT32 0x8c
100 #define CMD_GET_MT32 0x8d
101
102 #define CMD_ACK 0x80
103
104 #define IC_ODIE 1
105 #define IC_OPUS 2
106
107 typedef struct sscape_info
108 {
109 int base, irq, dma;
110
111 int codec, codec_irq; /* required to setup pnp cards*/
112 int codec_type;
113 int ic_type;
114 char* raw_buf;
115 unsigned long raw_buf_phys;
116 int buffsize; /* -------------------------- */
117
118 int ok; /* Properly detected */
119 int failed;
120 int dma_allocated;
121 int codec_audiodev;
122 int opened;
123 int *osp;
124 int my_audiodev;
125 } sscape_info;
126
127 static struct sscape_info adev_info = {
128 0
129 };
130
131 static struct sscape_info *devc = &adev_info;
132 static int sscape_mididev = -1;
133
134 /* Some older cards have assigned interrupt bits differently than new ones */
135 static char valid_interrupts_old[] = {
136 9, 7, 5, 15
137 };
138
139 static char valid_interrupts_new[] = {
140 9, 5, 7, 10
141 };
142
143 static char *valid_interrupts = valid_interrupts_new;
144
145 /*
146 * See the bottom of the driver. This can be set by spea =0/1.
147 */
148
149 #ifdef REVEAL_SPEA
150 static char old_hardware = 1;
151 #else
152 static char old_hardware = 0;
153 #endif
154
155 static void sleep(unsigned howlong)
156 {
157 current->state = TASK_INTERRUPTIBLE;
158 schedule_timeout(howlong);
159 }
160
161 static unsigned char sscape_read(struct sscape_info *devc, int reg)
162 {
163 unsigned long flags;
164 unsigned char val;
165
166 save_flags(flags);
167 cli();
168 outb(reg, PORT(ODIE_ADDR));
169 val = inb(PORT(ODIE_DATA));
170 restore_flags(flags);
171 return val;
172 }
173
174 static void sscape_write(struct sscape_info *devc, int reg, int data)
175 {
176 unsigned long flags;
177
178 save_flags(flags);
179 cli();
180 outb(reg, PORT(ODIE_ADDR));
181 outb(data, PORT(ODIE_DATA));
182 restore_flags(flags);
183 }
184
185 static unsigned char sscape_pnp_read_codec(sscape_info* devc, unsigned char reg)
186 {
187 unsigned char res;
188 unsigned long flags;
189
190 save_flags(flags);
191 cli();
192 outb( reg, devc -> codec);
193 res = inb (devc -> codec + 1);
194 restore_flags(flags);
195 return res;
196
197 }
198
199 static void sscape_pnp_write_codec(sscape_info* devc, unsigned char reg, unsigned char data)
200 {
201 unsigned long flags;
202
203 save_flags(flags);
204 cli();
205 outb( reg, devc -> codec);
206 outb( data, devc -> codec + 1);
207 restore_flags(flags);
208 }
209
210 static void host_open(struct sscape_info *devc)
211 {
212 outb((0x00), PORT(HOST_CTRL)); /* Put the board to the host mode */
213 }
214
215 static void host_close(struct sscape_info *devc)
216 {
217 outb((0x03), PORT(HOST_CTRL)); /* Put the board to the MIDI mode */
218 }
219
220 static int host_write(struct sscape_info *devc, unsigned char *data, int count)
221 {
222 unsigned long flags;
223 int i, timeout_val;
224
225 save_flags(flags);
226 cli();
227
228 /*
229 * Send the command and data bytes
230 */
231
232 for (i = 0; i < count; i++)
233 {
234 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
235 if (inb(PORT(HOST_CTRL)) & TX_READY)
236 break;
237
238 if (timeout_val <= 0)
239 {
240 restore_flags(flags);
241 return 0;
242 }
243 outb(data[i], PORT(HOST_DATA));
244 }
245 restore_flags(flags);
246 return 1;
247 }
248
249 static int host_read(struct sscape_info *devc)
250 {
251 unsigned long flags;
252 int timeout_val;
253 unsigned char data;
254
255 save_flags(flags);
256 cli();
257
258 /*
259 * Read a byte
260 */
261
262 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
263 if (inb(PORT(HOST_CTRL)) & RX_READY)
264 break;
265
266 if (timeout_val <= 0)
267 {
268 restore_flags(flags);
269 return -1;
270 }
271 data = inb(PORT(HOST_DATA));
272 restore_flags(flags);
273 return data;
274 }
275
276 #if 0 /* unused */
277 static int host_command1(struct sscape_info *devc, int cmd)
278 {
279 unsigned char buf[10];
280 buf[0] = (unsigned char) (cmd & 0xff);
281 return host_write(devc, buf, 1);
282 }
283 #endif /* unused */
284
285
286 static int host_command2(struct sscape_info *devc, int cmd, int parm1)
287 {
288 unsigned char buf[10];
289
290 buf[0] = (unsigned char) (cmd & 0xff);
291 buf[1] = (unsigned char) (parm1 & 0xff);
292
293 return host_write(devc, buf, 2);
294 }
295
296 static int host_command3(struct sscape_info *devc, int cmd, int parm1, int parm2)
297 {
298 unsigned char buf[10];
299
300 buf[0] = (unsigned char) (cmd & 0xff);
301 buf[1] = (unsigned char) (parm1 & 0xff);
302 buf[2] = (unsigned char) (parm2 & 0xff);
303 return host_write(devc, buf, 3);
304 }
305
306 static void set_mt32(struct sscape_info *devc, int value)
307 {
308 host_open(devc);
309 host_command2(devc, CMD_SET_MT32, value ? 1 : 0);
310 if (host_read(devc) != CMD_ACK)
311 {
312 /* printk( "SNDSCAPE: Setting MT32 mode failed\n"); */
313 }
314 host_close(devc);
315 }
316
317 static void set_control(struct sscape_info *devc, int ctrl, int value)
318 {
319 host_open(devc);
320 host_command3(devc, CMD_SET_CONTROL, ctrl, value);
321 if (host_read(devc) != CMD_ACK)
322 {
323 /* printk( "SNDSCAPE: Setting control (%d) failed\n", ctrl); */
324 }
325 host_close(devc);
326 }
327
328 static void do_dma(struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
329 {
330 unsigned char temp;
331
332 if (dma_chan != SSCAPE_DMA_A)
333 {
334 printk(KERN_WARNING "soundscape: Tried to use DMA channel != A. Why?\n");
335 return;
336 }
337 audio_devs[devc->codec_audiodev]->flags &= ~DMA_AUTOMODE;
338 DMAbuf_start_dma(devc->codec_audiodev, buf, blk_size, mode);
339 audio_devs[devc->codec_audiodev]->flags |= DMA_AUTOMODE;
340
341 temp = devc->dma << 4; /* Setup DMA channel select bits */
342 if (devc->dma <= 3)
343 temp |= 0x80; /* 8 bit DMA channel */
344
345 temp |= 1; /* Trigger DMA */
346 sscape_write(devc, GA_DMAA_REG, temp);
347 temp &= 0xfe; /* Clear DMA trigger */
348 sscape_write(devc, GA_DMAA_REG, temp);
349 }
350
351 static int verify_mpu(struct sscape_info *devc)
352 {
353 /*
354 * The SoundScape board could be in three modes (MPU, 8250 and host).
355 * If the card is not in the MPU mode, enabling the MPU driver will
356 * cause infinite loop (the driver believes that there is always some
357 * received data in the buffer.
358 *
359 * Detect this by looking if there are more than 10 received MIDI bytes
360 * (0x00) in the buffer.
361 */
362
363 int i;
364
365 for (i = 0; i < 10; i++)
366 {
367 if (inb(devc->base + HOST_CTRL) & 0x80)
368 return 1;
369
370 if (inb(devc->base) != 0x00)
371 return 1;
372 }
373 printk(KERN_WARNING "SoundScape: The device is not in the MPU-401 mode\n");
374 return 0;
375 }
376
377 static int sscape_coproc_open(void *dev_info, int sub_device)
378 {
379 if (sub_device == COPR_MIDI)
380 {
381 set_mt32(devc, 0);
382 if (!verify_mpu(devc))
383 return -EIO;
384 }
385 return 0;
386 }
387
388 static void sscape_coproc_close(void *dev_info, int sub_device)
389 {
390 struct sscape_info *devc = dev_info;
391 unsigned long flags;
392
393 save_flags(flags);
394 cli();
395 if (devc->dma_allocated)
396 {
397 sscape_write(devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
398 devc->dma_allocated = 0;
399 }
400 restore_flags(flags);
401 return;
402 }
403
404 static void sscape_coproc_reset(void *dev_info)
405 {
406 }
407
408 static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
409 {
410 unsigned long flags;
411 unsigned char temp;
412 volatile int done, timeout_val;
413 static unsigned char codec_dma_bits = 0;
414
415 if (flag & CPF_FIRST)
416 {
417 /*
418 * First block. Have to allocate DMA and to reset the board
419 * before continuing.
420 */
421
422 save_flags(flags);
423 cli();
424 codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);
425
426 if (devc->dma_allocated == 0)
427 devc->dma_allocated = 1;
428
429 restore_flags(flags);
430
431 sscape_write(devc, GA_HMCTL_REG,
432 (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
433
434 for (timeout_val = 10000; timeout_val > 0; timeout_val--)
435 sscape_read(devc, GA_HMCTL_REG); /* Delay */
436
437 /* Take board out of reset */
438 sscape_write(devc, GA_HMCTL_REG,
439 (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
440 }
441 /*
442 * Transfer one code block using DMA
443 */
444 if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
445 {
446 printk(KERN_WARNING "soundscape: DMA buffer not available\n");
447 return 0;
448 }
449 memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);
450
451 save_flags(flags);
452 cli();
453
454 /******** INTERRUPTS DISABLED NOW ********/
455
456 do_dma(devc, SSCAPE_DMA_A,
457 audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
458 size, DMA_MODE_WRITE);
459
460 /*
461 * Wait until transfer completes.
462 */
463
464 done = 0;
465 timeout_val = 30;
466 while (!done && timeout_val-- > 0)
467 {
468 int resid;
469
470 if (HZ / 50)
471 sleep(HZ / 50);
472 clear_dma_ff(devc->dma);
473 if ((resid = get_dma_residue(devc->dma)) == 0)
474 done = 1;
475 }
476
477 restore_flags(flags);
478 if (!done)
479 return 0;
480
481 if (flag & CPF_LAST)
482 {
483 /*
484 * Take the board out of reset
485 */
486 outb((0x00), PORT(HOST_CTRL));
487 outb((0x00), PORT(MIDI_CTRL));
488
489 temp = sscape_read(devc, GA_HMCTL_REG);
490 temp |= 0x40;
491 sscape_write(devc, GA_HMCTL_REG, temp); /* Kickstart the board */
492
493 /*
494 * Wait until the ODB wakes up
495 */
496
497 save_flags(flags);
498 cli();
499 done = 0;
500 timeout_val = 5 * HZ;
501 while (!done && timeout_val-- > 0)
502 {
503 unsigned char x;
504
505 sleep(1);
506 x = inb(PORT(HOST_DATA));
507 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
508 {
509 DDB(printk("Soundscape: Acknowledge = %x\n", x));
510 done = 1;
511 }
512 }
513 sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);
514
515 restore_flags(flags);
516 if (!done)
517 {
518 printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
519 return 0;
520 }
521 save_flags(flags);
522 cli();
523 done = 0;
524 timeout_val = 5 * HZ;
525 while (!done && timeout_val-- > 0)
526 {
527 sleep(1);
528 if (inb(PORT(HOST_DATA)) == 0xfe) /* Host startup acknowledge */
529 done = 1;
530 }
531 restore_flags(flags);
532 if (!done)
533 {
534 printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
535 return 0;
536 }
537 printk(KERN_INFO "SoundScape board initialized OK\n");
538 set_control(devc, CTL_MASTER_VOL, 100);
539 set_control(devc, CTL_SYNTH_VOL, 100);
540
541 #ifdef SSCAPE_DEBUG3
542 /*
543 * Temporary debugging aid. Print contents of the registers after
544 * downloading the code.
545 */
546 {
547 int i;
548
549 for (i = 0; i < 13; i++)
550 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
551 }
552 #endif
553
554 }
555 return 1;
556 }
557
558 static int download_boot_block(void *dev_info, copr_buffer * buf)
559 {
560 if (buf->len <= 0 || buf->len > sizeof(buf->data))
561 return -EINVAL;
562
563 if (!sscape_download_boot(devc, buf->data, buf->len, buf->flags))
564 {
565 printk(KERN_ERR "soundscape: Unable to load microcode block to the OBP.\n");
566 return -EIO;
567 }
568 return 0;
569 }
570
571 static int sscape_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
572 {
573 copr_buffer *buf;
574 int err;
575
576 switch (cmd)
577 {
578 case SNDCTL_COPR_RESET:
579 sscape_coproc_reset(dev_info);
580 return 0;
581
582 case SNDCTL_COPR_LOAD:
583 buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
584 if (buf == NULL)
585 return -ENOSPC;
586 if (copy_from_user(buf, arg, sizeof(copr_buffer)))
587 {
588 vfree(buf);
589 return -EFAULT;
590 }
591 err = download_boot_block(dev_info, buf);
592 vfree(buf);
593 return err;
594
595 default:
596 return -EINVAL;
597 }
598 }
599
600 static coproc_operations sscape_coproc_operations =
601 {
602 "SoundScape M68K",
603 sscape_coproc_open,
604 sscape_coproc_close,
605 sscape_coproc_ioctl,
606 sscape_coproc_reset,
607 &adev_info
608 };
609
610 static int sscape_detected = 0;
611 static int sscape_is_pnp = 0;
612
613 void __init attach_sscape(struct address_info *hw_config)
614 {
615 #ifndef SSCAPE_REGS
616 /*
617 * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
618 * These values are card
619 * dependent. If you have another SoundScape based card, you have to
620 * find the correct values. Do the following:
621 * - Compile this driver with SSCAPE_DEBUG1 defined.
622 * - Shut down and power off your machine.
623 * - Boot with DOS so that the SSINIT.EXE program is run.
624 * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
625 * when detecting the SoundScape.
626 * - Modify the following list to use the values printed during boot.
627 * Undefine the SSCAPE_DEBUG1
628 */
629 #define SSCAPE_REGS { \
630 /* I0 */ 0x00, \
631 /* I1 */ 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
632 /* I2 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
633 /* I3 */ 0x20, /* Note! Ignored. Set always to 0x20 */ \
634 /* I4 */ 0xf5, /* Ignored */ \
635 /* I5 */ 0x10, \
636 /* I6 */ 0x00, \
637 /* I7 */ 0x2e, /* I7 MEM config A. Likely to vary between models */ \
638 /* I8 */ 0x00, /* I8 MEM config B. Likely to vary between models */ \
639 /* I9 */ 0x40 /* Ignored */ \
640 }
641 #endif
642
643 unsigned long flags;
644 static unsigned char regs[10] = SSCAPE_REGS;
645
646 int i, irq_bits = 0xff;
647
648 if (sscape_detected != hw_config->io_base)
649 return;
650
651 request_region(devc->base + 2, 6, "SoundScape");
652 if (old_hardware)
653 {
654 valid_interrupts = valid_interrupts_old;
655 conf_printf("Ensoniq SoundScape (old)", hw_config);
656 }
657 else
658 conf_printf("Ensoniq SoundScape", hw_config);
659
660 for (i = 0; i < sizeof(valid_interrupts); i++)
661 {
662 if (hw_config->irq == valid_interrupts[i])
663 {
664 irq_bits = i;
665 break;
666 }
667 }
668 if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
669 {
670 printk(KERN_ERR "Invalid IRQ%d\n", hw_config->irq);
671 return;
672 }
673
674 if (sscape_is_pnp == 0) {
675
676 save_flags(flags);
677 cli();
678 for (i = 1; i < 10; i++)
679 {
680 switch (i)
681 {
682 case 1: /* Host interrupt enable */
683 sscape_write(devc, i, 0xf0); /* All interrupts enabled */
684 break;
685
686 case 2: /* DMA A status/trigger register */
687 case 3: /* DMA B status/trigger register */
688 sscape_write(devc, i, 0x20); /* DMA channel disabled */
689 break;
690
691 case 4: /* Host interrupt config reg */
692 sscape_write(devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
693 break;
694
695 case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
696 sscape_write(devc, i, (regs[i] & 0x3f) | (sscape_read(devc, i) & 0xc0));
697 break;
698
699 case 6: /* CD-ROM config (WSS codec actually) */
700 sscape_write(devc, i, regs[i]);
701 break;
702
703 case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
704 sscape_write(devc, i, (sscape_read(devc, i) & 0xf0) | 0x08);
705 break;
706
707 default:
708 sscape_write(devc, i, regs[i]);
709 }
710 }
711 restore_flags(flags);
712 }
713 #ifdef SSCAPE_DEBUG2
714 /*
715 * Temporary debugging aid. Print contents of the registers after
716 * changing them.
717 */
718 {
719 int i;
720
721 for (i = 0; i < 13; i++)
722 printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
723 }
724 #endif
725
726 if (probe_mpu401(hw_config))
727 hw_config->always_detect = 1;
728 hw_config->name = "SoundScape";
729
730 hw_config->irq *= -1; /* Negative value signals IRQ sharing */
731 attach_mpu401(hw_config, THIS_MODULE);
732 hw_config->irq *= -1; /* Restore it */
733
734 if (hw_config->slots[1] != -1) /* The MPU driver installed itself */
735 {
736 sscape_mididev = hw_config->slots[1];
737 midi_devs[hw_config->slots[1]]->coproc = &sscape_coproc_operations;
738 }
739 sscape_write(devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
740 devc->ok = 1;
741 devc->failed = 0;
742 }
743
744 static int detect_ga(sscape_info * devc)
745 {
746 unsigned char save;
747
748 DDB(printk("Entered Soundscape detect_ga(%x)\n", devc->base));
749
750 if (check_region(devc->base, 8))
751 return 0;
752
753 /*
754 * First check that the address register of "ODIE" is
755 * there and that it has exactly 4 writable bits.
756 * First 4 bits
757 */
758
759 if ((save = inb(PORT(ODIE_ADDR))) & 0xf0)
760 {
761 DDB(printk("soundscape: Detect error A\n"));
762 return 0;
763 }
764 outb((0x00), PORT(ODIE_ADDR));
765 if (inb(PORT(ODIE_ADDR)) != 0x00)
766 {
767 DDB(printk("soundscape: Detect error B\n"));
768 return 0;
769 }
770 outb((0xff), PORT(ODIE_ADDR));
771 if (inb(PORT(ODIE_ADDR)) != 0x0f)
772 {
773 DDB(printk("soundscape: Detect error C\n"));
774 return 0;
775 }
776 outb((save), PORT(ODIE_ADDR));
777
778 /*
779 * Now verify that some indirect registers return zero on some bits.
780 * This may break the driver with some future revisions of "ODIE" but...
781 */
782
783 if (sscape_read(devc, 0) & 0x0c)
784 {
785 DDB(printk("soundscape: Detect error D (%x)\n", sscape_read(devc, 0)));
786 return 0;
787 }
788 if (sscape_read(devc, 1) & 0x0f)
789 {
790 DDB(printk("soundscape: Detect error E\n"));
791 return 0;
792 }
793 if (sscape_read(devc, 5) & 0x0f)
794 {
795 DDB(printk("soundscape: Detect error F\n"));
796 return 0;
797 }
798 return 1;
799 }
800
801 static int sscape_read_host_ctrl(sscape_info* devc)
802 {
803 return host_read(devc);
804 }
805
806 static void sscape_write_host_ctrl2(sscape_info *devc, int a, int b)
807 {
808 host_command2(devc, a, b);
809 }
810
811 static int sscape_alloc_dma(sscape_info *devc)
812 {
813 char *start_addr, *end_addr;
814 int dma_pagesize;
815 int sz, size;
816 struct page *page;
817
818 if (devc->raw_buf != NULL) return 0; /* Already done */
819 dma_pagesize = (devc->dma < 4) ? (64 * 1024) : (128 * 1024);
820 devc->raw_buf = NULL;
821 devc->buffsize = 8192*4;
822 if (devc->buffsize > dma_pagesize) devc->buffsize = dma_pagesize;
823 start_addr = NULL;
824 /*
825 * Now loop until we get a free buffer. Try to get smaller buffer if
826 * it fails. Don't accept smaller than 8k buffer for performance
827 * reasons.
828 */
829 while (start_addr == NULL && devc->buffsize > PAGE_SIZE) {
830 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
831 devc->buffsize = PAGE_SIZE * (1 << sz);
832 start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA, sz);
833 if (start_addr == NULL) devc->buffsize /= 2;
834 }
835
836 if (start_addr == NULL) {
837 printk(KERN_ERR "sscape pnp init error: Couldn't allocate DMA buffer\n");
838 return 0;
839 } else {
840 /* make some checks */
841 end_addr = start_addr + devc->buffsize - 1;
842 /* now check if it fits into the same dma-pagesize */
843
844 if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
845 || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
846 printk(KERN_ERR "sscape pnp: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, devc->buffsize);
847 return 0;
848 }
849 }
850 devc->raw_buf = start_addr;
851 devc->raw_buf_phys = virt_to_bus(start_addr);
852
853 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
854 mem_map_reserve(page);
855 return 1;
856 }
857
858 static void sscape_free_dma(sscape_info *devc)
859 {
860 int sz, size;
861 unsigned long start_addr, end_addr;
862 struct page *page;
863
864 if (devc->raw_buf == NULL) return;
865 for (sz = 0, size = PAGE_SIZE; size < devc->buffsize; sz++, size <<= 1);
866 start_addr = (unsigned long) devc->raw_buf;
867 end_addr = start_addr + devc->buffsize;
868
869 for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
870 mem_map_unreserve(page);
871
872 free_pages((unsigned long) devc->raw_buf, sz);
873 devc->raw_buf = NULL;
874 }
875
876 /* Intel version !!!!!!!!! */
877
878 static int sscape_start_dma(int chan, unsigned long physaddr, int count, int dma_mode)
879 {
880 unsigned long flags;
881
882 flags = claim_dma_lock();
883 disable_dma(chan);
884 clear_dma_ff(chan);
885 set_dma_mode(chan, dma_mode);
886 set_dma_addr(chan, physaddr);
887 set_dma_count(chan, count);
888 enable_dma(chan);
889 release_dma_lock(flags);
890 return 0;
891 }
892
893 static void sscape_pnp_start_dma(sscape_info* devc, int arg )
894 {
895 int reg;
896 if (arg == 0) reg = 2;
897 else reg = 3;
898
899 sscape_write(devc, reg, sscape_read( devc, reg) | 0x01);
900 sscape_write(devc, reg, sscape_read( devc, reg) & 0xFE);
901 }
902
903 static int sscape_pnp_wait_dma (sscape_info* devc, int arg )
904 {
905 int reg;
906 unsigned long i;
907 unsigned char d;
908
909 if (arg == 0) reg = 2;
910 else reg = 3;
911
912 sleep ( 1 );
913 i = 0;
914 do {
915 d = sscape_read(devc, reg) & 1;
916 if ( d == 1) break;
917 i++;
918 } while (i < 500000);
919 d = sscape_read(devc, reg) & 1;
920 return d;
921 }
922
923 static int sscape_pnp_alloc_dma(sscape_info* devc)
924 {
925 /* printk(KERN_INFO "sscape: requesting dma\n"); */
926 if (request_dma(devc -> dma, "sscape")) return 0;
927 /* printk(KERN_INFO "sscape: dma channel allocated\n"); */
928 if (!sscape_alloc_dma(devc)) {
929 free_dma(devc -> dma);
930 return 0;
931 };
932 return 1;
933 }
934
935 static void sscape_pnp_free_dma(sscape_info* devc)
936 {
937 sscape_free_dma( devc);
938 free_dma(devc -> dma );
939 /* printk(KERN_INFO "sscape: dma released\n"); */
940 }
941
942 static int sscape_pnp_upload_file(sscape_info* devc, char* fn)
943 {
944 int done = 0;
945 int timeout_val;
946 char* data,*dt;
947 int len,l;
948 unsigned long flags;
949
950 sscape_write( devc, 9, sscape_read(devc, 9 ) & 0x3F );
951 sscape_write( devc, 2, (devc -> dma << 4) | 0x80 );
952 sscape_write( devc, 3, 0x20 );
953 sscape_write( devc, 9, sscape_read( devc, 9 ) | 0x80 );
954
955 len = mod_firmware_load(fn, &data);
956 if (len == 0) {
957 printk(KERN_ERR "sscape: file not found: %s\n", fn);
958 return 0;
959 }
960 dt = data;
961 save_flags(flags);
962 cli();
963 while ( len > 0 ) {
964 if (len > devc -> buffsize) l = devc->buffsize;
965 else l = len;
966 len -= l;
967 memcpy(devc->raw_buf, dt, l); dt += l;
968 sscape_start_dma(devc->dma, devc->raw_buf_phys, l, 0x48);
969 sscape_pnp_start_dma ( devc, 0 );
970 if (sscape_pnp_wait_dma ( devc, 0 ) == 0) return 0;
971 }
972
973 restore_flags(flags);
974 vfree(data);
975
976 outb(0, devc -> base + 2);
977 outb(0, devc -> base);
978
979 sscape_write ( devc, 9, sscape_read( devc, 9 ) | 0x40);
980
981 timeout_val = 5 * HZ;
982 while (!done && timeout_val-- > 0)
983 {
984 unsigned char x;
985 sleep(1);
986 x = inb( devc -> base + 3);
987 if (x == 0xff || x == 0xfe) /* OBP startup acknowledge */
988 {
989 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
990 done = 1;
991 }
992 }
993 timeout_val = 5 * HZ;
994 done = 0;
995 while (!done && timeout_val-- > 0)
996 {
997 unsigned char x;
998 sleep(1);
999 x = inb( devc -> base + 3);
1000 if (x == 0xfe) /* OBP startup acknowledge */
1001 {
1002 //printk(KERN_ERR "Soundscape: Acknowledge = %x\n", x);
1003 done = 1;
1004 }
1005 }
1006
1007 if ( !done ) printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
1008
1009 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1010 sscape_write( devc, 3, (devc -> dma << 4) + 0x80);
1011 return 1;
1012 }
1013
1014 static void __init sscape_pnp_init_hw(sscape_info* devc)
1015 {
1016 unsigned char midi_irq = 0, sb_irq = 0;
1017 unsigned i;
1018 static char code_file_name[23] = "/sndscape/sndscape.cox";
1019
1020 int sscape_sb_enable = 0;
1021 int sscape_joystic_enable = 0x7f;
1022 int sscape_mic_enable = 0;
1023 int sscape_ext_midi = 0;
1024
1025 if ( !sscape_pnp_alloc_dma(devc) ) {
1026 printk(KERN_ERR "sscape: faild to allocate dma\n");
1027 return;
1028 }
1029
1030 for (i = 0; i < 4; i++) {
1031 if ( devc -> irq == valid_interrupts[i] )
1032 midi_irq = i;
1033 if ( devc -> codec_irq == valid_interrupts[i] )
1034 sb_irq = i;
1035 }
1036
1037 sscape_write( devc, 5, 0x50);
1038 sscape_write( devc, 7, 0x2e);
1039 sscape_write( devc, 8, 0x00);
1040
1041 sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
1042 sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
1043
1044 if ( sscape_sb_enable )
1045 sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
1046 else
1047 sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
1048
1049 i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
1050 if ( sscape_sb_enable )
1051 i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;
1052 if (sscape_joystic_enable) i |= 8;
1053
1054 sscape_write (devc, 9, i);
1055 sscape_write (devc, 6, 0x80);
1056 sscape_write (devc, 1, 0x80);
1057
1058 if (devc -> codec_type == 2) {
1059 sscape_pnp_write_codec( devc, 0x0C, 0x50);
1060 sscape_pnp_write_codec( devc, 0x10, sscape_pnp_read_codec( devc, 0x10) & 0x3F);
1061 sscape_pnp_write_codec( devc, 0x11, sscape_pnp_read_codec( devc, 0x11) | 0xC0);
1062 sscape_pnp_write_codec( devc, 29, 0x20);
1063 }
1064
1065 if (sscape_pnp_upload_file(devc, "/sndscape/scope.cod") == 0 ) {
1066 printk(KERN_ERR "sscape: faild to upload file /sndscape/scope.cod\n");
1067 sscape_pnp_free_dma(devc);
1068 return;
1069 }
1070
1071 i = sscape_read_host_ctrl( devc );
1072
1073 if ( (i & 0x0F) > 7 ) {
1074 printk(KERN_ERR "sscape: scope.cod faild\n");
1075 sscape_pnp_free_dma(devc);
1076 return;
1077 }
1078 if ( i & 0x10 ) sscape_write( devc, 7, 0x2F);
1079 code_file_name[21] = (char) ( i & 0x0F) + 0x30;
1080 if (sscape_pnp_upload_file( devc, code_file_name) == 0) {
1081 printk(KERN_ERR "sscape: faild to upload file %s\n", code_file_name);
1082 sscape_pnp_free_dma(devc);
1083 return;
1084 }
1085
1086 if (devc->ic_type != IC_ODIE) {
1087 sscape_pnp_write_codec( devc, 10, (sscape_pnp_read_codec(devc, 10) & 0x7f) |
1088 ( sscape_mic_enable == 0 ? 0x00 : 0x80) );
1089 }
1090 sscape_write_host_ctrl2( devc, 0x84, 0x32 );
1091 sscape_write_host_ctrl2( devc, 0x86, 0x32 );
1092 sscape_write_host_ctrl2( devc, 0x8A, sscape_ext_midi);
1093
1094 sscape_pnp_write_codec ( devc, 6, 0x3f ); //WAV_VOL
1095 sscape_pnp_write_codec ( devc, 7, 0x3f ); //WAV_VOL
1096 sscape_pnp_write_codec ( devc, 2, 0x1F ); //WD_CDXVOLL
1097 sscape_pnp_write_codec ( devc, 3, 0x1F ); //WD_CDXVOLR
1098
1099 if (devc -> codec_type == 1) {
1100 sscape_pnp_write_codec ( devc, 4, 0x1F );
1101 sscape_pnp_write_codec ( devc, 5, 0x1F );
1102 sscape_write_host_ctrl2( devc, 0x88, sscape_mic_enable);
1103 } else {
1104 int t;
1105 sscape_pnp_write_codec ( devc, 0x10, 0x1F << 1);
1106 sscape_pnp_write_codec ( devc, 0x11, 0xC0 | (0x1F << 1));
1107
1108 t = sscape_pnp_read_codec( devc, 0x00) & 0xDF;
1109 if ( (sscape_mic_enable == 0)) t |= 0;
1110 else t |= 0x20;
1111 sscape_pnp_write_codec ( devc, 0x00, t);
1112 t = sscape_pnp_read_codec( devc, 0x01) & 0xDF;
1113 if ( (sscape_mic_enable == 0) ) t |= 0;
1114 else t |= 0x20;
1115 sscape_pnp_write_codec ( devc, 0x01, t);
1116 sscape_pnp_write_codec ( devc, 0x40 | 29 , 0x20);
1117 outb(0, devc -> codec);
1118 }
1119 if (devc -> ic_type == IC_OPUS ) {
1120 int i = sscape_read( devc, 9 );
1121 sscape_write( devc, 9, i | 3 );
1122 sscape_write( devc, 3, 0x40);
1123
1124 if (check_region(0x228, 1)) {
1125 outb(0, 0x228);
1126 release_region(0x228,1);
1127 }
1128 sscape_write( devc, 3, (devc -> dma << 4) | 0x80);
1129 sscape_write( devc, 9, i );
1130 }
1131
1132 host_close ( devc );
1133 sscape_pnp_free_dma(devc);
1134 }
1135
1136 static int __init detect_sscape_pnp(sscape_info* devc)
1137 {
1138 long i, irq_bits = 0xff;
1139 unsigned int d;
1140
1141 DDB(printk("Entered detect_sscape_pnp(%x)\n", devc->base));
1142
1143 if (check_region(devc->base, 8)) {
1144 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->base);
1145 return 0;
1146 }
1147
1148 if (check_region(devc->codec, 2)) {
1149 printk(KERN_ERR "detect_sscape_pnp: port %x is not free\n", devc->codec);
1150 return 0;
1151 }
1152
1153 if ( (inb( devc -> base + 2) & 0x78) != 0) return 0;
1154
1155 d = inb ( devc -> base + 4) & 0xF0;
1156 if ( (d & 0x80) != 0) return 0;
1157
1158 if (d == 0) {
1159 devc->codec_type = 1;
1160 devc->ic_type = IC_ODIE;
1161 }
1162 else if ( (d & 0x60) != 0) {
1163 devc->codec_type = 2;
1164 devc->ic_type = IC_OPUS;
1165 }
1166 else if ( (d & 0x40) != 0) {
1167 devc->codec_type = 2;
1168 devc->ic_type = IC_ODIE;
1169 }
1170 else return 0;
1171
1172 sscape_is_pnp = 1;
1173
1174 outb(0xFA, devc -> base+4);
1175 if ((inb( devc -> base+4) & 0x9F) != 0x0A)
1176 return 0;
1177 outb(0xFE, devc -> base+4);
1178 if ( (inb(devc -> base+4) & 0x9F) != 0x0E)
1179 return 0;
1180 if ( (inb(devc -> base+5) & 0x9F) != 0x0E)
1181 return 0;
1182
1183 if (devc->codec_type == 2) {
1184 if (devc -> codec != devc -> base + 8)
1185 printk("soundscape warning: incorrect codec port specified\n");
1186 devc -> codec = devc -> base + 8;
1187 d = 0x10 | (sscape_read(devc, 9) & 0xCF);
1188 sscape_write(devc, 9, d);
1189 sscape_write(devc, 6, 0x80);
1190 } else {
1191 //todo: check codec is not base + 8
1192 }
1193
1194 d = (sscape_read(devc, 9) & 0x3F) | 0xC0;
1195 sscape_write(devc, 9, d);
1196
1197 for (i = 0; i < 550000; i++)
1198 if ( !(inb(devc -> codec) & 0x80) ) break;
1199
1200 d = inb(devc -> codec);
1201 if (d & 0x80)
1202 return 0;
1203 if ( inb(devc -> codec + 2) == 0xFF)
1204 return 0;
1205
1206 sscape_write(devc, 9, sscape_read(devc, 9) & 0x3F );
1207
1208 d = inb(devc -> codec) & 0x80;
1209 if ( d == 0) {
1210 printk(KERN_INFO "soundscape: hardware detected\n");
1211 valid_interrupts = valid_interrupts_new;
1212 } else {
1213 printk(KERN_INFO "soundscape: board looks like media fx\n");
1214 valid_interrupts = valid_interrupts_old;
1215 old_hardware = 1;
1216 }
1217
1218 sscape_write( devc, 9, 0xC0 | (sscape_read(devc, 9) & 0x3F) );
1219
1220 for (i = 0; i < 550000; i++)
1221 if ( !(inb(devc -> codec) & 0x80))
1222 break;
1223
1224 sscape_pnp_init_hw(devc);
1225
1226 for (i = 0; i < sizeof(valid_interrupts); i++)
1227 {
1228 if (devc->codec_irq == valid_interrupts[i]) {
1229 irq_bits = i;
1230 break;
1231 }
1232 }
1233 sscape_write(devc, GA_INTENA_REG, 0x00);
1234 sscape_write(devc, GA_DMACFG_REG, 0x50);
1235 sscape_write(devc, GA_DMAA_REG, 0x70);
1236 sscape_write(devc, GA_DMAB_REG, 0x20);
1237 sscape_write(devc, GA_INTCFG_REG, 0xf0);
1238 sscape_write(devc, GA_CDCFG_REG, 0x89 | (devc->dma << 4) | (irq_bits << 1));
1239
1240 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 0) | 0x20);
1241 sscape_pnp_write_codec( devc, 0, sscape_pnp_read_codec( devc, 1) | 0x20);
1242
1243 release_region(devc->codec, 2);
1244 release_region(devc->base, 8);
1245
1246 return 1;
1247 }
1248
1249 static int __init probe_sscape(struct address_info *hw_config)
1250 {
1251
1252 if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1253 return 0;
1254
1255 devc->base = hw_config->io_base;
1256 devc->irq = hw_config->irq;
1257 devc->dma = hw_config->dma;
1258 devc->osp = hw_config->osp;
1259
1260 #ifdef SSCAPE_DEBUG1
1261 /*
1262 * Temporary debugging aid. Print contents of the registers before
1263 * changing them.
1264 */
1265 {
1266 int i;
1267
1268 for (i = 0; i < 13; i++)
1269 printk("I%d = %02x (old value)\n", i, sscape_read(devc, i));
1270 }
1271 #endif
1272 devc->failed = 1;
1273
1274 if (!detect_ga(devc)) {
1275 if (detect_sscape_pnp(devc)) {
1276 sscape_detected = hw_config->io_base;
1277 return 1;
1278 }
1279 else return 0;
1280 }
1281
1282 if (old_hardware) /* Check that it's really an old Spea/Reveal card. */
1283 {
1284 unsigned char tmp;
1285 int cc;
1286
1287 if (!((tmp = sscape_read(devc, GA_HMCTL_REG)) & 0xc0))
1288 {
1289 sscape_write(devc, GA_HMCTL_REG, tmp | 0x80);
1290 for (cc = 0; cc < 200000; ++cc)
1291 inb(devc->base + ODIE_ADDR);
1292 }
1293 }
1294 sscape_detected = hw_config->io_base;
1295 return 1;
1296 }
1297
1298 static int __init probe_ss_ms_sound(struct address_info *hw_config)
1299 {
1300 int i, irq_bits = 0xff;
1301 int ad_flags = 0;
1302
1303 if (devc->failed)
1304 {
1305 printk(KERN_ERR "soundscape: Card not detected\n");
1306 return 0;
1307 }
1308 if (devc->ok == 0)
1309 {
1310 printk(KERN_ERR "soundscape: Invalid initialization order.\n");
1311 return 0;
1312 }
1313 for (i = 0; i < sizeof(valid_interrupts); i++)
1314 {
1315 if (hw_config->irq == valid_interrupts[i])
1316 {
1317 irq_bits = i;
1318 break;
1319 }
1320 }
1321 if (hw_config->irq > 15 || irq_bits == 0xff)
1322 {
1323 printk(KERN_ERR "soundscape: Invalid MSS IRQ%d\n", hw_config->irq);
1324 return 0;
1325 }
1326
1327 if (!sscape_is_pnp) {
1328 if (old_hardware)
1329 ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1330 return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1331 }
1332 else {
1333 if (old_hardware)
1334 ad_flags = 0x12345677; /* Tell that we may have a CS4248 chip (Spea-V7 Media FX) */
1335 else
1336 ad_flags = 0x87654321; /* Tell that we have a soundscape pnp with 1845 chip */
1337 return ad1848_detect(hw_config->io_base, &ad_flags, hw_config->osp);
1338 }
1339 }
1340
1341 static void __init attach_ss_ms_sound(struct address_info *hw_config)
1342 {
1343 /*
1344 * This routine configures the SoundScape card for use with the
1345 * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1346 * config registers of the "ODIE".
1347 */
1348
1349 int i, irq_bits = 0xff;
1350
1351
1352 if (!sscape_is_pnp) /*pnp is already setup*/
1353 {
1354 /*
1355 * Setup the DMA polarity.
1356 */
1357 sscape_write(devc, GA_DMACFG_REG, 0x50);
1358
1359 /*
1360 * Take the gate-array off of the DMA channel.
1361 */
1362 sscape_write(devc, GA_DMAB_REG, 0x20);
1363
1364 /*
1365 * Init the AD1848 (CD-ROM) config reg.
1366 */
1367 for (i = 0; i < sizeof(valid_interrupts); i++)
1368 {
1369 if (hw_config->irq == valid_interrupts[i])
1370 {
1371 irq_bits = i;
1372 break;
1373 }
1374 }
1375 sscape_write(devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) | (irq_bits << 1));
1376 }
1377
1378 if (hw_config->irq == devc->irq)
1379 printk(KERN_WARNING "soundscape: Warning! The WSS mode can't share IRQ with MIDI\n");
1380
1381 hw_config->slots[0] = ad1848_init(
1382 sscape_is_pnp ? "SoundScape" : "SoundScape PNP",
1383 hw_config->io_base,
1384 hw_config->irq,
1385 hw_config->dma,
1386 hw_config->dma,
1387 0,
1388 devc->osp,
1389 THIS_MODULE);
1390
1391
1392 if (hw_config->slots[0] != -1) /* The AD1848 driver installed itself */
1393 {
1394 audio_devs[hw_config->slots[0]]->coproc = &sscape_coproc_operations;
1395 devc->codec_audiodev = hw_config->slots[0];
1396 devc->my_audiodev = hw_config->slots[0];
1397
1398 /* Set proper routings here (what are they) */
1399 AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
1400 }
1401
1402 #ifdef SSCAPE_DEBUG5
1403 /*
1404 * Temporary debugging aid. Print contents of the registers
1405 * after the AD1848 device has been initialized.
1406 */
1407 {
1408 int i;
1409
1410 for (i = 0; i < 13; i++)
1411 printk("I%d = %02x\n", i, sscape_read(devc, i));
1412 }
1413 #endif
1414
1415 }
1416
1417 static void __exit unload_sscape(struct address_info *hw_config)
1418 {
1419 release_region(devc->base + 2, 6);
1420 unload_mpu401(hw_config);
1421 }
1422
1423 static void __exit unload_ss_ms_sound(struct address_info *hw_config)
1424 {
1425 ad1848_unload(hw_config->io_base,
1426 hw_config->irq,
1427 devc->dma,
1428 devc->dma,
1429 0);
1430 sound_unload_audiodev(hw_config->slots[0]);
1431 }
1432
1433 static struct address_info cfg;
1434 static struct address_info cfg_mpu;
1435
1436 static int __initdata spea = -1;
1437 static int __initdata mss = 0;
1438 static int __initdata dma = -1;
1439 static int __initdata irq = -1;
1440 static int __initdata io = -1;
1441 static int __initdata mpu_irq = -1;
1442 static int __initdata mpu_io = -1;
1443
1444 MODULE_PARM(dma, "i");
1445 MODULE_PARM(irq, "i");
1446 MODULE_PARM(io, "i");
1447 MODULE_PARM(spea, "i"); /* spea=0/1 set the old_hardware */
1448 MODULE_PARM(mpu_irq, "i");
1449 MODULE_PARM(mpu_io, "i");
1450 MODULE_PARM(mss, "i");
1451
1452 static int __init init_sscape(void)
1453 {
1454 printk(KERN_INFO "Soundscape driver Copyright (C) by Hannu Savolainen 1993-1996\n");
1455
1456 cfg.irq = irq;
1457 cfg.dma = dma;
1458 cfg.io_base = io;
1459
1460 cfg_mpu.irq = mpu_irq;
1461 cfg_mpu.io_base = mpu_io;
1462 /* WEH - Try to get right dma channel */
1463 cfg_mpu.dma = dma;
1464
1465 devc->codec = cfg.io_base;
1466 devc->codec_irq = cfg.irq;
1467 devc->codec_type = 0;
1468 devc->ic_type = 0;
1469 devc->raw_buf = NULL;
1470
1471 if (cfg.dma == -1 || cfg.irq == -1 || cfg.io_base == -1) {
1472 printk(KERN_ERR "DMA, IRQ, and IO port must be specified.\n");
1473 return -EINVAL;
1474 }
1475
1476 if (cfg_mpu.irq == -1 && cfg_mpu.io_base != -1) {
1477 printk(KERN_ERR "MPU_IRQ must be specified if MPU_IO is set.\n");
1478 return -EINVAL;
1479 }
1480
1481 if(spea != -1) {
1482 old_hardware = spea;
1483 printk(KERN_INFO "Forcing %s hardware support.\n",
1484 spea?"new":"old");
1485 }
1486 if (probe_sscape(&cfg_mpu) == 0)
1487 return -ENODEV;
1488
1489 attach_sscape(&cfg_mpu);
1490
1491 mss = probe_ss_ms_sound(&cfg);
1492
1493 if (mss)
1494 attach_ss_ms_sound(&cfg);
1495
1496 return 0;
1497 }
1498
1499 static void __exit cleanup_sscape(void)
1500 {
1501 if (mss)
1502 unload_ss_ms_sound(&cfg);
1503 unload_sscape(&cfg_mpu);
1504 }
1505
1506 module_init(init_sscape);
1507 module_exit(cleanup_sscape);
1508
1509 #ifndef MODULE
1510 static int __init setup_sscape(char *str)
1511 {
1512 /* io, irq, dma, mpu_io, mpu_irq */
1513 int ints[6];
1514
1515 str = get_options(str, ARRAY_SIZE(ints), ints);
1516
1517 io = ints[1];
1518 irq = ints[2];
1519 dma = ints[3];
1520 mpu_io = ints[4];
1521 mpu_irq = ints[5];
1522
1523 return 1;
1524 }
1525
1526 __setup("sscape=", setup_sscape);
1527 #endif
1528
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.