Commits

Adam Hoka committed ad50370 Merge

merge with upstream

Comments (0)

Files changed (50)

 80cfc369d9256107108d19f6f46a42b37b00b18e v4-2-build2000
 f794ffc6c18524a62f4e3b81011e590b30bc5183 v4.2-build2001
 21b607a0014a5135cde83d02f3048a616295048e v4.2-build2002
+372b5c3940ab0478aadc4c45fbf79af9ce9195a3 v4.2-2003
-2002
+2003

cmd/ossdevlinks/ossdevlinks.c

  * -v      Produce verbose output.
  * -r      Remove all pre-existing legacy devices and reset the device
  *         numbering (not recommended).
+ * -N      Don't modify links
  */
 #define COPYING Copyright (C) Hannu Savolainen and Dev Mazumdar 2006. All rights reserved.
 
 #else
   static char * legacydev_file = NULL;
 #endif
-static int err = 0, mixerfd = -1, recreate_all = 0, verbose = 0;
+static int err = 0, mixerfd = -1, recreate_all = 0, verbose = 0,
+           no_links = 0;
 
 static void create_dsplinks (void);
 static void create_mixerlinks (void);
 	}
     }
 
-  while ((c = getopt (argc, argv, "f:rv")) != EOF)
+  while ((c = getopt (argc, argv, "Nf:rv")) != EOF)
   switch (c)
     {
     case 'f':
     case 'v':
       verbose++;
       break;
+
+    case 'N':
+      no_links = 1;
+      break;
     }
 
-  create_dsplinks ();
-  create_mixerlinks ();
+  if (!no_links) {
+    create_dsplinks ();
+    create_mixerlinks ();
 #ifdef CONFIG_OSS_MIDI
-  create_midilinks ();
+    create_midilinks ();
 #endif
+  }
 
   close (mixerfd);
 

cmd/ossdevlinks/ossdevlinks.man

 there are a few command line options.
 
 -f<name>	Write legacydev file to <fname>. 
+-N		Do not actually modify device files
 -r		Reset the legacy device numbering (do not use).
 -v		Verbose output
 

cmd/ossmix/ossmix.c

         }
       if (relative & RELLEFT) lefti += left;
       if (relative & RELRIGHT) righti += right;
-      if (relative & RELTOGGLE) lefti = !left;
+      if (relative & RELTOGGLE) lefti = (left?0:extrec.maxvalue);
     }
 
   if (lefti < 0) lefti = 0;

cmd/ossmixd/ossmixd.c

   int port = 7777;
   int c;
   int err;
-  extern int optind;
 
   if ((err = ossmix_init ()) < 0)
     {

cmd/ossplay/ossplay.c

 unsigned int amplification = 100;
 int eflag = 0, force_speed = 0, force_fmt = 0, force_channels = 0, verbose = 0,
     quiet = 0;
-flag from_stdin = 0, int_conv = 0, level_meters = 0, loop = 0, overwrite = 0,
+flag from_stdin = 0, int_conv = 0, level_meters = 0, loop = 0, 
      raw_file = 0, raw_mode = 0;
 double seek_time = 0;
 long seek_byte = 0;
              " single recording.\n");
   print_msg (HELPM,
              "            -R             Open sound device in raw mode.\n");
-  print_msg (HELPM, "            -O             Allow overwrite.\n");
   exit (E_USAGE);
 }
 
           dsp->reclevel = atoi (optarg);
           if (dsp->reclevel < 1 || dsp->reclevel > 100)
             {
-              print_msg (ERRORM, "%s: Bad recording level '%s'\n", argv[0],
-                         optarg);
+              print_msg (ERRORM, "%s: Bad recording level '%s'\n",
+                         argv[0]?argv[0]:"", optarg);
               exit (-1);
             }
           break;
           break;
 
         case 'w':
+        case 'O':
           break;
 
         case 'v':
           verbose = 1;
           break;
 
-	case 'O':
-	  overwrite = 1;
-	  break;
-
         case 'h':
         default:
           ossrecord_usage (argv[0]);

cmd/ossplay/ossplay.man

 -h		Display usage information.
 
 INTERRUPT
-Sending a SIGQUIT (Ctrl-\\ in most terminals) will make ossplay stop playing
+Sending a SIGQUIT (Ctrl-\e in most terminals) will make ossplay stop playing
 the currently played file and skip to the next file.
 
 NOTES

cmd/ossplay/ossplay_console.c

 void
 perror_msg (const char * s)
 {
-  perror (s);
+  if (quiet < 2) perror (s);
 }
 
 void

cmd/ossplay/ossplay_decode.c

 ima_values_t;
 
 extern int amplification, force_speed, force_fmt, force_channels;
-extern flag int_conv, overwrite, verbose;
+extern flag int_conv, verbose;
 extern char audio_devname[32];
 extern off_t (*ossplay_lseek) (int, off_t, int);
 extern double seek_time;
         dec->decoder = decode_nul;
         dec->metadata = metadata;
         obsize = bsize;
-        if (metadata == NULL) return E_DECODE;
+        if (metadata == NULL) goto exit;
         else
           {
             ogg_data_t * val = (ogg_data_t *)metadata;
             print_msg (WARNM, "Converting to format %s\n",
                        sample_format_name (tmp));
             ret = setup_device (dsp, tmp, channels, speed);
+            if (ret == E_FORMAT_UNSUPPORTED) goto exit;
             decoders = setup_normalize (&format, &obsize, decoders);
             goto dcont;
           }
     wave_fp = fdopen (1, "wb");
   else
     {
-      fd = open (fname, O_WRONLY | O_CREAT | (overwrite?0:O_EXCL), 0644);
+      fd = open (fname, O_WRONLY | O_CREAT, 0644);
       if (fd == -1)
         {
           perror (fname);
   unsigned char buf;
   fib_values_t * val;
 
+  if (read (fd, &buf, 1) <= 0) return NULL;
   val = (fib_values_t *)ossplay_malloc (sizeof (fib_values_t));
   if (format == AFMT_EXP_DELTA) val->table = CodeToExpDelta;
   else val->table = CodeToDelta;
 
-  if (read (fd, &buf, 1) <= 0) return NULL;
   val->pred = buf;
 
   return val;
   cradpcm_values_t * val;
   int i;
 
+  if (read (fd, &buf, 1) <= 0) return NULL;
   val = (cradpcm_values_t *)ossplay_malloc (sizeof (cradpcm_values_t));
   val->table = t_row;
 
       for (i=0; i < 2; i++) t_row[i] = T4[i];
     }
 
-  if (read (fd, &buf, 1) <= 0) return NULL;
   val->pred = buf;
 
   return val;

cmd/ossrecord/ossrecord.man

 ossrecord - Open Sound System recording program.
 
 SYNOPSIS
-ossrecord [-ORhlv] [-F cntname | ? ] [ -c channels ] [ -d devname ]
+ossrecord [-Rhlv] [-F cntname | ? ] [ -c channels ] [ -d devname ]
           [ -f fmtname | ? ] [ -g gain ] [ -i recsource | ? ] [ -m nfiles ]
           [ -r command ] [ -s rate ] [ -t maxsecs ] filename | - ...
 
 -t<maxsecs>	Do not record more than <maxsecs> seconds in a single recording
 		operation.
 -L<level>	Set the recording level to <level>.
--O		Allow overwriting of file when recording.
 -h		Display usage instructions.
 
 COMMAND SCRIPT

cmd/osstest/osstest.c

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <signal.h>
 #include <fcntl.h>
 #include <string.h>
 #include <errno.h>
 #define TF_QUICK	0x00000008	/* Shortened test */
 #define TF_LOOP		0x00000010	/* Loop until interrupted */
 
-static int mixerfd;
-static int cardno = -1;
-static int num_devices_tested = 0;
-int play_gain = 100;
+int cardno = -1, mixerfd, num_devices_tested = 0, play_gain = 100, skip = 0;
 
 static short *sample_buf;
 
   else
     test_data = sample_buf;
 
+  if (skip) goto tend;
+
   printf ("\n");
 
   /* TF_SNDCONF is used when longer messages should be printed. */
   else
     printf ("OK ");
 
+  if (skip) goto tend;
+
   if (flags & TF_SNDCONF)
     printf ("   Performing right channel test on %s\n", devnode);
   else
   else
     printf ("OK ");
 
+  if (skip) goto tend;
+
   if (flags & TF_SNDCONF)
     printf ("   Performing stereo test on %s\n", devnode);
   else
   else
     printf ("OK <measured srate %8.2f Hz (%4.2f%%)> ",
 	    (float) sample_rate * ratio / 100.0, ratio - 100.0);
+tend:
+  skip = 0;
   printf ("\n");
   num_devices_tested++;
 
   return code == 1;
 }
 
