blob: aa3c50db66c49d589102e6b68bd4f4c5b9075c47 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) by Hannu Savolainen 1993-1997
3 *
4 * mad16.c
5 *
6 * Initialization code for OPTi MAD16 compatible audio chips. Including
7 *
8 * OPTi 82C928 MAD16 (replaced by C929)
9 * OAK OTI-601D Mozart
10 * OAK OTI-605 Mozart (later version with MPU401 Midi)
11 * OPTi 82C929 MAD16 Pro
12 * OPTi 82C930
13 * OPTi 82C924
14 *
15 * These audio interface chips don't produce sound themselves. They just
16 * connect some other components (OPL-[234] and a WSS compatible codec)
17 * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
18 * also a UART for the MPU-401 mode (not 82C928/Mozart).
19 * The Mozart chip appears to be compatible with the 82C928, although later
20 * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi
21 * port. This port is configured differently to that of the OPTi audio chips.
22 *
23 * Changes
24 *
25 * Alan Cox Clean up, added module selections.
26 *
27 * A. Wik Added support for Opti924 PnP.
28 * Improved debugging support. 16-May-1998
29 * Fixed bug. 16-Jun-1998
30 *
31 * Torsten Duwe Made Opti924 PnP support non-destructive
32 * 23-Dec-1998
33 *
34 * Paul Grayson Added support for Midi on later Mozart cards.
35 * 25-Nov-1999
36 * Christoph Hellwig Adapted to module_init/module_exit.
37 * Arnaldo C. de Melo got rid of attach_uart401 21-Sep-2000
38 *
39 * Pavel Rabel Clean up Nov-2000
40 */
41
42#include <linux/config.h>
43#include <linux/init.h>
44#include <linux/module.h>
45#include <linux/gameport.h>
46#include <linux/spinlock.h>
47#include "sound_config.h"
48
49#include "ad1848.h"
50#include "sb.h"
51#include "mpu401.h"
52
Dmitry Torokhove6084602005-06-01 02:38:46 -050053#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
54#define SUPPORT_JOYSTICK 1
55#endif
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057static int mad16_conf;
58static int mad16_cdsel;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059static DEFINE_SPINLOCK(lock);
60
61#define C928 1
62#define MOZART 2
63#define C929 3
64#define C930 4
65#define C924 5
66
67/*
68 * Registers
69 *
70 * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
71 * All ports are inactive by default. They can be activated by
72 * writing 0xE2 or 0xE3 to the password register. The password is valid
73 * only until the next I/O read or write.
74 *
75 * 82C930 uses 0xE4 as the password and indirect addressing to access
76 * the config registers.
77 */
78
79#define MC0_PORT 0xf8c /* Dummy port */
80#define MC1_PORT 0xf8d /* SB address, CD-ROM interface type, joystick */
81#define MC2_PORT 0xf8e /* CD-ROM address, IRQ, DMA, plus OPL4 bit */
82#define MC3_PORT 0xf8f
83#define PASSWD_REG 0xf8f
84#define MC4_PORT 0xf90
85#define MC5_PORT 0xf91
86#define MC6_PORT 0xf92
87#define MC7_PORT 0xf93
88#define MC8_PORT 0xf94
89#define MC9_PORT 0xf95
90#define MC10_PORT 0xf96
91#define MC11_PORT 0xf97
92#define MC12_PORT 0xf98
93
94static int board_type = C928;
95
96static int *mad16_osp;
97static int c931_detected; /* minor differences from C930 */
98static char c924pnp; /* " " " C924 */
99static int debug; /* debugging output */
100
101#ifdef DDB
102#undef DDB
103#endif
104#define DDB(x) do {if (debug) x;} while (0)
105
106static unsigned char mad_read(int port)
107{
108 unsigned long flags;
109 unsigned char tmp;
110
111 spin_lock_irqsave(&lock,flags);
112
113 switch (board_type) /* Output password */
114 {
115 case C928:
116 case MOZART:
117 outb((0xE2), PASSWD_REG);
118 break;
119
120 case C929:
121 outb((0xE3), PASSWD_REG);
122 break;
123
124 case C930:
125 /* outb(( 0xE4), PASSWD_REG); */
126 break;
127
128 case C924:
129 /* the c924 has its ports relocated by -128 if
130 PnP is enabled -aw */
131 if (!c924pnp)
132 outb((0xE5), PASSWD_REG); else
133 outb((0xE5), PASSWD_REG - 0x80);
134 break;
135 }
136
137 if (board_type == C930)
138 {
139 outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
140 tmp = inb(0xe0f); /* Read from data reg */
141 }
142 else
143 if (!c924pnp)
144 tmp = inb(port); else
145 tmp = inb(port-0x80);
146 spin_unlock_irqrestore(&lock,flags);
147
148 return tmp;
149}
150
151static void mad_write(int port, int value)
152{
153 unsigned long flags;
154
155 spin_lock_irqsave(&lock,flags);
156
157 switch (board_type) /* Output password */
158 {
159 case C928:
160 case MOZART:
161 outb((0xE2), PASSWD_REG);
162 break;
163
164 case C929:
165 outb((0xE3), PASSWD_REG);
166 break;
167
168 case C930:
169 /* outb(( 0xE4), PASSWD_REG); */
170 break;
171
172 case C924:
173 if (!c924pnp)
174 outb((0xE5), PASSWD_REG); else
175 outb((0xE5), PASSWD_REG - 0x80);
176 break;
177 }
178
179 if (board_type == C930)
180 {
181 outb((port - MC0_PORT), 0xe0e); /* Write to index reg */
182 outb(((unsigned char) (value & 0xff)), 0xe0f);
183 }
184 else
185 if (!c924pnp)
186 outb(((unsigned char) (value & 0xff)), port); else
187 outb(((unsigned char) (value & 0xff)), port-0x80);
188 spin_unlock_irqrestore(&lock,flags);
189}
190
191static int __init detect_c930(void)
192{
193 unsigned char tmp = mad_read(MC1_PORT);
194
195 if ((tmp & 0x06) != 0x06)
196 {
197 DDB(printk("Wrong C930 signature (%x)\n", tmp));
198 /* return 0; */
199 }
200 mad_write(MC1_PORT, 0);
201
202 if (mad_read(MC1_PORT) != 0x06)
203 {
204 DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
205 /* return 0; */
206 }
207 mad_write(MC1_PORT, tmp); /* Restore bits */
208
209 mad_write(MC7_PORT, 0);
210 if ((tmp = mad_read(MC7_PORT)) != 0)
211 {
212 DDB(printk("MC7 not writable (%x)\n", tmp));
213 return 0;
214 }
215 mad_write(MC7_PORT, 0xcb);
216 if ((tmp = mad_read(MC7_PORT)) != 0xcb)
217 {
218 DDB(printk("MC7 not writable2 (%x)\n", tmp));
219 return 0;
220 }
221
222 tmp = mad_read(MC0_PORT+18);
223 if (tmp == 0xff || tmp == 0x00)
224 return 1;
225 /* We probably have a C931 */
226 DDB(printk("Detected C931 config=0x%02x\n", tmp));
227 c931_detected = 1;
228
229 /*
230 * We cannot configure the chip if it is in PnP mode.
231 * If we have a CSN assigned (bit 8 in MC13) we first try
232 * a software reset, then a software power off, finally
233 * Clearing PnP mode. The last option is not
234 * Bit 8 in MC13
235 */
236 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
237 return 1;
238
239 /* Software reset */
240 mad_write(MC9_PORT, 0x02);
241 mad_write(MC9_PORT, 0x00);
242
243 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
244 return 1;
245
246 /* Power off, and on again */
247 mad_write(MC9_PORT, 0xc2);
248 mad_write(MC9_PORT, 0xc0);
249
250 if ((mad_read(MC0_PORT+13) & 0x80) == 0)
251 return 1;
252
253#if 0
254 /* Force off PnP mode. This is not recommended because
255 * the PnP bios will not recognize the chip on the next
256 * warm boot and may assignd different resources to other
257 * PnP/PCI cards.
258 */
259 mad_write(MC0_PORT+17, 0x04);
260#endif
261 return 1;
262}
263
264static int __init detect_mad16(void)
265{
266 unsigned char tmp, tmp2, bit;
267 int i, port;
268
269 /*
270 * Check that reading a register doesn't return bus float (0xff)
271 * when the card is accessed using password. This may fail in case
272 * the card is in low power mode. Normally at least the power saving
273 * mode bit should be 0.
274 */
275
276 if ((tmp = mad_read(MC1_PORT)) == 0xff)
277 {
278 DDB(printk("MC1_PORT returned 0xff\n"));
279 return 0;
280 }
281 for (i = 0xf8d; i <= 0xf98; i++)
282 if (!c924pnp)
283 DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i)));
284 else
285 DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));
286
287 if (board_type == C930)
288 return detect_c930();
289
290 /*
291 * Now check that the gate is closed on first I/O after writing
292 * the password. (This is how a MAD16 compatible card works).
293 */
294
295 if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */
296 {
297 DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
298 return 0;
299 }
300
301 bit = (c924pnp) ? 0x20 : 0x80;
302 port = (c924pnp) ? MC2_PORT : MC1_PORT;
303
304 tmp = mad_read(port);
305 mad_write(port, tmp ^ bit); /* Toggle a bit */
306 if ((tmp2 = mad_read(port)) != (tmp ^ bit)) /* Compare the bit */
307 {
308 mad_write(port, tmp); /* Restore */
309 DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
310 return 0;
311 }
312 mad_write(port, tmp); /* Restore */
313 return 1; /* Bingo */
314}
315
316static int __init wss_init(struct address_info *hw_config)
317{
318 /*
319 * Check if the IO port returns valid signature. The original MS Sound
320 * system returns 0x04 while some cards (AudioTrix Pro for example)
321 * return 0x00.
322 */
323
324 if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 &&
325 (inb(hw_config->io_base + 3) & 0x3f) != 0x00)
326 {
327 DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3)));
328 return 0;
329 }
330 /*
331 * Check that DMA0 is not in use with a 8 bit board.
332 */
333 if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)
334 {
335 printk("MSS: Can't use DMA0 with a 8 bit card/slot\n");
336 return 0;
337 }
338 if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80)
339 printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
340 return 1;
341}
342
343static void __init init_c930(struct address_info *hw_config, int base)
344{
345 unsigned char cfg = 0;
346
347 cfg |= (0x0f & mad16_conf);
348
349 if(c931_detected)
350 {
351 /* Bit 0 has reversd meaning. Bits 1 and 2 sese
352 reversed on write.
353 Support only IDE cdrom. IDE port programmed
354 somewhere else. */
355 cfg = (cfg & 0x09) ^ 0x07;
356 }
357 cfg |= base << 4;
358 mad_write(MC1_PORT, cfg);
359
360 /* MC2 is CD configuration. Don't touch it. */
361
362 mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */
363
364 /* bit 2 of MC4 reverses it's meaning between the C930
365 and the C931. */
366 cfg = c931_detected ? 0x04 : 0x00;
367
368 if(mad16_cdsel & 0x20)
369 mad_write(MC4_PORT, 0x62|cfg); /* opl4 */
370 else
371 mad_write(MC4_PORT, 0x52|cfg); /* opl3 */
372
373 mad_write(MC5_PORT, 0x3C); /* Init it into mode2 */
374 mad_write(MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */
375 mad_write(MC7_PORT, 0xCB);
376 mad_write(MC10_PORT, 0x11);
377}
378
379static int __init chip_detect(void)
380{
381 int i;
382
383 /*
384 * Then try to detect with the old password
385 */
386 board_type = C924;
387
388 DDB(printk("Detect using password = 0xE5\n"));
389
390 if (detect_mad16()) {
391 return 1;
392 }
393
394 board_type = C928;
395
396 DDB(printk("Detect using password = 0xE2\n"));
397
398 if (detect_mad16())
399 {
400 unsigned char model;
401
402 if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
403 DDB(printk("mad16.c: Mozart detected\n"));
404 board_type = MOZART;
405 } else {
406 DDB(printk("mad16.c: 82C928 detected???\n"));
407 board_type = C928;
408 }
409 return 1;
410 }
411
412 board_type = C929;
413
414 DDB(printk("Detect using password = 0xE3\n"));
415
416 if (detect_mad16())
417 {
418 DDB(printk("mad16.c: 82C929 detected\n"));
419 return 1;
420 }
421
422 if (inb(PASSWD_REG) != 0xff)
423 return 0;
424
425 /*
426 * First relocate MC# registers to 0xe0e/0xe0f, disable password
427 */
428
429 outb((0xE4), PASSWD_REG);
430 outb((0x80), PASSWD_REG);
431
432 board_type = C930;
433
434 DDB(printk("Detect using password = 0xE4\n"));
435
436 for (i = 0xf8d; i <= 0xf93; i++)
437 DDB(printk("port %03x = %02x\n", i, mad_read(i)));
438
439 if(detect_mad16()) {
440 DDB(printk("mad16.c: 82C930 detected\n"));
441 return 1;
442 }
443
444 /* The C931 has the password reg at F8D */
445 outb((0xE4), 0xF8D);
446 outb((0x80), 0xF8D);
447 DDB(printk("Detect using password = 0xE4 for C931\n"));
448
449 if (detect_mad16()) {
450 return 1;
451 }
452
453 board_type = C924;
454 c924pnp++;
455 DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
456 if (detect_mad16()) {
457 DDB(printk("mad16.c: 82C924 PnP detected\n"));
458 return 1;
459 }
460
461 c924pnp=0;
462
463 return 0;
464}
465
466static int __init probe_mad16(struct address_info *hw_config)
467{
468 int i;
469 unsigned char tmp;
470 unsigned char cs4231_mode = 0;
471
472 int ad_flags = 0;
473
474 signed char bits;
475
476 static char dma_bits[4] = {
477 1, 2, 0, 3
478 };
479
480 int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
481 int dma = hw_config->dma, dma2 = hw_config->dma2;
482 unsigned char dma2_bit = 0;
483 int base;
484 struct resource *ports;
485
486 mad16_osp = hw_config->osp;
487
488 switch (hw_config->io_base) {
489 case 0x530:
490 base = 0;
491 break;
492 case 0xe80:
493 base = 1;
494 break;
495 case 0xf40:
496 base = 2;
497 break;
498 case 0x604:
499 base = 3;
500 break;
501 default:
502 printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
503 return 0;
504 }
505
506 if (dma != 0 && dma != 1 && dma != 3) {
507 printk(KERN_ERR "MSS: Bad DMA %d\n", dma);
508 return 0;
509 }
510
511 /*
512 * Check that all ports return 0xff (bus float) when no password
513 * is written to the password register.
514 */
515
516 DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
517 if (!chip_detect())
518 return 0;
519
520 switch (hw_config->irq) {
521 case 7:
522 bits = 8;
523 break;
524 case 9:
525 bits = 0x10;
526 break;
527 case 10:
528 bits = 0x18;
529 break;
530 case 12:
531 bits = 0x20;
532 break;
533 case 5: /* Also IRQ5 is possible on C930 */
534 if (board_type == C930 || c924pnp) {
535 bits = 0x28;
536 break;
537 }
538 default:
539 printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq);
540 return 0;
541 }
542
543 ports = request_region(hw_config->io_base + 4, 4, "ad1848");
544 if (!ports) {
545 printk(KERN_ERR "MSS: I/O port conflict\n");
546 return 0;
547 }
548 if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) {
549 release_region(hw_config->io_base + 4, 4);
550 printk(KERN_ERR "MSS: I/O port conflict\n");
551 return 0;
552 }
553
554 if (board_type == C930) {
555 init_c930(hw_config, base);
556 goto got_it;
557 }
558
559 for (i = 0xf8d; i <= 0xf93; i++) {
560 if (!c924pnp)
561 DDB(printk("port %03x = %02x\n", i, mad_read(i)));
562 else
563 DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));
564 }
565
566/*
567 * Set the WSS address
568 */
569
570 tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */
571 tmp |= base << 4; /* WSS port select bits */
572
573 /*
574 * Set optional CD-ROM and joystick settings.
575 */
576
577 tmp &= ~0x0f;
578 tmp |= (mad16_conf & 0x0f); /* CD-ROM and joystick bits */
579 mad_write(MC1_PORT, tmp);
580
581 tmp = mad16_cdsel;
582 mad_write(MC2_PORT, tmp);
583 mad_write(MC3_PORT, 0xf0); /* Disable SB */
584
585 if (board_type == C924) /* Specific C924 init values */
586 {
587 mad_write(MC4_PORT, 0xA0);
588 mad_write(MC5_PORT, 0x05);
589 mad_write(MC6_PORT, 0x03);
590 }
591 if (!ad1848_detect(ports, &ad_flags, mad16_osp))
592 goto fail;
593
594 if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
595 cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */
596
597 if (board_type == C929)
598 {
599 mad_write(MC4_PORT, 0xa2);
600 mad_write(MC5_PORT, 0xA5 | cs4231_mode);
601 mad_write(MC6_PORT, 0x03); /* Disable MPU401 */
602 }
603 else
604 {
605 mad_write(MC4_PORT, 0x02);
606 mad_write(MC5_PORT, 0x30 | cs4231_mode);
607 }
608
609 for (i = 0xf8d; i <= 0xf93; i++) {
610 if (!c924pnp)
611 DDB(printk("port %03x after init = %02x\n", i, mad_read(i)));
612 else
613 DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
614 }
615
616got_it:
617 ad_flags = 0;
618 if (!ad1848_detect(ports, &ad_flags, mad16_osp))
619 goto fail;
620
621 if (!wss_init(hw_config))
622 goto fail;
623
624 /*
625 * Set the IRQ and DMA addresses.
626 */
627
628 outb((bits | 0x40), config_port);
629 if ((inb(version_port) & 0x40) == 0)
630 printk(KERN_ERR "[IRQ Conflict?]\n");
631
632 /*
633 * Handle the capture DMA channel
634 */
635
636 if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
637 {
638 if (!((dma == 0 && dma2 == 1) ||
639 (dma == 1 && dma2 == 0) ||
640 (dma == 3 && dma2 == 0)))
641 { /* Unsupported combination. Try to swap channels */
642 int tmp = dma;
643
644 dma = dma2;
645 dma2 = tmp;
646 }
647 if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||
648 (dma == 3 && dma2 == 0))
649 {
650 dma2_bit = 0x04; /* Enable capture DMA */
651 }
652 else
653 {
654 printk("MAD16: Invalid capture DMA\n");
655 dma2 = dma;
656 }
657 }
658 else dma2 = dma;
659
660 outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */
661
662 hw_config->slots[0] = ad1848_init("mad16 WSS", ports,
663 hw_config->irq,
664 dma,
665 dma2, 0,
666 hw_config->osp,
667 THIS_MODULE);
668 return 1;
669
670fail:
671 release_region(hw_config->io_base + 4, 4);
672 release_region(hw_config->io_base, 4);
673 return 0;
674}
675
676static int __init probe_mad16_mpu(struct address_info *hw_config)
677{
678 unsigned char tmp;
679
680 if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
681 {
682
683#ifdef CONFIG_MAD16_OLDCARD
684
685 tmp = mad_read(MC3_PORT);
686
687 /*
688 * MAD16 SB base is defined by the WSS base. It cannot be changed
689 * alone.
690 * Ignore configured I/O base. Use the active setting.
691 */
692
693 if (mad_read(MC1_PORT) & 0x20)
694 hw_config->io_base = 0x240;
695 else
696 hw_config->io_base = 0x220;
697
698 switch (hw_config->irq)
699 {
700 case 5:
701 tmp = (tmp & 0x3f) | 0x80;
702 break;
703 case 7:
704 tmp = (tmp & 0x3f);
705 break;
706 case 11:
707 tmp = (tmp & 0x3f) | 0x40;
708 break;
709 default:
710 printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
711 return 0;
712 }
713
714 mad_write(MC3_PORT, tmp | 0x04);
715 hw_config->driver_use_1 = SB_MIDI_ONLY;
716 if (!request_region(hw_config->io_base, 16, "soundblaster"))
717 return 0;
718 if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
719 release_region(hw_config->io_base, 16);
720 return 0;
721 }
722
723 if (mad_read(MC1_PORT) & 0x20)
724 hw_config->io_base = 0x240;
725 else
726 hw_config->io_base = 0x220;
727
728 hw_config->name = "Mad16/Mozart";
729 sb_dsp_init(hw_config, THIS_MODULE);
730 return 1;
731#else
732 /* assuming all later Mozart cards are identified as
733 * either 82C928 or Mozart. If so, following code attempts
734 * to set MPU register. TODO - add probing
735 */
736
737 tmp = mad_read(MC8_PORT);
738
739 switch (hw_config->irq)
740 {
741 case 5:
742 tmp |= 0x08;
743 break;
744 case 7:
745 tmp |= 0x10;
746 break;
747 case 9:
748 tmp |= 0x18;
749 break;
750 case 10:
751 tmp |= 0x20;
752 break;
753 case 11:
754 tmp |= 0x28;
755 break;
756 default:
757 printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
758 return 0;
759 }
760
761 switch (hw_config->io_base)
762 {
763 case 0x300:
764 tmp |= 0x01;
765 break;
766 case 0x310:
767 tmp |= 0x03;
768 break;
769 case 0x320:
770 tmp |= 0x05;
771 break;
772 case 0x330:
773 tmp |= 0x07;
774 break;
775 default:
776 printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
777 return 0;
778 }
779
780 mad_write(MC8_PORT, tmp); /* write MPU port parameters */
781 goto probe_401;
782#endif
783 }
784 tmp = mad_read(MC6_PORT) & 0x83;
785 tmp |= 0x80; /* MPU-401 enable */
786
787 /* Set the MPU base bits */
788
789 switch (hw_config->io_base)
790 {
791 case 0x300:
792 tmp |= 0x60;
793 break;
794 case 0x310:
795 tmp |= 0x40;
796 break;
797 case 0x320:
798 tmp |= 0x20;
799 break;
800 case 0x330:
801 tmp |= 0x00;
802 break;
803 default:
804 printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
805 return 0;
806 }
807
808 /* Set the MPU IRQ bits */
809
810 switch (hw_config->irq)
811 {
812 case 5:
813 tmp |= 0x10;
814 break;
815 case 7:
816 tmp |= 0x18;
817 break;
818 case 9:
819 tmp |= 0x00;
820 break;
821 case 10:
822 tmp |= 0x08;
823 break;
824 default:
825 printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
826 break;
827 }
828
829 mad_write(MC6_PORT, tmp); /* Write MPU401 config */
830
831#ifndef CONFIG_MAD16_OLDCARD
832probe_401:
833#endif
834 hw_config->driver_use_1 = SB_MIDI_ONLY;
835 hw_config->name = "Mad16/Mozart";
836 return probe_uart401(hw_config, THIS_MODULE);
837}
838
839static void __exit unload_mad16(struct address_info *hw_config)
840{
841 ad1848_unload(hw_config->io_base + 4,
842 hw_config->irq,
843 hw_config->dma,
844 hw_config->dma2, 0);
845 release_region(hw_config->io_base, 4);
846 sound_unload_audiodev(hw_config->slots[0]);
847}
848
849static void __exit unload_mad16_mpu(struct address_info *hw_config)
850{
851#ifdef CONFIG_MAD16_OLDCARD
852 if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */
853 {
854 sb_dsp_unload(hw_config, 0);
855 return;
856 }
857#endif
858
859 unload_uart401(hw_config);
860}
861
862static struct address_info cfg;
863static struct address_info cfg_mpu;
864
865static int found_mpu;
866
867static int __initdata mpu_io = 0;
868static int __initdata mpu_irq = 0;
869static int __initdata io = -1;
870static int __initdata dma = -1;
871static int __initdata dma16 = -1; /* Set this for modules that need it */
872static int __initdata irq = -1;
873static int __initdata cdtype = 0;
874static int __initdata cdirq = 0;
875static int __initdata cdport = 0x340;
876static int __initdata cddma = -1;
877static int __initdata opl4 = 0;
878static int __initdata joystick = 0;
879
880module_param(mpu_io, int, 0);
881module_param(mpu_irq, int, 0);
882module_param(io, int, 0);
883module_param(dma, int, 0);
884module_param(dma16, int, 0);
885module_param(irq, int, 0);
886module_param(cdtype, int, 0);
887module_param(cdirq, int, 0);
888module_param(cdport, int, 0);
889module_param(cddma, int, 0);
890module_param(opl4, int, 0);
891module_param(joystick, bool, 0);
892module_param(debug, bool, 0644);
893
894static int __initdata dma_map[2][8] =
895{
896 {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},
897 {0x03, -1, 0x01, 0x00, -1, -1, -1, -1}
898};
899
900static int __initdata irq_map[16] =
901{
902 0x00, -1, -1, 0x0A,
903 -1, 0x04, -1, 0x08,
904 -1, 0x10, 0x14, 0x18,
905 -1, -1, -1, -1
906};
907
Dmitry Torokhove6084602005-06-01 02:38:46 -0500908#ifdef SUPPORT_JOYSTICK
909
910static struct gameport *gameport;
911
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912static int __devinit mad16_register_gameport(int io_port)
913{
914 if (!request_region(io_port, 1, "mad16 gameport")) {
915 printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port);
916 return -EBUSY;
917 }
918
919 gameport = gameport_allocate_port();
920 if (!gameport) {
921 printk(KERN_ERR "mad16: can not allocate memory for gameport\n");
922 release_region(io_port, 1);
923 return -ENOMEM;
924 }
925
926 gameport_set_name(gameport, "MAD16 Gameport");
927 gameport_set_phys(gameport, "isa%04x/gameport0", io_port);
928 gameport->io = io_port;
929
930 gameport_register_port(gameport);
931
932 return 0;
933}
934
Dmitry Torokhove6084602005-06-01 02:38:46 -0500935static inline void mad16_unregister_gameport(void)
936{
937 if (gameport) {
938 /* the gameport was initialized so we must free it up */
939 gameport_unregister_port(gameport);
940 gameport = NULL;
941 release_region(0x201, 1);
942 }
943}
944#else
945static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
946static inline void mad16_unregister_gameport(void) { }
947#endif
948
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949static int __devinit init_mad16(void)
950{
951 int dmatype = 0;
952
953 printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
954
955 printk(KERN_INFO "CDROM ");
956 switch (cdtype)
957 {
958 case 0x00:
959 printk("Disabled");
960 cdirq = 0;
961 break;
962 case 0x02:
963 printk("Sony CDU31A");
964 dmatype = 1;
965 if(cddma == -1) cddma = 3;
966 break;
967 case 0x04:
968 printk("Mitsumi");
969 dmatype = 0;
970 if(cddma == -1) cddma = 5;
971 break;
972 case 0x06:
973 printk("Panasonic Lasermate");
974 dmatype = 1;
975 if(cddma == -1) cddma = 3;
976 break;
977 case 0x08:
978 printk("Secondary IDE");
979 dmatype = 0;
980 if(cddma == -1) cddma = 5;
981 break;
982 case 0x0A:
983 printk("Primary IDE");
984 dmatype = 0;
985 if(cddma == -1) cddma = 5;
986 break;
987 default:
988 printk("\n");
989 printk(KERN_ERR "Invalid CDROM type\n");
990 return -EINVAL;
991 }
992
993 /*
994 * Build the config words
995 */
996
997 mad16_conf = (joystick ^ 1) | cdtype;
998 mad16_cdsel = 0;
999 if (opl4)
1000 mad16_cdsel |= 0x20;
1001
1002 if(cdtype){
1003 if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)
1004 {
1005 printk("\n");
1006 printk(KERN_ERR "Invalid CDROM DMA\n");
1007 return -EINVAL;
1008 }
1009 if (cddma)
1010 printk(", DMA %d", cddma);
1011 else
1012 printk(", no DMA");
1013
1014 if (!cdirq)
1015 printk(", no IRQ");
1016 else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)
1017 {
1018 printk(", invalid IRQ (disabling)");
1019 cdirq = 0;
1020 }
1021 else printk(", IRQ %d", cdirq);
1022
1023 mad16_cdsel |= dma_map[dmatype][cddma];
1024
1025 if (cdtype < 0x08)
1026 {
1027 switch (cdport)
1028 {
1029 case 0x340:
1030 mad16_cdsel |= 0x00;
1031 break;
1032 case 0x330:
1033 mad16_cdsel |= 0x40;
1034 break;
1035 case 0x360:
1036 mad16_cdsel |= 0x80;
1037 break;
1038 case 0x320:
1039 mad16_cdsel |= 0xC0;
1040 break;
1041 default:
1042 printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);
1043 return -EINVAL;
1044 }
1045 }
1046 mad16_cdsel |= irq_map[cdirq];
1047 }
1048
1049 printk(".\n");
1050
1051 cfg.io_base = io;
1052 cfg.irq = irq;
1053 cfg.dma = dma;
1054 cfg.dma2 = dma16;
1055
1056 if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
1057 printk(KERN_ERR "I/O, DMA and irq are mandatory\n");
1058 return -EINVAL;
1059 }
1060
1061 if (!request_region(MC0_PORT, 12, "mad16"))
1062 return -EBUSY;
1063
1064 if (!probe_mad16(&cfg)) {
1065 release_region(MC0_PORT, 12);
1066 return -ENODEV;
1067 }
1068
1069 cfg_mpu.io_base = mpu_io;
1070 cfg_mpu.irq = mpu_irq;
1071
1072 found_mpu = probe_mad16_mpu(&cfg_mpu);
1073
1074 if (joystick)
1075 mad16_register_gameport(0x201);
1076
1077 return 0;
1078}
1079
1080static void __exit cleanup_mad16(void)
1081{
1082 if (found_mpu)
1083 unload_mad16_mpu(&cfg_mpu);
Dmitry Torokhove6084602005-06-01 02:38:46 -05001084 mad16_unregister_gameport();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 unload_mad16(&cfg);
1086 release_region(MC0_PORT, 12);
1087}
1088
1089module_init(init_mad16);
1090module_exit(cleanup_mad16);
1091
1092#ifndef MODULE
1093static int __init setup_mad16(char *str)
1094{
1095 /* io, irq */
1096 int ints[8];
1097
1098 str = get_options(str, ARRAY_SIZE(ints), ints);
1099
1100 io = ints[1];
1101 irq = ints[2];
1102 dma = ints[3];
1103 dma16 = ints[4];
1104 mpu_io = ints[5];
1105 mpu_irq = ints[6];
1106 joystick = ints[7];
1107
1108 return 1;
1109}
1110
1111__setup("mad16=", setup_mad16);
1112#endif
1113MODULE_LICENSE("GPL");