patch-2.1.115 linux/drivers/sbus/audio/cs4231.c

Next file: linux/drivers/sbus/audio/cs4231.h
Previous file: linux/drivers/sbus/audio/audio.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.114/linux/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
@@ -1,5 +1,5 @@
 /*
- * Drivers/sbus/audio/cs4231.c
+ * drivers/sbus/audio/cs4231.c
  *
  * Copyright (C) 1996, 1997 Derrick J Brashear (shadow@andrew.cmu.edu)
  *
@@ -27,19 +27,12 @@
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/io.h>
+#include <asm/pgtable.h>
 #include <asm/sbus.h>
 
 #include <asm/audioio.h>
 #include "cs4231.h"
 
-/* Stolen for now from compat.h */
-#ifndef MAX                             /* Usually found in <sys/param.h>. */
-#define MAX(_a,_b)      ((_a)<(_b)?(_b):(_a))
-#endif
-#ifndef MIN                             /* Usually found in <sys/param.h>. */
-#define MIN(_a,_b)      ((_a)<(_b)?(_a):(_b))
-#endif
-
 #undef __CS4231_DEBUG
 #undef __CS4231_TRACE
 #undef __CS4231_ERROR
@@ -63,15 +56,19 @@
 static struct sparcaudio_driver drivers[MAX_DRIVERS];
 static int num_drivers;
 
-static int cs4231_record_gain(struct sparcaudio_driver *drv, int value, unsigned char balance);
-static int cs4231_play_gain(struct sparcaudio_driver *drv, int value, unsigned char balance);
+static int cs4231_record_gain(struct sparcaudio_driver *drv, int value, 
+                              unsigned char balance);
+static int cs4231_play_gain(struct sparcaudio_driver *drv, int value, 
+                            unsigned char balance);
 static void cs4231_ready(struct sparcaudio_driver *drv);
 static void cs4231_playintr(struct sparcaudio_driver *drv);
 static int cs4231_recintr(struct sparcaudio_driver *drv);
 static int cs4231_output_muted(struct sparcaudio_driver *drv, int value);
 static void cs4231_pollinput(struct sparcaudio_driver *drv);
-static int cs4231_length_to_samplecount(struct audio_prinfo *thisdir, unsigned int length);
-static void cs4231_getsamplecount(struct sparcaudio_driver *drv, unsigned int length, unsigned int value);
+static int cs4231_length_to_samplecount(struct audio_prinfo *thisdir, 
+                                        unsigned int length);
+static void cs4231_getsamplecount(struct sparcaudio_driver *drv, 
+                                  unsigned int length, unsigned int value);
 
 #define CHIP_READY udelay(100); cs4231_ready(drv); mdelay(1);
 
@@ -520,6 +517,8 @@
 static int cs4231_get_input_ports(struct sparcaudio_driver *drv)
 {
   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+
+  /* This apparently applies only to APC ultras, not ebus ultras */
   if (cs4231_chip->status & CS_STATUS_IS_ULTRA)
     return (AUDIO_LINE_IN | AUDIO_MICROPHONE | AUDIO_ANALOG_LOOPBACK);
   else
@@ -586,6 +585,7 @@
    */
 
   /* Ultra systems do not support AUDIO_INTERNAL_CD_IN */
+  /* This apparently applies only to APC ultras, not ebus ultras */
   if (!cs4231_chip->status & CS_STATUS_IS_ULTRA) {
     if (value & AUDIO_INTERNAL_CD_IN) {
       cs4231_chip->regs->iar = 0x1;
@@ -637,7 +637,8 @@
   /* This interpolation really sucks. The question is, be compatible 
    * with ScumOS/Sloaris or not?
    */
-  a = CS4231_MON_MAX_ATEN - (value * (CS4231_MON_MAX_ATEN + 1) / (AUDIO_MAX_GAIN + 1));
+  a = CS4231_MON_MAX_ATEN - (value * (CS4231_MON_MAX_ATEN + 1) / 
+                             (AUDIO_MAX_GAIN + 1));
 
   cs4231_chip->regs->iar = 0x0d;
   if (a >= CS4231_MON_MAX_ATEN) 
@@ -648,7 +649,9 @@
   if (value == AUDIO_MAX_GAIN) 
     cs4231_chip->perchip_info.monitor_gain = AUDIO_MAX_GAIN;
   else 
-    cs4231_chip->perchip_info.monitor_gain = ((CS4231_MAX_DEV_ATEN - a) * (AUDIO_MAX_GAIN + 1) / (CS4231_MAX_DEV_ATEN + 1));
+    cs4231_chip->perchip_info.monitor_gain = ((CS4231_MAX_DEV_ATEN - a) * 
+                                              (AUDIO_MAX_GAIN + 1) / 
+                                              (CS4231_MAX_DEV_ATEN + 1));
 
   return 0;
 }
@@ -666,7 +669,8 @@
 {
         struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
 
-	cs4231_record_gain(drv, value, cs4231_chip->perchip_info.record.balance);
+	cs4231_record_gain(drv, value, 
+                           cs4231_chip->perchip_info.record.balance);
 	
         return 0;
 }
@@ -700,7 +704,8 @@
         struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
 
 	cs4231_chip->perchip_info.record.balance = value;
-	cs4231_record_gain(drv, cs4231_chip->perchip_info.record.gain, cs4231_chip->perchip_info.record.balance);
+	cs4231_record_gain(drv, cs4231_chip->perchip_info.record.gain,
+                           cs4231_chip->perchip_info.record.balance);
 	
         return 0;
 }
@@ -717,7 +722,8 @@
         struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
 
 	cs4231_chip->perchip_info.play.balance = value;
-	cs4231_play_gain(drv, cs4231_chip->perchip_info.play.gain, cs4231_chip->perchip_info.play.balance);
+	cs4231_play_gain(drv, cs4231_chip->perchip_info.play.gain, 
+                         cs4231_chip->perchip_info.play.balance);
 	
         return 0;
 }