+static void
+skip_handler (int c)
+{
+  skip = 1;
+}
+
 int
 main (int argc, char *argv[])
 {
       exit (-1);
     }
 
+#ifdef SIGQUIT
+  signal (SIGQUIT, skip_handler);
+#endif
+
   do {
     if (dev > -1)
       {

cmd/ossxmix/ossxmix.c

 #ifndef GTK1_ONLY
 static gint manage_timeouts (GtkWidget *, GdkEventWindowState *, gpointer);
 #endif /* !GTK1_ONLY */
+static void parse_dimarg (const char *, GtkRequisition *);
 static gint poll_all (gpointer);
 static gint poll_peaks (gpointer);
 static gint poll_values (gpointer);
   return best;
 }
 
+static void
+parse_dimarg (const char * dimarg, GtkRequisition * Dimensions)
+{
+  long height = 0, width = 0;
+  char * p;
+
+  errno = 0;
+  width = strtol (dimarg, &p, 10);
+  if (errno || (width <= 0)) return;
+  if (width > Dimensions->width) width = Dimensions->width;
+  height = width;
+  if (*p != '\0')
+    {
+      errno = 0;
+      height = strtol (p+1, NULL, 10);
+      if (errno || (height <= 0)) height = width;
+    }
+
+  Dimensions->width = width;
+  if (height < Dimensions->height) Dimensions->height = height;
+  return;
+}
+
 int
 main (int argc, char **argv)
 {
   extern char * optarg;
+  char * dimarg = NULL;
   int i, v, c;
   GtkRequisition Dimensions;
 #ifndef GTK1_ONLY
   /* Get Gtk to process the startup arguments */
   gtk_init (&argc, &argv);
 
-  while ((c = getopt (argc, argv, "Sbd:w:n:xh")) != EOF)
+  while ((c = getopt (argc, argv, "Sbd:g:hn:w:x")) != EOF)
       switch (c)
 	{
 	case 'd':
 	  break;
 
 	case 'w':
+	  v = 0;
 	  v = atoi (optarg);
 	  if (v <= 0)
 	    v = 1;
 	  break;
 
 	case 'n':
+	  v = 0;
 	  v = atoi (optarg);
 	  if (v <= 0)
 	    v = 1;
 	  show_status_icon = 0;
 	  break;
 
+	case 'g':
+	  dimarg = optarg;
+	  break;
+
 	case 'h':
 	  printf ("Usage: %s [options...]\n", argv[0]);
 	  printf ("       -h          Prints help (this screen)\n");
 	  printf ("       -w[val]     Make mixer bit wider on screen\n");
 	  printf ("       -n[val]     Make mixer bit narrower on screen\n");
 	  printf ("       -b          Start mixer in background\n");
+	  printf ("       -g[w:h]     Start mixer window with w:h size\n");
 #ifdef STATUSICON
 	  printf ("       -S          Don't place an icon in system tray\n");
 #endif /* STATUSICON */
   /* Create the app's main window */
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   Dimensions = create_widgets ();
+  if (dimarg != NULL) parse_dimarg (dimarg, &Dimensions);
   gtk_window_set_default_size (GTK_WINDOW (window),
                                Dimensions.width, Dimensions.height);
 

cmd/ossxmix/ossxmix.man

 -n[value]   Make the mixer slightly narrower than normally. This may be
             necessary if the mixer is wider than the screen. The value can be
             1 (default) or 2.
+-g[w:h]     Start ossxmix window with dimnesions w:h.
 -b          Start in background.
 -S          Do not try to place an icon in the system tray.
 

cmd/vmixctl/vmixctl.c

 static void
 usage(void)
 {
-	fprintf (stderr, "Usage:\n");
-	fprintf (stderr, "%s attach [attach_options...] devname\n", cmdname);
-	fprintf (stderr, "%s attach [attach_options...] devname inputdev\n", cmdname);
-	fprintf (stderr, "%s detach devname\n", cmdname);
-	fprintf (stderr, "%s rate devname samplerate\n", cmdname);
-	fprintf (stderr, "\n");
-	fprintf (stderr, "Use ossinfo -a to find out the devname and inputdev parameters\n");
-	fprintf (stderr, "Use ossinfo -a -v2 to find out a suitable sample rate.\n");
-	fprintf (stderr, "\n");
-	fprintf (stderr, "attach_options:\n");
-	fprintf (stderr, "\n");
-	fprintf (stderr, "\t-r\tDisable recording\n");
-	fprintf (stderr, "\t-p\tDo not preallocate client engines\n");
-	fprintf (stderr, "\t-M\tUse more fragments\n");
-	fprintf (stderr, "\t-V\tMake clients visible by creating device files for them.\n");
-	fprintf (stderr, "\t-c<N>\tPrecreate <N> client engines (see -p).\n");
+	fprintf (stdout, "Usage:\n");
+	fprintf (stdout, "%s attach [attach_options...] devname\n", cmdname);
+	fprintf (stdout, "%s attach [attach_options...] devname inputdev\n", cmdname);
+	fprintf (stdout, "%s detach devname\n", cmdname);
+	fprintf (stdout, "%s rate devname samplerate\n", cmdname);
+	fprintf (stdout, "\n");
+	fprintf (stdout, "Use ossinfo -a to find out the devname and inputdev parameters\n");
+	fprintf (stdout, "Use ossinfo -a -v2 to find out a suitable sample rate.\n");
+	fprintf (stdout, "\n");
+	fprintf (stdout, "attach_options:\n");
+	fprintf (stdout, "\n");
+	fprintf (stdout, "\t-r\tDisable recording\n");
+	fprintf (stdout, "\t-p\tDo not preallocate client engines\n");
+	fprintf (stdout, "\t-M\tUse more fragments\n");
+	fprintf (stdout, "\t-V\tMake clients visible by creating device files for them.\n");
+	fprintf (stdout, "\t-c<N>\tPrecreate <N> client engines (see -p).\n");
 
 	exit(-1);
 }
 		exit(-1);
 	}
 
-	fprintf (stderr, "Virtual mixer attached to device.\n");
+	fprintf (stdout, "Virtual mixer attached to device.\n");
 
 	if (relink_devices)
 	{
 		exit(-1);
 	}
 
-	fprintf (stderr, "Virtual mixer detached from device.\n");
+	fprintf (stdout, "Virtual mixer detached from device.\n");
 
 	return 0;
 }
 		exit(-1);
 	}
 
-	fprintf (stderr, "Virtual mixer rate change requested.\n");
+	fprintf (stdout, "Virtual mixer rate change requested.\n");
 
 	return 0;
 }

kernel/OS/BeOS/os_beos.c

     {
     case DRV_PCI:
       /* NOP */
+#ifdef __HAIKU__
+      if (gPCI->reserve_device(osdev->dip->pciinfo.bus,
+      				   osdev->dip->pciinfo.device,
+				   osdev->dip->pciinfo.function,
+				   "oss", osdev) != B_OK) {
+      	cmn_err (CE_WARN, "Could not reserve PCI device\n");
+      	/* XXX: CLEANUP! */
+        return NULL;
+      }
+#endif
       break;
 
     case DRV_VIRTUAL:
       /* NOP */
       //pci_config_teardown (&osdev->pci_config_handle);
       //osdev->pci_config_handle = NULL;
+#ifdef __HAIKU__
+      gPCI->unreserve_device(osdev->dip->pciinfo.bus,
+      				 osdev->dip->pciinfo.device,
+				 osdev->dip->pciinfo.function,
+				 "oss", osdev);
+#endif
       break;
     }
 

kernel/drv/oss_audigyls/oss_audigyls.c

 
 	  case SOUND_MIXER_CENTERVOL:
 	    val = *arg;
-	    return *arg = audigyls_set_volume (devc, 2, val);
+	    return *arg = audigyls_set_volume (devc, 1, val);
 
 	  case SOUND_MIXER_REARVOL:
 	    val = *arg;
-	    return *arg = audigyls_set_volume (devc, 3, val);
+	    return *arg = audigyls_set_volume (devc, 2, val);
 	  }
       else
 	switch (cmd & 0xff)	/* Return Parameter */

