patch-2.1.6 linux/drivers/sound/mad16.c

Next file: linux/drivers/sound/maui.c
Previous file: linux/drivers/sound/lowlevel/lowlevel.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.5/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) by Hannu Savolainen 1993-1996
  *
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
  * Version 2 (June 1991). See the "COPYING" file distributed with this software
  * for more info.
  */
@@ -16,6 +16,7 @@
  *      OAK OTI-601D    Mozart
  *      OPTi 82C929     MAD16 Pro
  *      OPTi 82C930
+ *      OPTi 82C924     (in non PnP mode)
  *
  * These audio interface chips don't produce sound themselves. They just
  * connect some other components (OPL-[234] and a WSS compatible codec)
@@ -47,7 +48,7 @@
  *
  *      CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320
  *      OPL4 select: 0x20=OPL4, 0x00=OPL3
- *      CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3, 0x10=IRQ9,
+ *      CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0c=IRQ3, 0x10=IRQ9,
  *                  0x14=IRQ10 and 0x18=IRQ11.
  *
  *      CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or 0x03=disabled
@@ -69,6 +70,7 @@
 #define MOZART	2
 #define C929	3
 #define C930	4
+#define C924    5
 
 /*
  *    Registers
@@ -118,21 +120,25 @@
     {
     case C928:
     case MOZART:
-      outb (0xE2, PASSWD_REG);
+      outb ((0xE2), PASSWD_REG);
       break;
 
     case C929:
-      outb (0xE3, PASSWD_REG);
+      outb ((0xE3), PASSWD_REG);
       break;
 
     case C930:
-      /* outb( 0xE4,  PASSWD_REG); */
+      /* outb(( 0xE4),  PASSWD_REG); */
+      break;
+
+    case C924:
+      outb ((0xE5), PASSWD_REG);
       break;
     }
 
   if (board_type == C930)
     {
-      outb (port - MC0_PORT, 0xe0e);	/* Write to index reg */
+      outb ((port - MC0_PORT), 0xe0e);	/* Write to index reg */
       tmp = inb (0xe0f);	/* Read from data reg */
     }
   else
@@ -154,25 +160,29 @@
     {
     case C928:
     case MOZART:
-      outb (0xE2, PASSWD_REG);
+      outb ((0xE2), PASSWD_REG);
       break;
 
     case C929:
-      outb (0xE3, PASSWD_REG);
+      outb ((0xE3), PASSWD_REG);
       break;
 
     case C930:
-      /* outb( 0xE4,  PASSWD_REG); */
+      /* outb(( 0xE4),  PASSWD_REG); */
+      break;
+
+    case C924:
+      outb ((0xE5), PASSWD_REG);
       break;
     }
 
   if (board_type == C930)
     {
-      outb (port - MC0_PORT, 0xe0e);	/* Write to index reg */
-      outb ((unsigned char) (value & 0xff), 0xe0f);
+      outb ((port - MC0_PORT), 0xe0e);	/* Write to index reg */
+      outb (((unsigned char) (value & 0xff)), 0xe0f);
     }
   else
-    outb ((unsigned char) (value & 0xff), port);
+    outb (((unsigned char) (value & 0xff)), port);
   restore_flags (flags);
 }
 
@@ -354,107 +364,116 @@
   /* MC2 is CD configuration. Don't touch it. */
 
   mad_write (MC3_PORT, 0);	/* Disable SB mode IRQ and DMA */
-
   mad_write (MC4_PORT, 0x52);	/* ??? */
-  mad_write (MC5_PORT, 0x3D);	/* Init it into mode2 */
+  mad_write (MC5_PORT, 0x3C);	/* Init it into mode2 */
   mad_write (MC6_PORT, 0x02);	/* Enable WSS, Disable MPU and SB */
   mad_write (MC7_PORT, 0xCB);
   mad_write (MC10_PORT, 0x11);
 
-  if (!wss_init (hw_config))
-    return 0;
-
-/*
- * A temporary kludge which drops the device back to mode1.
- * This removes problems with interrupts but disables full duplex.
- * A better solution should be introduced later.
- */
-  mad_write (MC5_PORT, 0x1D);	/* Disable mode2 */
   return wss_init (hw_config);
 }
 
