patch-2.0.1 linux/drivers/sound/pas2_mixer.c

Next file: linux/drivers/sound/pas2_pcm.c
Previous file: linux/drivers/sound/pas2_midi.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.0/linux/drivers/sound/pas2_mixer.c linux/drivers/sound/pas2_mixer.c
@@ -5,43 +5,21 @@
  *
  * Mixer routines for the Pro Audio Spectrum cards.
  */
-/*
- * Copyright by Hannu Savolainen 1993-1996
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
+   
 #include <linux/config.h>
 
-
 #include "sound_config.h"
 
 #if defined(CONFIG_PAS)
 
-#include "pas.h"
-
-#define TRACE(what)		/* (what) */
+#ifndef DEB
+#define DEB(what)		/* (what) */
+#endif
 
 extern int      translat_code;
 extern char     pas_model;
 extern int     *pas_osp;
+extern int      pas_audiodev;
 
 static int      rec_devices = (SOUND_MASK_MIC);		/* Default recording source */
 static int      mode_control = 0;
@@ -51,8 +29,8 @@
 
 #define SUPPORTED_MIXER_DEVICES		(SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
 					 SOUND_MASK_CD | SOUND_MASK_ALTPCM | SOUND_MASK_IMIX | \
-					 SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | \
-					 SOUND_MASK_MUTE | SOUND_MASK_ENHANCE | SOUND_MASK_LOUD)
+					 SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV)
+
 
 static unsigned short levels[SOUND_MIXER_NRDEVICES] =
 {
@@ -81,7 +59,7 @@
    * sequence problem.
    */
 
-  if (pas_model == PAS_16D)
+  if (pas_model == 4)
     {
       outw (data | (data << 8), (ioaddr ^ translat_code) - 1);
       outb (0x80, 0);
@@ -98,7 +76,7 @@
   int             right = right_vol * div / 100;
 
 
-  if (bits & P_M_MV508_MIXER)
+  if (bits & 0x10)
     {				/*
 				 * Select input or output mixer
 				 */
@@ -106,20 +84,20 @@
       right |= mixer;
     }
 
-  if (bits == P_M_MV508_BASS || bits == P_M_MV508_TREBLE)
+  if (bits == 0x03 || bits == 0x04)
     {				/*
 				 * Bass and treble are mono devices
 				 */
-      mix_write (P_M_MV508_ADDRESS | bits, PARALLEL_MIXER);
-      mix_write (left, PARALLEL_MIXER);
+      mix_write (0x80 | bits, 0x078B);
+      mix_write (left, 0x078B);
       right_vol = left_vol;
     }
   else
     {
-      mix_write (P_M_MV508_ADDRESS | P_M_MV508_LEFT | bits, PARALLEL_MIXER);
-      mix_write (left, PARALLEL_MIXER);
-      mix_write (P_M_MV508_ADDRESS | P_M_MV508_RIGHT | bits, PARALLEL_MIXER);
-      mix_write (right, PARALLEL_MIXER);
+      mix_write (0x80 | 0x20 | bits, 0x078B);
+      mix_write (left, 0x078B);
+      mix_write (0x80 | 0x40 | bits, 0x078B);
+      mix_write (right, 0x078B);
     }
 
   return (left_vol | (right_vol << 8));
@@ -128,8 +106,8 @@
 void
 set_mode (int new_mode)
 {
-  mix_write (P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
-  mix_write (new_mode, PARALLEL_MIXER);
+  mix_write (0x80 | 0x05, 0x078B);
+  mix_write (new_mode, 0x078B);
 
   mode_control = new_mode;
 }
@@ -139,21 +117,21 @@
 {
   int             left, right, devmask, changed, i, mixer = 0;
 
-  TRACE (printk ("static int pas_mixer_set(int whichDev = %d, unsigned int level = %X)\n", whichDev, level));
+  DEB (printk ("static int pas_mixer_set(int whichDev = %d, unsigned int level = %X)\n", whichDev, level));
 
   left = level & 0x7f;
   right = (level & 0x7f00) >> 8;
 
   if (whichDev < SOUND_MIXER_NRDEVICES)
     if ((1 << whichDev) & rec_devices)
-      mixer = P_M_MV508_INPUTMIX;
+      mixer = 0x20;
     else
-      mixer = P_M_MV508_OUTPUTMIX;
+      mixer = 0x00;
 
   switch (whichDev)
     {
     case SOUND_MIXER_VOLUME:	/* Master volume (0-63) */
-      levels[whichDev] = mixer_output (right, left, 63, P_M_MV508_MASTER_A, 0);
+      levels[whichDev] = mixer_output (right, left, 63, 0x01, 0);
       break;
 
       /*
@@ -161,67 +139,41 @@
        * channel.
        */
     case SOUND_MIXER_BASS:	/* Bass (0-12) */
-      levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_BASS, 0);
+      levels[whichDev] = mixer_output (right, left, 12, 0x03, 0);
       break;
     case SOUND_MIXER_TREBLE:	/* Treble (0-12) */
-      levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_TREBLE, 0);
+      levels[whichDev] = mixer_output (right, left, 12, 0x04, 0);
       break;
 
     case SOUND_MIXER_SYNTH:	/* Internal synthesizer (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_FM, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x00, mixer);
       break;
     case SOUND_MIXER_PCM:	/* PAS PCM (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_PCM, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x05, mixer);
       break;
     case SOUND_MIXER_ALTPCM:	/* SB PCM (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SB, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x07, mixer);
       break;
     case SOUND_MIXER_SPEAKER:	/* PC speaker (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SPEAKER, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x06, mixer);
       break;
     case SOUND_MIXER_LINE:	/* External line (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_LINE, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x02, mixer);
       break;
     case SOUND_MIXER_CD:	/* CD (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_CDROM, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x03, mixer);
       break;
     case SOUND_MIXER_MIC:	/* External microphone (0-31) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_MIC, mixer);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x04, mixer);
       break;
     case SOUND_MIXER_IMIX:	/* Recording monitor (0-31) (Output mixer only) */
-      levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_IMIXER,
-				       P_M_MV508_OUTPUTMIX);
+      levels[whichDev] = mixer_output (right, left, 31, 0x10 | 0x01,
+				       0x00);
       break;
     case SOUND_MIXER_RECLEV:	/* Recording level (0-15) */
-      levels[whichDev] = mixer_output (right, left, 15, P_M_MV508_MASTER_B, 0);
+      levels[whichDev] = mixer_output (right, left, 15, 0x02, 0);
       break;
 
-    case SOUND_MIXER_MUTE:
-      return 0;
-      break;
-
-    case SOUND_MIXER_ENHANCE:
-      i = 0;
-      level &= 0x7f;
-      if (level)
-	i = (level / 20) - 1;
-
-      mode_control &= ~P_M_MV508_ENHANCE_BITS;
-      mode_control |= P_M_MV508_ENHANCE_BITS;
-      set_mode (mode_control);
-
-      if (i)
-	i = (i + 1) * 20;
-      return i;
-      break;
-
-    case SOUND_MIXER_LOUD:
-      mode_control &= ~P_M_MV508_LOUDNESS;
-      if (level)
-	mode_control |= P_M_MV508_LOUDNESS;
-      set_mode (mode_control);
-      return !!level;		/* 0 or 1 */
-      break;
 
     case SOUND_MIXER_RECSRC:
       devmask = level & POSSIBLE_RECORDING_DEVICES;
@@ -238,7 +190,7 @@
       break;
 
     default:
-      return -EINVAL;
+      return -(EINVAL);
     }
 
   return (levels[whichDev]);
@@ -251,18 +203,92 @@
 {
   int             foo;
 
-  TRACE (printk ("pas2_mixer.c: void pas_mixer_reset(void)\n"));
+  DEB (printk ("pas2_mixer.c: void pas_mixer_reset(void)\n"));
 
   for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
     pas_mixer_set (foo, levels[foo]);
 
-  set_mode (P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_40);
+  set_mode (0x04 | 0x01);
 }
 
 int
 pas_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
 {
-  TRACE (printk ("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
+  DEB (printk ("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
+
+  if (cmd == SOUND_MIXER_PRIVATE1)	/* Set loudness bit */
+    {
+      int             level = get_fs_long ((long *) arg);
+
+      if (level == -1)		/* Return current settings */
+	{
+	  if (mode_control & 0x04)
+	    return snd_ioctl_return ((int *) arg, 1);
+	  else
+	    return snd_ioctl_return ((int *) arg, 0);
+	}
+      else
+	{
+	  mode_control &= ~0x04;
+	  if (level)
+	    mode_control |= 0x04;
+	  set_mode (mode_control);
+	  return snd_ioctl_return ((int *) arg, !!level);	/* 0 or 1 */
+	}
+    }
+
+
+  if (cmd == SOUND_MIXER_PRIVATE2)	/* Set enhance bit */
+    {
+      int             level = get_fs_long ((long *) arg);
+
+      if (level == -1)		/* Return current settings */
+	{
+	  if (!(mode_control & 0x03))
+	    return snd_ioctl_return ((int *) arg, 0);
+	  return snd_ioctl_return ((int *) arg, ((mode_control & 0x03) + 1) * 20);
+	}
+      else
+	{
+	  int             i = 0;
+
+	  level &= 0x7f;
+	  if (level)
+	    i = (level / 20) - 1;
+
+	  mode_control &= ~0x03;
+	  mode_control |= i & 0x03;
+	  set_mode (mode_control);
+
+	  if (i)
+	    i = (i + 1) * 20;
+
+	  return i;
+	}
+    }
+
+  if (cmd == SOUND_MIXER_PRIVATE3)	/* Set mute bit */
+    {
+      int             level = get_fs_long ((long *) arg);
+
+      if (level == -1)		/* Return current settings */
+	{
+	  return snd_ioctl_return ((int *) arg,
+				   !(pas_read (0x0B8A) &
+				     0x20));
+	}
+      else
+	{
+	  if (level)
+	    pas_write (pas_read (0x0B8A) & (~0x20),
+		       0x0B8A);
+	  else
+	    pas_write (pas_read (0x0B8A) | 0x20,
+		       0x0B8A);
+
+	  return !(pas_read (0x0B8A) & 0x20);
+	}
+    }
 
   if (((cmd >> 8) & 0xff) == 'M')
     {
@@ -270,7 +296,7 @@
 	return snd_ioctl_return ((int *) arg, pas_mixer_set (cmd & 0xff, get_fs_long ((long *) arg)));
       else
 	{			/*
-				   * Read parameters
+				 * Read parameters
 				 */
 
 	  switch (cmd & 0xff)
@@ -296,32 +322,18 @@
 	      return snd_ioctl_return ((int *) arg, 0);		/* No special capabilities */
 	      break;
 
-	    case SOUND_MIXER_MUTE:
-	      return snd_ioctl_return ((int *) arg, 0);		/* No mute yet */
-	      break;
-
-	    case SOUND_MIXER_ENHANCE:
-	      if (!(mode_control & P_M_MV508_ENHANCE_BITS))
-		return snd_ioctl_return ((int *) arg, 0);
-	      return snd_ioctl_return ((int *) arg, ((mode_control & P_M_MV508_ENHANCE_BITS) + 1) * 20);
-	      break;
-
-	    case SOUND_MIXER_LOUD:
-	      if (mode_control & P_M_MV508_LOUDNESS)
-		return snd_ioctl_return ((int *) arg, 1);
-	      return snd_ioctl_return ((int *) arg, 0);
-	      break;
 
 	    default:
 	      return snd_ioctl_return ((int *) arg, levels[cmd & 0xff]);
 	    }
 	}
     }
-  return -EINVAL;
+  return -(EINVAL);
 }
 
 static struct mixer_operations pas_mixer_operations =
 {
+  "PAS16",
   "Pro Audio Spectrum 16",
   pas_mixer_ioctl
 };
@@ -332,7 +344,10 @@
   pas_mixer_reset ();
 
   if (num_mixers < MAX_MIXER_DEV)
-    mixer_devs[num_mixers++] = &pas_mixer_operations;
+    {
+      audio_devs[pas_audiodev]->mixer_dev = num_mixers;
+      mixer_devs[num_mixers++] = &pas_mixer_operations;
+    }
   return 1;
 }
 

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