kernel/drv/oss_cmi878x/.devices

 oss_cmi878x	pci1043,834f	Asus Xonar D1 (AV100)
 oss_cmi878x	pci1043,8275    Asus Xonar DX (AV100)
 oss_cmi878x	pci1043,82b7    Asus Xonar D2X (AV200)
+oss_cmi878x	pci1043,835c    Asus Xonar Essence STX (AV100)

kernel/drv/oss_cmi878x/oss_cmi878x.c

 #define SUBID_XONAR_D2X		0x82b7
 #define SUBID_XONAR_D1		0x834f
 #define SUBID_XONAR_DX		0x8275
+#define SUBID_XONAR_STX 	0x835c
 
 #define SUBID_GENERIC		0x0000
 
 #define XONAR_D2_LFEDAC 	0x9c
 #define XONAR_D2_REARDAC	0x9e
 
+/* defs for Xonar STX */
+#define XONAR_STX_FRONTDAC	0x98
+
 /* defs for AKM 4396 DAC */
 #define AK4396_CTL1        0x00
 #define AK4396_CTL2        0x01
   int trigger_bits;
   int audio_enabled;
   int audiodev;
-  int port_type;
+  int dac_type;
 #define ADEV_MULTICH	0
 #define ADEV_FRONTPANEL	2
 #define ADEV_SPDIF	3
+  int adc_type;
+#define ADEV_I2SADC1	0
+#define ADEV_I2SADC2	1
+#define ADEV_I2SADC3	2
   int play_dma_start, rec_dma_start;
   int play_irq_mask, rec_irq_mask;
   int play_chan_reset, rec_chan_reset;
 
   /* Mixer */
   ac97_devc ac97devc, fp_ac97devc;
-  int ac97_mixer_dev, fp_mixer_dev, spi_mixer_dev;
+  int ac97_mixer_dev, fp_mixer_dev, cmi_mixer_dev;
   int playvol[4];
   /* uart401 */
   oss_midi_inputbyte_t midi_input_intr;
 
   MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
   val = 0L;
+  val |= reg << 16;
+  val |= 1 << 23;		/*ac97 read the reg address */
   val |= 0 << 24;		/*codec 0 */
-  val |= 1 << 23;		/*ac97 read the reg address */
-  val |= reg << 16;
   OUTL (devc->osdev, val, AC97_CMD_DATA);
-  oss_udelay (100);
+  oss_udelay (200);
   data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF;
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
   return data;
   MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
   val = 0L;
+  val |= data & 0xFFFF;
+  val |= reg << 16;
+  val |= 0 << 23;		/*ac97 write operation */
   val |= 0 << 24;		/*on board codec */
-  val |= 0 << 23;		/*ac97 write operation */
-  val |= reg << 16;
-  val |= data & 0xFFFF;
   OUTL (devc->osdev, val, AC97_CMD_DATA);
-  oss_udelay (100);
+  oss_udelay (200);
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
   return 1;
 }
   int data, val;
   MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
   val = 0L;
+  val |= reg << 16;
+  val |= 1 << 23;		/*ac97 read the reg address */
   val |= 1 << 24;		/*fp codec1 */
-  val |= 1 << 23;		/*ac97 read the reg address */
-  val |= reg << 16;
   OUTL (devc->osdev, val, AC97_CMD_DATA);
-  oss_udelay (100);
+  oss_udelay (200);
   data = INL (devc->osdev, AC97_CMD_DATA) & 0xFFFF;
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
   return data;
   MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
 
   val = 0L;
+  val |= data & 0xFFFF;
+  val |= reg << 16;
+  val |= 0 << 23;		/*ac97 write operation */
   val |= 1 << 24;		/*fp codec1 */
-  val |= 0 << 23;		/*ac97 write operation */
-  val |= reg << 16;
-  val |= data & 0xFFFF;
   OUTL (devc->osdev, val, AC97_CMD_DATA);
-  oss_udelay (100);
+  oss_udelay (200);
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
   return 1;
 }
   /* select the codec number to address */
   OUTB (devc->osdev, codec_num, TWO_WIRE_ADDR);
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
-  oss_udelay(100); 
+  oss_udelay(100);
 
   return 1;
 
   OUTW(devc->osdev, 0x0100, TWO_WIRE_CTRL);
 
   // Power down, enable control mode.
-  two_wire_write(devc_, codec_, CS4398_MISC_CTRL, 
+  two_wire_write(devc_, codec_, CS4398_MISC_CTRL,
     CS4398_CPEN | CS4398_POWER_DOWN);
   // Left justified PCM (DAC and 8788 support I2S, but doesn't work.
   // Setting it introduces clipping like hell).
   two_wire_write(devc_, codec_, CS4398_MODE_CTRL, 0);
-  // That's the DAC default, set anyway. 
+  // That's the DAC default, set anyway.
   two_wire_write(devc_, codec_, 3, 0x09);
   // PCM auto-mute.
   two_wire_write(devc_, codec_, 4, 0x82);
 cs4362a_init(void * devc_, int codec_)
 {
   cmi8788_devc *devc = devc_;
-  
+
   // Fast Two-Wire. Reduces the wire ready time.
   OUTW(devc->osdev, 0x0100, TWO_WIRE_CTRL);
 
-  /* Power down and enable control port. */ 
+  /* Power down and enable control port. */
   two_wire_write(devc_, codec_, CS4362A_MODE1_CTRL, CS4362A_CPEN | CS4362A_POWER_DOWN);
   /* Left-justified PCM */
   two_wire_write(devc_, codec_, CS4362A_MODE2_CTRL, CS4362A_DIF_LJUST);
   /* Ramp & Automute, re-set DAC defaults. */
-  two_wire_write(devc_, codec_, CS4362A_MODE3_CTRL, 0x84); 
+  two_wire_write(devc_, codec_, CS4362A_MODE3_CTRL, 0x84);
   /* Filter control, DAC defs. */
   two_wire_write(devc_, codec_, CS4362A_FILTER_CTRL, 0);
   /* Invert control, DAC defs. */
 }
 #endif
 
+
 static void
 xonar_dx_set_play_volume(cmi8788_devc * devc, int codec_id, int value)
 {
   }
 }
 
+static void
+xonar_d2_set_play_volume(cmi8788_devc * devc, int codec_id, int value)
+{
+  int left, right;
+
+  left = (value & 0x00FF);
+  right = (value & 0xFF00) >> 8;
+
+  pcm1796_write (devc, codec_id, 16, mix_scale(left,8));
+  pcm1796_write (devc, codec_id, 17, mix_scale(right,8));
+}
+
+static void
+xonar_stx_set_play_volume(cmi8788_devc * devc, int codec_id, int value)
+{
+  int left, right;
+
+  left = (value & 0x00FF);
+  right = (value & 0xFF00) >> 8;
+
+  if (codec_id == 0)
+  {
+      two_wire_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(left,8));
+      two_wire_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(right,8));
+  }
+}
+
 
 static int
 cmi8788_set_play_volume (cmi8788_devc * devc, int codec_id, int value)
       break;
     case SUBID_XONAR_D2:
     case SUBID_XONAR_D2X:
-      pcm1796_write (devc, codec_id, 16, mix_scale(left,8));
-      pcm1796_write (devc, codec_id, 17, mix_scale(right,8));
+      xonar_d2_set_play_volume(devc, codec_id, value);
       break;
+    case SUBID_XONAR_STX:
+      xonar_stx_set_play_volume(devc, codec_id, value);
+      break;
+
     default:
       /* Assume default AKM DACs */
       data[0] = left;
   int channels, bits, i2s_bits, i2s_rate;
 
   MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