-int
-probe_mad16 (struct address_info *hw_config)
+static int
+chip_detect (void)
 {
   int             i;
-  static int      valid_ports[] =
-  {0x530, 0xe80, 0xf40, 0x604};
-  unsigned char   tmp;
-  unsigned char   cs4231_mode = 0;
-
-  int             ad_flags = 0;
-
-  if (already_initialized)
-    return 0;
-
-  mad16_osp = hw_config->osp;
-/*
- *    Check that all ports return 0xff (bus float) when no password
- *      is written to the password register.
- */
-
-  DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
-
 
 /*
  *    Then try to detect with the old password
  */
-  board_type = C928;
+  board_type = C924;
 
-  DDB (printk ("Detect using password = 0xE2\n"));
+  DDB (printk ("Detect using password = 0xE5\n"));
 
   if (!detect_mad16 ())		/* No luck. Try different model */
     {
-      board_type = C929;
+      board_type = C928;
 
-      DDB (printk ("Detect using password = 0xE3\n"));
+      DDB (printk ("Detect using password = 0xE2\n"));
 
       if (!detect_mad16 ())
 	{
-	  if (inb (PASSWD_REG) != 0xff)
-	    return 0;
+	  board_type = C929;
+
+	  DDB (printk ("Detect using password = 0xE3\n"));
+
+	  if (!detect_mad16 ())
+	    {
+	      if (inb (PASSWD_REG) != 0xff)
+		return 0;
 
 /*
  * First relocate MC# registers to 0xe0e/0xe0f, disable password 
  */
 
-	  outb (0xE4, PASSWD_REG);
-	  outb (0x80, PASSWD_REG);
+	      outb ((0xE4), PASSWD_REG);
+	      outb ((0x80), PASSWD_REG);
 
-	  board_type = C930;
+	      board_type = C930;
 
-	  DDB (printk ("Detect using password = 0xE4\n"));
+	      DDB (printk ("Detect using password = 0xE4\n"));
 
-	  for (i = 0xf8d; i <= 0xf93; i++)
-	    DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
+	      for (i = 0xf8d; i <= 0xf93; i++)
+		DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
 
-	  if (!detect_mad16 ())
-	    return 0;
+	      if (!detect_mad16 ())
+		return 0;
 
-	  DDB (printk ("mad16.c: 82C930 detected\n"));
-	  return init_c930 (hw_config);
+	      DDB (printk ("mad16.c: 82C930 detected\n"));
+	    }
+	  else
+	    {
+	      DDB (printk ("mad16.c: 82C929 detected\n"));
+	    }
 	}
       else
 	{
-	  DDB (printk ("mad16.c: 82C929 detected\n"));
-	}
-    }
-  else
-    {
-      unsigned char   model;
+	  unsigned char   model;
 
-      if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
-	{
-	  DDB (printk ("mad16.c: Mozart detected\n"));
-	  board_type = MOZART;
-	}
-      else
-	{
-	  DDB (printk ("mad16.c: 82C928 detected???\n"));
-	  board_type = C928;
+	  if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
+	    {
+	      DDB (printk ("mad16.c: Mozart detected\n"));
+	      board_type = MOZART;
+	    }
+	  else
+	    {
+	      DDB (printk ("mad16.c: 82C928 detected???\n"));
+	      board_type = C928;
+	    }
 	}
     }
 
+  return 1;
+}
+
+int
+probe_mad16 (struct address_info *hw_config)
+{
+  int             i;
+  static int      valid_ports[] =
+  {0x530, 0xe80, 0xf40, 0x604};
+  unsigned char   tmp;
+  unsigned char   cs4231_mode = 0;
+
+  int             ad_flags = 0;
+
+  if (already_initialized)
+    return 0;
+
+  mad16_osp = hw_config->osp;
+/*
+ *    Check that all ports return 0xff (bus float) when no password
+ *      is written to the password register.
+ */
+
+  DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
+  if (!chip_detect ())
+    return 0;
+
+  if (board_type == C930)
+    return init_c930 (hw_config);
+
+
   for (i = 0xf8d; i <= 0xf93; i++)
     DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
 
@@ -462,7 +481,7 @@
  * Set the WSS address
  */
 
-  tmp = 0x80;			/* Enable WSS, Disable SB */
+  tmp = (mad_read (MC1_PORT) & 0x0f) | 0x80;	/* Enable WSS, Disable SB */
 
   for (i = 0; i < 5; i++)
     {
@@ -484,6 +503,7 @@
  */
 
 #ifdef MAD16_CONF
+  tmp &= ~0x0f;
   tmp |= ((MAD16_CONF) & 0x0f);	/* CD-ROM and joystick bits */
 #endif
   mad_write (MC1_PORT, tmp);
@@ -491,7 +511,7 @@
 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
   tmp = MAD16_CDSEL;
 #else
-  tmp = 0x03;
+  tmp = mad_read (MC2_PORT);
 #endif
 
 #ifdef MAD16_OPL4
@@ -501,6 +521,13 @@
   mad_write (MC2_PORT, tmp);
   mad_write (MC3_PORT, 0xf0);	/* Disable SB */
 
+  if (board_type == C924)	/* Specific C924 init values */
+    {
+      mad_write (MC4_PORT, 0xA0);
+      mad_write (MC5_PORT, 0x05);
+      mad_write (MC6_PORT, 0x03);
+    }
+
   if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
     return 0;
 
@@ -554,12 +581,14 @@
   /*
      * Set the IRQ and DMA addresses.
    */
+  if (board_type == C930)
+    interrupt_bits[5] = 0x28;	/* Also IRQ5 is possible on C930 */
 
   bits = interrupt_bits[hw_config->irq];
   if (bits == -1)
     return;
 
-  outb (bits | 0x40, config_port);
+  outb ((bits | 0x40), config_port);
   if ((inb (version_port) & 0x40) == 0)
     printk ("[IRQ Conflict?]");
 
@@ -594,7 +623,7 @@
   else
     dma2 = dma;
 
-  outb (bits | dma_bits[dma] | dma2_bit, config_port);	/* Write IRQ+DMA setup */
+  outb ((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */
 
   ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
 	       hw_config->irq,
@@ -766,10 +795,12 @@
     }
 #endif
 
-#if (defined(CONFIG_UART401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
+#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
   unload_uart401 (hw_config);
 #endif
 }
+
+
 
 /* That's all folks */
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov