~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/sound/mad16.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.