-
-  switch (portc->port_type)
+  switch (portc->adc_type)
     {
-    case ADEV_MULTICH:
+    case ADEV_I2SADC1:
       {
 	portc->rec_dma_start = 0x1;
 	portc->rec_irq_mask = 0x1;
 	break;
       }
 
-    case ADEV_FRONTPANEL:
+    case ADEV_I2SADC2:
       {
 	portc->rec_dma_start = 0x2;
 	portc->rec_irq_mask = 0x2;
 	OUTL (devc->osdev, dmap->dmabuf_phys, RECB_ADDR);
 	OUTW (devc->osdev, dmap->bytes_in_use / 4 - 1, RECB_SIZE);
 	OUTW (devc->osdev, dmap->fragment_size / 4 - 1, RECB_FRAG);
-	ac97_recrate (&devc->fp_ac97devc, portc->speed);
+
+        switch (portc->bits)
+          {
+#if 0
+          case AFMT_S24_LE:
+            bits = 0x04;
+            break;
+#endif
+          case AFMT_S32_LE:
+            bits = 0x08;
+            break;
+          default:              /*  AFMT_S16_LE */
+            bits = 0x0;
+            break;
+          }
+
+        OUTB (devc->osdev, (INB (devc->osdev, REC_FORMAT) & ~0x0C) | bits,
+              REC_FORMAT);
+
+        /* setup i2s bits */
+        i2s_bits = i2s_calc_bits (portc->bits);
+        OUTB (devc->osdev,
+              (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0xC0) | i2s_bits,
+              I2S_ADC2_FORMAT);
+
+        /* setup speed */
+        i2s_rate = i2s_calc_rate (portc->speed);
+        OUTB (devc->osdev,
+              (INB (devc->osdev, I2S_ADC2_FORMAT) & ~0x7) | i2s_rate,
+              I2S_ADC2_FORMAT);
 
 	break;
       }
 
-    case ADEV_SPDIF:
+    case ADEV_I2SADC3:
       {
 	portc->rec_dma_start = 0x4;
 	portc->rec_irq_mask = 0x4;
 
   MUTEX_ENTER_IRQDISABLE (devc->mutex, flags);
 
-  switch (portc->port_type)
+  switch (portc->dac_type)
     {
     case ADEV_MULTICH:
       {
   MUTEX_ENTER_IRQDISABLE (devc->low_mutex, flags);
   if (direction == PCM_ENABLE_INPUT)
     {
-      switch (portc->port_type)
+      switch (portc->adc_type)
 	{
-	case ADEV_MULTICH:
+	case ADEV_I2SADC1:
 	  ptr = INL (devc->osdev, RECA_ADDR);
 	  break;
-	case ADEV_FRONTPANEL:
+	case ADEV_I2SADC2:
 	  ptr = INL (devc->osdev, RECB_ADDR);
 	  break;
-	case ADEV_SPDIF:
+	case ADEV_I2SADC3:
 	  ptr = INL (devc->osdev, RECC_ADDR);
 	  break;
 	}
 
   if (direction == PCM_ENABLE_OUTPUT)
     {
-      switch (portc->port_type)
+      switch (portc->dac_type)
 	{
 	case ADEV_MULTICH:
 	  ptr = INL (devc->osdev, MULTICH_ADDR);
   ptr -= dmap->dmabuf_phys;
   ptr %= dmap->bytes_in_use;
   MUTEX_EXIT_IRQRESTORE (devc->low_mutex, flags);
-  // cmn_err (CE_CONT, "ptr=%x\n", ptr);
   return ptr;
 }
 
 	    return *arg = 0;
 	    break;
 
-	  case SOUND_MIXER_PCM:
+	  case SOUND_MIXER_VOLUME:
 	    val = *arg;
 	    return *arg = cmi8788_set_play_volume (devc, 0, val);
 	    break;
 
 	  default:
 	    val = *arg;
-	    return *arg = cmi8788_set_play_volume (devc, 0, val);
+	    return *arg = 0;
 	    break;
 	  }
       else
 	    break;
 
 	  case SOUND_MIXER_DEVMASK:
-	    return *arg =
-	      SOUND_MASK_PCM | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL |
+		if (devc->model == SUBID_XONAR_STX)
+		   return *arg = SOUND_MASK_VOLUME;
+		else
+		   return *arg =
+	      SOUND_MASK_VOLUME | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL |
 	      SOUND_MASK_SIDEVOL;
 	    break;
 
 	  case SOUND_MIXER_STEREODEVS:
-	    return *arg =
-	      SOUND_MASK_PCM | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL |
-	      SOUND_MASK_SIDEVOL;
+                if (devc->model == SUBID_XONAR_STX)
+                   return *arg = SOUND_MASK_VOLUME;
+                else
+                   return *arg =
+              SOUND_MASK_VOLUME | SOUND_MASK_REARVOL | SOUND_MASK_CENTERVOL |
+              SOUND_MASK_SIDEVOL;
 	    break;
 
 	  case SOUND_MIXER_CAPS:
 	    return *arg = SOUND_CAP_EXCL_INPUT;
 	    break;
 
-	  case SOUND_MIXER_PCM:
+	  case SOUND_MIXER_VOLUME:
 	    return *arg = devc->playvol[0];
 	    break;
 
 	    break;
 
 	  default:
-	    return *arg = devc->playvol[0];
+	    return *arg = 0;
 	    break;
 	  }
     }
 	case 0:		/* Record Monitor */
 	  value = (INB (devc->osdev, REC_MONITOR) & 0x1) ? 1 : 0;
 	  break;
-	case 1:		/* Front Panel Monitor */
-	  value = (INB (devc->osdev, REC_MONITOR) & 0x4) ? 1 : 0;
-	  break;
-	case 2:		/* SPDIFIN Monitor */
+	case 1:		/* SPDIFIN Monitor */
 	  value = (INB (devc->osdev, REC_MONITOR) & 0x10) ? 1 : 0;
 	  break;
-	case 3:		/* Speaker Spread - just check bit15 to see if it's set */
+	case 2:		/* Record source select */
+	  value = (ac97_read (devc, 0x72) & 0x1) ? 1 : 0;
+	  break;
+	case 3:		/* Speaker Spread - check bit15 to see if it's set */
 	  value = (INW (devc->osdev, PLAY_ROUTING) & 0x8000) ? 0 : 1;
 	  break;
 	case 4:		/* SPDIF IN->OUT Loopback */
 	  value = (INW (devc->osdev, SPDIF_FUNC) & 0x4) ? 1 : 0;
 	  break;
-
+	case 5:
+	  value = (INW (devc->osdev, GPIO_DATA) & 0x80) ? 1 : 0;
+	  break;
 	default:
 	  return OSS_EINVAL;
+	  break;
 	}
 
       return value;
 	{
 	case 0:		/* Record Monitor */
 	  if (value)
-	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x1,
+	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0xF,
 		  REC_MONITOR);
 	  else
-	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x1,
+	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0xF,
 		  REC_MONITOR);
 	  break;
 
-	case 1:		/* Front Panel Record Monitor */
-	  if (value)
-	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x4,
-		  REC_MONITOR);
-	  else
-	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) & ~0x4,
-		  REC_MONITOR);
-	  break;
-
-	case 2:		/* SPDIFIN Monitor */
+	case 1:		/* SPDIFIN Monitor */
 	  if (value)
 	    OUTB (devc->osdev, INB (devc->osdev, REC_MONITOR) | 0x10,
 		  REC_MONITOR);
 		  REC_MONITOR);
 	  break;
 
+	case 2:
+	  if (value)
+          {
+             if (devc->model == SUBID_XONAR_D1 || devc->model == SUBID_XONAR_DX)
+		OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x100, GPIO_DATA);
+	     ac97_write(devc, 0x72, ac97_read(devc, 0x72) | 0x1);
+	  }
+	  else
+	  {
+             if (devc->model == SUBID_XONAR_D1 || devc->model == SUBID_XONAR_DX)
+		OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) & ~0x100, GPIO_DATA);
+	     ac97_write(devc, 0x72, ac97_read(devc, 0x72) & ~0x1);
+	  }
+	  break;
+
 	case 3:		/* Speaker Spread (clone front to all channels) */
 	  if (value)
 	    OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) & 0x00FF,
 		  SPDIF_FUNC);
 	  break;
 
+	case 5:
+          if (value)
+		OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x80, GPIO_DATA) ;
+	  else
+		OUTW(devc->osdev, (INW(devc->osdev, GPIO_DATA) & ~0x80), GPIO_DATA);
+          break;
+
 	default:
 	  return OSS_EINVAL;