@@ -739,9 +745,13 @@
   r = l = value;
 
   if (balance < AUDIO_MID_BALANCE) {
-    r = MAX(0, (int)(value - ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT)));
+      r = (int)(value - ((AUDIO_MID_BALANCE - balance) 
+                         << AUDIO_BALANCE_SHIFT));
+      if (r < 0) r = 0;
   } else if (balance > AUDIO_MID_BALANCE) {
-    l = MAX(0, (int)(value - ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT)));
+      l = (int)(value - ((balance - AUDIO_MID_BALANCE) 
+                         << AUDIO_BALANCE_SHIFT));
+      if (l < 0) l = 0;
   }
 
   l_adj = l * (CS4231_MAX_GAIN + 1) / (AUDIO_MAX_GAIN + 1);
@@ -755,9 +765,11 @@
   cs4231_chip->regs->idr = RECGAIN_SET(old_gain, r_adj);
   
   if (l == value) {
-    (l == 0) ? (tmp = 0) : (tmp = ((l_adj + 1) * AUDIO_MAX_GAIN) / (CS4231_MAX_GAIN + 1));
+    (l == 0) ? (tmp = 0) : (tmp = ((l_adj + 1) * AUDIO_MAX_GAIN) / 
+                            (CS4231_MAX_GAIN + 1));
   } else if (r == value) {
-    (r == 0) ? (tmp = 0) : (tmp = ((r_adj + 1) * AUDIO_MAX_GAIN) / (CS4231_MAX_GAIN + 1));
+    (r == 0) ? (tmp = 0) : (tmp = ((r_adj + 1) * AUDIO_MAX_GAIN) / 
+                            (CS4231_MAX_GAIN + 1));
   }
   cs4231_chip->perchip_info.record.gain = tmp;
   return 0;
@@ -773,13 +785,21 @@
   tprintk(("in play_gain: %d %c\n", value, balance));
   r = l = value;
   if (balance < AUDIO_MID_BALANCE) {
-    r = MAX(0, (int)(value - ((AUDIO_MID_BALANCE - balance) << AUDIO_BALANCE_SHIFT)));
+      r = (int)(value - ((AUDIO_MID_BALANCE - balance)
+                         << AUDIO_BALANCE_SHIFT));
+      if (r < 0) r = 0;
   } else if (balance > AUDIO_MID_BALANCE) {
-    l = MAX(0, (int)(value - ((balance - AUDIO_MID_BALANCE) << AUDIO_BALANCE_SHIFT)));
+      l = (int)(value - ((balance - AUDIO_MID_BALANCE) 
+                         << AUDIO_BALANCE_SHIFT));
+      if (l < 0) l = 0;
   }
 
-  (l == 0) ? (l_adj = CS4231_MAX_DEV_ATEN) : (l_adj = CS4231_MAX_ATEN - (l * (CS4231_MAX_ATEN + 1) / (AUDIO_MAX_GAIN + 1)));
-  (r == 0) ? (r_adj = CS4231_MAX_DEV_ATEN) : (r_adj = CS4231_MAX_ATEN - (r * (CS4231_MAX_ATEN + 1) / (AUDIO_MAX_GAIN + 1)));
+  (l == 0) ? (l_adj = CS4231_MAX_DEV_ATEN) : (l_adj = CS4231_MAX_ATEN - 
+                                              (l * (CS4231_MAX_ATEN + 1) / 
+                                               (AUDIO_MAX_GAIN + 1)));
+  (r == 0) ? (r_adj = CS4231_MAX_DEV_ATEN) : (r_adj = CS4231_MAX_ATEN - 
+                                              (r * (CS4231_MAX_ATEN + 1) / 
+                                               (AUDIO_MAX_GAIN + 1)));
   
   cs4231_chip->regs->iar = 0x6;
   old_gain = cs4231_chip->regs->idr;