+	  break;
 	}
       return (value);
     }
 cmi8788_mix_init (int dev)
 {
   int group, parent, ctl;
+  cmi8788_devc *devc = mixer_devs[dev]->hw_devc;
 
   if ((parent = mixer_ext_create_group (dev, 0, "EXT")) < 0)
     return parent;
 
   if ((ctl =
        mixer_ext_create_control (dev, group, 0, cmi8788_ext,
-				 MIXT_ONOFF, "MULTICHANNEL", 1,
+				 MIXT_ONOFF, "ANALOG", 1,
 				 MIXF_READABLE | MIXF_WRITEABLE)) < 0)
     return ctl;
 
   if ((ctl =
        mixer_ext_create_control (dev, group, 1, cmi8788_ext,
-				 MIXT_ONOFF, "FRONTPANEL", 1,
-				 MIXF_READABLE | MIXF_WRITEABLE)) < 0)
-    return ctl;
-
-  if ((ctl =
-       mixer_ext_create_control (dev, group, 2, cmi8788_ext,
 				 MIXT_ONOFF, "SPDIF", 1,
 				 MIXF_READABLE | MIXF_WRITEABLE)) < 0)
     return ctl;
 
+ if ((ctl =
+	mixer_ext_create_control (dev, group, 2, cmi8788_ext, MIXT_ENUM,
+				  "inputsrc", 2,
+				  MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+	return ctl;
+    mixer_ext_set_strings (dev, ctl, "Line Mic", 0);
+
 /* Create PLAYBACK ROUTING */
   if ((group = mixer_ext_create_group (dev, parent, "OUTPUT_ROUTING")) < 0)
     return group;
 				 MIXF_READABLE | MIXF_WRITEABLE)) < 0)
     return ctl;
 
+  if (devc->model == SUBID_XONAR_D2 || devc->model == SUBID_XONAR_D2X)
+    if ((ctl = mixer_ext_create_control (dev, group, 5, cmi8788_ext,
+				 MIXT_ONOFF, "PCM-LOOPBACK", 1,
+				 MIXF_READABLE | MIXF_WRITEABLE)) < 0)
+		        return ctl;
+
+
 /* Create SPDIF OUTPUT */
   if ((group = mixer_ext_create_group (dev, 0, "SPDIF-OUT")) < 0)
     return group;
   return 0;
 }
 
+void ac97_hwinit(cmi8788_devc *devc)
+{
+
+    /* Gpio #0 programmed as output, set CMI9780 Reg0x70 */
+    ac97_write(devc, 0x70, 0x100);
+
+    /* LI2LI,MIC2MIC; let them always on, FOE on, ROE/BKOE/CBOE off */
+    ac97_write(devc, 0x62, 0x180F);
+
+    /* change PCBeep path, set Mix2FR on, option for quality issue */
+    ac97_write(devc, 0x64, 0x8043);
+#if 0
+   /* unmute Master Volume */
+    ac97_write(devc, 0x02, 0x0);
+
+
+    /* mute PCBeep, option for quality issues */
+    ac97_write(devc, 0x0A, 0x8000);
+
+    /* Record Select Control Register (Index 1Ah) */
+    ac97_write(devc, 0x1A, 0x0000);
+
+    /* set Mic Volume Register 0x0Eh umute and enable micboost */
+    ac97_write(devc, 0x0E, 0x0848);
+
+    /* set Line in Volume Register 0x10h mute */
+    ac97_write(devc, 0x10, 0x8808);
+
+    /* set CD Volume Register 0x12h mute */
+    ac97_write(devc, 0x12, 0x8808);
+
+    /* set AUX Volume Register 0x16h max */
+    ac97_write(devc, 0x16, 0x0808);
+
+    /* set record gain Register 0x1Ch to max */
+    ac97_write(devc, 0x1C, 0x0F0F);
+#endif
+    ac97_write(devc, 0x71, 0x0001);
+}
 
 static int
 init_cmi8788 (cmi8788_devc * devc)
 
   bVal = INB (devc->osdev, FUNCTION);
   bVal |= 0x02; /* Reset codec*/
-
-
-  switch(devc->model)
-  {
-    case SUBID_XONAR_D1:
-    case SUBID_XONAR_DX:
-      /* Two-Wire communication for Xonar DX DACs. */
-      bVal |= 0x40;
-      break;
-    default:
-      /* SPI default for anything else, including the D2/D2X */
-      bVal &= ~0x40;
-      /* Enable SPI outputs 4 and 5 */
-      bVal |= 0x80;
-      break;
-  }
-
-  OUTB (devc->osdev, bVal, FUNCTION);
-  
-  if (devc->model == SUBID_XONAR_D2 || devc->model == SUBID_XONAR_D2X)
-  {
-        int i;
-
-        /* unmute, set to 24Bit SPI */
-        for (i = 0; i < 4; ++i) {
-             pcm1796_write(devc, i, 16, mix_scale(75,8)); /* left default vol */
-             pcm1796_write(devc, i, 17, mix_scale(75,8)); /* right default vol */
-             pcm1796_write(devc, i, 18, 0x30 | 0x80); /* unmute/24LSB/ATLD */
-        }
-  }
+  OUTB(devc->osdev, bVal, FUNCTION);
+
 
   /* I2S to 16bit, see below. */
-  sDac = 0x010A; 
- 
+  sDac = 0x010A;
+
   /* Non-generic DAC initialization */
   switch(devc->model)
   {
     case SUBID_XONAR_D1:
     case SUBID_XONAR_DX:
-      /* Front DAC. */
-      cs4398_init(devc, XONAR_DX_FRONTDAC); 
-      /* Surround DAC. */
-      cs4362a_init(devc, XONAR_DX_SURRDAC);
+    case SUBID_XONAR_D2:
+    case SUBID_XONAR_D2X:
+    case SUBID_XONAR_STX:
       /* Must set master clock. */
       sDac |= XONAR_DX_MCLOCK_256;
       break;
 
   /* Setup I2S to use 16bit instead of 24Bit */
   OUTW (devc->osdev, sDac, I2S_MULTICH_FORMAT);
-  OUTW (devc->osdev, 0x010A, I2S_ADC1_FORMAT);
-  OUTW (devc->osdev, 0x010A, I2S_ADC2_FORMAT);
-  OUTW (devc->osdev, 0x010A, I2S_ADC3_FORMAT);
+  OUTW (devc->osdev, sDac, I2S_ADC1_FORMAT);
+  OUTW (devc->osdev, sDac, I2S_ADC2_FORMAT);
+  OUTW (devc->osdev, sDac, I2S_ADC3_FORMAT);
 
   /* setup Routing regs (default vals) */
   OUTW (devc->osdev, 0xE400, PLAY_ROUTING);
   OUTB (devc->osdev, 0x00, REC_MONITOR);
   OUTB (devc->osdev, 0xE4, MONITOR_ROUTING);
 
+
   /* install the CMI8788 mixer */
-  if ((devc->spi_mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
+  if ((devc->cmi_mixer_dev = oss_install_mixer (OSS_MIXER_DRIVER_VERSION,
 						devc->osdev,
 						devc->osdev,
 						"CMedia CMI8788",
       return 0;
     }
 
-  mixer_devs[devc->spi_mixer_dev]->hw_devc = devc;
-  mixer_devs[devc->spi_mixer_dev]->priority = 10;	/* Possible default mixer candidate */
-  mixer_ext_set_init_fn (devc->spi_mixer_dev, cmi8788_mix_init, 25);
+  mixer_devs[devc->cmi_mixer_dev]->hw_devc = devc;
+  mixer_devs[devc->cmi_mixer_dev]->priority = 10;	/* Possible default mixer candidate */
+  mixer_ext_set_init_fn (devc->cmi_mixer_dev, cmi8788_mix_init, 25);
 
   /* Cold reset onboard AC97 */
   OUTW (devc->osdev, 0x1, AC97_CTRL);
   if (sVal & 0x10)
     {
       /* disable CODEC0 OUTPUT */
-      OUTW (devc->osdev, INW (devc->osdev, AC97_OUT_CHAN_CONFIG) & ~0xFF00,
+      OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_OUT_CHAN_CONFIG) & ~0xFF00,*/
 	    AC97_OUT_CHAN_CONFIG);
 
       /* enable CODEC0 INPUT */
-      OUTW (devc->osdev, INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0300,
+      OUTW (devc->osdev, 0, /* INW (devc->osdev, AC97_IN_CHAN_CONFIG) | 0x0300,*/
 	    AC97_IN_CHAN_CONFIG);
 
-      /* set Playback routing to I2S mode */
-      OUTW (devc->osdev, INW (devc->osdev, PLAY_ROUTING) & ~0x10,
-	    PLAY_ROUTING);
-
-      /* setup record channel A (MULTICH) and B (Front Panel) in AC97 mode */
-      OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
-
       devc->ac97_mixer_dev =
 	ac97_install (&devc->ac97devc, "AC97 Input Mixer", ac97_read,
 		      ac97_write, devc, devc->osdev);
-
-      if (devc->ac97_mixer_dev >= 0)
-	{
-	  /* setup the Codec0 as the input mux */
-	  ac97_write (devc, 0x70, 0x0300);
-	  ac97_write (devc, 0x64, 0x8041);
-	  ac97_write (devc, 0x62, 0x180F);
-	  ac97_remove_control (&devc->ac97devc, UNUSED_CMI9780_CONTROLS, 0);
-	}
     }
 
   /* check if there's an front panel AC97 codec (CODEC1) and install the mixer */
     }
 
 
+
+    switch(devc->model) {
+            case SUBID_XONAR_D1:
+            case SUBID_XONAR_DX:
+                    /*GPIO8 = 0x100 controls mic/line-in */
+                    /*GPIO0 = 0x001controls output */
+                    /*GPIO2/3 = 0x00C codec output control*/
+
+                    /* setup for 2wire communication mode */
+                    OUTB(devc->osdev, INB (devc->osdev, FUNCTION) | 0x40, FUNCTION);
+                    /* setup GPIO direction */
+                    OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x010D, GPIO_CONTROL);
+                    /* setup GPIO pins */
+                    OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0101, GPIO_DATA);
+
+                    /* init the front and rear dacs */
+                    cs4398_init(devc, XONAR_DX_FRONTDAC);
+                    cs4362a_init(devc, XONAR_DX_SURRDAC);
+  		    /* initialize the codec 0 */
+  		    ac97_hwinit(devc);
+                    break;
+
+
+            case SUBID_XONAR_D2:
+            case SUBID_XONAR_D2X:
+                    /*GPIO7 = 0x0080 controls mic/line-in */
+                    /*GPIO8 = 0x0100 controls output */
+                    /*GPIO2/3 = 0x000C codec output control*/
+
+                    /* setup for spi communication mode */
+                    OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION);
+                    /* setup the GPIO direction */
+                    OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x018C, GPIO_CONTROL);
+	            /* setup GPIO Pins */
+	            OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x0100, GPIO_DATA);
+
+                    /* for all 4 codecs: unmute, set to 24Bit SPI */
+		    for (i = 0; i < 4; ++i) {
+			pcm1796_write(devc, i, 16, mix_scale(75,8)); /* left vol*/
+			pcm1796_write(devc, i, 17, mix_scale(75,8)); /* right vol */
+			pcm1796_write(devc, i, 18, 0x30 | 0x80); /* unmute/24LSB/ATLD */
+		    }
+  		    /* initialize the codec 0 */
+  		    ac97_hwinit(devc);
+		    break;
+
+       case SUBID_XONAR_STX:
+	    /*GPIO0 = Antipop control */
+	    /*GPIO1 = frontpanel h/p control*/
+            /*GPIO7 = 0x0080 controls analog out*/
+            /*GPIO8 = 0x0100 controls mic/line in*/
+            /*GPIO2/3 = 0x000C codec input control*/
+
+            /* setup for 2wire communication mode */
+            OUTB(devc->osdev, INB (devc->osdev, FUNCTION) | 0x40, FUNCTION);
+
+	    /* setup the GPIO direction control register */
+            OUTW(devc->osdev, INW(devc->osdev, GPIO_CONTROL) | 0x018F, GPIO_CONTROL);
+            /* setup GPIO pins mic/output */
+            OUTW(devc->osdev, INW(devc->osdev, GPIO_DATA) | 0x111, GPIO_DATA);
+
+            OUTW(devc->osdev, INW(devc, TWO_WIRE_CTRL)|0x0100, TWO_WIRE_CTRL);
+
+	    /* initialize the PCM1796 DAC */
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 16, mix_scale(75,8));
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 17, mix_scale(75,8));
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 18, 0x00|0x30|0x80); /*unmute, 24LSB, ATLD */
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 19, 0); /*ATS1/FLT_SHARP*/
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 20, 0); /*OS_64*/
+            two_wire_write(devc, XONAR_STX_FRONTDAC, 21, 0); 
+
+            /* initialize the codec 0 */
+            ac97_hwinit(devc);
+
+	   default:
+		   /* SPI default for anything else, including the */
+		   OUTB(devc->osdev, (INB (devc->osdev, FUNCTION) & ~0x40) | 0x80, FUNCTION);
+		   break;
+  }
+
   /* check if MPU401 is enabled in MISC register */
   if (INB (devc->osdev, MISC_REG) & 0x40)
     attach_mpu (devc);
 	  sprintf (tmp_name, "%s (MultiChannel)", devc->chip_name);
 	  caps |= ADEV_DUPLEX;
 	  fmt |= AFMT_S32_LE;
-	  portc->port_type = ADEV_MULTICH;
+	  portc->dac_type = ADEV_MULTICH;
+	  switch(devc->model)
+  	  {
+		case SUBID_XONAR_D1:
+		case SUBID_XONAR_DX:
+		case SUBID_XONAR_D2:
+		case SUBID_XONAR_D2X:
+		case SUBID_XONAR_STX:
+			portc->adc_type = ADEV_I2SADC2;
+      			break;
+		default:
+			portc->adc_type = ADEV_I2SADC1;
+      			OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
+			break;
+  	  }
+
 	  portc->min_rate = 32000;
 	  portc->max_rate = 192000;
 	  portc->min_chan = 2;
 	  sprintf (tmp_name, "%s (Multichannel)", devc->chip_name);
 	  caps |= ADEV_DUPLEX | ADEV_SHADOW;
 	  fmt |= AFMT_S32_LE;
-	  portc->port_type = ADEV_MULTICH;
+	  portc->dac_type = ADEV_MULTICH;
+          switch(devc->model)
+          {
+                case SUBID_XONAR_D1:
+                case SUBID_XONAR_DX:
+                case SUBID_XONAR_D2:
+                case SUBID_XONAR_D2X:
+                case SUBID_XONAR_STX:
+                        portc->adc_type = ADEV_I2SADC2;
+                        break;
+                default:
+                        portc->adc_type = ADEV_I2SADC1;
+      			OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
+                        break;
+          }
+
 	  portc->min_rate = 32000;
 	  portc->max_rate = 192000;
 	  portc->min_chan = 2;
 	  caps |=
 	    ADEV_DUPLEX | ADEV_16BITONLY | ADEV_STEREOONLY | ADEV_SPECIAL;
 	  fmt |= AFMT_AC3;
-	  portc->port_type = ADEV_FRONTPANEL;
+	  portc->dac_type = ADEV_FRONTPANEL;
+	  portc->adc_type = ADEV_I2SADC2;
+      	  OUTB (devc->osdev, INB (devc->osdev, REC_ROUTING) | 0x18, REC_ROUTING);
 	  portc->min_rate = 8000;
 	  portc->max_rate = 48000;
 	  portc->min_chan = 2;
 	  sprintf (tmp_name, "%s (SPDIF)", devc->chip_name);
 	  caps |= ADEV_DUPLEX | ADEV_STEREOONLY | ADEV_SPECIAL;
 	  fmt |= AFMT_AC3 | AFMT_S32_LE;
-	  portc->port_type = ADEV_SPDIF;
+	  portc->dac_type = ADEV_SPDIF;
+	  portc->adc_type = ADEV_I2SADC3;
 	  portc->min_rate = 32000;
 	  portc->max_rate = 192000;
 	  portc->min_chan = 2;
    */
   default_vol = 0x4b4b;
   devc->playvol[0] =
-    cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev,
+    cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
 			 MIXER_WRITE (SOUND_MIXER_PCM), &default_vol);
   devc->playvol[1] =
-    cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev,
+    cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
 			 MIXER_WRITE (SOUND_MIXER_REARVOL), &default_vol);
   devc->playvol[2] =
-    cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev,
+    cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
 			 MIXER_WRITE (SOUND_MIXER_CENTERVOL), &default_vol);
   devc->playvol[3] =
-    cmi8788_mixer_ioctl (devc->spi_mixer_dev, first_dev,
+    cmi8788_mixer_ioctl (devc->cmi_mixer_dev, first_dev,
 			 MIXER_WRITE (SOUND_MIXER_SIDEVOL), &default_vol);
 
-  /* Enable Xonar output */
-  switch(devc->model)
-  {
-    case SUBID_XONAR_D1:
-    case SUBID_XONAR_DX:
-      OUTW(devc->osdev, XONAR_DX_OUTPUT, GPIO_CONTROL);
-      OUTW(devc->osdev, XONAR_DX_OUTPUT, GPIO_DATA);
-      break;
-    case SUBID_XONAR_D2:
-    case SUBID_XONAR_D2X:
-      OUTW(devc->osdev, 0x100, GPIO_CONTROL);
-      OUTW(devc->osdev, 0x100, GPIO_DATA);
-      break;
-  }
-
   return 1;
 }
 
           case SUBID_XONAR_D2X:
             devc->chip_name = "Asus Xonar D2X (AV200)";
             break;