@@ -791,11 +811,12 @@
   if ((value == 0) || (value == AUDIO_MAX_GAIN)) {
     tmp = value;
   } else {
-    if (l == value) {
-      tmp = ((CS4231_MAX_ATEN - l_adj) * (AUDIO_MAX_GAIN + 1) / (CS4231_MAX_ATEN + 1));
-    } else if (r == value) {
-      tmp = ((CS4231_MAX_ATEN - r_adj) * (AUDIO_MAX_GAIN + 1) / (CS4231_MAX_ATEN + 1));
-    }
+    if (value == l) 
+      tmp = ((CS4231_MAX_ATEN - l_adj) * (AUDIO_MAX_GAIN + 1) / 
+             (CS4231_MAX_ATEN + 1));
+    else if (r == value) 
+      tmp = ((CS4231_MAX_ATEN - r_adj) * (AUDIO_MAX_GAIN + 1) / 
+             (CS4231_MAX_ATEN + 1));
   }
   cs4231_chip->perchip_info.play.gain = tmp;
 
@@ -969,7 +990,9 @@
   if (file->f_mode & FMODE_WRITE) 
       cs4231_chip->perchip_info.play.open = 0;
 
-  if (!cs4231_chip->perchip_info.play.open && !cs4231_chip->perchip_info.record.open && (cs4231_chip->status & CS_STATUS_INIT_ON_CLOSE)) {
+  if (!cs4231_chip->perchip_info.play.open && 
+      !cs4231_chip->perchip_info.record.open && 
+      (cs4231_chip->status & CS_STATUS_INIT_ON_CLOSE)) {
     cs4231_chip_reset(drv);
     cs4231_chip->status &= ~CS_STATUS_INIT_ON_CLOSE;
   }
@@ -984,12 +1007,25 @@
   if (cs4231_chip->playlen == 0)
     cs4231_chip->playlen = cs4231_chip->output_size;
 
+  if (cs4231_chip->output_dma_handle) {
+      mmu_release_scsi_one((char *)cs4231_chip->output_dma_handle, 
+                           4096, drv->dev->my_bus);
+      cs4231_chip->output_dma_handle = 0;
+  }
+  if (cs4231_chip->output_next_dma_handle) {
+      cs4231_chip->output_dma_handle = cs4231_chip->output_next_dma_handle;
+      cs4231_chip->output_next_dma_handle = 0;
+  }
+
   if (cs4231_chip->output_ptr && cs4231_chip->output_size > 0) {
-    cs4231_chip->regs->dmapnva = (__u32) cs4231_chip->output_ptr;
-    cs4231_chip->regs->dmapnc = cs4231_chip->output_size;
-    cs4231_chip->output_size = 0;
-    cs4231_chip->output_ptr = NULL;
-    cs4231_chip->playing_count++;
+      cs4231_chip->output_next_dma_handle = 
+          mmu_get_scsi_one((char *) cs4231_chip->output_ptr, 4096, 
+                           drv->dev->my_bus);
+      cs4231_chip->regs->dmapnva = cs4231_chip->output_next_dma_handle;
+      cs4231_chip->regs->dmapnc = cs4231_chip->output_size;
+      cs4231_chip->output_size = 0;
+      cs4231_chip->output_ptr = NULL;
+      cs4231_chip->playing_count++;
   }
 
   /* Get two buffers into the pipe, then chain... */
@@ -1037,14 +1073,16 @@
   return 1;
 }
 
-static void cs4231_start_output(struct sparcaudio_driver *drv, __u8 * buffer, unsigned long count)
+static void cs4231_start_output(struct sparcaudio_driver *drv, __u8 * buffer,
+                                unsigned long count)
 {
   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
 
   cs4231_chip->output_ptr = buffer;
   cs4231_chip->output_size = count;
 
-  if (cs4231_chip->perchip_info.play.active || (cs4231_chip->perchip_info.play.pause))
+  if (cs4231_chip->perchip_info.play.active || 
+      (cs4231_chip->perchip_info.play.pause))
     return;
 
   cs4231_ready(drv);
@@ -1058,7 +1096,7 @@
   cs4231_playintr(drv);
   cs4231_enable_play(drv);
   cs4231_chip->regs->dmacsr |= CS_PLAY_SETUP;
-  cs4231_output_muted(drv, 0);
+
   cs4231_ready(drv);
 }
 