+          case SUBID_XONAR_STX:
+            devc->chip_name = "Asus Xonar Essence STX (AV100)";
+            break;
           default:
             devc->chip_name = "Asus Xonar (unknown)";
             sub_id = SUBID_GENERIC;

kernel/drv/oss_envy24ht/envy24ht.h

   int (*get_locked_status) (envy24ht_devc * devc);
   int (*spdif_mixer_init) (envy24ht_devc * devc, int dev, int group);
   int (*private1) (envy24ht_devc * devc, int value);
-  int (*audio_ioctl) (envy24ht_devc * devc, envy24ht_portc * portc, int cmd,
-		      int *arg);
+  int (*audio_ioctl) (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+		      ioctl_arg arg);
   void (*card_uninit) (envy24ht_devc * devc);
 };
 

kernel/drv/oss_envy24ht/envy24ht_ap192.c

 }
 
 static int
-ap192_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, int cmd,
-		   int *arg)
+ap192_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+		   ioctl_arg arg)
 {
   int left, right, value;
 

kernel/drv/oss_envy24ht/envy24ht_julia.c

   for (i = 0; rate_sel[i].rate; i++)
     if (rate_sel[i].spdifin == spdifin)
      {
-      if (devc->speed != rate_sel[i].rate);
+      if (devc->speed != rate_sel[i].rate)
        {
         devc->speed = rate_sel[i].rate;
         mixer_devs[devc->mixer_dev]->modify_counter++;
 }
 
 static int
-julia_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, int cmd,
-		   int *arg)
+julia_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+		   ioctl_arg arg)
 {
   int left, right, value;
 

kernel/drv/oss_envy24ht/envy24ht_revo51.c

 }
 
 static int
-revo51_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, int cmd,
-		    int *arg)
+revo51_audio_ioctl (envy24ht_devc * devc, envy24ht_portc * portc, unsigned int cmd,
+		    ioctl_arg arg)
 {
   int value;
 

kernel/drv/oss_hdaudio/hdaudio_codec.c

 		break;
 	  }
 
+	  if (mixer->copied_outendpoints >= HDA_MAX_OUTSTREAMS)
+	     {
+	          cmn_err (CE_WARN,
+			   "Too many output endpoints (%d)\n",
+			   mixer->copied_outendpoints);
+		  continue;
+	     }
+
 	  memcpy(&mixer->outendpoints[mixer->copied_outendpoints++], ep, sizeof(*ep));
 	  ep->already_used=1;
 	}
 		break;
 	  }
 
+	  if (mixer->copied_inendpoints >= HDA_MAX_INSTREAMS)
+	     {
+	          cmn_err (CE_WARN,
+			   "Too many output endpoints (%d)\n",
+			   mixer->copied_inendpoints);
+		  continue;
+	     }
+
 	  memcpy(&mixer->inendpoints[mixer->copied_inendpoints++], ep, sizeof(*ep));
 	  ep->already_used=1;
 	}

kernel/drv/oss_hdaudio/hdaudio_codecids.h

    * Assume the audio codec is identical with Vaio AGN (above).
    */
   {0x104d1e00, "Vaio/STAC9872AK", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847662, 0x104d9008},
+  /* Vaio VGC-LA1 */
+  {0x104d1200, "Vaio/STAC9872AK", VF_VAIO_HACK, (char**) &vaio_remap, 0x76540213, hdaudio_vaio_vgn_mixer_init, 0x83847662, 0x104d8205},
 
 /*
  * Thinkpad R61

kernel/drv/oss_hdaudio/hdaudio_vaio_vgn.c

 
   HDA_OUTAMP_F (0x05, top_group, "speaker", 90, MIXF_MAINVOL);
   /* We sync the volume of the headphone DAC to the speaker DAC */
-#if 0
+#if 1
   HDA_OUTAMP_F (0x02, top_group, "headphone", 90, MIXF_MAINVOL);
 #endif
 

kernel/drv/oss_imux/oss_imux.c

   devc->device_started = 1;
   devc->hw_channels = 2;
 
-  devc->hw_channels = devc->hw_channels =
+  devc->hw_channels =
     oss_audio_set_channels (devc->hw_dev, devc->hw_channels);
 
 /*

kernel/drv/oss_usb/oss_usb.c

       return "boost";
     case 9:
       return "loud";
+    case 10:
+      return "igain";
+    case 11:
+      return "igainpad";
+    case 12:
+      return "phaseinv";
+    case 13:
+      return "underflow";
+    case 14:
+      return "overflow";
     default:
       return "misc";
     }
 
 struct chmasks
 {
-  int mask;
+  unsigned int mask;
   char *name;
   char type;
   char channels;
 };
 
 static const struct chmasks chmasks[] = {
-  {0x0003, "front", MIXT_STEREOSLIDER, 2},
-  {0x0001, "L", MIXT_MONOSLIDER, 1},
-  {0x0002, "R", MIXT_MONOSLIDER, 1},
-  {0x0030, "surr", MIXT_STEREOSLIDER, 2},
-  {0x0010, "LS", MIXT_MONOSLIDER, 1},
-  {0x0020, "RS", MIXT_MONOSLIDER, 1},
-  {0x000c, "C/L", MIXT_STEREOSLIDER, 2},
-  {0x0004, "C", MIXT_MONOSLIDER, 1},
-  {0x0008, "LFE", MIXT_MONOSLIDER, 1},
-  {0x00c0, "center", MIXT_STEREOSLIDER, 2},
-  {0x0040, "LC", MIXT_MONOSLIDER, 1},
-  {0x0080, "RC", MIXT_MONOSLIDER, 1},
-  {0x0100, "surr", MIXT_STEREOSLIDER, 2},
-  {0x0600, "side", MIXT_STEREOSLIDER, 2},
-  {0x0200, "SL", MIXT_MONOSLIDER, 1},
-  {0x0400, "SR", MIXT_MONOSLIDER, 1},
-  {0x0800, "top", MIXT_MONOSLIDER, 1},
+  {0x00000003, "front", MIXT_STEREOSLIDER, 2},
+  {0x00000001, "L", MIXT_MONOSLIDER, 1},
+  {0x00000002, "R", MIXT_MONOSLIDER, 1},
+  {0x00000030, "surr", MIXT_STEREOSLIDER, 2},
+  {0x00000010, "LS", MIXT_MONOSLIDER, 1},
+  {0x00000020, "RS", MIXT_MONOSLIDER, 1},
+  {0x0000000c, "C/L", MIXT_STEREOSLIDER, 2},
+  {0x00000004, "C", MIXT_MONOSLIDER, 1},
+  {0x00000008, "LFE", MIXT_MONOSLIDER, 1},
+  {0x000000c0, "center", MIXT_STEREOSLIDER, 2},
+  {0x00000040, "LC", MIXT_MONOSLIDER, 1},
+  {0x00000080, "RC", MIXT_MONOSLIDER, 1},
+  {0x00000100, "surr", MIXT_STEREOSLIDER, 2},
+  {0x00000600, "side", MIXT_STEREOSLIDER, 2},
+  {0x00000200, "SL", MIXT_MONOSLIDER, 1},
+  {0x00000400, "SR", MIXT_MONOSLIDER, 1},
+  {0x00000800, "TC", MIXT_MONOSLIDER, 1},
+  {0x00001000, "TFL", MIXT_MONOSLIDER, 1},
+  {0x00002000, "TFC", MIXT_MONOSLIDER, 1},
+  {0x00004000, "TFR", MIXT_MONOSLIDER, 1},
+  {0x00008000, "TBL", MIXT_MONOSLIDER, 1},
+  {0x00010000, "TBC", MIXT_MONOSLIDER, 1},
+  {0x00020000, "TBR", MIXT_MONOSLIDER, 1},
+  {0x00040000, "TFLC", MIXT_MONOSLIDER, 1},
+  {0x00080000, "TFRC", MIXT_MONOSLIDER, 1},
+  {0x00100000, "LLFE", MIXT_MONOSLIDER, 1},
+  {0x00200000, "RLFE", MIXT_MONOSLIDER, 1},
+  {0x00400000, "TSL", MIXT_MONOSLIDER, 1},
+  {0x00800000, "TSR", MIXT_MONOSLIDER, 1},
+  {0x01000000, "BC", MIXT_MONOSLIDER, 1},
+  {0x02000000, "BLC", MIXT_MONOSLIDER, 1},
+  {0x04000000, "BRC", MIXT_MONOSLIDER, 1},
+  {0x80000000, "RD", MIXT_MONOSLIDER, 1},
   {0, NULL}
 };
 
 /*ARGSUSED*/
 static void
 add_multich_volumes (ossusb_devc * devc, usb_audio_unit_t * un, int group,
-		     int fea, int mask, unsigned short *feature_mask)
+		     int fea, int mask, unsigned int *feature_mask)
 {
   int i;
 
       if (!(mask & m))
 	continue;
 
-      ctl = new_ctl (devc, un, fea, chmasks[i].type, m);
+      ctl = new_ctl (devc, un, fea, chmasks[i].type, chmasks[i].mask);
       c = &devc->controls[ctl];
 
       UDB (cmn_err
 }
 
 static void
-translate_feature_mask (usb_audio_unit_t * un, unsigned short *feature_mask)
+translate_feature_mask_usb2 (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
 {
   int i, n, c;
   unsigned char *d = un->desc;
 
+  n = 4;
+  d = d + 5 + n;		// Skip the global mask
+
+/*
+ * USB 2.0 uses 2 bits for each control
+ * 	01b means that the control is read only and 11b means it's RW
+ */
+  for (c = 0; c < un->channels; c++)
+    {
+      unsigned int mask;
+      unsigned char *p = d + c * n;
+
+      mask = p[3] |
+	     (p[2] << 8) |
+	     (p[1] << 16) |
+	     (p[0] << 24);
+
+      for (i = 0; i < n * 4; i++)
+	if ((mask & (3 << 2*i)) && (un->ctl_avail & (1 << i)))
+	  {
+	    feature_mask[i] |= 1 << c;
+	  }
+    }
+}
+
+static void
+translate_feature_mask (ossusb_devc *devc, usb_audio_unit_t * un, unsigned int *feature_mask)
+{
+  int i, n, c;
+  unsigned char *d = un->desc;
+
+  if (devc->usb_version > 1)
+  {
+	translate_feature_mask_usb2(devc, un, feature_mask);
+	return;
+  }
+
   n = d[5];
   if (n < 1 || n > 2)
     {
-      cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
-      return;
+      	cmn_err (CE_CONT, "Bad feature mask size %d\n", n);
+       	return;
     }
 
-  d = d + 6 + n;		// Skip the global mask
+    d = d + 6 + n;		// Skip the global mask
 
   for (c = 0; c < un->channels; c++)
     {
 	    feature_mask[i] |= 1 << c;
 	  }
     }
-
 }
 
 static void
 			  int group)
 {
   int i;
-  unsigned short feature_mask[16], global_mask;
+  unsigned int feature_mask[16], global_mask;
 
   if (!un->ctl_avail)
     return;
   // Translate the channel/feature availability matrix
 
   memset (feature_mask, 0, sizeof (feature_mask));
-  translate_feature_mask (un, feature_mask);
+  translate_feature_mask (devc, un, feature_mask);
 
   for (i = 0; i < 16; i++)
     if (feature_mask[i])
   int old = 1;
   int i;
   int class, subclass;
-  int vendor, product;
+  int vendor, product, version;
 
   devpath = udi_usbdev_get_devpath (usbdev);
   inum = udi_usbdev_get_inum (usbdev);
   subclass = udi_usbdev_get_subclass (usbdev);
   vendor = udi_usbdev_get_vendor (usbdev);
   product = udi_usbdev_get_product (usbdev);
+  version = udi_usbdev_get_usb_version (usbdev);
 
   if ((devc = find_devc (devpath, vendor, product)) == NULL)
     {
 
       devc->vendor = vendor;
       devc->product = product;
+      devc->usb_version = version;
       devc->dev_name = udi_usbdev_get_name (usbdev);
 
       strcpy (devc->devpath, udi_usbdev_get_devpath (usbdev));

kernel/drv/oss_usb/ossusb.h

   char *dev_name, devpath[32];
   int nports;
   int disabled;
+  int usb_version; // 1 or 2
 
   /*
    * Units

kernel/framework/audio/oss_audio_core.c

  * Handle mixer ioctl calls on audio fd.
  */
 
+  if (cmd == SOUND_MIXER_WRITE_PCM) cmd = SNDCTL_DSP_SETPLAYVOL;
+  if (cmd == SOUND_MIXER_WRITE_RECLEV) cmd = SNDCTL_DSP_SETRECVOL;
+  if (cmd == SOUND_MIXER_READ_PCM) cmd = SNDCTL_DSP_GETPLAYVOL;
+  if (cmd == SOUND_MIXER_READ_RECLEV) cmd = SNDCTL_DSP_GETRECVOL;
+
   if ((mixdev = adev->mixer_dev) != -1)
     {
       if (((cmd >> 8) & 0xff) == 'M' && num_mixers > 0)	/* Mixer ioctl */
   adev = audio_engines[dev];
   dmap = adev->dmap_out;
 
+  MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
+
   if (dmap->dmabuf == NULL)
     {
+      MUTEX_EXIT_IRQRESTORE (dmap->mutex, flags);
       cmn_err (CE_WARN, "Output interrupt when no buffer is allocated\n");
       return;
     }
 
-  MUTEX_ENTER_IRQDISABLE (dmap->mutex, flags);
-
   if (!(intr_flags & AINTR_NO_POINTER_UPDATES))
     {
       dmap->byte_counter += dmap->fragment_size;

kernel/framework/audio/oss_spdif.c

 }
 
 int
-oss_spdif_ioctl (spdif_devc * devc, int open_mode, signed int cmd,
+oss_spdif_ioctl (spdif_devc * devc, int open_mode, unsigned int cmd,
 		 ioctl_arg arg)
 {
   if (!devc->is_ok)

kernel/framework/include/spdif.h

 extern void oss_spdif_close (spdif_devc * devc, int open_mode);
 extern void oss_spdif_setrate (spdif_devc * devc, int rate);
 extern int oss_spdif_mix_init (spdif_devc * devc);
-extern int oss_spdif_ioctl (spdif_devc * devc, int open_mode, signed int cmd,
+extern int oss_spdif_ioctl (spdif_devc * devc, int open_mode, unsigned int cmd,
 			    ioctl_arg arg);
 
 /*

kernel/framework/include/udi.h

 extern char *udi_usbdev_get_string (udi_usb_devc * usbdev, int ix);
 extern char *udi_usbdev_get_devpath (udi_usb_devc * usbdev);
 extern int udi_usbdev_get_num_altsettings (udi_usb_devc * usbdev);
+extern int udi_usbdev_get_usb_version (udi_usb_devc * usbdev);
 extern unsigned char *udi_usbdev_get_altsetting (udi_usb_devc * usbdev, int n,
 						 int *size);
 extern int udi_usbdev_set_interface (udi_usb_devc * usbdev, int inum,

kernel/framework/midi/oss_midi_core.c

 	  }
 
       MDB (cmn_err (CE_CONT, "Bytes in buffer=%d\n", len));
+#if 0
       if (buf != NULL)
 	MDB (cmn_err (CE_CONT, "First=%02x\n", buf[0]));
+#endif
 
       if (hdr == NULL)
 	{

kernel/framework/vmix_core/vmix_core.c

 	mixer = audio_engines[masterdev]->vmix_mixer;
 
 	if (mixer==NULL)
-	   return OSS_EPERM;
+	   return OSS_ENXIO;
 
 	mixer->rate = rate;
 

kernel/framework/vmix_core/vmix_output.c

   if (!mixer->multich_enable)
     mixer->play_engine.channels = 2;
 
-
-  /* Force the device to stereo before trying with (possibly) imultiple channels */
+  /* Force the device to stereo before trying with (possibly) multiple channels */
   adev->d->adrv_set_channels (mixer->masterdev, 2);
 
   mixer->play_engine.channels =

lib/libOSSlib/libmain.c

 #include <stdlib.h>
 #include <string.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 
 #define OSSLIB
 #include "../../include/soundcard.h"

os_cmd/FreeBSD/ossdetect/ossdetect.c

   if ((f = fopen ("/etc/oss.conf", "r")) == NULL)
     {
       perror ("/etc/oss.conf");
-      goto oexit;
+      goto oexit2;
     }