@@ -1069,6 +1107,16 @@
   tprintk(("in cs4231_stop_output\n"));
   cs4231_chip->output_ptr = NULL;
   cs4231_chip->output_size = 0;
+  if (cs4231_chip->output_dma_handle) {
+      mmu_release_scsi_one((char *)cs4231_chip->output_dma_handle,
+                           4096, drv->dev->my_bus);
+      cs4231_chip->output_dma_handle = 0;
+  }
+  if (cs4231_chip->output_next_dma_handle) {
+      mmu_release_scsi_one((char *)cs4231_chip->output_next_dma_handle,
+                           4096, drv->dev->my_bus);
+      cs4231_chip->output_next_dma_handle = 0;
+  }
   cs4231_chip->perchip_info.play.active = 0;
   cs4231_chip->regs->dmacsr |= (CS_PPAUSE);
 }
@@ -1084,11 +1132,13 @@
   cs4231_chip->regs->dmacsr |= CS_XINT_CEMP;
 }
 
-static void cs4231_start_input(struct sparcaudio_driver *drv, __u8 * buffer, unsigned long count)
+static void cs4231_start_input(struct sparcaudio_driver *drv, __u8 * buffer, 
+                               unsigned long count)
 {
   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
 
-  if (cs4231_chip->perchip_info.record.active || (cs4231_chip->perchip_info.record.pause))
+  if (cs4231_chip->perchip_info.record.active || 
+      (cs4231_chip->perchip_info.record.pause))
     return;
 
   cs4231_ready(drv);
@@ -1124,6 +1174,7 @@
 
   strncpy(audinfo->name, "SUNW,CS4231", sizeof(audinfo->name) - 1);
   /* versions: SPARCstation 4/5=a, Ultra=b */
+  /* apparently Ultra 1, Ultra 2 don't have internal CD input */
   if (cs4231_chip->status & CS_STATUS_IS_ULTRA)
     strncpy(audinfo->version, "b", sizeof(audinfo->version) - 1);
   else
@@ -1189,6 +1240,7 @@
 				     cs4231_chip->playlen);
       cs4231_playintr(drv);
     }
+    /* Any other conditions we need worry about? */
   }
 
   if (dummy & CS_CAPT_INT) {
@@ -1198,16 +1250,18 @@
 				     cs4231_chip->reclen);
       cs4231_recintr(drv);
     }
+    /* Any other conditions we need worry about? */
   }
+
   if ((dummy & CS_XINT_CEMP) 
       && (cs4231_chip->perchip_info.record.active == 0)) 
     {
-      cs4231_chip->perchip_info.record.active = 0;
+        /* Fix me */
+        cs4231_chip->perchip_info.record.active = 0;
     }
   if ((dummy & CS_XINT_EMPT) && (cs4231_chip->perchip_info.play.active == 0)) {
     cs4231_chip->regs->dmacsr |= (CS_PPAUSE);
     cs4231_disable_play(drv);
-    cs4231_output_muted(drv, 1);
     
     cs4231_getsamplecount(drv, cs4231_chip->playlen, 0);
   }
@@ -1272,9 +1326,6 @@
   struct cs4231_chip *cs4231_chip;
   int err;
   struct linux_sbus *sbus = sdev->my_bus;
-#ifdef __sparc_v9__
-  struct devid_cookie dcookie;
-#endif
 
   /* Allocate our private information structure. */
   drv->private = kmalloc(sizeof(struct cs4231_chip), GFP_KERNEL);
@@ -1288,6 +1339,8 @@
   cs4231_chip->input_size = cs4231_chip->output_size = 0;
   cs4231_chip->status = 0;
 
+  drv->dev = sdev;
+
   /* Map the registers into memory. */
   prom_apply_sbus_ranges(sbus, sdev->reg_addrs, 1, sdev);
   cs4231_chip->regs_size = sdev->reg_addrs[0].reg_size;
@@ -1303,18 +1356,9 @@
   }
 
   /* Attach the interrupt handler to the audio interrupt. */
-  cs4231_chip->irq = sdev->irqs[0].pri;
+  cs4231_chip->irq = sdev->irqs[0];
 
-#ifndef __sparc_v9__
   request_irq(cs4231_chip->irq, cs4231_interrupt, SA_SHIRQ, "cs4231", drv);
-#else
-  dcookie.real_dev_id = drv;
-  dcookie.imap = dcookie.iclr = 0;
-  dcookie.pil = -1;
-  dcookie.bus_cookie = sdev->my_bus;
-  request_irq (cs4231_chip->irq, cs4231_interrupt, (SA_SHIRQ | SA_SBUS | SA_DCOOKIE), "cs4231", &dcookie);
-  cs4231_chip->irq = dcookie.ret_ino;
-#endif
   enable_irq(cs4231_chip->irq);
 
   cs4231_enable_interrupts(drv);

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