Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 13cba95..2f27f39 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -167,7 +167,7 @@
     spdif           - Support SPDIF I/O
     		    - Default: disabled
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports one chip and autoprobe.
 
     The power-management is supported.
 
@@ -206,7 +206,7 @@
 			  See "AC97 Quirk Option" section below.
     spdif_aclink	- S/PDIF transfer over AC-link (default = 1)
 
-    This module supports up to 8 cards and autoprobe.
+    This module supports one card and autoprobe.
 
     ATI IXP has two different methods to control SPDIF output.  One is
     over AC-link and another is over the "direct" SPDIF output.  The
@@ -218,7 +218,7 @@
 
     Module for ATI IXP 150/200/250 AC97 modem controllers.
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
@@ -637,7 +637,7 @@
     model	- force the model name
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Each codec may have a model table for different configurations.
     If your machine isn't listed there, the default (usually minimal)
@@ -663,6 +663,10 @@
 			adjusted.  Appearing only when compiled with
 			$CONFIG_SND_DEBUG=y
 
+	ALC260
+	  hp		HP machines
+	  fujitsu	Fujitsu S7020
+
 	CMI9880
 	  minimal	3-jack in back
 	  min_fp	3-jack in back, 2-jack in front
@@ -811,7 +815,7 @@
 		    semaphores (e.g. on some ASUS laptops)
 		    (default off)
 
-    Module supports autoprobe and multiple bus-master chips (max 8).
+    This module supports one chip and autoprobe.
 
     Note: the latest driver supports auto-detection of chip clock.
     if you still encounter too fast playback, specify the clock
@@ -830,7 +834,7 @@
 
     ac97_clock	  - AC'97 codec clock base (0 = auto-detect)
 
-    This module supports up to 8 cards and autoprobe.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
@@ -950,8 +954,10 @@
     use_cache        - 0 or 1 (disabled by default)
     vaio_hack        - alias buffer_top=0x25a800
     reset_workaround - enable AC97 RESET workaround for some laptops
+    reset_workaround2 - enable extended AC97 RESET workaround for some
+		      other laptops
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports one chip and autoprobe.
 
     The power-management is supported.
 
@@ -980,6 +986,11 @@
     workaround is enabled automatically.  For other laptops with a
     hard freeze, you can try reset_workaround=1 option.
 
+    Note: Dell Latitude CSx laptops have another problem regarding
+    AC97 RESET.  On these laptops, reset_workaround2 option is
+    turned on as default.  This option is worth to try if the
+    previous reset_workaround option doesn't help.
+
     Note: This driver is really crappy.  It's a porting from the
     OSS driver, which is a result of black-magic reverse engineering.
     The detection of codec will fail if the driver is loaded *after*
@@ -1310,7 +1321,7 @@
     ac97_quirk  - AC'97 workaround for strange hardware
 		  See "AC97 Quirk Option" section below.
 
-    Module supports autoprobe and multiple bus-master chips (max 8).
+    This module supports one chip and autoprobe.
 
     Note: on some SMP motherboards like MSI 694D the interrupts might
           not be generated properly.  In such a case, please try to
@@ -1352,7 +1363,7 @@
 
     ac97_clock	- AC'97 codec clock base (default 48000Hz)
 
-    Module supports up to 8 cards.
+    This module supports one card and autoprobe.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 24e8552..260334c 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
       </affiliation>
      </author>
 
-     <date>March 6, 2005</date>
-     <edition>0.3.4</edition>
+     <date>October 6, 2005</date>
+     <edition>0.3.5</edition>
 
     <abstract>
       <para>
@@ -30,7 +30,7 @@
 
     <legalnotice>
     <para>
-    Copyright (c) 2002-2004  Takashi Iwai <email>tiwai@suse.de</email>
+    Copyright (c) 2002-2005  Takashi Iwai <email>tiwai@suse.de</email>
     </para>
 
     <para>
@@ -1433,25 +1433,10 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  if (chip->res_port) {
-          release_resource(chip->res_port);
-          kfree_nocheck(chip->res_port);
-  }
+  release_and_free_resource(chip->res_port);
 ]]>
           </programlisting>
         </informalexample>
-
-      As you can see, the resource pointer is also to be freed
-      via <function>kfree_nocheck()</function> after
-      <function>release_resource()</function> is called. You
-      cannot use <function>kfree()</function> here, because on ALSA,
-      <function>kfree()</function> may be a wrapper to its own
-      allocator with the memory debugging. Since the resource pointer
-      is allocated externally outside the ALSA, it must be released
-      via the native
-      <function>kfree()</function>.
-      <function>kfree_nocheck()</function> is used for that; it calls
-      the native <function>kfree()</function> without wrapper. 
       </para>
 
       <para>
@@ -2190,8 +2175,7 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
-	int tstamp_timespec;		/* use timeval (0) or timespec (1) */
-	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
+	struct timespec tstamp_mode;	/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
 	snd_pcm_uframes_t xfer_align;	/* xfer size need to be a multiple */
@@ -3709,8 +3693,7 @@
         <para>
           Here, the chip instance is retrieved via
         <function>snd_kcontrol_chip()</function> macro.  This macro
-        converts from kcontrol-&gt;private_data to the type defined by
-        <type>chip_t</type>. The
+        just accesses to kcontrol-&gt;private_data. The
         kcontrol-&gt;private_data field is 
         given as the argument of <function>snd_ctl_new()</function>
         (see the later subsection
@@ -5998,32 +5981,23 @@
         The first argument is the expression to evaluate, and the
       second argument is the action if it fails. When
       <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
-      error message such as <computeroutput>BUG? (xxx) (called from
-      yyy)</computeroutput>. When no debug flag is set, this is
-      ignored. 
+      error message such as <computeroutput>BUG? (xxx)</computeroutput>
+      together with stack trace.
       </para>
-    </section>
-
-    <section id="useful-functions-snd-runtime-check">
-      <title><function>snd_runtime_check()</function></title>
       <para>
-        This macro is quite similar with
-      <function>snd_assert()</function>. Unlike
-      <function>snd_assert()</function>, the expression is always
-      evaluated regardless of
-      <constant>CONFIG_SND_DEBUG</constant>. When
-      <constant>CONFIG_SND_DEBUG</constant> is set, the macro will
-      show a message like <computeroutput>ERROR (xx) (called from
-      yyy)</computeroutput>. 
+	 When no debug flag is set, this macro is ignored. 
       </para>
     </section>
 
     <section id="useful-functions-snd-bug">
       <title><function>snd_BUG()</function></title>
       <para>
-        It calls <function>snd_assert(0,)</function> -- that is, just
-      prints the error message at the point. It's useful to show that
-      a fatal error happens there. 
+        It shows <computeroutput>BUG?</computeroutput> message and
+      stack trace as well as <function>snd_assert</function> at the point.
+      It's useful to show that a fatal error happens there. 
+      </para>
+      <para>
+	 When no debug flag is set, this macro is ignored. 
       </para>
     </section>
   </chapter>
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 63fff7c..a7f099f 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -149,8 +149,22 @@
 #ifdef RTC_IRQ
 static void rtc_dropped_irq(unsigned long data);
 
-static void set_rtc_irq_bit(unsigned char bit);
-static void mask_rtc_irq_bit(unsigned char bit);
+static void set_rtc_irq_bit_locked(unsigned char bit);
+static void mask_rtc_irq_bit_locked(unsigned char bit);
+
+static inline void set_rtc_irq_bit(unsigned char bit)
+{
+	spin_lock_irq(&rtc_lock);
+	set_rtc_irq_bit_locked(bit);
+	spin_unlock_irq(&rtc_lock);
+}
+
+static void mask_rtc_irq_bit(unsigned char bit)
+{
+	spin_lock_irq(&rtc_lock);
+	mask_rtc_irq_bit_locked(bit);
+	spin_unlock_irq(&rtc_lock);
+}
 #endif
 
 static int rtc_proc_open(struct inode *inode, struct file *file);
@@ -401,18 +415,19 @@
 	}
 	case RTC_PIE_OFF:	/* Mask periodic int. enab. bit	*/
 	{
-		mask_rtc_irq_bit(RTC_PIE);
+		unsigned long flags; /* can be called from isr via rtc_control() */
+		spin_lock_irqsave (&rtc_lock, flags);
+		mask_rtc_irq_bit_locked(RTC_PIE);
 		if (rtc_status & RTC_TIMER_ON) {
-			spin_lock_irq (&rtc_lock);
 			rtc_status &= ~RTC_TIMER_ON;
 			del_timer(&rtc_irq_timer);
-			spin_unlock_irq (&rtc_lock);
 		}
+		spin_unlock_irqrestore (&rtc_lock, flags);
 		return 0;
 	}
 	case RTC_PIE_ON:	/* Allow periodic ints		*/
 	{
-
+		unsigned long flags; /* can be called from isr via rtc_control() */
 		/*
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
@@ -421,14 +436,14 @@
 			(!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
+		spin_lock_irqsave (&rtc_lock, flags);
 		if (!(rtc_status & RTC_TIMER_ON)) {
-			spin_lock_irq (&rtc_lock);
 			rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
 			add_timer(&rtc_irq_timer);
 			rtc_status |= RTC_TIMER_ON;
-			spin_unlock_irq (&rtc_lock);
 		}
-		set_rtc_irq_bit(RTC_PIE);
+		set_rtc_irq_bit_locked(RTC_PIE);
+		spin_unlock_irqrestore (&rtc_lock, flags);
 		return 0;
 	}
 	case RTC_UIE_OFF:	/* Mask ints from RTC updates.	*/
@@ -609,6 +624,7 @@
 	{
 		int tmp = 0;
 		unsigned char val;
+		unsigned long flags; /* can be called from isr via rtc_control() */
 
 		/* 
 		 * The max we can do is 8192Hz.
@@ -631,9 +647,9 @@
 		if (arg != (1<<tmp))
 			return -EINVAL;
 
-		spin_lock_irq(&rtc_lock);
+		spin_lock_irqsave(&rtc_lock, flags);
 		if (hpet_set_periodic_freq(arg)) {
-			spin_unlock_irq(&rtc_lock);
+			spin_unlock_irqrestore(&rtc_lock, flags);
 			return 0;
 		}
 		rtc_freq = arg;
@@ -641,7 +657,7 @@
 		val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
 		val |= (16 - tmp);
 		CMOS_WRITE(val, RTC_FREQ_SELECT);
-		spin_unlock_irq(&rtc_lock);
+		spin_unlock_irqrestore(&rtc_lock, flags);
 		return 0;
 	}
 #endif
@@ -844,12 +860,15 @@
 #ifndef RTC_IRQ
 	return -EIO;
 #else
-	spin_lock_irq(&rtc_task_lock);
+	unsigned long flags;
+	if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
+		return -EINVAL;
+	spin_lock_irqsave(&rtc_task_lock, flags);
 	if (rtc_callback != task) {
-		spin_unlock_irq(&rtc_task_lock);
+		spin_unlock_irqrestore(&rtc_task_lock, flags);
 		return -ENXIO;
 	}
-	spin_unlock_irq(&rtc_task_lock);
+	spin_unlock_irqrestore(&rtc_task_lock, flags);
 	return rtc_do_ioctl(cmd, arg, 1);
 #endif
 }
@@ -1306,40 +1325,32 @@
  * meddles with the interrupt enable/disable bits.
  */
 
-static void mask_rtc_irq_bit(unsigned char bit)
+static void mask_rtc_irq_bit_locked(unsigned char bit)
 {
 	unsigned char val;
 
-	spin_lock_irq(&rtc_lock);
-	if (hpet_mask_rtc_irq_bit(bit)) {
-		spin_unlock_irq(&rtc_lock);
+	if (hpet_mask_rtc_irq_bit(bit))
 		return;
-	}
 	val = CMOS_READ(RTC_CONTROL);
 	val &=  ~bit;
 	CMOS_WRITE(val, RTC_CONTROL);
 	CMOS_READ(RTC_INTR_FLAGS);
 
 	rtc_irq_data = 0;
-	spin_unlock_irq(&rtc_lock);
 }
 
-static void set_rtc_irq_bit(unsigned char bit)
+static void set_rtc_irq_bit_locked(unsigned char bit)
 {
 	unsigned char val;
 
-	spin_lock_irq(&rtc_lock);
-	if (hpet_set_rtc_irq_bit(bit)) {
-		spin_unlock_irq(&rtc_lock);
+	if (hpet_set_rtc_irq_bit(bit))
 		return;
-	}
 	val = CMOS_READ(RTC_CONTROL);
 	val |= bit;
 	CMOS_WRITE(val, RTC_CONTROL);
 	CMOS_READ(RTC_INTR_FLAGS);
 
 	rtc_irq_data = 0;
-	spin_unlock_irq(&rtc_lock);
 }
 #endif
 
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index d11f348..7f0ca79 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -387,15 +387,6 @@
 #define AC97_RATES_MIC_ADC	4
 #define AC97_RATES_SPDIF	5
 
-/* shared controllers */
-enum {
-	AC97_SHARED_TYPE_NONE,
-	AC97_SHARED_TYPE_ICH,
-	AC97_SHARED_TYPE_ATIIXP,
-	AC97_SHARED_TYPE_VIA,
-	AC97_SHARED_TYPES
-};
-
 /*
  *
  */
@@ -468,7 +459,6 @@
 	unsigned short used_slots[2][4]; /* actually used PCM slots */
 	unsigned short pcms_count; /* count of PCMs */
 	struct ac97_pcm *pcms;
-	unsigned int shared_type;	/* type of shared controller betwen audio and modem */
 	ac97_t *codec[4];
 	snd_info_entry_t *proc;
 };
diff --git a/include/sound/core.h b/include/sound/core.h
index 6d971a4..2be65ad 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -29,7 +29,6 @@
 #include <linux/pm.h>			/* pm_message_t */
 
 /* Typedef's */
-typedef struct timespec snd_timestamp_t;
 typedef struct sndrv_interval snd_interval_t;
 typedef enum sndrv_card_type snd_card_type;
 typedef struct sndrv_xferi snd_xferi_t;
@@ -256,6 +255,7 @@
 
 /* sound.c */
 
+extern int snd_major;
 extern int snd_ecards_limit;
 
 void snd_request_card(int card);
@@ -285,39 +285,6 @@
 
 /* memory.c */
 
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void snd_memory_init(void);
-void snd_memory_done(void);
-int snd_memory_info_init(void);
-int snd_memory_info_done(void);
-void *snd_hidden_kmalloc(size_t size, gfp_t flags);
-void *snd_hidden_kzalloc(size_t size, gfp_t flags);
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
-void snd_hidden_kfree(const void *obj);
-void *snd_hidden_vmalloc(unsigned long size);
-void snd_hidden_vfree(void *obj);
-char *snd_hidden_kstrdup(const char *s, gfp_t flags);
-#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
-#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
-#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
-#define kfree(obj) snd_hidden_kfree(obj)
-#define vmalloc(size) snd_hidden_vmalloc(size)
-#define vfree(obj) snd_hidden_vfree(obj)
-#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
-#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
-#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
-#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
-#define kstrdup(s, flags)  snd_hidden_kstrdup(s, flags)
-#else
-#define snd_memory_init() /*NOP*/
-#define snd_memory_done() /*NOP*/
-#define snd_memory_info_init() /*NOP*/
-#define snd_memory_info_done() /*NOP*/
-#define kmalloc_nocheck(size, flags) kmalloc(size, flags)
-#define vmalloc_nocheck(size) vmalloc(size)
-#define kfree_nocheck(obj) kfree(obj)
-#define vfree_nocheck(obj) vfree(obj)
-#endif
 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
 
@@ -373,8 +340,9 @@
 #endif
 
 /* misc.c */
+struct resource;
+void release_and_free_resource(struct resource *res);
 
-int snd_task_name(struct task_struct *task, char *name, size_t size);
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 void snd_verbose_printk(const char *file, int line, const char *format, ...)
      __attribute__ ((format (printf, 3, 4)));
@@ -429,34 +397,24 @@
  * When CONFIG_SND_DEBUG is not set, the expression is executed but
  * not checked.
  */
-#define snd_assert(expr, args...) do {\
-	if (unlikely(!(expr))) {				\
-		snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
-		args;\
-	}\
+#define snd_assert(expr, args...) do {					\
+	if (unlikely(!(expr))) {					\
+		snd_printk(KERN_ERR "BUG? (%s)\n", __ASTRING__(expr));	\
+		dump_stack();						\
+		args;							\
+	}								\
 } while (0)
-/**
- * snd_runtime_check - run-time assertion macro
- * @expr: expression
- * @args...: the action
- *
- * This macro checks the expression in run-time and invokes the commands
- * given in the rest arguments if the assertion is failed.
- * Unlike snd_assert(), the action commands are executed even if
- * CONFIG_SND_DEBUG is not set but without any error messages.
- */
-#define snd_runtime_check(expr, args...) do {\
-	if (unlikely(!(expr))) {				\
-		snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
-		args;\
-	}\
+
+#define snd_BUG() do {				\
+	snd_printk(KERN_ERR "BUG?\n");		\
+	dump_stack();				\
 } while (0)
 
 #else /* !CONFIG_SND_DEBUG */
 
 #define snd_printd(fmt, args...)	/* nothing */
 #define snd_assert(expr, args...)	(void)(expr)
-#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0)
+#define snd_BUG()			/* nothing */
 
 #endif /* CONFIG_SND_DEBUG */
 
@@ -473,30 +431,6 @@
 #define snd_printdd(format, args...) /* nothing */
 #endif
 
-#define snd_BUG() snd_assert(0, )
-
-
-static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
-{
-	struct timeval val;
-	/* FIXME: use a linear time source */
-	do_gettimeofday(&val);
-	tstamp->tv_sec = val.tv_sec;
-	tstamp->tv_nsec = val.tv_usec;
-	if (timespec)
-		tstamp->tv_nsec *= 1000L;
-}
-
-static inline void snd_timestamp_zero(struct timespec *tstamp)
-{
-	tstamp->tv_sec = 0;
-	tstamp->tv_nsec = 0;
-}
-
-static inline int snd_timestamp_null(struct timespec *tstamp)
-{
-	return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
-}
 
 #define SNDRV_OSS_VERSION         ((3<<16)|(8<<8)|(1<<4)|(0))	/* 3.8.1a */
 
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 1ec2fae..3f0416a 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -44,21 +44,4 @@
 
 #include <linux/module.h>
 
-/*
- *  ==========================================================================
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-void *snd_wrapper_kmalloc(size_t, gfp_t);
-#undef kmalloc
-void snd_wrapper_kfree(const void *);
-#undef kfree
-void *snd_wrapper_vmalloc(size_t);
-#undef vmalloc
-void snd_wrapper_vfree(void *);
-#undef vfree
-#endif
-
 #endif /* __SOUND_DRIVER_H */
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 46e3c0b..8411c7e 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -48,7 +48,8 @@
 
 /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
 #define EMU10K1_DMA_MASK	0x7fffffffUL	/* 31bit */
-#define AUDIGY_DMA_MASK		0xffffffffUL	/* 32bit */
+#define AUDIGY_DMA_MASK		0x7fffffffUL	/* 31bit FIXME - 32 should work? */
+						/* See ALSA bug #1276 - rlrevell */
 
 #define TMEMSIZE        256*1024
 #define TMEMSIZEREG     4
diff --git a/include/sound/minors.h b/include/sound/minors.h
index b7b0d83..a17b5c9 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -27,8 +27,9 @@
 #define SNDRV_MINOR(card, dev)		(((card) << 5) | (dev))
 
 #define SNDRV_MINOR_CONTROL		0	/* 0 - 0 */
-#define SNDRV_MINOR_SEQUENCER		1
-#define SNDRV_MINOR_TIMER		(1+32)
+#define SNDRV_MINOR_GLOBAL		1	/* 1 */
+#define SNDRV_MINOR_SEQUENCER		(SNDRV_MINOR_GLOBAL + 0 * 32)
+#define SNDRV_MINOR_TIMER		(SNDRV_MINOR_GLOBAL + 1 * 32)
 #define SNDRV_MINOR_HWDEP		4	/* 4 - 7 */
 #define SNDRV_MINOR_HWDEPS		4
 #define SNDRV_MINOR_RAWMIDI		8	/* 8 - 15 */
@@ -39,12 +40,9 @@
 
 #define SNDRV_DEVICE_TYPE_CONTROL	SNDRV_MINOR_CONTROL
 #define SNDRV_DEVICE_TYPE_HWDEP		SNDRV_MINOR_HWDEP
-#define SNDRV_DEVICE_TYPE_MIXER		SNDRV_MINOR_MIXER
 #define SNDRV_DEVICE_TYPE_RAWMIDI	SNDRV_MINOR_RAWMIDI
 #define SNDRV_DEVICE_TYPE_PCM_PLAYBACK	SNDRV_MINOR_PCM_PLAYBACK
-#define SNDRV_DEVICE_TYPE_PCM_PLOOP	SNDRV_MINOR_PCM_PLOOP
 #define SNDRV_DEVICE_TYPE_PCM_CAPTURE	SNDRV_MINOR_PCM_CAPTURE
-#define SNDRV_DEVICE_TYPE_PCM_CLOOP	SNDRV_MINOR_PCM_CLOOP
 #define SNDRV_DEVICE_TYPE_SEQUENCER	SNDRV_MINOR_SEQUENCER
 #define SNDRV_DEVICE_TYPE_TIMER		SNDRV_MINOR_TIMER
 
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 2b23a59..acc4fa9 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -281,7 +281,7 @@
 struct _snd_pcm_runtime {
 	/* -- Status -- */
 	snd_pcm_substream_t *trigger_master;
-	snd_timestamp_t trigger_tstamp;	/* trigger timestamp */
+	struct timespec trigger_tstamp;	/* trigger timestamp */
 	int overrange;
 	snd_pcm_uframes_t avail_max;
 	snd_pcm_uframes_t hw_ptr_base;	/* Position at buffer restart */
@@ -306,7 +306,6 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
-	int tstamp_timespec;		/* use timeval (0) or timespec (1) */
 	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
diff --git a/include/sound/timer.h b/include/sound/timer.h
index 1898511..b55f38a 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -88,6 +88,7 @@
 struct _snd_timer {
 	snd_timer_class_t tmr_class;
 	snd_card_t *card;
+	struct module *module;
 	int tmr_device;
 	int tmr_subdevice;
 	char id[64];
diff --git a/include/sound/version.h b/include/sound/version.h
index ee32af2..d1bd3b7 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.10rc1"
-#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.10rc3"
+#define CONFIG_SND_DATE " (Mon Nov 07 13:30:21 2005 UTC)"
diff --git a/sound/Kconfig b/sound/Kconfig
index b65ee47..d8f1140 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -48,6 +48,14 @@
 
 	  For more information, see <http://www.alsa-project.org/>
 
+config SND_AC97_CODEC
+	tristate
+	select SND_PCM
+	select SND_AC97_BUS
+
+config SND_AC97_BUS
+	tristate
+
 source "sound/core/Kconfig"
 
 source "sound/drivers/Kconfig"
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 48cf45c..8271883 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -127,12 +127,6 @@
 	help
 	  Say Y here to enable ALSA debug code.
 
-config SND_DEBUG_MEMORY
-	bool "Debug memory"
-	depends on SND_DEBUG
-	help
-	  Say Y here to enable debugging of memory allocations.
-
 config SND_DEBUG_DETECT
 	bool "Debug detection"
 	depends on SND_DEBUG
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 969d755..5a01c76 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -3,8 +3,7 @@
 # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-objs     := sound.o init.o memory.o info.o control.o misc.o \
-                device.o wrappers.o
+snd-objs     := sound.o init.o memory.o info.o control.o misc.o device.o
 ifeq ($(CONFIG_ISA_DMA_API),y)
 snd-objs     += isadma.o
 endif
diff --git a/sound/core/control.c b/sound/core/control.c
index 736edf3..212c46a 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -144,7 +144,7 @@
 	snd_ctl_file_t *ctl;
 	snd_kctl_event_t *ev;
 	
-	snd_runtime_check(card != NULL && id != NULL, return);
+	snd_assert(card != NULL && id != NULL, return);
 	read_lock(&card->ctl_files_rwlock);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	card->mixer_oss_change_count++;
@@ -193,8 +193,8 @@
 	snd_kcontrol_t *kctl;
 	unsigned int idx;
 	
-	snd_runtime_check(control != NULL, return NULL);
-	snd_runtime_check(control->count > 0, return NULL);
+	snd_assert(control != NULL, return NULL);
+	snd_assert(control->count > 0, return NULL);
 	kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
 	if (kctl == NULL)
 		return NULL;
@@ -220,7 +220,7 @@
 	snd_kcontrol_t kctl;
 	unsigned int access;
 	
-	snd_runtime_check(ncontrol != NULL, return NULL);
+	snd_assert(ncontrol != NULL, return NULL);
 	snd_assert(ncontrol->info != NULL, return NULL);
 	memset(&kctl, 0, sizeof(kctl));
 	kctl.id.iface = ncontrol->iface;
@@ -309,7 +309,7 @@
 	snd_ctl_elem_id_t id;
 	unsigned int idx;
 
-	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
 	snd_assert(kcontrol->info != NULL, return -EINVAL);
 	id = kcontrol->id;
 	down_write(&card->controls_rwsem);
@@ -355,7 +355,7 @@
 	snd_ctl_elem_id_t id;
 	unsigned int idx;
 
-	snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
+	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
 	list_del(&kcontrol->list);
 	card->controls_count -= kcontrol->count;
 	id = kcontrol->id;
@@ -468,7 +468,7 @@
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
-	snd_runtime_check(card != NULL && numid != 0, return NULL);
+	snd_assert(card != NULL && numid != 0, return NULL);
 	list_for_each(list, &card->controls) {
 		kctl = snd_kcontrol(list);
 		if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
@@ -494,7 +494,7 @@
 	struct list_head *list;
 	snd_kcontrol_t *kctl;
 
-	snd_runtime_check(card != NULL && id != NULL, return NULL);
+	snd_assert(card != NULL && id != NULL, return NULL);
 	if (id->numid != 0)
 		return snd_ctl_find_numid(card, id->numid);
 	list_for_each(list, &card->controls) {
@@ -1215,7 +1215,7 @@
 	struct list_head *list;
 	snd_kctl_ioctl_t *p;
 
-	snd_runtime_check(fcn != NULL, return -EINVAL);
+	snd_assert(fcn != NULL, return -EINVAL);
 	down_write(&snd_ioctl_rwsem);
 	list_for_each(list, lists) {
 		p = list_entry(list, snd_kctl_ioctl_t, list);
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 9383f12..e91cee3 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -81,20 +81,16 @@
 	int err;
 	wait_queue_t wait;
 
-	switch (major) {
-	case CONFIG_SND_MAJOR:
+	if (major == snd_major) {
 		cardnum = SNDRV_MINOR_CARD(iminor(inode));
 		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
-		break;
 #ifdef CONFIG_SND_OSSEMUL
-	case SOUND_MAJOR:
+	} else if (major == SOUND_MAJOR) {
 		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
 		device = 0;
-		break;
 #endif
-	default:
+	} else
 		return -ENXIO;
-	}
 	cardnum %= SNDRV_CARDS;
 	device %= SNDRV_MINOR_HWDEPS;
 	hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];
diff --git a/sound/core/info.c b/sound/core/info.c
index 37024d6..39f9b97 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -566,7 +566,6 @@
 	}
 #endif
 	snd_info_version_init();
-	snd_memory_info_init();
 	snd_minor_info_init();
 	snd_minor_info_oss_init();
 	snd_card_info_init();
@@ -578,7 +577,6 @@
 	snd_card_info_done();
 	snd_minor_info_oss_done();
 	snd_minor_info_done();
-	snd_memory_info_done();
 	snd_info_version_done();
 	if (snd_proc_root) {
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
diff --git a/sound/core/init.c b/sound/core/init.c
index 41e2249..d9ee27a 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -420,7 +420,7 @@
 	int err;
 	snd_info_entry_t *entry;
 
-	snd_runtime_check(card != NULL, return -EINVAL);
+	snd_assert(card != NULL, return -EINVAL);
 	if ((err = snd_device_register_all(card)) < 0)
 		return err;
 	write_lock(&snd_card_rwlock);
@@ -524,7 +524,8 @@
 	snd_info_entry_t *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
-	snd_runtime_check(entry != NULL, return -ENOMEM);
+	if (! entry)
+		return -ENOMEM;
 	entry->c.text.read_size = PAGE_SIZE;
 	entry->c.text.read = snd_card_info_read;
 	if (snd_info_register(entry) < 0) {
@@ -840,7 +841,7 @@
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
 		return 0;
-	if (card->pm_suspend)
+	if (card->pm_resume)
 		card->pm_resume(card);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
diff --git a/sound/core/memory.c b/sound/core/memory.c
index 7d8e2ee..862d62d 100644
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  * 
- *  Memory allocation helpers.
+ *  Misc memory accessors
  *
  *
  *   This program is free software; you can redistribute it and/or modify
@@ -20,221 +20,9 @@
  *
  */
 
-#include <sound/driver.h>
+#include <linux/config.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/pci.h>
-#include <sound/core.h>
-#include <sound/info.h>
-
-/*
- *  memory allocation helpers and debug routines
- */
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-
-struct snd_alloc_track {
-	unsigned long magic;
-	void *caller;
-	size_t size;
-	struct list_head list;
-	long data[0];
-};
-
-#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)
-
-static long snd_alloc_kmalloc;
-static long snd_alloc_vmalloc;
-static LIST_HEAD(snd_alloc_kmalloc_list);
-static LIST_HEAD(snd_alloc_vmalloc_list);
-static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
-static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
-#define KMALLOC_MAGIC 0x87654321
-#define VMALLOC_MAGIC 0x87654320
-static snd_info_entry_t *snd_memory_info_entry;
-
-void __init snd_memory_init(void)
-{
-	snd_alloc_kmalloc = 0;
-	snd_alloc_vmalloc = 0;
-}
-
-void snd_memory_done(void)
-{
-	struct list_head *head;
-	struct snd_alloc_track *t;
-
-	if (snd_alloc_kmalloc > 0)
-		snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
-	if (snd_alloc_vmalloc > 0)
-		snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc);
-	list_for_each_prev(head, &snd_alloc_kmalloc_list) {
-		t = list_entry(head, struct snd_alloc_track, list);
-		if (t->magic != KMALLOC_MAGIC) {
-			snd_printk(KERN_ERR "Corrupted kmalloc\n");
-			break;
-		}
-		snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
-	}
-	list_for_each_prev(head, &snd_alloc_vmalloc_list) {
-		t = list_entry(head, struct snd_alloc_track, list);
-		if (t->magic != VMALLOC_MAGIC) {
-			snd_printk(KERN_ERR "Corrupted vmalloc\n");
-			break;
-		}
-		snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
-	}
-}
-
-static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
-{
-	unsigned long cpu_flags;
-	struct snd_alloc_track *t;
-	void *ptr;
-	
-	ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags);
-	if (ptr != NULL) {
-		t = (struct snd_alloc_track *)ptr;
-		t->magic = KMALLOC_MAGIC;
-		t->caller = caller;
-		spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags);
-		list_add_tail(&t->list, &snd_alloc_kmalloc_list);
-		spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags);
-		t->size = size;
-		snd_alloc_kmalloc += size;
-		ptr = t->data;
-	}
-	return ptr;
-}
-
-#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
-void *snd_hidden_kmalloc(size_t size, gfp_t flags)
-{
-	return _snd_kmalloc(size, flags);
-}
-
-void *snd_hidden_kzalloc(size_t size, gfp_t flags)
-{
-	void *ret = _snd_kmalloc(size, flags);
-	if (ret)
-		memset(ret, 0, size);
-	return ret;
-}
-EXPORT_SYMBOL(snd_hidden_kzalloc);
-
-void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags)
-{
-	void *ret = NULL;
-	if (n != 0 && size > INT_MAX / n)
-		return ret;
-	return snd_hidden_kzalloc(n * size, flags);
-}
-
-void snd_hidden_kfree(const void *obj)
-{
-	unsigned long flags;
-	struct snd_alloc_track *t;
-	if (obj == NULL)
-		return;
-	t = snd_alloc_track_entry(obj);
-	if (t->magic != KMALLOC_MAGIC) {
-		snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0));
-		return;
-	}
-	spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags);
-	list_del(&t->list);
-	spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags);
-	t->magic = 0;
-	snd_alloc_kmalloc -= t->size;
-	obj = t;
-	snd_wrapper_kfree(obj);
-}
-
-void *snd_hidden_vmalloc(unsigned long size)
-{
-	void *ptr;
-	ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track));
-	if (ptr) {
-		struct snd_alloc_track *t = (struct snd_alloc_track *)ptr;
-		t->magic = VMALLOC_MAGIC;
-		t->caller = __builtin_return_address(0);
-		spin_lock(&snd_alloc_vmalloc_lock);
-		list_add_tail(&t->list, &snd_alloc_vmalloc_list);
-		spin_unlock(&snd_alloc_vmalloc_lock);
-		t->size = size;
-		snd_alloc_vmalloc += size;
-		ptr = t->data;
-	}
-	return ptr;
-}
-
-void snd_hidden_vfree(void *obj)
-{
-	struct snd_alloc_track *t;
-	if (obj == NULL)
-		return;
-	t = snd_alloc_track_entry(obj);
-	if (t->magic != VMALLOC_MAGIC) {
-		snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
-		return;
-	}
-	spin_lock(&snd_alloc_vmalloc_lock);
-	list_del(&t->list);
-	spin_unlock(&snd_alloc_vmalloc_lock);
-	t->magic = 0;
-	snd_alloc_vmalloc -= t->size;
-	obj = t;
-	snd_wrapper_vfree(obj);
-}
-
-char *snd_hidden_kstrdup(const char *s, gfp_t flags)
-{
-	int len;
-	char *buf;
-
-	if (!s) return NULL;
-
-	len = strlen(s) + 1;
-	buf = _snd_kmalloc(len, flags);
-	if (buf)
-		memcpy(buf, s, len);
-	return buf;
-}
-
-static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
-{
-	snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
-	snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
-}
-
-int __init snd_memory_info_init(void)
-{
-	snd_info_entry_t *entry;
-
-	entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL);
-	if (entry) {
-		entry->c.text.read_size = 256;
-		entry->c.text.read = snd_memory_info_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	snd_memory_info_entry = entry;
-	return 0;
-}
-
-int __exit snd_memory_info_done(void)
-{
-	if (snd_memory_info_entry)
-		snd_info_unregister(snd_memory_info_entry);
-	return 0;
-}
-
-#endif /* CONFIG_SND_DEBUG_MEMORY */
 
 /**
  * copy_to_user_fromio - copy data from mmio-space to user-space
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 1a81fe4d..b53e563 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -23,17 +23,15 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/time.h>
+#include <linux/ioport.h>
 #include <sound/core.h>
 
-int snd_task_name(struct task_struct *task, char *name, size_t size)
+void release_and_free_resource(struct resource *res)
 {
-	unsigned int idx;
-
-	snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
-	for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
-		name[idx] = task->comm[idx];
-	name[idx] = '\0';
-	return 0;
+	if (res) {
+		release_resource(res);
+		kfree(res);
+	}
 }
 
 #ifdef CONFIG_SND_VERBOSE_PRINTK
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 69e1059..214933c 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -521,9 +521,13 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
-	snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (kctl->get(kctl, uctl))
+		goto __unalloc;
+	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+		goto __unalloc;
 	*left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
 	if (uinfo->count > 1)
 		*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
@@ -555,8 +559,10 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (kctl->get(kctl, uctl))
+		goto __unalloc;
 	if (!uctl->value.integer.value[0]) {
 		*left = 0;
 		if (uinfo->count == 1)
@@ -616,12 +622,16 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
-	snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
+	if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
+	    uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
+		goto __unalloc;
 	uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
 	if (uinfo->count > 1)
 		uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
-	snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+	if ((res = kctl->put(kctl, uctl)) < 0)
+		goto __unalloc;
 	if (res > 0)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
@@ -653,7 +663,8 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (uinfo == NULL || uctl == NULL)
 		goto __unalloc;
-	snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc);
+	if (kctl->info(kctl, uinfo))
+		goto __unalloc;
 	if (uinfo->count > 1) {
 		uctl->value.integer.value[0] = left > 0 ? 1 : 0;
 		uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
@@ -664,7 +675,8 @@
 	} else {
 		uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
 	}
-	snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc);
+	if ((res = kctl->put(kctl, uctl)) < 0)
+		goto __unalloc;
 	if (res > 0)
 		snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
       __unalloc:
@@ -776,9 +788,14 @@
 	}
 	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
-	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
-	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
-	snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock);
+	if (! kctl) {
+		err = -ENOENT;
+		goto __unlock;
+	}
+	if ((err = kctl->info(kctl, uinfo)) < 0)
+		goto __unlock;
+	if ((err = kctl->get(kctl, uctl)) < 0)
+		goto __unlock;
 	for (idx = 0; idx < 32; idx++) {
 		if (!(mixer->mask_recsrc & (1 << idx)))
 			continue;
@@ -821,8 +838,12 @@
 	}
 	down_read(&card->controls_rwsem);
 	kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
-	snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock);
-	snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock);
+	if (! kctl) {
+		err = -ENOENT;
+		goto __unlock;
+	}
+	if ((err = kctl->info(kctl, uinfo)) < 0)
+		goto __unlock;
 	for (idx = 0; idx < 32; idx++) {
 		if (!(mixer->mask_recsrc & (1 << idx)))
 			continue;
@@ -836,10 +857,11 @@
 			break;
 		slot = NULL;
 	}
-	snd_runtime_check(slot != NULL, goto __unlock);
+	if (! slot)
+		goto __unlock;
 	for (idx = 0; idx < uinfo->count; idx++)
 		uctl->value.enumerated.item[idx] = slot->capture_item;
-	snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, );
+	err = kctl->put(kctl, uctl);
 	if (err > 0)
 		snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
 	err = 0;
@@ -1008,7 +1030,8 @@
 	up_read(&mixer->card->controls_rwsem);
 	if (slot.present != 0) {
 		pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
-		snd_runtime_check(pslot != NULL, return -ENOMEM);
+		if (! pslot)
+			return -ENOMEM;
 		*pslot = slot;
 		pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;
 		pslot->assigned = ptr;
@@ -1271,7 +1294,8 @@
 						   card, 0,
 						   &snd_mixer_oss_reg,
 						   name)) < 0) {
-			snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0);
+			snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
+				   card->number, 0);
 			kfree(mixer);
 			return err;
 		}
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 842c28b..bcc9707 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1821,6 +1821,17 @@
 }
 
 
+static int snd_task_name(struct task_struct *task, char *name, size_t size)
+{
+	unsigned int idx;
+
+	snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
+	for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
+		name[idx] = task->comm[idx];
+	name[idx] = '\0';
+	return 0;
+}
+
 static int snd_pcm_oss_open(struct inode *inode, struct file *file)
 {
 	int minor = iminor(inode);
@@ -2446,7 +2457,8 @@
 	if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
 				    pcm->card, index, &snd_pcm_oss_reg,
 				    name) < 0) {
-		snd_printk("unable to register OSS PCM device %i:%i\n", pcm->card->number, pcm->device);
+		snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
+			   pcm->card->number, pcm->device);
 	}
 }
 
@@ -2528,11 +2540,13 @@
 	/* check device map table */
 	for (i = 0; i < SNDRV_CARDS; i++) {
 		if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk("invalid dsp_map[%d] = %d\n", i, dsp_map[i]);
+			snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
+				   i, dsp_map[i]);
 			dsp_map[i] = 0;
 		}
 		if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk("invalid adsp_map[%d] = %d\n", i, adsp_map[i]);
+			snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
+				   i, adsp_map[i]);
 			adsp_map[i] = 1;
 		}
 	}
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1be470e..184e74b 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -273,7 +273,8 @@
 	snd_pcm_info_t *info;
 	int err;
 
-	snd_runtime_check(substream, return);
+	if (! substream)
+		return;
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (! info) {
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 0503980..3dbf9bf 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -152,13 +152,12 @@
 	if (pos == SNDRV_PCM_POS_XRUN)
 		return pos; /* XRUN */
 	if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
-		snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec);
+		getnstimeofday((struct timespec *)&runtime->status->tstamp);
 #ifdef CONFIG_SND_DEBUG
 	if (pos >= runtime->buffer_size) {
 		snd_printk(KERN_ERR  "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
-	} else
+	}
 #endif
-	snd_runtime_check(pos < runtime->buffer_size, return 0);
 	pos -= pos % runtime->min_align;
 	return pos;
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e97b2d1..16e252f 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -565,9 +565,9 @@
 		if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
 			status->tstamp = runtime->status->tstamp;
 		else
-			snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+			getnstimeofday(&status->tstamp);
 	} else
-		snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec);
+		getnstimeofday(&status->tstamp);
 	status->appl_ptr = runtime->control->appl_ptr;
 	status->hw_ptr = runtime->status->hw_ptr;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -652,7 +652,7 @@
 	if (runtime->trigger_master == NULL)
 		return;
 	if (runtime->trigger_master == substream) {
-		snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec);
+		getnstimeofday(&runtime->trigger_tstamp);
 	} else {
 		snd_pcm_trigger_tstamp(runtime->trigger_master);
 		runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -1522,7 +1522,6 @@
 
 
 /* WARNING: Don't forget to fput back the file */
-extern int snd_major;
 static struct file *snd_pcm_file_fd(int fd)
 {
 	struct file *file;
@@ -2053,7 +2052,8 @@
 	snd_pcm_file_t *pcm_file;
 	wait_queue_t wait;
 
-	snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO);
+	if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES)
+		return -ENXIO;
 	pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
 	if (pcm == NULL) {
 		err = -ENODEV;
@@ -2445,14 +2445,8 @@
 		return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
 	case SNDRV_PCM_IOCTL_INFO:
 		return snd_pcm_info_user(substream, arg);
-	case SNDRV_PCM_IOCTL_TSTAMP:
-	{
-		int xarg;
-		if (get_user(xarg, (int __user *)arg))
-			return -EFAULT;
-		substream->runtime->tstamp_timespec = xarg ? 1 : 0;
+	case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
 		return 0;
-	}
 	case SNDRV_PCM_IOCTL_HW_REFINE:
 		return snd_pcm_hw_refine_user(substream, arg);
 	case SNDRV_PCM_IOCTL_HW_PARAMS:
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7c20eaf..d033e61 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -378,24 +378,20 @@
 	struct list_head *list;
 	snd_ctl_file_t *kctl;
 
-	switch (maj) {
-	case CONFIG_SND_MAJOR:
+	if (maj == snd_major) {
 		cardnum = SNDRV_MINOR_CARD(iminor(inode));
 		cardnum %= SNDRV_CARDS;
 		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
 		device %= SNDRV_MINOR_RAWMIDIS;
-		break;
 #ifdef CONFIG_SND_OSSEMUL
-	case SOUND_MAJOR:
+	} else if (maj == SOUND_MAJOR) {
 		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
 		cardnum %= SNDRV_CARDS;
 		device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
 			midi_map[cardnum] : amidi_map[cardnum];
-		break;
 #endif
-	default:
+	} else
 		return -ENXIO;
-	}
 
 	rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
 	if (rmidi == NULL)
@@ -411,7 +407,7 @@
 	if (err < 0)
 		return -ENODEV;
 	fflags = snd_rawmidi_file_flags(file);
-	if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */
+	if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
 		fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
 	fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
 	rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index bd5d584..c3c1856 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -60,7 +60,6 @@
 
 static int rtctimer_freq = RTC_FREQ;		/* frequency */
 static snd_timer_t *rtctimer;
-static atomic_t rtc_inc = ATOMIC_INIT(0);
 static rtc_task_t rtc_task;
 
 
@@ -94,7 +93,6 @@
 	snd_assert(rtc != NULL, return -EINVAL);
 	rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
 	rtc_control(rtc, RTC_PIE_ON, 0);
-	atomic_set(&rtc_inc, 0);
 	return 0;
 }
 
@@ -112,12 +110,7 @@
  */
 static void rtctimer_interrupt(void *private_data)
 {
-	int ticks;
-
-	atomic_inc(&rtc_inc);
-	ticks = atomic_read(&rtc_inc);
-	snd_timer_interrupt((snd_timer_t*)private_data, ticks);
-	atomic_sub(ticks, &rtc_inc);
+	snd_timer_interrupt(private_data, 1);
 }
 
 
@@ -126,17 +119,13 @@
  */
 static int __init rtctimer_init(void)
 {
-	int order, err;
+	int err;
 	snd_timer_t *timer;
 
-	if (rtctimer_freq < 2 || rtctimer_freq > 8192) {
-		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
-		return -EINVAL;
-	}
-	for (order = 1; rtctimer_freq > order; order <<= 1)
-		;
-	if (rtctimer_freq != order) {
-		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
+	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
+	    (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
+			   rtctimer_freq);
 		return -EINVAL;
 	}
 
@@ -145,6 +134,7 @@
 	if (err < 0)
 		return err;
 
+	timer->module = THIS_MODULE;
 	strcpy(timer->name, "RTC timer");
 	timer->hw = rtc_hw;
 	timer->hw.resolution = NANO_SEC / rtctimer_freq;
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 019d43a..1d525b1 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -109,8 +109,7 @@
 			spin_lock_irqsave(&list->lock, flags);
 			while (instr->use) {
 				spin_unlock_irqrestore(&list->lock, flags);
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
+				schedule_timeout_interruptible(1);
 				spin_lock_irqsave(&list->lock, flags);
 			}				
 			spin_unlock_irqrestore(&list->lock, flags);
@@ -199,10 +198,8 @@
 		while (flist) {
 			instr = flist;
 			flist = instr->next;
-			while (instr->use) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}				
+			while (instr->use)
+				schedule_timeout_interruptible(1);
 			if (snd_seq_instr_free(instr, atomic)<0)
 				snd_printk(KERN_WARNING "instrument free problem\n");
 			instr = next;
@@ -554,8 +551,7 @@
 			instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
 		while (instr->use) {
 			spin_unlock_irqrestore(&list->lock, flags);
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			spin_lock_irqsave(&list->lock, flags);
 		}				
 		spin_unlock_irqrestore(&list->lock, flags);
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index b09cee0..a837a94 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -39,8 +39,7 @@
 			snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 		max_count--;
 	}
 }
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index d4d7d32..8416bcf 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -423,8 +423,7 @@
 			snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 		max_count--;
 	}
 	
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index b4674ae..f89f40f 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -449,11 +449,9 @@
 	client->ports_per_device[device] = 0;
 	msynth = client->ports[device];
 	client->ports[device] = NULL;
-	snd_runtime_check(msynth != NULL || ports <= 0, goto __skip);
 	for (p = 0; p < ports; p++)
 		snd_seq_midisynth_delete(&msynth[p]);
 	kfree(msynth);
-      __skip:
 	client->num_ports--;
 	if (client->num_ports <= 0) {
 		snd_seq_delete_kernel_client(client->seq_client);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index b57a3c0..65b64a7 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -34,10 +34,15 @@
 extern int seq_default_timer_subdevice;
 extern int seq_default_timer_resolution;
 
+/* allowed sequencer timer frequencies, in Hz */
+#define MIN_FREQUENCY		10
+#define MAX_FREQUENCY		6250
+#define DEFAULT_FREQUENCY	1000
+
 #define SKEW_BASE	0x10000	/* 16bit shift */
 
 static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
-					      int tempo, int ppq, int nticks)
+					      int tempo, int ppq)
 {
 	if (tempo < 1000000)
 		tick->resolution = (tempo * 1000) / ppq;
@@ -51,7 +56,6 @@
 	}
 	if (tick->resolution <= 0)
 		tick->resolution = 1;
-	tick->resolution *= nticks;
 	snd_seq_timer_update_tick(tick, 0);
 }
 
@@ -100,7 +104,7 @@
 	/* setup defaults */
 	tmr->ppq = 96;		/* 96 PPQ */
 	tmr->tempo = 500000;	/* 120 BPM */
-	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	tmr->running = 0;
 
 	tmr->type = SNDRV_SEQ_TIMER_ALSA;
@@ -183,7 +187,7 @@
 	spin_lock_irqsave(&tmr->lock, flags);
 	if ((unsigned int)tempo != tmr->tempo) {
 		tmr->tempo = tempo;
-		snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+		snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	}
 	spin_unlock_irqrestore(&tmr->lock, flags);
 	return 0;
@@ -207,7 +211,7 @@
 	}
 
 	tmr->ppq = ppq;
-	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1);
+	snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
 	spin_unlock_irqrestore(&tmr->lock, flags);
 	return 0;
 }
@@ -326,17 +330,26 @@
 static int initialize_timer(seq_timer_t *tmr)
 {
 	snd_timer_t *t;
+	unsigned long freq;
+
 	t = tmr->timeri->timer;
 	snd_assert(t, return -EINVAL);
 
+	freq = tmr->preferred_resolution;
+	if (!freq)
+		freq = DEFAULT_FREQUENCY;
+	else if (freq < MIN_FREQUENCY)
+		freq = MIN_FREQUENCY;
+	else if (freq > MAX_FREQUENCY)
+		freq = MAX_FREQUENCY;
+
 	tmr->ticks = 1;
-	if (tmr->preferred_resolution &&
-	    ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
+	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
 		unsigned long r = t->hw.resolution;
 		if (! r && t->hw.c_resolution)
 			r = t->hw.c_resolution(t);
 		if (r) {
-			tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution));
+			tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
 			if (! tmr->ticks)
 				tmr->ticks = 1;
 		}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index b57519a..1139dd8 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -130,7 +130,7 @@
 	struct file_operations *old_fops;
 	int err = 0;
 
-	if (dev != SNDRV_MINOR_SEQUENCER && dev != SNDRV_MINOR_TIMER) {
+	if (dev != SNDRV_MINOR_GLOBAL) {
 		if (snd_cards[card] == NULL) {
 #ifdef CONFIG_KMOD
 			snd_request_card(card);
@@ -287,7 +287,7 @@
 	for (card = 0; card < SNDRV_CARDS; card++) {
 		list_for_each(list, &snd_minors_hash[card]) {
 			mptr = list_entry(list, snd_minor_t, list);
-			if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_SEQUENCER) {
+			if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) {
 				if ((device = mptr->device) >= 0)
 					snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment);
 				else
@@ -350,9 +350,7 @@
 		devfs_remove("snd");
 		return -EIO;
 	}
-	snd_memory_init();
 	if (snd_info_init() < 0) {
-		snd_memory_done();
 		unregister_chrdev(major, "alsa");
 		devfs_remove("snd");
 		return -ENOMEM;
@@ -381,7 +379,6 @@
 #endif
 	snd_info_minor_unregister();
 	snd_info_done();
-	snd_memory_done();
 	if (unregister_chrdev(major, "alsa") != 0)
 		snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
 	devfs_remove("snd");
@@ -403,14 +400,6 @@
 EXPORT_SYMBOL(snd_unregister_oss_device);
 #endif
   /* memory.c */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_hidden_kmalloc);
-EXPORT_SYMBOL(snd_hidden_kcalloc);
-EXPORT_SYMBOL(snd_hidden_kfree);
-EXPORT_SYMBOL(snd_hidden_vmalloc);
-EXPORT_SYMBOL(snd_hidden_vfree);
-EXPORT_SYMBOL(snd_hidden_kstrdup);
-#endif
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
@@ -487,17 +476,10 @@
 EXPORT_SYMBOL(snd_ctl_elem_read);
 EXPORT_SYMBOL(snd_ctl_elem_write);
   /* misc.c */
-EXPORT_SYMBOL(snd_task_name);
+EXPORT_SYMBOL(release_and_free_resource);
 #ifdef CONFIG_SND_VERBOSE_PRINTK
 EXPORT_SYMBOL(snd_verbose_printk);
 #endif
 #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
 EXPORT_SYMBOL(snd_verbose_printd);
 #endif
-  /* wrappers */
-#ifdef CONFIG_SND_DEBUG_MEMORY
-EXPORT_SYMBOL(snd_wrapper_kmalloc);
-EXPORT_SYMBOL(snd_wrapper_kfree);
-EXPORT_SYMBOL(snd_wrapper_vmalloc);
-EXPORT_SYMBOL(snd_wrapper_vfree);
-#endif
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 22b1046..1b90a38 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -55,7 +55,7 @@
 
 typedef struct {
 	snd_timer_instance_t *timeri;
-	int tread;			/* enhanced read with timestamps and events */
+	int tread;		/* enhanced read with timestamps and events */
 	unsigned long ticks;
 	unsigned long overrun;
 	int qhead;
@@ -95,7 +95,8 @@
  * create a timer instance with the given owner string.
  * when timer is not NULL, increments the module counter
  */
-static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer)
+static snd_timer_instance_t *snd_timer_instance_new(char *owner,
+						    snd_timer_t *timer)
 {
 	snd_timer_instance_t *timeri;
 	timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
@@ -113,7 +114,7 @@
 	INIT_LIST_HEAD(&timeri->slave_active_head);
 
 	timeri->timer = timer;
-	if (timer && timer->card && !try_module_get(timer->card->module)) {
+	if (timer && !try_module_get(timer->module)) {
 		kfree(timeri->owner);
 		kfree(timeri);
 		return NULL;
@@ -131,7 +132,7 @@
 	struct list_head *p;
 
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 
 		if (timer->tmr_class != tid->dev_class)
 			continue;
@@ -186,13 +187,14 @@
 
 	/* FIXME: it's really dumb to look up all entries.. */
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 		list_for_each(q, &timer->open_list_head) {
-			master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
+			master = list_entry(q, snd_timer_instance_t, open_list);
 			if (slave->slave_class == master->slave_class &&
 			    slave->slave_id == master->slave_id) {
 				list_del(&slave->open_list);
-				list_add_tail(&slave->open_list, &master->slave_list_head);
+				list_add_tail(&slave->open_list,
+					      &master->slave_list_head);
 				spin_lock_irq(&slave_active_lock);
 				slave->master = master;
 				slave->timer = master->timer;
@@ -216,7 +218,7 @@
 
 	/* check all pending slaves */
 	list_for_each_safe(p, n, &snd_timer_slave_list) {
-		slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+		slave = list_entry(p, snd_timer_instance_t, open_list);
 		if (slave->slave_class == master->slave_class &&
 		    slave->slave_id == master->slave_id) {
 			list_del(p);
@@ -225,7 +227,8 @@
 			slave->master = master;
 			slave->timer = master->timer;
 			if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
-				list_add_tail(&slave->active_list, &master->slave_active_head);
+				list_add_tail(&slave->active_list,
+					      &master->slave_active_head);
 			spin_unlock_irq(&slave_active_lock);
 		}
 	}
@@ -241,7 +244,7 @@
 {
 	snd_timer_t *timer;
 	snd_timer_instance_t *timeri = NULL;
-	
+
 	if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
 		/* open a slave instance */
 		if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
@@ -251,6 +254,10 @@
 		}
 		down(&register_mutex);
 		timeri = snd_timer_instance_new(owner, NULL);
+		if (!timeri) {
+			up(&register_mutex);
+			return -ENOMEM;
+		}
 		timeri->slave_class = tid->dev_sclass;
 		timeri->slave_id = tid->device;
 		timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
@@ -272,33 +279,36 @@
 		timer = snd_timer_find(tid);
 	}
 #endif
-	if (timer) {
-		if (!list_empty(&timer->open_list_head)) {
-			timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list);
-			if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
-				up(&register_mutex);
-				return -EBUSY;
-			}
-		}
-		timeri = snd_timer_instance_new(owner, timer);
-		if (timeri) {
-			timeri->slave_class = tid->dev_sclass;
-			timeri->slave_id = slave_id;
-			if (list_empty(&timer->open_list_head) && timer->hw.open)
-				timer->hw.open(timer);
-			list_add_tail(&timeri->open_list, &timer->open_list_head);
-			snd_timer_check_master(timeri);
-		}
-	} else {
+	if (!timer) {
 		up(&register_mutex);
 		return -ENODEV;
 	}
+	if (!list_empty(&timer->open_list_head)) {
+		timeri = list_entry(timer->open_list_head.next,
+				    snd_timer_instance_t, open_list);
+		if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
+			up(&register_mutex);
+			return -EBUSY;
+		}
+	}
+	timeri = snd_timer_instance_new(owner, timer);
+	if (!timeri) {
+		up(&register_mutex);
+		return -ENOMEM;
+	}
+	timeri->slave_class = tid->dev_sclass;
+	timeri->slave_id = slave_id;
+	if (list_empty(&timer->open_list_head) && timer->hw.open)
+		timer->hw.open(timer);
+	list_add_tail(&timeri->open_list, &timer->open_list_head);
+	snd_timer_check_master(timeri);
 	up(&register_mutex);
 	*ti = timeri;
 	return 0;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event);
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+			   int keep_flag, enum sndrv_timer_event event);
 
 /*
  * close a timer instance
@@ -338,11 +348,12 @@
 		spin_unlock_irq(&timer->lock);
 		down(&register_mutex);
 		list_del(&timeri->open_list);
-		if (timer && list_empty(&timer->open_list_head) && timer->hw.close)
+		if (timer && list_empty(&timer->open_list_head) &&
+		    timer->hw.close)
 			timer->hw.close(timer);
 		/* remove slave links */
 		list_for_each_safe(p, n, &timeri->slave_list_head) {
-			slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+			slave = list_entry(p, snd_timer_instance_t, open_list);
 			spin_lock_irq(&slave_active_lock);
 			_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
 			list_del(p);
@@ -357,8 +368,8 @@
 		timeri->private_free(timeri);
 	kfree(timeri->owner);
 	kfree(timeri);
-	if (timer && timer->card)
-		module_put(timer->card->module);
+	if (timer)
+		module_put(timer->module);
 	return 0;
 }
 
@@ -376,7 +387,8 @@
 	return 0;
 }
 
-static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event)
+static void snd_timer_notify1(snd_timer_instance_t *ti,
+			      enum sndrv_timer_event event)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
@@ -385,9 +397,11 @@
 	struct list_head *n;
 	struct timespec tstamp;
 
-	snd_timestamp_now(&tstamp, 1);
-	snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return);
-	if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE)
+	getnstimeofday(&tstamp);
+	snd_assert(event >= SNDRV_TIMER_EVENT_START &&
+		   event <= SNDRV_TIMER_EVENT_PAUSE, return);
+	if (event == SNDRV_TIMER_EVENT_START ||
+	    event == SNDRV_TIMER_EVENT_CONTINUE)
 		resolution = snd_timer_resolution(ti);
 	if (ti->ccallback)
 		ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
@@ -400,14 +414,15 @@
 		return;
 	spin_lock_irqsave(&timer->lock, flags);
 	list_for_each(n, &ti->slave_active_head) {
-		ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+		ts = list_entry(n, snd_timer_instance_t, active_list);
 		if (ts->ccallback)
 			ts->ccallback(ti, event + 100, &tstamp, resolution);
 	}
 	spin_unlock_irqrestore(&timer->lock, flags);
 }
 
-static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks)
+static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri,
+			    unsigned long sticks)
 {
 	list_del(&timeri->active_list);
 	list_add_tail(&timeri->active_list, &timer->active_list_head);
@@ -434,14 +449,15 @@
 	spin_lock_irqsave(&slave_active_lock, flags);
 	timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
 	if (timeri->master)
-		list_add_tail(&timeri->active_list, &timeri->master->slave_active_head);
+		list_add_tail(&timeri->active_list,
+			      &timeri->master->slave_active_head);
 	spin_unlock_irqrestore(&slave_active_lock, flags);
 	return 1; /* delayed start */
 }
 
 /*
  *  start the timer instance
- */ 
+ */
 int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
 {
 	snd_timer_t *timer;
@@ -467,7 +483,8 @@
 	return result;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event)
+static int _snd_timer_stop(snd_timer_instance_t * timeri,
+			   int keep_flag, enum sndrv_timer_event event)
 {
 	snd_timer_t *timer;
 	unsigned long flags;
@@ -501,7 +518,8 @@
 		}
 	}
 	if (!keep_flag)
-		timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START);
+		timeri->flags &=
+			~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
 	spin_unlock_irqrestore(&timer->lock, flags);
       __end:
 	if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@@ -578,7 +596,7 @@
 	struct list_head *p;
 
 	list_for_each(p, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (ti->flags & SNDRV_TIMER_IFLG_START) {
 			ti->flags &= ~SNDRV_TIMER_IFLG_START;
 			ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
@@ -615,11 +633,11 @@
 	/* now process all callbacks */
 	while (!list_empty(&timer->sack_list_head)) {
 		p = timer->sack_list_head.next;		/* get first item */
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
+		ti = list_entry(p, snd_timer_instance_t, ack_list);
 
 		/* remove from ack_list and make empty */
 		list_del_init(p);
-		
+
 		ticks = ti->pticks;
 		ti->pticks = 0;
 		resolution = ti->resolution;
@@ -644,7 +662,7 @@
 {
 	snd_timer_instance_t *ti, *ts;
 	unsigned long resolution, ticks;
-	struct list_head *p, *q, *n;
+	struct list_head *p, *q, *n, *ack_list_head;
 	int use_tasklet = 0;
 
 	if (timer == NULL)
@@ -659,11 +677,12 @@
 		resolution = timer->hw.resolution;
 
 	/* loop for all active instances
-	 * here we cannot use list_for_each because the active_list of a processed
-	 * instance is relinked to done_list_head before callback is called.
+	 * Here we cannot use list_for_each because the active_list of a
+	 * processed instance is relinked to done_list_head before the callback
+	 * is called.
 	 */
 	list_for_each_safe(p, n, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
 			continue;
 		ti->pticks += ticks_left;
@@ -681,26 +700,19 @@
 			if (--timer->running)
 				list_del(p);
 		}
-		if (list_empty(&ti->ack_list)) {
-			if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
-			    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
-				list_add_tail(&ti->ack_list, &timer->ack_list_head);
-			} else {
-				list_add_tail(&ti->ack_list, &timer->sack_list_head);
-			}
-		}
+		if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+		    (ti->flags & SNDRV_TIMER_IFLG_FAST))
+			ack_list_head = &timer->ack_list_head;
+		else
+			ack_list_head = &timer->sack_list_head;
+		if (list_empty(&ti->ack_list))
+			list_add_tail(&ti->ack_list, ack_list_head);
 		list_for_each(q, &ti->slave_active_head) {
-			ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list);
+			ts = list_entry(q, snd_timer_instance_t, active_list);
 			ts->pticks = ti->pticks;
 			ts->resolution = resolution;
-			if (list_empty(&ts->ack_list)) {
-				if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
-				    (ti->flags & SNDRV_TIMER_IFLG_FAST)) {
-					list_add_tail(&ts->ack_list, &timer->ack_list_head);
-				} else {
-					list_add_tail(&ts->ack_list, &timer->sack_list_head);
-				}
-			}
+			if (list_empty(&ts->ack_list))
+				list_add_tail(&ts->ack_list, ack_list_head);
 		}
 	}
 	if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
@@ -723,11 +735,11 @@
 	/* now process all fast callbacks */
 	while (!list_empty(&timer->ack_list_head)) {
 		p = timer->ack_list_head.next;		/* get first item */
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list);
-		
+		ti = list_entry(p, snd_timer_instance_t, ack_list);
+
 		/* remove from ack_list and make empty */
 		list_del_init(p);
-		
+
 		ticks = ti->pticks;
 		ti->pticks = 0;
 
@@ -751,7 +763,8 @@
 
  */
 
-int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer)
+int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid,
+		  snd_timer_t **rtimer)
 {
 	snd_timer_t *timer;
 	int err;
@@ -779,9 +792,12 @@
 	INIT_LIST_HEAD(&timer->ack_list_head);
 	INIT_LIST_HEAD(&timer->sack_list_head);
 	spin_lock_init(&timer->lock);
-	tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer);
+	tasklet_init(&timer->task_queue, snd_timer_tasklet,
+		     (unsigned long)timer);
 	if (card != NULL) {
-		if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) {
+		timer->module = card->module;
+		err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
+		if (err < 0) {
 			snd_timer_free(timer);
 			return err;
 		}
@@ -811,14 +827,15 @@
 	snd_timer_t *timer1;
 	struct list_head *p;
 
-	snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO);
+	snd_assert(timer != NULL && timer->hw.start != NULL &&
+		   timer->hw.stop != NULL, return -ENXIO);
 	if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
 	    !timer->hw.resolution && timer->hw.c_resolution == NULL)
 	    	return -EINVAL;
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer1 = list_entry(p, snd_timer_t, device_list);
 		if (timer1->tmr_class > timer->tmr_class)
 			break;
 		if (timer1->tmr_class < timer->tmr_class)
@@ -857,7 +874,7 @@
 		snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
 		list_for_each_safe(p, n, &timer->open_list_head) {
 			list_del_init(p);
-			ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list);
+			ti = list_entry(p, snd_timer_instance_t, open_list);
 			ti->timer = NULL;
 		}
 	}
@@ -872,15 +889,18 @@
 	return snd_timer_unregister(timer);
 }
 
-void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp)
+void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event,
+		      struct timespec *tstamp)
 {
 	unsigned long flags;
 	unsigned long resolution = 0;
 	snd_timer_instance_t *ti, *ts;
 	struct list_head *p, *n;
 
-	snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return);	
-	snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return);
+	if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
+		return;
+	snd_assert(event >= SNDRV_TIMER_EVENT_MSTART &&
+		   event <= SNDRV_TIMER_EVENT_MRESUME, return);
 	spin_lock_irqsave(&timer->lock, flags);
 	if (event == SNDRV_TIMER_EVENT_MSTART ||
 	    event == SNDRV_TIMER_EVENT_MCONTINUE ||
@@ -891,11 +911,11 @@
 			resolution = timer->hw.resolution;
 	}
 	list_for_each(p, &timer->active_list_head) {
-		ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, snd_timer_instance_t, active_list);
 		if (ti->ccallback)
 			ti->ccallback(ti, event, tstamp, resolution);
 		list_for_each(n, &ti->slave_active_head) {
-			ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list);
+			ts = list_entry(n, snd_timer_instance_t, active_list);
 			if (ts->ccallback)
 				ts->ccallback(ts, event, tstamp, resolution);
 		}
@@ -909,7 +929,7 @@
 int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
 {
 	snd_timer_id_t tid;
-	
+
 	tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
 	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
 	tid.card = -1;
@@ -937,7 +957,7 @@
 	return snd_timer_unregister(timer);
 }
 
-/* 
+/*
  *  System timer
  */
 
@@ -1013,7 +1033,8 @@
 	struct snd_timer_system_private *priv;
 	int err;
 
-	if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0)
+	err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
+	if (err < 0)
 		return err;
 	strcpy(timer->name, "system timer");
 	timer->hw = snd_timer_system;
@@ -1044,33 +1065,41 @@
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, snd_timer_t, device_list);
 		switch (timer->tmr_class) {
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			snd_iprintf(buffer, "G%i: ", timer->tmr_device);
 			break;
 		case SNDRV_TIMER_CLASS_CARD:
-			snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device);
+			snd_iprintf(buffer, "C%i-%i: ",
+				    timer->card->number, timer->tmr_device);
 			break;
 		case SNDRV_TIMER_CLASS_PCM:
-			snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice);
+			snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
+				    timer->tmr_device, timer->tmr_subdevice);
 			break;
 		default:
-			snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice);
+			snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
+				    timer->card ? timer->card->number : -1,
+				    timer->tmr_device, timer->tmr_subdevice);
 		}
 		snd_iprintf(buffer, "%s :", timer->name);
 		if (timer->hw.resolution)
-			snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks);
+			snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
+				    timer->hw.resolution / 1000,
+				    timer->hw.resolution % 1000,
+				    timer->hw.ticks);
 		if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
 			snd_iprintf(buffer, " SLAVE");
 		snd_iprintf(buffer, "\n");
 		spin_lock_irqsave(&timer->lock, flags);
 		list_for_each(q, &timer->open_list_head) {
-			ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list);
-			snd_iprintf(buffer, "  Client %s : %s : lost interrupts %li\n",
-					ti->owner ? ti->owner : "unknown",
-					ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped",
-					ti->lost);
+			ti = list_entry(q, snd_timer_instance_t, open_list);
+			snd_iprintf(buffer, "  Client %s : %s\n",
+				    ti->owner ? ti->owner : "unknown",
+				    ti->flags & (SNDRV_TIMER_IFLG_START |
+						 SNDRV_TIMER_IFLG_RUNNING)
+				    ? "running" : "stopped");
 		}
 		spin_unlock_irqrestore(&timer->lock, flags);
 	}
@@ -1088,7 +1117,7 @@
 	snd_timer_user_t *tu = timeri->callback_data;
 	snd_timer_read_t *r;
 	int prev;
-	
+
 	spin_lock(&tu->qlock);
 	if (tu->qused > 0) {
 		prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
@@ -1113,7 +1142,8 @@
 	wake_up(&tu->qchange_sleep);
 }
 
-static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread)
+static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu,
+					    snd_timer_tread_t *tread)
 {
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
@@ -1132,7 +1162,8 @@
 	snd_timer_user_t *tu = timeri->callback_data;
 	snd_timer_tread_t r1;
 
-	if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE)
+	if (event >= SNDRV_TIMER_EVENT_START &&
+	    event <= SNDRV_TIMER_EVENT_PAUSE)
 		tu->tstamp = *tstamp;
 	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
 		return;
@@ -1155,15 +1186,17 @@
 	struct timespec tstamp;
 	int prev, append = 0;
 
-	snd_timestamp_zero(&tstamp);
+	memset(&tstamp, 0, sizeof(tstamp));
 	spin_lock(&tu->qlock);
-	if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
+	if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
+			   (1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
 		spin_unlock(&tu->qlock);
 		return;
 	}
 	if (tu->last_resolution != resolution || ticks > 0)
-		snd_timestamp_now(&tstamp, 1);
-	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) {
+		getnstimeofday(&tstamp);
+	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
+	    tu->last_resolution != resolution) {
 		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
 		r1.tstamp = tstamp;
 		r1.val = resolution;
@@ -1201,7 +1234,7 @@
 static int snd_timer_user_open(struct inode *inode, struct file *file)
 {
 	snd_timer_user_t *tu;
-	
+
 	tu = kzalloc(sizeof(*tu), GFP_KERNEL);
 	if (tu == NULL)
 		return -ENOMEM;
@@ -1210,7 +1243,8 @@
 	init_MUTEX(&tu->tread_sem);
 	tu->ticks = 1;
 	tu->queue_size = 128;
-	tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+	tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+			    GFP_KERNEL);
 	if (tu->queue == NULL) {
 		kfree(tu);
 		return -ENOMEM;
@@ -1259,7 +1293,7 @@
 	snd_timer_id_t id;
 	snd_timer_t *timer;
 	struct list_head *p;
-	
+
 	if (copy_from_user(&id, _tid, sizeof(id)))
 		return -EFAULT;
 	down(&register_mutex);
@@ -1267,7 +1301,8 @@
 		if (list_empty(&snd_timer_list))
 			snd_timer_user_zero_id(&id);
 		else {
-			timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list);
+			timer = list_entry(snd_timer_list.next,
+					   snd_timer_t, device_list);
 			snd_timer_user_copy_id(&id, timer);
 		}
 	} else {
@@ -1275,7 +1310,7 @@
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			id.device = id.device < 0 ? 0 : id.device + 1;
 			list_for_each(p, &snd_timer_list) {
-				timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, snd_timer_t, device_list);
 				if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1299,12 +1334,16 @@
 					if (id.device < 0) {
 						id.device = 0;
 					} else {
-						id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1;
+						if (id.subdevice < 0) {
+							id.subdevice = 0;
+						} else {
+							id.subdevice++;
+						}
 					}
 				}
 			}
 			list_for_each(p, &snd_timer_list) {
-				timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, snd_timer_t, device_list);
 				if (timer->tmr_class > id.dev_class) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1343,9 +1382,10 @@
 	if (copy_to_user(_tid, &id, sizeof(*_tid)))
 		return -EFAULT;
 	return 0;
-} 
+}
 
-static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo)
+static int snd_timer_user_ginfo(struct file *file,
+				snd_timer_ginfo_t __user *_ginfo)
 {
 	snd_timer_ginfo_t *ginfo;
 	snd_timer_id_t tid;
@@ -1389,7 +1429,8 @@
 	return err;
 }
 
-static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams)
+static int snd_timer_user_gparams(struct file *file,
+				  snd_timer_gparams_t __user *_gparams)
 {
 	snd_timer_gparams_t gparams;
 	snd_timer_t *t;
@@ -1399,23 +1440,26 @@
 		return -EFAULT;
 	down(&register_mutex);
 	t = snd_timer_find(&gparams.tid);
-	if (t != NULL) {
-		if (list_empty(&t->open_list_head)) {
-			if (t->hw.set_period)
-				err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
-			else
-				err = -ENOSYS;
-		} else {
-			err = -EBUSY;
-		}
-	} else {
+	if (!t) {
 		err = -ENODEV;
+		goto _error;
 	}
+	if (!list_empty(&t->open_list_head)) {
+		err = -EBUSY;
+		goto _error;
+	}
+	if (!t->hw.set_period) {
+		err = -ENOSYS;
+		goto _error;
+	}
+	err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
+_error:
 	up(&register_mutex);
 	return err;
 }
 
-static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus)
+static int snd_timer_user_gstatus(struct file *file,
+				  snd_timer_gstatus_t __user *_gstatus)
 {
 	snd_timer_gstatus_t gstatus;
 	snd_timer_id_t tid;
@@ -1435,7 +1479,8 @@
 		else
 			gstatus.resolution = t->hw.resolution;
 		if (t->hw.precise_resolution) {
-			t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den);
+			t->hw.precise_resolution(t, &gstatus.resolution_num,
+						 &gstatus.resolution_den);
 		} else {
 			gstatus.resolution_num = gstatus.resolution;
 			gstatus.resolution_den = 1000000000uL;
@@ -1449,13 +1494,14 @@
 	return err;
 }
 
-static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect)
+static int snd_timer_user_tselect(struct file *file,
+				  snd_timer_select_t __user *_tselect)
 {
 	snd_timer_user_t *tu;
 	snd_timer_select_t tselect;
 	char str[32];
 	int err = 0;
-	
+
 	tu = file->private_data;
 	down(&tu->tread_sem);
 	if (tu->timeri) {
@@ -1469,7 +1515,8 @@
 	sprintf(str, "application %i", current->pid);
 	if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
-	if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
+	err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
+	if (err < 0)
 		goto __err;
 
 	kfree(tu->queue);
@@ -1477,21 +1524,24 @@
 	kfree(tu->tqueue);
 	tu->tqueue = NULL;
 	if (tu->tread) {
-		tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+		tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t),
+				     GFP_KERNEL);
 		if (tu->tqueue == NULL)
 			err = -ENOMEM;
 	} else {
-		tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+		tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+				    GFP_KERNEL);
 		if (tu->queue == NULL)
 			err = -ENOMEM;
 	}
-	
+
       	if (err < 0) {
 		snd_timer_close(tu->timeri);
       		tu->timeri = NULL;
       	} else {
 		tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
-		tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+		tu->timeri->callback = tu->tread
+			? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
 		tu->timeri->ccallback = snd_timer_user_ccallback;
 		tu->timeri->callback_data = (void *)tu;
 	}
@@ -1501,7 +1551,8 @@
 	return err;
 }
 
-static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
+static int snd_timer_user_info(struct file *file,
+			       snd_timer_info_t __user *_info)
 {
 	snd_timer_user_t *tu;
 	snd_timer_info_t *info;
@@ -1528,7 +1579,8 @@
 	return err;
 }
 
-static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params)
+static int snd_timer_user_params(struct file *file,
+				 snd_timer_params_t __user *_params)
 {
 	snd_timer_user_t *tu;
 	snd_timer_params_t params;
@@ -1536,7 +1588,7 @@
 	snd_timer_read_t *tr;
 	snd_timer_tread_t *ttr;
 	int err;
-	
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	t = tu->timeri->timer;
@@ -1547,7 +1599,8 @@
 		err = -EINVAL;
 		goto _end;
 	}
-	if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) {
+	if (params.queue_size > 0 &&
+	    (params.queue_size < 32 || params.queue_size > 1024)) {
 		err = -EINVAL;
 		goto _end;
 	}
@@ -1580,16 +1633,19 @@
 	if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
 		tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
 	spin_unlock_irq(&t->lock);
-	if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) {
+	if (params.queue_size > 0 &&
+	    (unsigned int)tu->queue_size != params.queue_size) {
 		if (tu->tread) {
-			ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
+			ttr = kmalloc(params.queue_size * sizeof(*ttr),
+				      GFP_KERNEL);
 			if (ttr) {
 				kfree(tu->tqueue);
 				tu->queue_size = params.queue_size;
 				tu->tqueue = ttr;
 			}
 		} else {
-			tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
+			tr = kmalloc(params.queue_size * sizeof(*tr),
+				     GFP_KERNEL);
 			if (tr) {
 				kfree(tu->queue);
 				tu->queue_size = params.queue_size;
@@ -1613,7 +1669,6 @@
 			tu->qused++;
 			tu->qtail++;
 		}
-		
 	}
 	tu->filter = params.filter;
 	tu->ticks = params.ticks;
@@ -1624,11 +1679,12 @@
 	return err;
 }
 
-static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status)
+static int snd_timer_user_status(struct file *file,
+				 snd_timer_status_t __user *_status)
 {
 	snd_timer_user_t *tu;
 	snd_timer_status_t status;
-	
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	memset(&status, 0, sizeof(status));
@@ -1648,7 +1704,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	snd_timer_stop(tu->timeri);
@@ -1661,7 +1717,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
@@ -1671,7 +1727,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	tu->timeri->lost = 0;
@@ -1682,7 +1738,7 @@
 {
 	int err;
 	snd_timer_user_t *tu;
-		
+
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
 	return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
@@ -1695,12 +1751,13 @@
 	SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
 };
 
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+				 unsigned long arg)
 {
 	snd_timer_user_t *tu;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
-	
+
 	tu = file->private_data;
 	switch (cmd) {
 	case SNDRV_TIMER_IOCTL_PVERSION:
@@ -1710,7 +1767,7 @@
 	case SNDRV_TIMER_IOCTL_TREAD:
 	{
 		int xarg;
-		
+
 		down(&tu->tread_sem);
 		if (tu->timeri)	{	/* too late */
 			up(&tu->tread_sem);
@@ -1758,7 +1815,7 @@
 {
 	snd_timer_user_t *tu;
 	int err;
-	
+
 	tu = file->private_data;
 	err = fasync_helper(fd, file, on, &tu->fasync);
         if (err < 0)
@@ -1766,12 +1823,13 @@
 	return 0;
 }
 
-static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset)
+static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+				   size_t count, loff_t *offset)
 {
 	snd_timer_user_t *tu;
 	long result = 0, unit;
 	int err = 0;
-	
+
 	tu = file->private_data;
 	unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
 	spin_lock_irq(&tu->qlock);
@@ -1805,12 +1863,14 @@
 			goto _error;
 
 		if (tu->tread) {
-			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) {
+			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
+					 sizeof(snd_timer_tread_t))) {
 				err = -EFAULT;
 				goto _error;
 			}
 		} else {
-			if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) {
+			if (copy_to_user(buffer, &tu->queue[tu->qhead++],
+					 sizeof(snd_timer_read_t))) {
 				err = -EFAULT;
 				goto _error;
 			}
@@ -1837,7 +1897,7 @@
         tu = file->private_data;
 
         poll_wait(file, &tu->qchange_sleep, wait);
-	
+
 	mask = 0;
 	if (tu->qused)
 		mask |= POLLIN | POLLRDNORM;
@@ -1881,9 +1941,11 @@
 	snd_info_entry_t *entry;
 
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
-	snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer");
+	snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
+			      "system timer");
 #endif
-	if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) {
+	entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
+	if (entry != NULL) {
 		entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
 		entry->c.text.read = snd_timer_proc_read;
 		if (snd_info_register(entry) < 0) {
@@ -1893,10 +1955,12 @@
 	}
 	snd_timer_proc_entry = entry;
 	if ((err = snd_timer_register_system()) < 0)
-		snd_printk(KERN_ERR "unable to register system timer (%i)\n", err);
+		snd_printk(KERN_ERR "unable to register system timer (%i)\n",
+			   err);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
 					NULL, 0, &snd_timer_reg, "timer"))<0)
-		snd_printk(KERN_ERR "unable to register timer device (%i)\n", err);
+		snd_printk(KERN_ERR "unable to register timer device (%i)\n",
+			   err);
 	return 0;
 }
 
@@ -1907,7 +1971,7 @@
 	snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
 	/* unregister the system timer */
 	list_for_each_safe(p, n, &snd_timer_list) {
-		snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list);
+		snd_timer_t *timer = list_entry(p, snd_timer_t, device_list);
 		snd_timer_unregister(timer);
 	}
 	if (snd_timer_proc_entry) {
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c
deleted file mode 100644
index 296b716..0000000
--- a/sound/core/wrappers.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Various wrappers
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
- *
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-
-#ifdef CONFIG_SND_DEBUG_MEMORY
-void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
-{
-	return kmalloc(size, flags);
-}
-
-void snd_wrapper_kfree(const void *obj)
-{
-	kfree(obj);
-}
-
-void *snd_wrapper_vmalloc(unsigned long size)
-{
-	return vmalloc(size);
-}
-
-void snd_wrapper_vfree(void *obj)
-{
-	vfree(obj);
-}
-#endif
-
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index fe3f921..bdeb2c0 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -423,10 +423,7 @@
 	mpu401_t *mpu = rmidi->private_data;
 	if (mpu->irq_flags && mpu->irq >= 0)
 		free_irq(mpu->irq, (void *) mpu);
-	if (mpu->res) {
-		release_resource(mpu->res);
-		kfree_nocheck(mpu->res);
-	}
+	release_and_free_resource(mpu->res);
 	kfree(mpu);
 }
 
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 3a25c89..e9d52c6 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -717,10 +717,7 @@
 	spin_unlock_irqrestore(&crd->spinlock, flags);
 	if (crd->irq >= 0)
 		free_irq(crd->irq, (void *)crd);
-	if (crd->res_port) {
-		release_resource(crd->res_port);
-		kfree_nocheck(crd->res_port);
-	}
+	release_and_free_resource(crd->res_port);
 	kfree(crd);
 }
 
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 1f84d78..0624650 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -325,14 +325,8 @@
 	snd_assert(opl3 != NULL, return -ENXIO);
 	if (opl3->private_free)
 		opl3->private_free(opl3);
-	if (opl3->res_l_port) {
-		release_resource(opl3->res_l_port);
-		kfree_nocheck(opl3->res_l_port);
-	}
-	if (opl3->res_r_port) {
-		release_resource(opl3->res_r_port);
-		kfree_nocheck(opl3->res_r_port);
-	}
+	release_and_free_resource(opl3->res_l_port);
+	release_and_free_resource(opl3->res_r_port);
 	kfree(opl3);
 	return 0;
 }
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 380c2c7..4ae5dd8 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -169,14 +169,8 @@
 #ifdef CONFIG_PROC_FS
 	snd_opl4_free_proc(opl4);
 #endif
-	if (opl4->res_fm_port) {
-		release_resource(opl4->res_fm_port);
-		kfree_nocheck(opl4->res_fm_port);
-	}
-	if (opl4->res_pcm_port) {
-		release_resource(opl4->res_pcm_port);
-		kfree_nocheck(opl4->res_pcm_port);
-	}
+	release_and_free_resource(opl4->res_fm_port);
+	release_and_free_resource(opl4->res_pcm_port);
 	kfree(opl4);
 }
 
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 416172e..1ed58df 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -749,10 +749,7 @@
 {
 	if (uart->irq >= 0)
 		free_irq(uart->irq, (void *)uart);
-	if (uart->res_base) {
-		release_resource(uart->res_base);
-		kfree_nocheck(uart->res_base);
-	}
+	release_and_free_resource(uart->res_base);
 	kfree(uart);
 	return 0;
 };
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index c2312d9..2b46758 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -79,7 +79,7 @@
 		/* already allocated */
 		if (runtime->dma_bytes >= size)
 			return 0; /* already enough large */
-		vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+		vfree(runtime->dma_area);
 	}
 	runtime->dma_area = vmalloc_32(size);
 	if (! runtime->dma_area)
@@ -98,7 +98,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index a21f7d5..1a05cfb 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -75,7 +75,7 @@
 	buf[0] = reg & 0x7f;
 	buf[1] = val;
 	if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
-		snd_printk("unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
+		snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
 		return err < 0 ? err : -EIO;
 	}
 	return 0;
@@ -87,11 +87,11 @@
 	unsigned char buf;
 
 	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
-		snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
 		return err < 0 ? err : -EIO;
 	}
 	if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
-		snd_printk("unable to read register 0x%x byte from CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to read register 0x%x byte from CS8427\n", reg);
 		return err < 0 ? err : -EIO;
 	}
 	return buf;
@@ -210,7 +210,7 @@
 	snd_i2c_lock(bus);
 	if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) {
 		snd_i2c_unlock(bus);
-		snd_printk("unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
+		snd_printk(KERN_ERR "unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
 		return -EFAULT;
 	}
 	/* turn off run bit while making changes to configuration */
@@ -260,7 +260,7 @@
 	snd_i2c_sendbytes(device, buf, 1);
 	snd_i2c_readbytes(device, buf, 127);
 	for (xx = 0; xx < 127; xx++)
-		printk("reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
+		printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
 	}
 #endif
 	
@@ -302,8 +302,7 @@
 		snd_i2c_unlock(cs8427->bus);
 		if (!(data & CS8427_UNLOCK))
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	snd_i2c_lock(cs8427->bus);
 	chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
@@ -354,12 +353,12 @@
 
 	snd_i2c_lock(device->bus);
 	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
-		snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
+		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
 		snd_i2c_unlock(device->bus);
 		return err < 0 ? err : -EIO;
 	}
 	if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) {
-		snd_printk("unable to read Q-subcode bytes from CS8427\n");
+		snd_printk(KERN_ERR "unable to read Q-subcode bytes from CS8427\n");
 		snd_i2c_unlock(device->bus);
 		return err < 0 ? err : -EIO;
 	}
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index af5eadc..d351b3a 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -56,9 +56,9 @@
 {
 	int i;
 
-	printk("AK4114 REG DUMP:\n");
+	printk(KERN_DEBUG "AK4114 REG DUMP:\n");
 	for (i = 0; i < 0x20; i++)
-		printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
+		printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
 }
 #endif
 
@@ -552,7 +552,7 @@
 	if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
 		snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
 		if (snd_pcm_running(ak4114->capture_substream)) {
-			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
+			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
 			snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
 			res = 1;
 		}
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index d51b51d..35b4584 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -54,9 +54,9 @@
 {
 	int i;
 
-	printk("AK4117 REG DUMP:\n");
+	printk(KERN_DEBUG "AK4117 REG DUMP:\n");
 	for (i = 0; i < 0x1b; i++)
-		printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
+		printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
 }
 #endif
 
@@ -477,7 +477,7 @@
 		goto __rate;
 	rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
 	rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
-	// printk("AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
+	// printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
 	spin_lock_irqsave(&ak4117->lock, _flags);
 	if (rcs0 & AK4117_PAR)
 		ak4117->parity_errors++;
@@ -530,7 +530,7 @@
 	if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
 		snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
 		if (snd_pcm_running(ak4117->substream)) {
-			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
+			// printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
 			snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
 			wake_up(&runtime->sleep);
 			res = 1;
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index fd65da6..4fdd1fb 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -58,7 +58,7 @@
 			     unsigned char addr, unsigned char value)
 {
 #if 0
-	printk("set - 0x%x/0x%x\n", addr, value);
+	printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
 #endif
 	snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
 }
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 27a9dcf..7ae0239 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -542,10 +542,7 @@
 
 static int snd_ad1816a_free(ad1816a_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma1 >= 0) {
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 303861c..891bacc 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -109,7 +109,7 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+		snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
 #endif
 	outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
 	outb(chip->image[reg] = value, AD1848P(chip, REG));
@@ -139,7 +139,7 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("auto calibration time out - reg = 0x%x\n", reg);
+		snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
 #endif
 	outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
 	mb();
@@ -185,13 +185,13 @@
 		udelay(100);
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("mce_up - auto calibration time out (0)\n");
+		snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
 #endif
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit |= AD1848_MCE;
 	timeout = inb(AD1848P(chip, REGSEL));
 	if (timeout == 0x80)
-		snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if (!(timeout & AD1848_MCE))
 		outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -214,13 +214,13 @@
 #endif
 #ifdef CONFIG_SND_DEBUG
 	if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
-		snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
+		snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
 #endif
 	chip->mce_bit &= ~AD1848_MCE;
 	timeout = inb(AD1848P(chip, REGSEL));
 	outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
 	if (timeout == 0x80)
-		snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
 	if ((timeout & AD1848_MCE) == 0) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		return;
@@ -240,11 +240,10 @@
 	while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
-			snd_printk("mce_down - auto calibration time out (2)\n");
+			snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
+		time = schedule_timeout_interruptible(time);
 		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
 #if 0
@@ -254,11 +253,10 @@
 	while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 		if (time <= 0) {
-			snd_printk("mce_down - auto calibration time out (3)\n");
+			snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
 			return;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		time = schedule_timeout(time);
+		time = schedule_timeout_interruptible(time);
 		spin_lock_irqsave(&chip->reg_lock, flags);
 	}
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -846,10 +844,7 @@
 
 static int snd_ad1848_free(ad1848_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma >= 0) {
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 3231825..4af7690 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -1417,14 +1417,8 @@
 
 static int snd_cs4231_free(cs4231_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
-	if (chip->res_cport) {
-		release_resource(chip->res_cport);
-		kfree_nocheck(chip->res_cport);
-	}
+	release_and_free_resource(chip->res_port);
+	release_and_free_resource(chip->res_cport);
 	if (chip->irq >= 0) {
 		disable_irq(chip->irq);
 		if (!(chip->hwshare & CS4231_HWSHARE_IRQ))
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index d28315d..d60a55e 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -379,12 +379,8 @@
 {
 	struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
 
-	if (acard) {
-		if (acard->res_sb_port) {
-			release_resource(acard->res_sb_port);
-			kfree_nocheck(acard->res_sb_port);
-		}
-	}
+	if (acard)
+		release_and_free_resource(acard->res_sb_port);
 }
 
 #ifdef CONFIG_PNP
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 2128d4b..1adb88d 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -173,7 +173,10 @@
 	case 2117:	return 6;
 	case 2558:	return 7;
 	default:
-		snd_runtime_check(divisor >= 21 && divisor <= 192, return 192);
+		if (divisor < 21 || divisor > 192) {
+			snd_BUG();
+			return 192;
+		}
 		return divisor;
 	}
 }
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index aac8987..2edc9c9 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -606,8 +606,7 @@
 {
 	if (chip->res_port) {
 		snd_es1688_init(chip, 0);
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
+		release_and_free_resource(chip->res_port);
 	}
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index d0ea19f..970e2aa 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -173,7 +173,7 @@
                         outb(val, chip->port + 0x0C);
                         return 0;
                 }
-        snd_printk("dsp_command: timeout (0x%x)\n", val);
+	snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
         return -EINVAL;
 }
 
@@ -184,7 +184,8 @@
         for(i = MILLISECOND/10; i; i--)
                 if (inb(chip->port + 0x0C) & 0x40)
                         return inb(chip->port + 0x0A);
-        snd_printk("dsp_get_byte failed: 0x%lx = 0x%x!!!\n", chip->port + 0x0A, inb(chip->port + 0x0A));
+	snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
+		   chip->port + 0x0A, inb(chip->port + 0x0A));
         return -ENODEV;
 }
 
@@ -204,7 +205,7 @@
  end:
         spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
 #endif
 	return ret;
 }
@@ -223,7 +224,7 @@
 	data = snd_es18xx_dsp_get_byte(chip);
 	ret = data;
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x now is %02x (%d)\n", reg, data, ret);
+	snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
 #endif
  end:
         spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -259,7 +260,8 @@
 		if (ret < 0)
 			goto end;
 #ifdef REG_DEBUG
-		snd_printk("Reg %02x was %02x, set to %02x (%d)\n", reg, old, new, ret);
+		snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
+			   reg, old, new, ret);
 #endif
 	}
 	ret = oval;
@@ -277,7 +279,7 @@
         outb(data, chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
 #endif
 }
 
@@ -290,7 +292,7 @@
 	data = inb(chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
 #endif
         return data;
 }
@@ -309,7 +311,8 @@
 		new = (old & ~mask) | (val & mask);
 		outb(new, chip->port + 0x05);
 #ifdef REG_DEBUG
-		snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -329,7 +332,8 @@
 	new = inb(chip->port + 0x05);
         spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x was %02x, set to %02x, now is %02x\n", reg, old, expected, new);
+	snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
+		   reg, old, expected, new);
 #endif
 	return expected == new;
 }
@@ -1281,7 +1285,7 @@
 	outb(reg, chip->ctrl_port);
 	outb(data, chip->ctrl_port + 1);
 #ifdef REG_DEBUG
-	snd_printk("Config reg %02x set to %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
 #endif
 }
 
@@ -1346,7 +1350,7 @@
 			irqmask = 3;
 			break;
 		default:
-			snd_printk("invalid irq %d\n", chip->irq);
+			snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
 			return -ENODEV;
 		}
 		switch (chip->dma1) {
@@ -1360,7 +1364,7 @@
 			dma1mask = 3;
 			break;
 		default:
-			snd_printk("invalid dma1 %d\n", chip->dma1);
+			snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
 			return -ENODEV;
 		}
 		switch (chip->dma2) {
@@ -1377,7 +1381,7 @@
 			dma2mask = 3;
 			break;
 		default:
-			snd_printk("invalid dma2 %d\n", chip->dma2);
+			snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
 			return -ENODEV;
 		}
 
@@ -1440,7 +1444,7 @@
 
 	/* reset */
 	if (snd_es18xx_reset(chip) < 0) {
-                snd_printk("reset at 0x%lx failed!!!\n", chip->port);
+		snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
 		return -ENODEV;
 	}
 
@@ -1527,7 +1531,7 @@
 		chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
 		break;
 	default:
-                snd_printk("[0x%lx] unsupported chip ES%x\n",
+		snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
                            chip->port, chip->version);
                 return -ENODEV;
         }
@@ -1640,18 +1644,9 @@
 
 static int snd_es18xx_free(es18xx_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
-	if (chip->res_ctrl_port) {
-		release_resource(chip->res_ctrl_port);
-		kfree_nocheck(chip->res_ctrl_port);
-	}
-	if (chip->res_mpu_port) {
-		release_resource(chip->res_mpu_port);
-		kfree_nocheck(chip->res_mpu_port);
-	}
+	release_and_free_resource(chip->res_port);
+	release_and_free_resource(chip->res_ctrl_port);
+	release_and_free_resource(chip->res_mpu_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 	if (chip->dma1 >= 0) {
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index de4b56d..ef1b2e9 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -199,7 +199,7 @@
 
 	block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
 	if (block == NULL) {
-		snd_printk("gf1: DMA transfer failure; not enough memory\n");
+		snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n");
 		return -ENOMEM;
 	}
 	*block = *__block;
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index 23e1b5f..8d5752b 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -343,7 +343,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_pokew - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
 #endif
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -367,7 +367,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_peekw - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
 #endif
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@@ -393,7 +393,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (!gus->interwave)
-		snd_printk("snd_gf1_dram_setmem - GF1!!!\n");
+		snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
 #endif
 	addr &= ~1;
 	count >>= 1;
@@ -449,30 +449,30 @@
 	int voice, ctrl;
 
 	voice = gus->gf1.active_voice;
-	printk(" -%i- GF1  voice ctrl, ramp ctrl  = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
-	printk(" -%i- GF1  frequency              = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
-	printk(" -%i- GF1  loop start, end        = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
-	printk(" -%i- GF1  ramp start, end, rate  = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
-	printk(" -%i- GF1  volume                 = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
-	printk(" -%i- GF1  position               = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
+	printk(KERN_INFO " -%i- GF1  voice ctrl, ramp ctrl  = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
+	printk(KERN_INFO " -%i- GF1  frequency              = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
+	printk(KERN_INFO " -%i- GF1  loop start, end        = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
+	printk(KERN_INFO " -%i- GF1  ramp start, end, rate  = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
+	printk(KERN_INFO" -%i- GF1  volume                 = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
+	printk(KERN_INFO " -%i- GF1  position               = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
 	if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) {	/* enhanced mode */
 		mode = snd_gf1_i_read8(gus, 0x15);
-		printk(" -%i- GFA1 mode                   = 0x%x\n", voice, mode);
+		printk(KERN_INFO " -%i- GFA1 mode                   = 0x%x\n", voice, mode);
 		if (mode & 0x01) {	/* Effect processor */
-			printk(" -%i- GFA1 effect address         = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
-			printk(" -%i- GFA1 effect volume          = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
-			printk(" -%i- GFA1 effect volume final    = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
-			printk(" -%i- GFA1 effect acumulator      = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
+			printk(KERN_INFO " -%i- GFA1 effect address         = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
+			printk(KERN_INFO " -%i- GFA1 effect volume          = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
+			printk(KERN_INFO " -%i- GFA1 effect volume final    = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
+			printk(KERN_INFO " -%i- GFA1 effect acumulator      = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
 		}
 		if (mode & 0x20) {
-			printk(" -%i- GFA1 left offset            = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
-			printk(" -%i- GFA1 left offset final      = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
-			printk(" -%i- GFA1 right offset           = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
-			printk(" -%i- GFA1 right offset final     = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
+			printk(KERN_INFO " -%i- GFA1 left offset            = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
+			printk(KERN_INFO " -%i- GFA1 left offset final      = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
+			printk(KERN_INFO " -%i- GFA1 right offset           = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
+			printk(KERN_INFO " -%i- GFA1 right offset final     = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
 		} else
-			printk(" -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+			printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
 	} else
-		printk(" -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
+		printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
 }
 
 #if 0
@@ -481,45 +481,45 @@
 {
 	unsigned char global_mode = 0x00;
 
-	printk(" -G- GF1 active voices            = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
+	printk(KERN_INFO " -G- GF1 active voices            = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
 	if (gus->interwave) {
 		global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
-		printk(" -G- GF1 global mode              = 0x%x\n", global_mode);
+		printk(KERN_INFO " -G- GF1 global mode              = 0x%x\n", global_mode);
 	}
 	if (global_mode & 0x02)	/* LFO enabled? */
-		printk(" -G- GF1 LFO base                 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
-	printk(" -G- GF1 voices IRQ read          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
-	printk(" -G- GF1 DRAM DMA control         = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
-	printk(" -G- GF1 DRAM DMA high/low        = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
-	printk(" -G- GF1 DRAM IO high/low         = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
+		printk(KERN_INFO " -G- GF1 LFO base                 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
+	printk(KERN_INFO " -G- GF1 voices IRQ read          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
+	printk(KERN_INFO " -G- GF1 DRAM DMA control         = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
+	printk(KERN_INFO " -G- GF1 DRAM DMA high/low        = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
+	printk(KERN_INFO " -G- GF1 DRAM IO high/low         = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
 	if (!gus->interwave)
-		printk(" -G- GF1 record DMA control       = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
-	printk(" -G- GF1 DRAM IO 16               = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
+		printk(KERN_INFO " -G- GF1 record DMA control       = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
+	printk(KERN_INFO " -G- GF1 DRAM IO 16               = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
 	if (gus->gf1.enh_mode) {
-		printk(" -G- GFA1 memory config           = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
-		printk(" -G- GFA1 memory control          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
-		printk(" -G- GFA1 FIFO record base        = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
-		printk(" -G- GFA1 FIFO playback base      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
-		printk(" -G- GFA1 interleave control      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
+		printk(KERN_INFO " -G- GFA1 memory config           = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
+		printk(KERN_INFO " -G- GFA1 memory control          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
+		printk(KERN_INFO " -G- GFA1 FIFO record base        = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
+		printk(KERN_INFO " -G- GFA1 FIFO playback base      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
+		printk(KERN_INFO " -G- GFA1 interleave control      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
 	}
 }
 
 void snd_gf1_print_setup_registers(snd_gus_card_t * gus)
 {
-	printk(" -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
-	printk(" -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
-	printk(" -S- timer control                = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
-	printk(" -S- timer data                   = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
-	printk(" -S- status read                  = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
-	printk(" -S- Sound Blaster control        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
-	printk(" -S- AdLib timer 1/2              = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
-	printk(" -S- reset                        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
+	printk(KERN_INFO " -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
+	printk(KERN_INFO " -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
+	printk(KERN_INFO " -S- timer control                = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
+	printk(KERN_INFO " -S- timer data                   = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
+	printk(KERN_INFO " -S- status read                  = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
+	printk(KERN_INFO " -S- Sound Blaster control        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
+	printk(KERN_INFO " -S- AdLib timer 1/2              = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
+	printk(KERN_INFO " -S- reset                        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
 	if (gus->interwave) {
-		printk(" -S- compatibility                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
-		printk(" -S- decode control               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
-		printk(" -S- version number               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
-		printk(" -S- MPU-401 emul. control A/B    = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
-		printk(" -S- emulation IRQ                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
+		printk(KERN_INFO " -S- compatibility                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
+		printk(KERN_INFO " -S- decode control               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
+		printk(KERN_INFO " -S- version number               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
+		printk(KERN_INFO " -S- MPU-401 emul. control A/B    = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
+		printk(KERN_INFO " -S- emulation IRQ                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
 	}
 }
 
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 8f2872f..4f57ff4 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -113,14 +113,8 @@
 	snd_gf1_stop(gus);
 	snd_gus_init_dma_irq(gus, 0);
       __hw_end:
-	if (gus->gf1.res_port1) {
-		release_resource(gus->gf1.res_port1);
-		kfree_nocheck(gus->gf1.res_port1);
-	}
-	if (gus->gf1.res_port2) {
-		release_resource(gus->gf1.res_port2);
-		kfree_nocheck(gus->gf1.res_port2);
-	}
+	release_and_free_resource(gus->gf1.res_port1);
+	release_and_free_resource(gus->gf1.res_port2);
 	if (gus->gf1.irq >= 0)
 		free_irq(gus->gf1.irq, (void *) gus);
 	if (gus->gf1.dma1 >= 0) {
@@ -252,7 +246,7 @@
 	snd_gf1_poke(gus, 0L, 0xaa);
 	snd_gf1_poke(gus, 1L, 0x55);
 	if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
-		snd_printk("plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
+		snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
 		return -ENOMEM;
 	}
 	for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
@@ -305,20 +299,17 @@
 	dma2 = gus->gf1.dma2;
 	dma2 = dma2 < 0 ? -dma2 : dma2;
 	dma2 = dmas[dma2 & 7];
-#if 0
-	printk("dma1 = %i, dma2 = %i\n", gus->gf1.dma1, gus->gf1.dma2);
-#endif
 	dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);
 
 	if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
-		snd_printk("Error! DMA isn't defined.\n");
+		snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
 		return -EINVAL;
 	}
 	irq = gus->gf1.irq;
 	irq = irq < 0 ? -irq : irq;
 	irq = irqs[irq & 0x0f];
 	if (irq == 0) {
-		snd_printk("Error! IRQ isn't defined.\n");
+		snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
 		return -EINVAL;
 	}
 	irq |= 0x40;
@@ -406,8 +397,8 @@
 				strcpy(card->longname, "Gravis UltraSound Extreme");
 				gus->ess_flag = 1;
 			} else {
-				snd_printk("unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
-				snd_printk("  please - report to <perex@suse.cz>\n");
+				snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
+				snd_printk(KERN_ERR "  please - report to <perex@suse.cz>\n");
 			}
 		}
 	}
@@ -431,7 +422,7 @@
 
 	if (!gus->interwave) {
 		if ((err = snd_gus_check_version(gus)) < 0) {
-			snd_printk("version check failed\n");
+			snd_printk(KERN_ERR "version check failed\n");
 			return err;
 		}
 		if ((err = snd_gus_detect_memory(gus)) < 0)
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 5eb766d..2e23f2a 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -198,7 +198,7 @@
 		if (nblock != NULL) {
 			if (size != (int)nblock->size) {
 				/* TODO: remove in the future */
-				snd_printk("snd_gf1_mem_alloc - share: sizes differ\n");
+				snd_printk(KERN_ERR "snd_gf1_mem_alloc - share: sizes differ\n");
 				goto __std;
 			}
 			nblock->share++;
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index beb0136..1cc89fb 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -333,8 +333,7 @@
 			}
 		}
 		if (count > 0 && !in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			if (signal_pending(current))
 				return -EAGAIN;
 		}
@@ -698,7 +697,7 @@
 	gus_pcm_private_t *pcmp = runtime->private_data;
 	
 	if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
-		snd_printk("gf1 pcm - serious DMA problem\n");
+		snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
 
 	snd_gf1_dma_done(gus);	
 	return 0;
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index ef687ab..9071096 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -134,7 +134,7 @@
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	snd_gf1_select_voice(gus, voice);
 #if 0
-	printk(" -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+	printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
 #endif
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
@@ -148,7 +148,7 @@
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	snd_gf1_select_voice(gus, voice);
 #if 0
-	printk(" -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
+	printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
 #endif
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
 	snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c
index c122e7b..dfed85b 100644
--- a/sound/isa/gus/gus_simple.c
+++ b/sound/isa/gus/gus_simple.c
@@ -136,7 +136,7 @@
 		snd_gf1_select_voice(gus, voice->number);
 		snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
 		snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume);
-		printk("gf1_volume = 0x%x\n", voice->gf1_volume);
+		/* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */
 		spin_unlock_irqrestore(&gus->reg_lock, flags);
 		return;
 	}
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index 1bc2da8..fbc95e9 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -104,7 +104,7 @@
 	gus->midi_substream_output = substream;
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 #if 0
-	snd_printk("write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
+	snd_printk(KERN_DEBUG "write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
 #endif
 	return 0;
 }
@@ -126,7 +126,7 @@
 		for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++)
 			snd_gf1_uart_get(gus);	/* clean Rx */
 		if (i >= 1000)
-			snd_printk("gus midi uart init read - cleanup error\n");
+			snd_printk(KERN_ERR "gus midi uart init read - cleanup error\n");
 	}
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 #if 0
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
index 3d36f6c..b3382fe 100644
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -119,7 +119,7 @@
 		freq16 = 50;
 	if (freq16 & 0xf8000000) {
 		freq16 = ~0xf8000000;
-		snd_printk("snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
+		snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
 	}
 	return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
 }
@@ -203,14 +203,14 @@
 	fc = (freq << 10) / rate;
 	if (fc > 97391L) {
 		fc = 97391;
-		snd_printk("patch: (1) fc frequency overflow - %u\n", fc);
+		snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
 	}
 	fc = (fc * 44100UL) / mix_rate;
 	while (scale--)
 		fc <<= 1;
 	if (fc > 65535L) {
 		fc = 65535;
-		snd_printk("patch: (2) fc frequency overflow - %u\n", fc);
+		snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
 	}
 	return (unsigned short) fc;
 }
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 358cba9..f703a9f 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -437,7 +437,7 @@
 		for (i = 0; i < 8; ++i)
 			iwave[i] = snd_gf1_peek(gus, bank_pos + i);
 #ifdef CONFIG_SND_DEBUG_ROM
-		printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
+		printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
 		       iwave[0], iwave[1], iwave[2], iwave[3],
 		       iwave[4], iwave[5], iwave[6], iwave[7]);
 #endif
@@ -447,7 +447,7 @@
 		for (i = 0; i < sizeof(struct rom_hdr); i++)
 			csum += snd_gf1_peek(gus, bank_pos + i);
 #ifdef CONFIG_SND_DEBUG_ROM
-		printk("ROM checksum = 0x%x (computed)\n", csum);
+		printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum);
 #endif
 		if (csum != 0)
 			continue;	/* not valid rom */
@@ -638,10 +638,7 @@
 	if (iwcard == NULL)
 		return;
 #ifdef SNDRV_STB
-	if (iwcard->i2c_res) {
-		release_resource(iwcard->i2c_res);
-		kfree_nocheck(iwcard->i2c_res);
-	}
+	release_and_free_resource(iwcard->i2c_res);
 #endif
 	if (iwcard->irq >= 0)
 		free_irq(iwcard->irq, (void *)iwcard);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 4ba268f..47cabda 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -656,10 +656,7 @@
 {
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	kfree(chip);
 	return 0;
 }
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 73573cb..b94339f 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -299,10 +299,8 @@
 static long snd_legacy_find_free_ioport(long *port_table, long size)
 {
 	while (*port_table != -1) {
-		struct resource *res;
-		if ((res = request_region(*port_table, size, "ALSA test")) != NULL) {
-			release_resource(res);
-			kfree_nocheck(res);
+		if (request_region(*port_table, size, "ALSA test")) {
+			release_region(*port_table, size);
 			return *port_table;
 		}
 		port_table++;
@@ -1227,10 +1225,7 @@
 
 static int snd_opti93x_free(opti93x_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
 	if (chip->dma1 >= 0) {
 		disable_dma(chip->dma1);
 		free_dma(chip->dma1);
@@ -1656,8 +1651,7 @@
 			if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
 				return 1;
 
-		release_resource(chip->res_mc_base);
-		kfree_nocheck(chip->res_mc_base);
+		release_and_free_resource(chip->res_mc_base);
 		chip->res_mc_base = NULL;
 
 	}
@@ -1683,8 +1677,7 @@
 		if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
 			return 1;
 
-		release_resource(chip->res_mc_base);
-		kfree_nocheck(chip->res_mc_base);
+		release_and_free_resource(chip->res_mc_base);
 		chip->res_mc_base = NULL;
 	}
 #endif	/* OPTi93X */
@@ -1886,12 +1879,8 @@
 {
 	opti9xx_t *chip = (opti9xx_t *)card->private_data;
         
-	if (chip) {
-		if (chip->res_mc_base) {
-			release_resource(chip->res_mc_base);
-			kfree_nocheck(chip->res_mc_base);
-		}
-	}
+	if (chip)
+		release_and_free_resource(chip->res_mc_base);
 }
 
 static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 5375705..b09c657 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -135,8 +135,7 @@
 snd_emu8000_read_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -148,8 +147,7 @@
 snd_emu8000_write_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -437,8 +435,7 @@
 	for (i = 0; i < 10000; i++) {
 		if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
 			break;
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
@@ -1054,18 +1051,9 @@
  */
 static int snd_emu8000_free(emu8000_t *hw)
 {
-	if (hw->res_port1) {
-		release_resource(hw->res_port1);
-		kfree_nocheck(hw->res_port1);
-	}
-	if (hw->res_port2) {
-		release_resource(hw->res_port2);
-		kfree_nocheck(hw->res_port2);
-	}
-	if (hw->res_port3) {
-		release_resource(hw->res_port3);
-		kfree_nocheck(hw->res_port3);
-	}
+	release_and_free_resource(hw->res_port1);
+	release_and_free_resource(hw->res_port2);
+	release_and_free_resource(hw->res_port3);
 	kfree(hw);
 	return 0;
 }
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 26e6930..2fea67e 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -109,8 +109,7 @@
 snd_emu8000_write_wait(emu8000_t *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 		if (signal_pending(current))
 			break;
 	}
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index 0209790..b323bee 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -117,8 +117,7 @@
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 		if (can_schedule) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_interruptible(1);
 			if (signal_pending(current))
 				break;
 		}
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c
index 1f63aa5..f68e2174 100644
--- a/sound/isa/sb/emu8000_synth.c
+++ b/sound/isa/sb/emu8000_synth.c
@@ -56,7 +56,7 @@
 	emu->num_ports = hw->seq_ports;
 
 	if (hw->memhdr) {
-		snd_printk("memhdr is already initialized!?\n");
+		snd_printk(KERN_ERR "memhdr is already initialized!?\n");
 		snd_util_memhdr_free(hw->memhdr);
 	}
 	hw->memhdr = snd_util_memhdr_new(hw->mem_size);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 7888783..c2fa451 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -345,10 +345,7 @@
         
 	if (acard == NULL)
 		return;
-	if (acard->fm_res) {
-		release_resource(acard->fm_res);
-		kfree_nocheck(acard->fm_res);
-	}
+	release_and_free_resource(acard->fm_res);
 }
 
 #ifdef CONFIG_PNP
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index a99e642..556b95e 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -747,7 +747,7 @@
 	unsigned char realirq, realdma, realmpureg;
 	/* note: mpu register should be present only on SB16 Vibra soundcards */
 
-	// printk("codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
+	// printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
 	spin_lock_irqsave(&chip->mixer_lock, flags);
 	mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -821,9 +821,9 @@
 
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 	if ((~realirq) & irqreg || (~realdma) & dmareg) {
-		snd_printk("SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
-		snd_printk("SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
-		snd_printk("SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
+		snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
+		snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
+		snd_printk(KERN_ERR "SB16 [0x%lx]:    got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
 		return -ENODEV;
 	}
 	return 0;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index c41ac25..0bc0a3a 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -78,10 +78,7 @@
 
 	if (acard == NULL)
 		return;
-	if (acard->fm_res) {
-		release_resource(acard->fm_res);
-		kfree_nocheck(acard->fm_res);
-	}
+	release_and_free_resource(acard->fm_res);
 }
 
 static int __init snd_sb8_probe(int dev)
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 87c9b1b..5ddc6e4 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -334,9 +334,6 @@
 	snd_pcm_substream_t *substream;
 	snd_pcm_runtime_t *runtime;
 
-#if 0
-	snd_printk("sb8: interrupt\n");
-#endif
 	snd_sb_ack_8bit(chip);
 	switch (chip->mode) {
 	case SB_MODE_PLAYBACK_8:	/* ok.. playback is active */
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index f0f205a..603e923 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -45,7 +45,7 @@
 {
 	int i;
 #ifdef IO_DEBUG
-	snd_printk("command 0x%x\n", val);
+	snd_printk(KERN_DEBUG "command 0x%x\n", val);
 #endif
 	for (i = BUSY_LOOPS; i; i--)
 		if ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
@@ -64,7 +64,7 @@
 		if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
 			val = inb(SBP(chip, READ));
 #ifdef IO_DEBUG
-			snd_printk("get_byte 0x%x\n", val);
+			snd_printk(KERN_DEBUG "get_byte 0x%x\n", val);
 #endif
 			return val;
 		}
@@ -154,7 +154,7 @@
 			str = "16";
 			break;
 		default:
-			snd_printk("SB [0x%lx]: unknown DSP chip version %i.%i\n",
+			snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n",
 				   chip->port, major, minor);
 			return -ENODEV;
 		}
@@ -178,10 +178,8 @@
 
 static int snd_sbdsp_free(sb_t *chip)
 {
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	if (chip->res_port)
+		release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *) chip);
 #ifdef CONFIG_ISA
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index ff4b599..5a926a4 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -36,7 +36,7 @@
 	outb(data, SBP(chip, MIXER_DATA));
 	udelay(10);
 #ifdef IO_DEBUG
-	snd_printk("mixer_write 0x%x 0x%x\n", reg, data);
+	snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data);
 #endif
 }
 
@@ -49,7 +49,7 @@
 	result = inb(SBP(chip, MIXER_DATA));
 	udelay(10);
 #ifdef IO_DEBUG
-	snd_printk("mixer_read 0x%x 0x%x\n", reg, result);
+	snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result);
 #endif
 	return result;
 }
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 9f6b58c..1158806 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -338,25 +338,11 @@
 static void soundscape_free(snd_card_t * c)
 {
 	register struct soundscape *sscape = get_card_soundscape(c);
-	release_resource(sscape->io_res);
-	kfree_nocheck(sscape->io_res);
+	release_and_free_resource(sscape->io_res);
 	free_dma(sscape->chip->dma1);
 }
 
 /*
- * Put this process into an idle wait-state for a certain number
- * of "jiffies". The process can almost certainly be rescheduled
- * while we're waiting, and so we must NOT be holding any spinlocks
- * when we call this function. If we are then we risk DEADLOCK in
- * SMP (Ha!) or pre-emptible kernels.
- */
-static inline void sleep(long jiffs, int state)
-{
-	set_current_state(state);
-	schedule_timeout(jiffs);
-}
-
-/*
  * Tell the SoundScape to begin a DMA tranfer using the given channel.
  * All locking issues are left to the caller.
  */
@@ -393,7 +379,7 @@
 		unsigned long flags;
 		unsigned char x;
 
-		sleep(1, TASK_INTERRUPTIBLE);
+		schedule_timeout_interruptible(1);
 
 		spin_lock_irqsave(&s->lock, flags);
 		x = inb(HOST_DATA_IO(s->io_base));
@@ -420,7 +406,7 @@
 		unsigned long flags;
 		unsigned char x;
 
-		sleep(1, TASK_INTERRUPTIBLE);
+		schedule_timeout_interruptible(1);
 
 		spin_lock_irqsave(&s->lock, flags);
 		x = inb(HOST_DATA_IO(s->io_base));
@@ -1288,8 +1274,7 @@
 	free_dma(params->dma1);
 
 	_release_region:
-	release_resource(io_res);
-	kfree_nocheck(io_res);
+	release_and_free_resource(io_res);
 
 	return err;
 }
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 0a572e0..1818f10 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -379,10 +379,7 @@
 	snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
 	
 	if (acard) {
-		if (acard->wavefront.res_base != NULL) {
-			release_resource(acard->wavefront.res_base);
-			kfree_nocheck(acard->wavefront.res_base);
-		}
+		release_and_free_resource(acard->wavefront.res_base);
 		if (acard->wavefront.irq > 0)
 			free_irq(acard->wavefront.irq, (void *)acard);
 	}
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 0c3c951..abd79b7 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -275,8 +275,7 @@
 wavefront_sleep (int limit)
 
 {
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(limit);
+	schedule_timeout_interruptible(limit);
 
 	return signal_pending(current);
 }
@@ -1788,8 +1787,7 @@
 	outb (val,port);
 	spin_unlock_irq(&dev->irq_lock);
 	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		if ((timeout = schedule_timeout(timeout)) == 0)
+		if ((timeout = schedule_timeout_interruptible(timeout)) == 0)
 			return;
 		if (dev->irq_ok)
 			return;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 3f9684f..d08a42b 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -57,8 +57,6 @@
 MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
 #endif
 
-#define chip_t au1000_t
-
 #define PLAYBACK 0
 #define CAPTURE 1
 #define AC97_SLOT_3 0x01
@@ -474,7 +472,7 @@
 	u32 volatile cmd;
 	u16 volatile data;
 	int             i;
-	spin_lock(au1000->ac97_lock);
+	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
@@ -497,7 +495,7 @@
 	}
 
 	data = au1000->ac97_ioport->cmd & 0xffff;
-	spin_unlock(au1000->ac97_lock);
+	spin_unlock(&au1000->ac97_lock);
 
 	return data;
 
@@ -509,7 +507,7 @@
 {
 	u32 cmd;
 	int i;
-	spin_lock(au1000->ac97_lock);
+	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
 	for (i = 0; i < 0x5000; i++)
@@ -522,7 +520,7 @@
 	cmd &= ~AC97C_READ;
 	cmd |= ((u32) val << AC97C_WD_BIT);
 	au1000->ac97_ioport->cmd = cmd;
-	spin_unlock(au1000->ac97_lock);
+	spin_unlock(&au1000->ac97_lock);
 }
 static void
 snd_au1000_ac97_free(ac97_t *ac97)
@@ -606,8 +604,7 @@
 		/* put internal AC97 block into reset */
 		au1000->ac97_ioport->cntrl = AC97C_RS;
 		au1000->ac97_ioport = NULL;
-		release_resource(au1000->ac97_res_port);
-		kfree_nocheck(au1000->ac97_res_port);
+		release_and_free_resource(au1000->ac97_res_port);
 	}
 
 	if (au1000->stream[PLAYBACK]->dma >= 0)
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index a5d593c..0fb16cf 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -1,13 +1,5 @@
 # ALSA PCI drivers
 
-config SND_AC97_CODEC
-	tristate
-	select SND_PCM
-	select SND_AC97_BUS
-
-config SND_AC97_BUS
-	tristate
-
 menu "PCI devices"
 	depends on SND!=n && PCI
 
@@ -192,6 +184,7 @@
 	tristate "SB Audigy LS / Live 24bit"
 	depends on SND
 	select SND_AC97_CODEC
+	select SND_RAWMIDI
 	help
 	  Say Y here to include support for the Sound Blaster Audigy LS
 	  and Live 24bit.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 41fc290..9bde76c 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -220,12 +220,6 @@
   /*  31 */ "Reserved 31"
 };
 
-/*
- * Shared AC97 controllers (ICH, ATIIXP...)
- */
-static DECLARE_MUTEX(shared_codec_mutex);
-static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
-
 
 /*
  *  I/O routines
@@ -996,14 +990,8 @@
 {
 	if (ac97) {
 		snd_ac97_proc_done(ac97);
-		if (ac97->bus) {
+		if (ac97->bus)
 			ac97->bus->codec[ac97->num] = NULL;
-			if (ac97->bus->shared_type) {
-				down(&shared_codec_mutex);
-				shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
-				up(&shared_codec_mutex);
-			}
-		}
 		if (ac97->private_free)
 			ac97->private_free(ac97);
 		kfree(ac97);
@@ -1139,7 +1127,6 @@
 {
 	snd_kcontrol_new_t template;
 	memcpy(&template, _template, sizeof(template));
-	snd_runtime_check(!template.index, return NULL);
 	template.index = ac97->num;
 	return snd_ctl_new1(&template, ac97);
 }
@@ -1758,8 +1745,7 @@
 			if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
 				return 0;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	return -ENODEV;
 }
@@ -1889,21 +1875,6 @@
 	snd_assert(bus != NULL && template != NULL, return -EINVAL);
 	snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
 
-	snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
-	if (bus->shared_type) {
-		/* already shared? */
-		down(&shared_codec_mutex);
-		ac97 = shared_codec[bus->shared_type-1][template->num];
-		if (ac97) {
-			if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
-			    (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
-				up(&shared_codec_mutex);
-				return -EACCES; /* skip this */
-			}
-		}
-		up(&shared_codec_mutex);
-	}
-
 	card = bus->card;
 	ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
 	if (ac97 == NULL)
@@ -2020,8 +1991,7 @@
 		do {
 			if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
 				goto __ready_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
 	}
@@ -2053,8 +2023,7 @@
 		do {
 			if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
 				goto __ready_ok;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
 	}
@@ -2077,6 +2046,8 @@
 		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
 		if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
 			ac97->flags |= AC97_DOUBLE_RATE;
+		/* restore to slots 10/11 to avoid the confliction with surrounds */
+		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
 	}
 	if (ac97->ext_id & AC97_EI_VRA) {	/* VRA support */
 		snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
@@ -2153,7 +2124,7 @@
 		}
 	}
 	/* make sure the proper powerdown bits are cleared */
-	if (ac97->scaps) {
+	if (ac97->scaps && ac97_is_audio(ac97)) {
 		reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
 		if (ac97->scaps & AC97_SCAP_SURROUND_DAC) 
 			reg &= ~AC97_EA_PRJ;
@@ -2167,13 +2138,6 @@
 		return err;
 	}
 	*rac97 = ac97;
-
-	if (bus->shared_type) {
-		down(&shared_codec_mutex);
-		shared_codec[bus->shared_type-1][ac97->num] = ac97;
-		up(&shared_codec_mutex);
-	}
-
 	return 0;
 }
 
@@ -2295,8 +2259,7 @@
 		do {
 			if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		/* FIXME: extra delay */
 		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
@@ -2308,8 +2271,7 @@
 			unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
 			if (val != 0xffff && (val & 1) != 0)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	}
 __reset_ready:
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 0238cc6..de1c72a 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -163,14 +163,24 @@
 		.private_value = 1, \
 	}
 
+static inline int is_surround_on(ac97_t *ac97)
+{
+	return ac97->channel_mode >= 1;
+}
+
+static inline int is_clfe_on(ac97_t *ac97)
+{
+	return ac97->channel_mode >= 2;
+}
+
 static inline int is_shared_linein(ac97_t *ac97)
 {
-	return ! ac97->indep_surround && ac97->channel_mode >= 1;
+	return ! ac97->indep_surround && is_surround_on(ac97);
 }
 
 static inline int is_shared_micin(ac97_t *ac97)
 {
-	return ! ac97->indep_surround && ac97->channel_mode >= 2;
+	return ! ac97->indep_surround && is_clfe_on(ac97);
 }
 
 
@@ -1450,7 +1460,8 @@
 	codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
 	codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
 
-	snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end);
+	if (! (codecs[0] || codecs[1] || codecs[2]))
+		goto __end;
 
 	for (idx = 0; idx < 3; idx++)
 		if (ac97->spec.ad18xx.unchained[idx])
@@ -1753,12 +1764,13 @@
 
 static void ad1888_update_jacks(ac97_t *ac97)
 {
+	unsigned short val = 0;
+	if (! is_shared_linein(ac97))
+		val |= (1 << 12);
+	if (! is_shared_micin(ac97))
+		val |= (1 << 11);
 	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
-			     is_shared_linein(ac97) ? 0 : 1 << 12);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
-			     is_shared_micin(ac97) ? 0 : 1 << 11);
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
 }
 
 static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
@@ -1852,12 +1864,7 @@
 
 static void ad1985_update_jacks(ac97_t *ac97)
 {
-	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
-			     is_shared_linein(ac97) ? 0 : 1 << 12);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
-			     is_shared_micin(ac97) ? 0 : 1 << 11);
+	ad1888_update_jacks(ac97);
 	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
 			     is_shared_micin(ac97) ? 0 : 1 << 9);
 }
@@ -2442,21 +2449,37 @@
 
 static void cm9761_update_jacks(ac97_t *ac97)
 {
-	unsigned short surr_vals[2][2] = {
-		{ 0x0008, 0x0400 }, /* off, on */
-		{ 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
+	/* FIXME: check the bits for each model
+	 *        model 83 is confirmed to work
+	 */
+	static unsigned short surr_on[3][2] = {
+		{ 0x0008, 0x0000 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x0008 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x0008 }, /* 9761-83 */
 	};
-	unsigned short clfe_vals[2][2] = {
-		{ 0x2000, 0x1880 }, /* off, on */
-		{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+	static unsigned short clfe_on[3][2] = {
+		{ 0x0000, 0x1000 }, /* 9761-78 & 82 */
+		{ 0x1000, 0x0000 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x1000 }, /* 9761-83 */
 	};
+	static unsigned short surr_shared[3][2] = {
+		{ 0x0000, 0x0400 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x0400 }, /* 9761-82 rev.B */
+		{ 0x0000, 0x0400 }, /* 9761-83 */
+	};
+	static unsigned short clfe_shared[3][2] = {
+		{ 0x2000, 0x0880 }, /* 9761-78 & 82 */
+		{ 0x0000, 0x2880 }, /* 9761-82 rev.B */
+		{ 0x2000, 0x0800 }, /* 9761-83 */
+	};
+	unsigned short val = 0;
 
-	/* shared Line-In */
-	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408,
-			     surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]);
-	/* shared Mic */
-	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
-			     clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]);
+	val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
+	val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
+	val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
+	val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
+
+	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
 }
 
 static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
@@ -2551,7 +2574,7 @@
 	snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
 	snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
 
-	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */
+	ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
 	if (ac97->id == AC97_ID_CM9761_82) {
 		unsigned short tmp;
 		/* check page 1, reg 0x60 */
@@ -2560,7 +2583,8 @@
 		tmp = snd_ac97_read(ac97, 0x60);
 		ac97->spec.dev_flags = tmp & 1; /* revision B? */
 		snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
-	}
+	} else if (ac97->id == AC97_ID_CM9761_83)
+		ac97->spec.dev_flags = 2;
 
 	ac97->build_ops = &patch_cm9761_ops;
 
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index dd289b9..ded1316 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -303,6 +303,15 @@
 				     AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
 	snd_ac97_update(ac97, reg, tmp & 0xffff);
 	snd_ac97_read(ac97, reg);
+	if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
+		/* Intel controllers require double rate data to be put in
+		 * slots 7+8
+		 */
+		snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
+				     AC97_GP_DRSS_MASK,
+				     dbl ? AC97_GP_DRSS_78 : 0);
+		snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
+	}
 	return 0;
 }
 
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index d7d99a2..e72ccd1 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -50,7 +50,7 @@
 #include "ad1889.h"
 #include "ac97/ac97_id.h"
 
-#define	AD1889_DRVVER	"$Revision: 1.3 $"
+#define	AD1889_DRVVER	"$Revision: 1.4 $"
 
 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
 MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@@ -982,8 +982,7 @@
 	return 0;
 
 free_and_ret:
-	if (chip)
-		kfree(chip);
+	kfree(chip);
 	pci_disable_device(pci);
 
 	return err;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index f35b558..4e76c4a 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -45,23 +45,25 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32};
-static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = SNDRV_DEFAULT_IDX1;	/* Index */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int pcm_channels = 32;
+static int spdif = 0;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
-module_param_array(pcm_channels, int, NULL, 0444);
+module_param(pcm_channels, int, 0444);
 MODULE_PARM_DESC(pcm_channels, "PCM Channels");
-module_param_array(spdif, bool, NULL, 0444);
+module_param(spdif, bool, 0444);
 MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
 /*
  *  Debug part definitions
  */
@@ -396,10 +398,8 @@
 		res = snd_ali_5451_peek(codec,port);
 		if (! (res & 0x8000))
 			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (sched)
+			schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	snd_ali_5451_poke(codec, port, res & ~0x8000);
 	snd_printdd("ali_codec_ready: codec is not ready.\n ");
@@ -419,12 +419,10 @@
 		dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 		if (dwChk2 != dwChk1)
 			return 0;
-		if (sched) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (sched)
+			schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("ali_stimer_read: stimer is not ready.\n");
+	snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
 	return -EIO;
 }
 
@@ -436,7 +434,7 @@
 	unsigned int port = 0;
 
 	if (reg >= 0x80) {
-		snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg);
+		snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
 		return;
 	}
 
@@ -465,7 +463,7 @@
 	unsigned int port = 0;
 
 	if (reg >= 0x80) {
-		snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg);
+		snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
 		return ~0;
 	}
 
@@ -669,7 +667,7 @@
 	unsigned int idx =  channel & 0x1f;
 
 	if (codec->synth.chcnt >= ALI_CHANNELS){
-		snd_printk("ali_alloc_pcm_channel: no free channels.\n");
+		snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
 		return -1;
 	}
 
@@ -700,7 +698,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
 			return result;
 		} else {
-			snd_printk("ali_find_free_channel: record channel is busy now.\n");
+			snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
 			return -1;
 		}
 	}
@@ -712,7 +710,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
 			return result;
 		} else {
-			snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n");
+			snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
 		}
 	}
 
@@ -720,7 +718,7 @@
 		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
 			return result;
 	}
-	snd_printk("ali_find_free_channel: no free channels.\n");
+	snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
 	return -1;
 }
 
@@ -734,7 +732,7 @@
 		return;
 
 	if (!(codec->synth.chmap & (1 << idx))) {
-		snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel);
+		snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
 		return;
 	} else {
 		codec->synth.chmap &= ~(1 << idx);
@@ -796,7 +794,7 @@
 	}
 
 	if (count > 50000) {
-		snd_printk("ali_detect_spdif_rate: timeout!\n");
+		snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
 		return;
 	}
 
@@ -809,7 +807,7 @@
 	}
 
 	if (count > 50000) {
-		snd_printk("ali_detect_spdif_rate: timeout!\n");
+		snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
 		return;
 	}
 
@@ -1077,7 +1075,7 @@
 		idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
 			snd_ali_find_free_channel(codec,rec);
 		if(idx < 0) {
-			snd_printk("ali_alloc_voice: err.\n");
+			snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
 			spin_unlock_irqrestore(&codec->voice_alloc, flags);
 			return NULL;
 		}
@@ -1479,13 +1477,13 @@
 		}
 		rate = snd_ali_get_spdif_in_rate(codec);
 		if (rate == 0) {
-			snd_printk("ali_capture_preapre: spdif rate detect err!\n");
+			snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
 			rate = 48000;
 		}
 		bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
 		if (bValue & 0x10) {
 			outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
-			printk("clear SPDIF parity error flag.\n");
+			printk(KERN_WARNING "clear SPDIF parity error flag.\n");
 		}
 
 		if (rate != 48000)
@@ -1795,6 +1793,7 @@
 	unsigned int capture_num;
 	snd_pcm_ops_t *playback_ops;
 	snd_pcm_ops_t *capture_ops;
+	unsigned short class;
 };
 
 
@@ -1813,12 +1812,11 @@
 	err = snd_pcm_new(codec->card, desc->name, device,
 			  desc->playback_num, desc->capture_num, &pcm);
 	if (err < 0) {
-		snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
+		snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
 		return err;
 	}
 	pcm->private_data = codec;
 	pcm->private_free = snd_ali_pcm_free;
-	pcm->info_flags = 0;
 	if (desc->playback_ops)
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
 	if (desc->capture_ops)
@@ -1828,6 +1826,7 @@
 					      snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
 
 	pcm->info_flags = 0;
+	pcm->dev_class = desc->class;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, desc->name);
 	codec->pcm[0] = pcm;
@@ -1836,7 +1835,7 @@
 
 static struct ali_pcm_description ali_pcms[] = {
 	{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
-	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
+	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
 };
 
 static int __devinit snd_ali_build_pcms(ali_t *codec)
@@ -1991,7 +1990,7 @@
 	for ( i = 0 ; i < codec->num_of_codecs ; i++) {
 		ac97.num = i;
 		if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
-			snd_printk("ali mixer %d creating error.\n", i);
+			snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
 			if(i == 0)
 				return err;
 			codec->num_of_codecs = 1;
@@ -2125,7 +2124,7 @@
 	snd_ali_printk("chip initializing ... \n");
 
 	if (snd_ali_reset_5451(codec)) {
-		snd_printk("ali_chip_init: reset 5451 error.\n");
+		snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
 		return -1;
 	}
 
@@ -2200,7 +2199,7 @@
 	codec->port = pci_resource_start(codec->pci, 0);
 
 	if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
-		snd_printk("Unable to request irq.\n");
+		snd_printk(KERN_ERR "Unable to request irq.\n");
 		return -EBUSY;
 	}
 	codec->irq = codec->pci->irq;
@@ -2240,7 +2239,7 @@
 	/* check, if we can restrict PCI DMA transfers to 31 bits */
 	if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
-		snd_printk("architecture does not support 31bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2329,7 +2328,7 @@
 	}
 
 	if ((err = snd_ali_chip_init(codec)) < 0) {
-		snd_printk("ali create: chip init error.\n");
+		snd_printk(KERN_ERR "ali create: chip init error.\n");
 		return err;
 	}
 
@@ -2352,25 +2351,17 @@
 static int __devinit snd_ali_probe(struct pci_dev *pci,
 				   const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	ali_t *codec;
 	int err;
 
 	snd_ali_printk("probe ...\n");
 
-        if (dev >= SNDRV_CARDS)
-                return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
-	if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) {
+	if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2401,7 +2392,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 196ec1c..7c61561f 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -594,8 +594,7 @@
 	acard->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -622,8 +621,7 @@
 		acard->gameport = NULL;
 
 		snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -669,7 +667,7 @@
 	/* check, if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-		snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 241eacf..f5dad92 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -39,26 +39,27 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int spdif_aclink = 1;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(spdif_aclink, bool, NULL, 0444);
+module_param(spdif_aclink, bool, 0444);
 MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  */
@@ -329,8 +330,7 @@
 
 /* delay for one tick */
 #define do_delay() do { \
-	set_current_state(TASK_UNINTERRUPTIBLE); \
-	schedule_timeout(1); \
+	schedule_timeout_uninterruptible(1); \
 } while (0)
 
 
@@ -1372,7 +1372,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		return err;
 	pbus->clock = clock;
-	pbus->shared_type = AC97_SHARED_TYPE_ATIIXP;	/* shared with modem driver */
 	chip->ac97_bus = pbus;
 
 	codec_count = 0;
@@ -1579,26 +1578,18 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	atiixp_t *chip;
 	unsigned char revision;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
 	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
 
-	strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA");
+	strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
 	strcpy(card->shortname, "ATI IXP");
 	if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
 		goto __error;
@@ -1606,9 +1597,9 @@
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
 
-	chip->spdif_over_aclink = spdif_aclink[dev];
+	chip->spdif_over_aclink = spdif_aclink;
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1629,7 +1620,6 @@
 		goto __error;
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index c1a239a..0cf2020 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -39,20 +39,21 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  */
@@ -306,8 +307,7 @@
 
 /* delay for one tick */
 #define do_delay() do { \
-	set_current_state(TASK_UNINTERRUPTIBLE); \
-	schedule_timeout(1); \
+	schedule_timeout_uninterruptible(1); \
 } while (0)
 
 
@@ -989,6 +989,7 @@
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	pcm->private_data = chip;
 	strcpy(pcm->name, "ATI IXP MC97");
 	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
@@ -1067,7 +1068,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		return err;
 	pbus->clock = clock;
-	pbus->shared_type = AC97_SHARED_TYPE_ATIIXP;	/* shared with audio driver */
 	chip->ac97_bus = pbus;
 
 	codec_count = 0;
@@ -1256,20 +1256,12 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				      const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	atiixp_t *chip;
 	unsigned char revision;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1283,7 +1275,7 @@
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
 
-	if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0)
+	if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
 		goto __error;
 
 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
@@ -1302,7 +1294,6 @@
 		goto __error;
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 3837d2b..5d69c31 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -178,11 +178,6 @@
 #define		EN_SPDIF	0x000c0000
 
 #define VORTEX_CODEC_CHN 	0x29080
-#define VORTEX_CODEC_WRITE	0x00800000
-#define VORTEX_CODEC_ADDSHIFT 	16
-#define VORTEX_CODEC_ADDMASK	0x7f0000	/* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT	0
-#define VORTEX_CODEC_DATMASK	0xffff
 #define VORTEX_CODEC_IO		0x29188
 
 /* SPDIF */
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index be8022e..abbe85e 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -162,11 +162,6 @@
 #define		EN_SPORT	0x00030000
 #define		EN_SPDIF	0x000c0000
 #define VORTEX_CODEC_CHN 0x11880
-#define VORTEX_CODEC_WRITE 0x00800000
-#define VORTEX_CODEC_ADDSHIFT 16
-#define VORTEX_CODEC_ADDMASK 0x7f0000	/* 0x000f0000 */
-#define VORTEX_CODEC_DATSHIFT 0
-#define VORTEX_CODEC_DATMASK 0xffff
 #define VORTEX_CODEC_IO 0x11988
 
 #define VORTEX_SPDIF_FLAGS		0x1005c	/* FIXME */
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index aa77826..04ece1b 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -194,11 +194,6 @@
 
 #define VORTEX_CODEC_CTRL 0x29184
 #define VORTEX_CODEC_IO 0x29188
-#define 	VORTEX_CODEC_WRITE 0x00800000
-#define 	VORTEX_CODEC_ADDSHIFT 16
-#define 	VORTEX_CODEC_ADDMASK 0x7f0000	/* 0x000f0000 */
-#define 	VORTEX_CODEC_DATSHIFT 0
-#define 	VORTEX_CODEC_DATMASK 0xffff
 
 #define VORTEX_CODEC_SPORTCTRL 0x2918c
 
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 04b695d..6af3b13 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -303,7 +303,7 @@
 	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
 			       sizeof(snd_vortex_synth_arg_t), &wave) < 0
 	    || wave == NULL) {
-		snd_printk("Can't initialize Aureal wavetable synth\n");
+		snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
 	} else {
 		snd_vortex_synth_arg_t *arg;
 
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index ee1ede1..b1197cf 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -79,6 +79,14 @@
 #define VORTEX_RESOURCE_A3D	0x00000004
 #define VORTEX_RESOURCE_LAST	0x00000005
 
+/* codec io: VORTEX_CODEC_IO bits */
+#define VORTEX_CODEC_ID_SHIFT	24
+#define VORTEX_CODEC_WRITE	0x00800000
+#define VORTEX_CODEC_ADDSHIFT 	16
+#define VORTEX_CODEC_ADDMASK	0x7f0000
+#define VORTEX_CODEC_DATSHIFT	0
+#define VORTEX_CODEC_DATMASK	0xffff
+
 /* Check for SDAC bit in "Extended audio ID" AC97 register */
 //#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ?  0 : ((x)->codec->ext_id&0x80))
 #define VORTEX_IS_QUAD(x) ((x)->isquad)
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index 9ea2ba7..d5755db 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -488,7 +488,7 @@
 	int i, var, var2;
 
 	if ((a->vortex) == NULL) {
-		printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
+		printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
 		return;
 	}
 
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index f0eda4b..5905188 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2033,7 +2033,7 @@
 			}
 		}
 	}
-	printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
+	printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
 	return -ENOMEM;
 }
 
@@ -2165,7 +2165,7 @@
 				memset(stream->resources, 0,
 				       sizeof(unsigned char) *
 				       VORTEX_RESOURCE_LAST);
-				printk("vortex: out of A3D sources. Sorry\n");
+				printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
 				return -EBUSY;
 			}
 			/* (De)Initialize A3D hardware source. */
@@ -2532,7 +2532,8 @@
 	hwwrite(card->mmio, VORTEX_CODEC_IO,
 		((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
 		((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
-		VORTEX_CODEC_WRITE);
+		VORTEX_CODEC_WRITE |
+		(codec->num << VORTEX_CODEC_ID_SHIFT) );
 
 	/* Flush Caches. */
 	hwread(card->mmio, VORTEX_CODEC_IO);
@@ -2554,7 +2555,8 @@
 		}
 	}
 	/* set up read address */
-	read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK);
+	read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
+		(codec->num << VORTEX_CODEC_ID_SHIFT) ;
 	hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
 
 	/* wait for address */
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 53b47a4..9d933cc 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -854,7 +854,7 @@
 
 	vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
 	if (count != 20) {
-		printk("vortex: peak count error 20 != %d \n", count);
+		printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
 		return -1;
 	}
 	for (i = 0; i < 20; i++)
diff --git a/sound/pci/au88x0/au88x0_synth.c b/sound/pci/au88x0/au88x0_synth.c
index 400417d..65f375b 100644
--- a/sound/pci/au88x0/au88x0_synth.c
+++ b/sound/pci/au88x0/au88x0_synth.c
@@ -90,7 +90,7 @@
 	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
 
 	temp = hwread(vortex->mmio, WT_PARM(wt, 3));
-	printk("vortex: WT PARM3: %x\n", temp);
+	printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
 	//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
 
 	hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
@@ -98,7 +98,7 @@
 	hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
 	hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
 
-	printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+	printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
 
 	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
 	hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
@@ -106,7 +106,7 @@
 	voice->parm0 = voice->parm1 = 0xcfb23e2f;
 	hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
 	hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
-	printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
+	printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
 	return 0;
 }
 
@@ -203,7 +203,7 @@
 		}
 	} else {
 		if (wt >= NR_WT) {
-			printk("vortex: WT SetReg: voice out of range\n");
+			printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
 			return 0;
 		}
 	}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index d5261bd..da99b1b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
 /*
  *  azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- *  Copyright (C) 2002 by Andreas Mohr <hw7oshyuv3001@sneakemail.com>
+ *  Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
  *
  *  Framework borrowed from Bart Hartgers's als4000.c.
  *  Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -46,7 +46,7 @@
  *  - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
  *  - game port (legacy address support)
  *  - built-in General DirectX timer having a 20 bits counter
- *    with 1us resolution (FIXME: where is it?)
+ *    with 1us resolution (see below!)
  *  - I2S serial port for external DAC
  *  - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
  *  - supports hardware volume control
@@ -55,13 +55,23 @@
  *    required for Microsoft's logo compliance (FIXME: where?)
  *  - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
  *
+ *  Note that this driver now is actually *better* than the Windows driver,
+ *  since it additionally supports the card's 1MHz DirectX timer - just try
+ *  the following snd-seq module parameters etc.:
+ *  - options snd-seq seq_default_timer_class=2 seq_default_timer_sclass=0
+ *    seq_default_timer_card=0 seq_client_load=1 seq_default_timer_device=0
+ *    seq_default_timer_subdevice=0 seq_default_timer_resolution=1000000
+ *  - "timidity -iAv -B2,8 -Os -EFreverb=0"
+ *  - "pmidi -p 128:0 jazz.mid"
+ *
  *  Certain PCI versions of this card are susceptible to DMA traffic underruns
  *  in some systems (resulting in sound crackling/clicking/popping),
  *  probably because they don't have a DMA FIFO buffer or so.
  *  Overview (PCI ID/PCI subID/PCI rev.):
  *  - no DMA crackling on SiS735: 0x50DC/0x1801/16
  *  - unknown performance: 0x50DC/0x1801/10
- *  
+ *    (well, it's not bad on an Athlon 1800 with now very optimized IRQ handler)
+ *
  *  Crackling happens with VIA chipsets or, in my case, an SiS735, which is
  *  supposed to be very fast and supposed to get rid of crackling much
  *  better than a VIA, yet ironically I still get crackling, like many other
@@ -76,18 +86,13 @@
  *  - Disable ACPI/power management/"Auto Detect RAM/PCI Clk" in BIOS
  * 
  * BUGS
- *  - when Ctrl-C'ing mpg321, the playback loops a bit
- *    (premature DMA playback reset?)
- *  - full-duplex sometimes breaks (IRQ management issues?).
- *    Once even a spontaneous REBOOT happened!!!
+ *  - full-duplex might *still* be problematic, not fully tested recently
  * 
  * TODO
  *  - test MPU401 MIDI playback etc.
- *  - power management (CONFIG_PM). See e.g. intel8x0 or cs4281.
+ *  - power management. See e.g. intel8x0 or cs4281.
  *    This would be nice since the chip runs a bit hot, and it's *required*
- *    anyway for proper ACPI power management. In other words: rest
- *    assured that I *will* implement this very soon; as soon as Linux 2.5.x
- *    has power management that's bugfree enough to work properly on my desktop.
+ *    anyway for proper ACPI power management.
  *  - figure out what all unknown port bits are responsible for
  */
 
@@ -108,7 +113,7 @@
 #include <sound/initval.h>
 #include "azt3328.h"
 
-MODULE_AUTHOR("Andreas Mohr <hw7oshyuv3001@sneakemail.com>");
+MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
 MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
@@ -122,6 +127,7 @@
 #define DEBUG_MIXER	0
 #define DEBUG_PLAY_REC	0
 #define DEBUG_IO	0
+#define DEBUG_TIMER	0
 #define MIXER_TESTING	0
 
 #if DEBUG_MISC
@@ -132,8 +138,8 @@
 
 #if DEBUG_CALLS
 #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
-#define snd_azf3328_dbgcallenter() printk(KERN_ERR "entering %s\n", __FUNCTION__)
-#define snd_azf3328_dbgcallleave() printk(KERN_ERR "leaving %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __FUNCTION__)
+#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __FUNCTION__)
 #else
 #define snd_azf3328_dbgcalls(format, args...)
 #define snd_azf3328_dbgcallenter()
@@ -152,13 +158,12 @@
 #define snd_azf3328_dbgplay(format, args...)
 #endif		
 
-#if DEBUG_IO
-#define snd_azf3328_dbgio(chip, where) \
-	    printk(KERN_ERR "%s: IDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", where, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS))
+#if DEBUG_MISC
+#define snd_azf3328_dbgtimer(format, args...) printk(KERN_ERR format, ##args)
 #else
-#define snd_azf3328_dbgio(chip, where)
-#endif
-	    
+#define snd_azf3328_dbgtimer(format, args...)
+#endif		
+
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
@@ -177,35 +182,40 @@
 MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard.");
 #endif
 
-typedef struct _snd_azf3328 azf3328_t;
+static int seqtimer_scaling = 128;
+module_param(seqtimer_scaling, int, 0444);
+MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
 
-struct _snd_azf3328 {
-	int irq;
-
+typedef struct _snd_azf3328 {
+	/* often-used fields towards beginning, then grouped */
 	unsigned long codec_port;
 	unsigned long io2_port;
 	unsigned long mpu_port;
 	unsigned long synth_port;
 	unsigned long mixer_port;
 
-#ifdef SUPPORT_JOYSTICK
-	struct gameport *gameport;
-#endif
+	spinlock_t reg_lock;
 
-	struct pci_dev *pci;
-	snd_card_t *card;
-
+	snd_timer_t *timer;
+	
 	snd_pcm_t *pcm;
-	snd_rawmidi_t *rmidi;
 	snd_pcm_substream_t *playback_substream;
 	snd_pcm_substream_t *capture_substream;
 	unsigned int is_playing;
 	unsigned int is_recording;
 
-	spinlock_t reg_lock;
-};
+	snd_card_t *card;
+	snd_rawmidi_t *rmidi;
 
-static struct pci_device_id snd_azf3328_ids[] = {
+#ifdef SUPPORT_JOYSTICK
+	struct gameport *gameport;
+#endif
+
+	struct pci_dev *pci;
+	int irq;
+} azf3328_t;
+
+static const struct pci_device_id snd_azf3328_ids[] = {
 	{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* PCI168/3328 */
 	{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* 3328 */
 	{ 0, }
@@ -213,57 +223,90 @@
 
 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
 
-static inline void snd_azf3328_io2_write(azf3328_t *chip, int reg, unsigned char value)
+static inline void
+snd_azf3328_codec_outb(const azf3328_t *chip, int reg, u8 value)
+{
+	outb(value, chip->codec_port + reg);
+}
+
+static inline u8
+snd_azf3328_codec_inb(const azf3328_t *chip, int reg)
+{
+	return inb(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outw(const azf3328_t *chip, int reg, u16 value)
+{
+	outw(value, chip->codec_port + reg);
+}
+
+static inline u16
+snd_azf3328_codec_inw(const azf3328_t *chip, int reg)
+{
+	return inw(chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_codec_outl(const azf3328_t *chip, int reg, u32 value)
+{
+	outl(value, chip->codec_port + reg);
+}
+
+static inline void
+snd_azf3328_io2_outb(const azf3328_t *chip, int reg, u8 value)
 {
 	outb(value, chip->io2_port + reg);
 }
 
-static inline unsigned char snd_azf3328_io2_read(azf3328_t *chip, int reg)
+static inline u8
+snd_azf3328_io2_inb(const azf3328_t *chip, int reg)
 {
 	return inb(chip->io2_port + reg);
 }
 
-static void snd_azf3328_mixer_write(azf3328_t *chip, int reg, unsigned long value, int type)
+static inline void
+snd_azf3328_mixer_outw(const azf3328_t *chip, int reg, u16 value)
 {
-	switch(type) {
-	case WORD_VALUE:
-		outw(value, chip->mixer_port + reg);
-		break;
-	case DWORD_VALUE:
-		outl(value, chip->mixer_port + reg);
-		break;
-	case BYTE_VALUE:
-		outb(value, chip->mixer_port + reg);
-		break;
-	}
+	outw(value, chip->mixer_port + reg);
 }
 
-static void snd_azf3328_mixer_set_mute(azf3328_t *chip, int reg, int do_mute)
+static inline u16
+snd_azf3328_mixer_inw(const azf3328_t *chip, int reg)
 {
+	return inw(chip->mixer_port + reg);
+}
+
+static void
+snd_azf3328_mixer_set_mute(const azf3328_t *chip, int reg, int do_mute)
+{
+	unsigned long portbase = chip->mixer_port + reg + 1;
 	unsigned char oldval;
 
 	/* the mute bit is on the *second* (i.e. right) register of a
 	 * left/right channel setting */
-	oldval = inb(chip->mixer_port + reg + 1);
+	oldval = inb(portbase);
 	if (do_mute)
 		oldval |= 0x80;
 	else
 		oldval &= ~0x80;
-	outb(oldval, chip->mixer_port + reg + 1);
+	outb(oldval, portbase);
 }
 
-static void snd_azf3328_mixer_write_volume_gradually(azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+static void
+snd_azf3328_mixer_write_volume_gradually(const azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
 {
+	unsigned long portbase = chip->mixer_port + reg;
 	unsigned char curr_vol_left = 0, curr_vol_right = 0;
 	int left_done = 0, right_done = 0;
 	
 	snd_azf3328_dbgcallenter();
 	if (chan_sel & SET_CHAN_LEFT)
-		curr_vol_left  = inb(chip->mixer_port + reg + 1);
+		curr_vol_left  = inb(portbase + 1);
 	else
 		left_done = 1;
 	if (chan_sel & SET_CHAN_RIGHT)
-		curr_vol_right = inb(chip->mixer_port + reg + 0);
+		curr_vol_right = inb(portbase + 0);
 	else
 		right_done = 1;
 	
@@ -284,7 +327,7 @@
 				curr_vol_left++;
 			else
 			    left_done = 1;
-			outb(curr_vol_left, chip->mixer_port + reg + 1);
+			outb(curr_vol_left, portbase + 1);
 		}
 		if (!right_done)
 		{
@@ -298,7 +341,7 @@
 			/* during volume change, the right channel is crackling
 			 * somewhat more than the left channel, unfortunately.
 			 * This seems to be a hardware issue. */
-			outb(curr_vol_right, chip->mixer_port + reg + 0);
+			outb(curr_vol_right, portbase + 0);
 		}
 		if (delay)
 			mdelay(delay);
@@ -320,7 +363,11 @@
 } azf3328_mixer_reg_t;
 
 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
- ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | (mask << 16) | (invert << 24) | (stereo << 25) | (enum_c << 26))
+ ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
+  (mask << 16) | \
+  (invert << 24) | \
+  (stereo << 25) | \
+  (enum_c << 26))
 
 static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
 {
@@ -372,13 +419,15 @@
   .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
 }
 
-static int snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int
+snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	azf3328_mixer_reg_t reg;
 
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->type = reg.mask == 1 ?
+		SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = reg.stereo + 1;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = reg.mask;
@@ -386,7 +435,8 @@
 	return 0;
 }
 
-static int snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
 	azf3328_mixer_reg_t reg;
@@ -395,7 +445,7 @@
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
 
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = (oreg >> reg.lchan_shift) & reg.mask;
 	if (reg.invert)
 		val = reg.mask - val;
@@ -406,12 +456,17 @@
 			val = reg.mask - val;
 		ucontrol->value.integer.value[1] = val;
 	}
-	snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx (shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n", reg.reg, oreg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
+	snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
+			     "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
+		reg.reg, oreg,
+		ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+		reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
 	azf3328_mixer_reg_t reg;
@@ -419,7 +474,7 @@
 
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = ucontrol->value.integer.value[0] & reg.mask;
 	if (reg.invert)
 		val = reg.mask - val;
@@ -433,24 +488,37 @@
 		nreg |= (val << reg.rchan_shift);
 	}
 	if (reg.mask >= 0x07) /* it's a volume control, so better take care */
-		snd_azf3328_mixer_write_volume_gradually(chip, reg.reg, nreg >> 8, nreg & 0xff, SET_CHAN_LEFT|SET_CHAN_RIGHT, 0); /* just set both channels, doesn't matter */
+		snd_azf3328_mixer_write_volume_gradually(
+			chip, reg.reg, nreg >> 8, nreg & 0xff,
+			/* just set both channels, doesn't matter */
+			SET_CHAN_LEFT|SET_CHAN_RIGHT,
+			0);
 	else
-        	outw(nreg, chip->mixer_port + reg.reg);
+        	snd_azf3328_mixer_outw(chip, reg.reg, nreg);
 
-	snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n", reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1], oreg, reg.lchan_shift, reg.rchan_shift, nreg, inw(chip->mixer_port + reg.reg));
+	snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
+			     "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
+		reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
+		oreg, reg.lchan_shift, reg.rchan_shift,
+		nreg, snd_azf3328_mixer_inw(chip, reg.reg));
 	snd_azf3328_dbgcallleave();
 	return (nreg != oreg);
 }
 
-static int snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int
+snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
-	azf3328_mixer_reg_t reg;
-	static char *texts1[2] = { "ModemOut1", "ModemOut2" };
-	static char *texts2[2] = { "MonoSelectSource1", "MonoSelectSource2" };
-        static char *texts3[8] = {
-                "Mic", "CD", "Video", "Aux", "Line",
-                "Mix", "Mix Mono", "Phone"
+	static const char * const texts1[] = {
+		"ModemOut1", "ModemOut2"
+	};
+	static const char * const texts2[] = {
+		"MonoSelectSource1", "MonoSelectSource2"
+	};
+	static const char * const texts3[] = {
+                "Mic", "CD", "Video", "Aux",
+		"Line", "Mix", "Mix Mono", "Phone"
         };
+	azf3328_mixer_reg_t reg;
 
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -471,14 +539,15 @@
         return 0;
 }
 
-static int snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	azf3328_mixer_reg_t reg;
         azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+	azf3328_mixer_reg_t reg;
         unsigned short val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	val = inw(chip->mixer_port + reg.reg);
+	val = snd_azf3328_mixer_inw(chip, reg.reg);
 	if (reg.reg == IDX_MIXER_REC_SELECT)
 	{
         	ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
@@ -486,18 +555,22 @@
 	}
 	else
         	ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
-	snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n", reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1], reg.lchan_shift, reg.enum_c);
+
+	snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
+		reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
+		reg.lchan_shift, reg.enum_c);
         return 0;
 }
 
-static int snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int
+snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
-	azf3328_mixer_reg_t reg;
         azf3328_t *chip = snd_kcontrol_chip(kcontrol);
+	azf3328_mixer_reg_t reg;
 	unsigned int oreg, nreg, val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
-	oreg = inw(chip->mixer_port + reg.reg);
+	oreg = snd_azf3328_mixer_inw(chip, reg.reg);
 	val = oreg;
 	if (reg.reg == IDX_MIXER_REC_SELECT)
 	{
@@ -514,19 +587,19 @@
 		val &= ~((reg.enum_c - 1) << reg.lchan_shift);
         	val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
 	}
-	outw(val, chip->mixer_port + reg.reg);
+	snd_azf3328_mixer_outw(chip, reg.reg, val);
 	nreg = val;
 
 	snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
 	return (nreg != oreg);
 }
 
-static snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
+static const snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
 	AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Wave Playback Volume", IDX_MIXER_WAVEOUT, 0x1f, 1),
-	AZF3328_MIXER_SWITCH("Wave Playback 3D Bypass", IDX_MIXER_ADVCTL2, 7, 1),
+	AZF3328_MIXER_SWITCH("Wave 3D Bypass Playback Switch", IDX_MIXER_ADVCTL2, 7, 1),
 	AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
@@ -539,8 +612,8 @@
 	AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
 	AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
-	AZF3328_MIXER_SWITCH("PCBeep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
-	AZF3328_MIXER_VOL_SPECIAL("PCBeep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
+	AZF3328_MIXER_SWITCH("PC Speaker Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
+	AZF3328_MIXER_VOL_SPECIAL("PC Speaker Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
 	AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
@@ -553,8 +626,8 @@
 	AZF3328_MIXER_ENUM("Mono Select Source", IDX_MIXER_ADVCTL2, 2, 9),
 	AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
 	AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
-	AZF3328_MIXER_SWITCH("3D Control - Toggle", IDX_MIXER_ADVCTL2, 13, 0),
-	AZF3328_MIXER_VOL_SPECIAL("3D Control - Volume", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
+	AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
+	AZF3328_MIXER_VOL_SPECIAL("3D Control - Wide", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
 	AZF3328_MIXER_VOL_SPECIAL("3D Control - Space", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
 #if MIXER_TESTING
 	AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
@@ -576,9 +649,7 @@
 #endif
 };
 
-#define AZF3328_INIT_VALUES (sizeof(snd_azf3328_init_values)/sizeof(unsigned int)/2)
-
-static unsigned int snd_azf3328_init_values[][2] = {
+static const u16 __devinitdata snd_azf3328_init_values[][2] = {
         { IDX_MIXER_PLAY_MASTER,	MIXER_MUTE_MASK|0x1f1f },
         { IDX_MIXER_MODEMOUT,		MIXER_MUTE_MASK|0x1f1f },
 	{ IDX_MIXER_BASSTREBLE,		0x0000 },
@@ -594,10 +665,11 @@
         { IDX_MIXER_REC_VOLUME,		MIXER_MUTE_MASK|0x0707 },
 };
 
-static int __devinit snd_azf3328_mixer_new(azf3328_t *chip)
+static int __devinit
+snd_azf3328_mixer_new(azf3328_t *chip)
 {
 	snd_card_t *card;
-	snd_kcontrol_new_t *sw;
+	const snd_kcontrol_new_t *sw;
 	unsigned int idx;
 	int err;
 
@@ -607,11 +679,13 @@
 	card = chip->card;
 
 	/* mixer reset */
-	snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+	snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
 
 	/* mute and zero volume channels */
-	for (idx = 0; idx < AZF3328_INIT_VALUES; idx++) {
-		snd_azf3328_mixer_write(chip, snd_azf3328_init_values[idx][0], snd_azf3328_init_values[idx][1], WORD_VALUE);
+	for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); idx++) {
+		snd_azf3328_mixer_outw(chip,
+			snd_azf3328_init_values[idx][0],
+			snd_azf3328_init_values[idx][1]);
 	}
 	
 	/* add mixer controls */
@@ -627,7 +701,8 @@
 	return 0;
 }
 
-static int snd_azf3328_hw_params(snd_pcm_substream_t * substream,
+static int
+snd_azf3328_hw_params(snd_pcm_substream_t * substream,
 				 snd_pcm_hw_params_t * hw_params)
 {
 	int res;
@@ -637,7 +712,8 @@
 	return res;
 }
 
-static int snd_azf3328_hw_free(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_hw_free(snd_pcm_substream_t * substream)
 {
 	snd_azf3328_dbgcallenter();
 	snd_pcm_lib_free_pages(substream);
@@ -645,43 +721,48 @@
 	return 0;
 }
 
-static void snd_azf3328_setfmt(azf3328_t *chip,
+static void
+snd_azf3328_setfmt(azf3328_t *chip,
 			       unsigned int reg,
 			       unsigned int bitrate,
 			       unsigned int format_width,
 			       unsigned int channels
 )
 {
-	unsigned int val = 0xff00;
+	u16 val = 0xff00;
 	unsigned long flags;
 
 	snd_azf3328_dbgcallenter();
 	switch (bitrate) {
-	case  5512: val |= 0x0d; break; /* the AZF3328 names it "5510" for some strange reason */
-	case  6620: val |= 0x0b; break;
-	case  8000: val |= 0x00; break;
-	case  9600: val |= 0x08; break;
-	case 11025: val |= 0x01; break;
-	case 16000: val |= 0x02; break;
-	case 22050: val |= 0x03; break;
-	case 32000: val |= 0x04; break;
-	case 44100: val |= 0x05; break;
-	case 48000: val |= 0x06; break;
-	case 64000: val |= 0x07; break;
+	case  4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+	case  4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+	case  5512: val |= SOUNDFORMAT_FREQ_5510; break; /* the AZF3328 names it "5510" for some strange reason */
+	case  6620: val |= SOUNDFORMAT_FREQ_6620; break;
+	case  8000: val |= SOUNDFORMAT_FREQ_8000; break;
+	case  9600: val |= SOUNDFORMAT_FREQ_9600; break;
+	case 11025: val |= SOUNDFORMAT_FREQ_11025; break;
+	case 13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+	case 16000: val |= SOUNDFORMAT_FREQ_16000; break;
+	case 22050: val |= SOUNDFORMAT_FREQ_22050; break;
+	case 32000: val |= SOUNDFORMAT_FREQ_32000; break;
+	case 44100: val |= SOUNDFORMAT_FREQ_44100; break;
+	case 48000: val |= SOUNDFORMAT_FREQ_48000; break;
+	case 66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
 	default:
-		snd_printk("unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
-		val |= 0x05; /* 44100 */
+		snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
+		val |= SOUNDFORMAT_FREQ_44100;
 		break;
 	}
-	/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) */
-	/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) */
-	/* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) */
-	/* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) */
+	/* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
+	/* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
+	/* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
+	/* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
 	/* val = 0xff05; 5m11.556s (... -> 44100Hz) */
 	/* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
 	/* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
 	/* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
 	/* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
+
 	if (channels == 2)
 		val |= SOUNDFORMAT_FLAG_2CHANNELS;
 
@@ -691,7 +772,7 @@
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	
 	/* set bitrate/format */
-	outw(val, chip->codec_port+reg);
+	snd_azf3328_codec_outw(chip, reg, val);
 	
 	/* changing the bitrate/format settings switches off the
 	 * audio output with an annoying click in case of 8/16bit format change
@@ -701,47 +782,67 @@
 	 * FIXME: does this have some side effects for full-duplex
 	 * or other dramatic side effects? */
 	if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */
-		outw(inw(chip->codec_port + IDX_IO_PLAY_FLAGS)|DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) |
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2 |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE
+		);
 
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	snd_azf3328_dbgcallleave();
 }
 
-static void snd_azf3328_setdmaa(azf3328_t *chip,
+static void
+snd_azf3328_setdmaa(azf3328_t *chip,
 				long unsigned int addr,
                                 unsigned int count,
                                 unsigned int size,
 				int do_recording)
 {
-	long unsigned int addr1;
-	long unsigned int addr2;
-	unsigned int count1;
-	unsigned int count2;
-	unsigned long flags;
-	int reg_offs = do_recording ? 0x20 : 0x00;
+	unsigned long flags, portbase;
+	unsigned int is_running;
 
 	snd_azf3328_dbgcallenter();
-	/* AZF3328 uses a two buffer pointer DMA playback approach */
-	if (!chip->is_playing)
+	if (do_recording)
 	{
-		addr1 = addr;
-		addr2 = addr+(size/2);
-		count1 = (size/2)-1;
-		count2 = (size/2)-1;
-#if DEBUG_PLAY_REC
-		snd_azf3328_dbgplay("setting dma: buf1 %08lx[%d], buf2 %08lx[%d]\n", addr1, count1, addr2, count2);
-#endif
+		/* access capture registers, i.e. skip playback reg section */
+		portbase = chip->codec_port + 0x20;
+		is_running = chip->is_recording;
+	}
+	else
+	{
+		/* access the playback register section */
+		portbase = chip->codec_port + 0x00;
+		is_running = chip->is_playing;
+	}
+
+	/* AZF3328 uses a two buffer pointer DMA playback approach */
+	if (!is_running)
+	{
+		unsigned long addr_area2;
+		unsigned long count_areas, count_tmp; /* width 32bit -- overflow!! */
+		count_areas = size/2;
+		addr_area2 = addr+count_areas;
+		count_areas--; /* max. index */
+		snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas);
+
+		/* build combined I/O buffer length word */
+		count_tmp = count_areas;
+		count_areas |= (count_tmp << 16);
 		spin_lock_irqsave(&chip->reg_lock, flags);
-		outl(addr1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_1);
-		outl(addr2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_START_2);
-		outw(count1, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_1);
-		outw(count2, chip->codec_port+reg_offs+IDX_IO_PLAY_DMA_LEN_2);
+		outl(addr, portbase + IDX_IO_PLAY_DMA_START_1);
+		outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2);
+		outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1);
 		spin_unlock_irqrestore(&chip->reg_lock, flags);
 	}
 	snd_azf3328_dbgcallleave();
 }
 
-static int snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
+static int
+snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
 {
 #if 0
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -752,14 +853,18 @@
 
 	snd_azf3328_dbgcallenter();
 #if 0
-	snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+	snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+		runtime->rate,
+		snd_pcm_format_width(runtime->format),
+		runtime->channels);
 	snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 0);
 #endif
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
 {
 #if 0
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
@@ -770,14 +875,18 @@
 
 	snd_azf3328_dbgcallenter();
 #if 0
-	snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+	snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+		runtime->rate,
+		snd_pcm_format_width(runtime->format),
+		runtime->channels);
 	snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, 1);
 #endif
 	snd_azf3328_dbgcallleave();
 	return 0;
 }
 
-static int snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -785,79 +894,98 @@
 	unsigned int status1;
 
 	snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-
-		snd_azf3328_dbgio(chip, "trigger1");
+		snd_azf3328_dbgplay("START PLAYBACK\n");
 
 		/* mute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
 
-		snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+		snd_azf3328_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT,
+			runtime->rate,
+			snd_pcm_format_width(runtime->format),
+			runtime->channels);
 
 		spin_lock(&chip->reg_lock);
 		/* stop playback */
-		status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 	    
 		/* FIXME: clear interrupts or what??? */
-		outw(0xffff, chip->codec_port+IDX_IO_PLAY_IRQMASK);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff);
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 0);
+		snd_azf3328_setdmaa(chip, runtime->dma_addr,
+			snd_pcm_lib_period_bytes(substream),
+			snd_pcm_lib_buffer_bytes(substream),
+			0);
 
 		spin_lock(&chip->reg_lock);
 #ifdef WIN9X
 		/* FIXME: enable playback/recording??? */
 		status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
 		/* start playback again */
 		/* FIXME: what is this value (0x0010)??? */
 		status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 #else /* NT4 */
-		outw(0x00, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_PLAY_FLAGS);
-		outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			0x0000);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_PLAY_SOMETHING1);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS,
+			DMA_RESUME |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE);
 #endif
 		spin_unlock(&chip->reg_lock);
 
 		/* now unmute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
 
-		snd_azf3328_dbgio(chip, "trigger2");
 		chip->is_playing = 1;
+		snd_azf3328_dbgplay("STARTED PLAYBACK\n");
 		break;
-        case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_azf3328_dbgplay("STOP PLAYBACK\n");
+
 		/* mute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
 
 		spin_lock(&chip->reg_lock);
 		/* stop playback */
-		status1 = inw(chip->codec_port+IDX_IO_PLAY_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS);
 
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
+		/* hmm, is this really required? we're resetting the same bit
+		 * immediately thereafter... */
 		status1 |= DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 
 		status1 &= ~DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_PLAY_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1);
 		spin_unlock(&chip->reg_lock);
 	    
 		/* now unmute WaveOut */
 		snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0);
 		chip->is_playing = 0;
+		snd_azf3328_dbgplay("STOPPED PLAYBACK\n");
 		break;
         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
                 break;
         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
                 break;
         default:
                 return -EINVAL;
@@ -869,7 +997,8 @@
 
 /* this is just analogous to playback; I'm not quite sure whether recording
  * should actually be triggered like that */
-static int snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int
+snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -877,68 +1006,86 @@
 	unsigned int status1;
 
 	snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
+
         switch (cmd) {
         case SNDRV_PCM_TRIGGER_START:
 
-		snd_azf3328_dbgio(chip, "trigger1");
+		snd_azf3328_dbgplay("START CAPTURE\n");
 
-		snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT, runtime->rate, snd_pcm_format_width(runtime->format), runtime->channels);
+		snd_azf3328_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
+			runtime->rate,
+			snd_pcm_format_width(runtime->format),
+			runtime->channels);
 
 		spin_lock(&chip->reg_lock);
 		/* stop recording */
-		status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 	    
 		/* FIXME: clear interrupts or what??? */
-		outw(0xffff, chip->codec_port+IDX_IO_REC_IRQMASK);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_setdmaa(chip, runtime->dma_addr, snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream), 1);
+		snd_azf3328_setdmaa(chip, runtime->dma_addr,
+			snd_pcm_lib_period_bytes(substream),
+			snd_pcm_lib_buffer_bytes(substream),
+			1);
 
 		spin_lock(&chip->reg_lock);
 #ifdef WIN9X
 		/* FIXME: enable playback/recording??? */
 		status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
-		/* start playback again */
+		/* start capture again */
 		/* FIXME: what is this value (0x0010)??? */
 		status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 #else
-		outw(0x00, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_PLAY_SOMETHING1, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_PLAY_SOMETHING1|DMA_PLAY_SOMETHING2, chip->codec_port+IDX_IO_REC_FLAGS);
-		outw(DMA_RESUME|SOMETHING_ALMOST_ALWAYS_SET|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			0x0000);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_PLAY_SOMETHING1);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_PLAY_SOMETHING1 |
+			DMA_PLAY_SOMETHING2);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
+			DMA_RESUME |
+			SOMETHING_ALMOST_ALWAYS_SET |
+			DMA_EPILOGUE_SOMETHING |
+			DMA_SOMETHING_ELSE);
 #endif
 		spin_unlock(&chip->reg_lock);
 
-		snd_azf3328_dbgio(chip, "trigger2");
-		chip->is_playing = 1;
+		chip->is_recording = 1;
+		snd_azf3328_dbgplay("STARTED CAPTURE\n");
 		break;
         case SNDRV_PCM_TRIGGER_STOP:
+		snd_azf3328_dbgplay("STOP CAPTURE\n");
+
 		spin_lock(&chip->reg_lock);
 		/* stop recording */
-		status1 = inw(chip->codec_port+IDX_IO_REC_FLAGS);
+		status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
 
 		status1 &= ~DMA_RESUME;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
 		status1 |= DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 
 		status1 &= ~DMA_PLAY_SOMETHING1;
-		outw(status1, chip->codec_port+IDX_IO_REC_FLAGS);
+		snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
 		spin_unlock(&chip->reg_lock);
 	    
-		chip->is_playing = 0;
+		chip->is_recording = 0;
+		snd_azf3328_dbgplay("STOPPED CAPTURE\n");
 		break;
         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
                 break;
         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		snd_printk("FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
+		snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
                 break;
         default:
                 return -EINVAL;
@@ -948,11 +1095,11 @@
 	return result;
 }
 
-static snd_pcm_uframes_t snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	unsigned long bufptr, playptr;
-	unsigned long result;
+	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
 #ifdef QUERY_HARDWARE
@@ -960,19 +1107,20 @@
 #else
 	bufptr = substream->runtime->dma_addr;
 #endif
-	playptr = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
+	result = inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS);
 
-	result = playptr - bufptr;
-	frmres = bytes_to_frames( substream->runtime, result );
-	snd_azf3328_dbgplay("result %lx, playptr %lx (base %x), frames %ld\n", result, playptr, substream->runtime->dma_addr, frmres);
+	/* calculate offset */
+	result -= bufptr;
+	frmres = bytes_to_frames( substream->runtime, result);
+	snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres);
 	return frmres;
 }
 
-static snd_pcm_uframes_t snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t
+snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	unsigned long bufptr, recptr;
-	unsigned long result;
+	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
 #ifdef QUERY_HARDWARE
@@ -980,96 +1128,116 @@
 #else
 	bufptr = substream->runtime->dma_addr;
 #endif
-	recptr = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
+	result = inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS);
 
-	result = recptr - bufptr;
-	frmres = bytes_to_frames( substream->runtime, result );
-	snd_azf3328_dbgplay("result %lx, rec ptr %lx (base %x), frames %ld\n", result, recptr, substream->runtime->dma_addr, frmres);
+	/* calculate offset */
+	result -= bufptr;
+	frmres = bytes_to_frames( substream->runtime, result);
+	snd_azf3328_dbgplay("REC  @ 0x%8lx, frames %8ld\n", result, frmres);
 	return frmres;
 }
 
-static irqreturn_t snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	azf3328_t *chip = dev_id;
-	unsigned int status, which;
-	static unsigned long count;
+	u8 status, which;
+	static unsigned long irq_count;
 
-	status  = inw(chip->codec_port+IDX_IO_IRQSTATUS);
+	status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS);
 
         /* fast path out, to ease interrupt sharing */
-	if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_SOMEIRQ)))
+	if (!(status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_MPU401|IRQ_TIMER)))
 		return IRQ_NONE; /* must be interrupt for another device */
 
-	snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQMASK %04x, IDX_IO_IRQSTATUS %04x\n", count, inw(chip->codec_port+IDX_IO_PLAY_FLAGS), inw(chip->codec_port+IDX_IO_PLAY_IRQMASK), inw(chip->codec_port+IDX_IO_IRQSTATUS));
+	snd_azf3328_dbgplay("Interrupt %ld!\nIDX_IO_PLAY_FLAGS %04x, IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
+		irq_count,
+		snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
+		snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
+		status);
 		
+	if (status & IRQ_TIMER)
+	{
+		/* snd_azf3328_dbgplay("timer %ld\n", inl(chip->codec_port+IDX_IO_TIMER_VALUE) & TIMER_VALUE_MASK); */
+		if (chip->timer)
+			snd_timer_interrupt(chip->timer, chip->timer->sticks);
+		/* ACK timer */
+                spin_lock(&chip->reg_lock);
+		snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
+		spin_unlock(&chip->reg_lock);
+		snd_azf3328_dbgplay("azt3328: timer IRQ\n");
+	}
 	if (status & IRQ_PLAYBACK)
 	{
 		spin_lock(&chip->reg_lock);
-		which = inw(chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_FINISHED_PLAYBUF_1)
-			/* ack IRQ */
-			outw(which | IRQ_FINISHED_PLAYBUF_1, chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_FINISHED_PLAYBUF_2)
-			/* ack IRQ */
-			outw(which | IRQ_FINISHED_PLAYBUF_2, chip->codec_port+IDX_IO_PLAY_IRQMASK);
-		if (which & IRQ_PLAY_SOMETHING)
-		{
-			snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
-		}
+		which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
+		/* ack all IRQ types immediately */
+		snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
+               	spin_unlock(&chip->reg_lock);
+
 		if (chip->pcm && chip->playback_substream)
 		{
-			snd_azf3328_dbgplay("which %x, playptr %lx\n", which, inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
 			snd_pcm_period_elapsed(chip->playback_substream);
-			snd_azf3328_dbgplay("period done, playptr %lx.\n", inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
+			snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
+				which,
+				inl(chip->codec_port+IDX_IO_PLAY_DMA_CURRPOS));
 		}
 		else
 			snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
-               	spin_unlock(&chip->reg_lock);
+		if (which & IRQ_PLAY_SOMETHING)
+			snd_azf3328_dbgplay("azt3328: unknown play IRQ type occurred, please report!\n");
 	}
 	if (status & IRQ_RECORDING)
 	{
                 spin_lock(&chip->reg_lock);
-		which = inw(chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_FINISHED_RECBUF_1)
-			/* ack interrupt */
-			outw(which | IRQ_FINISHED_RECBUF_1, chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_FINISHED_RECBUF_2)
-			/* ack interrupt */
-			outw(which | IRQ_FINISHED_RECBUF_2, chip->codec_port+IDX_IO_REC_IRQMASK);
-		if (which & IRQ_REC_SOMETHING)
-		{
-			snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
-		}
+		which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
+		/* ack all IRQ types immediately */
+		snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
+		spin_unlock(&chip->reg_lock);
+
 		if (chip->pcm && chip->capture_substream)
 		{
-			snd_azf3328_dbgplay("which %x, recptr %lx\n", which, inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
-			spin_unlock(&chip->reg_lock);
 			snd_pcm_period_elapsed(chip->capture_substream);
-			spin_lock(&chip->reg_lock);
-			snd_azf3328_dbgplay("period done, recptr %lx.\n", inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
+			snd_azf3328_dbgplay("REC  period done (#%x), @ %x\n",
+				which,
+				inl(chip->codec_port+IDX_IO_REC_DMA_CURRPOS));
 		}
-               	spin_unlock(&chip->reg_lock);
+		else
+			snd_azf3328_dbgplay("azt3328: ouch, irq handler problem!\n");
+		if (which & IRQ_REC_SOMETHING)
+			snd_azf3328_dbgplay("azt3328: unknown rec IRQ type occurred, please report!\n");
 	}
+	/* MPU401 has less critical IRQ requirements
+	 * than timer and playback/recording, right? */
 	if (status & IRQ_MPU401)
+	{
 		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
-	if (status & IRQ_SOMEIRQ)
-		snd_azf3328_dbgplay("azt3328: unknown IRQ type occurred, please report!\n");
-	count++;
+
+		/* hmm, do we have to ack the IRQ here somehow?
+		 * If so, then I don't know how... */
+		snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n");
+	}
+	irq_count++;
 	return IRQ_HANDLED;
 }
 
 /*****************************************************************/
 
-static snd_pcm_hardware_t snd_azf3328_playback =
+static const snd_pcm_hardware_t snd_azf3328_playback =
 {
 	/* FIXME!! Correct? */
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
-				SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
-	.rates =		SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
-	.rate_min =		5512,
-	.rate_max =		64000,
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_MMAP_VALID,
+	.formats =		SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_U8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_U16_LE,
+	.rates =		SNDRV_PCM_RATE_5512 |
+				SNDRV_PCM_RATE_8000_48000 |
+				SNDRV_PCM_RATE_KNOT,
+	.rate_min =		4000,
+	.rate_max =		66200,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	65536,
@@ -1083,16 +1251,21 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_azf3328_capture =
+static const snd_pcm_hardware_t snd_azf3328_capture =
 {
 	/* FIXME */
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
-				SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE,
-	.rates =		SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_KNOT,
-	.rate_min =		5512,
-	.rate_max =		64000,
+	.info =			SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_MMAP_VALID,
+	.formats =		SNDRV_PCM_FMTBIT_S8 |
+				SNDRV_PCM_FMTBIT_U8 |
+				SNDRV_PCM_FMTBIT_S16_LE |
+				SNDRV_PCM_FMTBIT_U16_LE,
+	.rates =		SNDRV_PCM_RATE_5512 |
+				SNDRV_PCM_RATE_8000_48000 |
+				SNDRV_PCM_RATE_KNOT,
+	.rate_min =		4000,
+	.rate_max =		66200,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	65536,
@@ -1105,8 +1278,8 @@
 
 
 static unsigned int snd_azf3328_fixed_rates[] = {
-	5512, 6620, 8000, 9600, 11025, 16000, 22050, 32000, 44100, 48000, 64000
-};
+	4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
+	44100, 48000, 66200 };
 static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
 	.count = ARRAY_SIZE(snd_azf3328_fixed_rates), 
 	.list = snd_azf3328_fixed_rates,
@@ -1115,7 +1288,8 @@
 
 /*****************************************************************/
 
-static int snd_azf3328_playback_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_open(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1129,7 +1303,8 @@
 	return 0;
 }
 
-static int snd_azf3328_capture_open(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_open(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1143,7 +1318,8 @@
 	return 0;
 }
 
-static int snd_azf3328_playback_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_playback_close(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 
@@ -1154,7 +1330,8 @@
 	return 0;
 }
 
-static int snd_azf3328_capture_close(snd_pcm_substream_t * substream)
+static int
+snd_azf3328_capture_close(snd_pcm_substream_t * substream)
 {
 	azf3328_t *chip = snd_pcm_substream_chip(substream);
 
@@ -1188,14 +1365,16 @@
 	.pointer =	snd_azf3328_capture_pointer
 };
 
-static void snd_azf3328_pcm_free(snd_pcm_t *pcm)
+static void
+snd_azf3328_pcm_free(snd_pcm_t *pcm)
 {
 	azf3328_t *chip = pcm->private_data;
 	chip->pcm = NULL;
 	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
-static int __devinit snd_azf3328_pcm(azf3328_t *chip, int device)
+static int __devinit
+snd_azf3328_pcm(azf3328_t *chip, int device)
 {
 	snd_pcm_t *pcm;
 	int err;
@@ -1222,7 +1401,8 @@
 /******************************************************************/
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev)
+static int __devinit
+snd_azf3328_config_joystick(azf3328_t *chip, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -1238,8 +1418,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -1249,15 +1428,16 @@
 	gp->io = 0x200;
 	gameport_set_port_data(gp, r);
 
-	snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-			      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
+	snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+			      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY);
 
 	gameport_register_port(chip->gameport);
 
 	return 0;
 }
 
-static void snd_azf3328_free_joystick(azf3328_t *chip)
+static void
+snd_azf3328_free_joystick(azf3328_t *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1265,33 +1445,36 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 		/* disable gameport */
-		snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-				      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
-		release_resource(r);
-		kfree_nocheck(r);
+		snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+				      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+		release_and_free_resource(r);
 	}
 }
 #else
-static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
-static inline void snd_azf3328_free_joystick(azf3328_t *chip) { }
+static inline int
+snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
+static inline void
+snd_azf3328_free_joystick(azf3328_t *chip) { }
 #endif
 
 /******************************************************************/
 
-static int snd_azf3328_free(azf3328_t *chip)
+static int
+snd_azf3328_free(azf3328_t *chip)
 {
         if (chip->irq < 0)
                 goto __end_hw;
 
 	/* reset (close) mixer */
 	snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); /* first mute master volume */
-	snd_azf3328_mixer_write(chip, IDX_MIXER_RESET, 0x0, WORD_VALUE);
+	snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
 
-        /* interrupt setup - mask everything */
-	/* FIXME */
+        /* interrupt setup - mask everything (FIXME!) */
+	/* well, at least we know how to disable the timer IRQ */
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00);
 
         synchronize_irq(chip->irq);
-      __end_hw:
+__end_hw:
 	snd_azf3328_free_joystick(chip);
         if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -1302,15 +1485,129 @@
         return 0;
 }
 
-static int snd_azf3328_dev_free(snd_device_t *device)
+static int
+snd_azf3328_dev_free(snd_device_t *device)
 {
 	azf3328_t *chip = device->device_data;
 	return snd_azf3328_free(chip);
 }
 
+/******************************************************************/
+
+/*** NOTE: the physical timer resolution actually is 1024000 ticks per second,
+ *** but announcing those attributes to user-space would make programs
+ *** configure the timer to a 1 tick value, resulting in an absolutely fatal
+ *** timer IRQ storm.
+ *** Thus I chose to announce a down-scaled virtual timer to the outside and
+ *** calculate real timer countdown values internally.
+ *** (the scale factor can be set via module parameter "seqtimer_scaling").
+ ***/
+
+static int
+snd_azf3328_timer_start(snd_timer_t *timer)
+{
+	azf3328_t *chip;
+	unsigned long flags;
+	unsigned int delay;
+
+	snd_azf3328_dbgcallenter();
+	chip = snd_timer_chip(timer);
+	delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
+	if (delay < 49)
+	{
+		/* uhoh, that's not good, since user-space won't know about
+		 * this timing tweak
+		 * (we need to do it to avoid a lockup, though) */
+
+		snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
+		delay = 49; /* minimum time is 49 ticks */
+	}
+	snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
+	delay |= TIMER_ENABLE_COUNTDOWN | TIMER_ENABLE_IRQ;
+	spin_lock_irqsave(&chip->reg_lock, flags);
+	snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+static int
+snd_azf3328_timer_stop(snd_timer_t *timer)
+{
+	azf3328_t *chip;
+	unsigned long flags;
+
+	snd_azf3328_dbgcallenter();
+	chip = snd_timer_chip(timer);
+	spin_lock_irqsave(&chip->reg_lock, flags);
+	/* disable timer countdown and interrupt */
+	/* FIXME: should we write TIMER_ACK_IRQ here? */
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
+	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+
+static int
+snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
+					       unsigned long *num, unsigned long *den)
+{
+	snd_azf3328_dbgcallenter();
+	*num = 1;
+	*den = 1024000 / seqtimer_scaling;
+	snd_azf3328_dbgcallleave();
+	return 0;
+}
+
+static struct _snd_timer_hardware snd_azf3328_timer_hw = {
+	.flags = SNDRV_TIMER_HW_AUTO,
+	.resolution = 977, /* 1000000/1024000 = 0.9765625us */
+	.ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
+	.start = snd_azf3328_timer_start,
+	.stop = snd_azf3328_timer_stop,
+	.precise_resolution = snd_azf3328_timer_precise_resolution,
+};
+
+static int __devinit
+snd_azf3328_timer(azf3328_t *chip, int device)
+{
+	snd_timer_t *timer = NULL;
+	snd_timer_id_t tid;
+	int err;
+
+	snd_azf3328_dbgcallenter();
+	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
+	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
+	tid.card = chip->card->number;
+	tid.device = device;
+	tid.subdevice = 0;
+
+	snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
+	snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
+	if ((err = snd_timer_new(chip->card, "AZF3328", &tid, &timer)) < 0) {
+		goto out;
+	}
+
+	strcpy(timer->name, "AZF3328 timer");
+	timer->private_data = chip;
+	timer->hw = snd_azf3328_timer_hw;
+
+	chip->timer = timer;
+
+	err = 0;
+
+out:
+	snd_azf3328_dbgcallleave();
+	return err;
+}
+
+/******************************************************************/
+
 #if 0
 /* check whether a bit can be modified */
-static void snd_azf3328_test_bit(unsigned int reg, int bit)
+static void
+snd_azf3328_test_bit(unsigned int reg, int bit)
 {
 	unsigned char val, valoff, valon;
 
@@ -1328,7 +1625,26 @@
 }
 #endif
 
-static int __devinit snd_azf3328_create(snd_card_t * card,
+static void
+snd_azf3328_debug_show_ports(const azf3328_t *chip)
+{
+#if DEBUG_MISC
+	u16 tmp;
+
+	snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
+
+	snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_inb(chip, 0), snd_azf3328_io2_inb(chip, 1), snd_azf3328_io2_inb(chip, 2), snd_azf3328_io2_inb(chip, 3), snd_azf3328_io2_inb(chip, 4), snd_azf3328_io2_inb(chip, 5));
+
+	for (tmp=0; tmp <= 0x01; tmp += 1)
+		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
+
+	for (tmp = 0; tmp <= 0x6E; tmp += 2)
+		snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp));
+#endif
+}
+
+static int __devinit
+snd_azf3328_create(snd_card_t * card,
                                          struct pci_dev *pci,
                                          unsigned long device_type,
                                          azf3328_t ** rchip)
@@ -1347,8 +1663,8 @@
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
-		pci_disable_device(pci);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_err;
 	}
 	spin_lock_init(&chip->reg_lock);
 	chip->card = card;
@@ -1358,47 +1674,39 @@
 	/* check if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-		snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
-		pci_disable_device(pci);
-		return -ENXIO;
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
+		err = -ENXIO;
+		goto out_err;
 	}
 
 	if ((err = pci_request_regions(pci, "Aztech AZF3328")) < 0) {
-		kfree(chip);
-		pci_disable_device(pci);
-		return err;
+		goto out_err;
 	}
 
 	chip->codec_port = pci_resource_start(pci, 0);
-	chip->io2_port = pci_resource_start(pci, 1);
-	chip->mpu_port = pci_resource_start(pci, 2);
+	chip->io2_port   = pci_resource_start(pci, 1);
+	chip->mpu_port   = pci_resource_start(pci, 2);
 	chip->synth_port = pci_resource_start(pci, 3);
 	chip->mixer_port = pci_resource_start(pci, 4);
 
 	if (request_irq(pci->irq, snd_azf3328_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		snd_azf3328_free(chip);
-		return -EBUSY;
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		err = -EBUSY;
+		goto out_err;
 	}
 	chip->irq = pci->irq;
 	pci_set_master(pci);
 	synchronize_irq(chip->irq);
 
-	snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq);
-
-	snd_azf3328_dbgmisc("io2 %02x %02x %02x %02x %02x %02x\n", snd_azf3328_io2_read(chip, 0), snd_azf3328_io2_read(chip, 1), snd_azf3328_io2_read(chip, 2), snd_azf3328_io2_read(chip, 3), snd_azf3328_io2_read(chip, 4), snd_azf3328_io2_read(chip, 5));
-
-	for (tmp=0; tmp <= 0x01; tmp += 1)
-		snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp));
-
+	snd_azf3328_debug_show_ports(chip);
+	
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
-		snd_azf3328_free(chip);
-		return err;
+		goto out_err;
 	}
 
 	/* create mixer interface & switches */
 	if ((err = snd_azf3328_mixer_new(chip)) < 0)
-		return err;
+		goto out_err;
 
 #if 0
 	/* set very low bitrate to reduce noise and power consumption? */
@@ -1406,22 +1714,34 @@
 #endif
 
 	/* standard chip init stuff */
-	spin_lock_irq(&chip->reg_lock);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_PLAY_FLAGS);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_SOMETHING_FLAGS);
-	outb(DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE, chip->codec_port + IDX_IO_REC_FLAGS);
-	outb(0x0, chip->codec_port + IDX_IO_IRQ63H);
+	/* default IRQ init value */
+	tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
 
+	spin_lock_irq(&chip->reg_lock);
+	snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp);
+	snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x00); /* disable timer */
 	spin_unlock_irq(&chip->reg_lock);
 
 	snd_card_set_dev(card, &pci->dev);
 
 	*rchip = chip;
-	return 0;
+
+	err = 0;
+	goto out;
+
+out_err:
+	if (chip)
+		snd_azf3328_free(chip);
+	pci_disable_device(pci);
+
+out:
+	return err;
 }
 
-static int __devinit snd_azf3328_probe(struct pci_dev *pci,
-					  const struct pci_device_id *pci_id)
+static int __devinit
+snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
 	snd_card_t *card;
@@ -1445,63 +1765,70 @@
 	strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
 
         if ((err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_MPU401,
 				        chip->mpu_port, 1, pci->irq, 0,
 				        &chip->rmidi)) < 0) {
-		snd_printk("azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
-		snd_card_free(card);
-		return err;
+		snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+		goto out_err;
+	}
+
+	if ((err = snd_azf3328_timer(chip, 0)) < 0) {
+		goto out_err;
 	}
 
 	if ((err = snd_azf3328_pcm(chip, 0)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 	if (snd_opl3_create(card, chip->synth_port, chip->synth_port+2,
 			    OPL3_HW_AUTO, 1, &opl3) < 0) {
-		snd_printk("azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
+		snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
 			   chip->synth_port, chip->synth_port+2 );
 	} else {
 		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
+			goto out_err;
 		}
 	}
 
-	snd_azf3328_dbgio(chip, "create");
-
 	sprintf(card->longname, "%s at 0x%lx, irq %i",
 		card->shortname, chip->codec_port, chip->irq);
 
 	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 
 #ifdef MODULE
 	printk(
-"azt3328: Experimental driver for Aztech AZF3328-based soundcards such as PCI168.\n"
-"azt3328: ZERO support from Aztech: you might think hard about future purchase.\n"
-"azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n");
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
+"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
+"azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
+	1024000 / seqtimer_scaling, seqtimer_scaling);
 #endif
 
 	if (snd_azf3328_config_joystick(chip, dev) < 0)
-		snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR,
-			      snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
+		snd_azf3328_io2_outb(chip, IDX_IO2_LEGACY_ADDR,
+			      snd_azf3328_io2_inb(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY);
 
 	pci_set_drvdata(pci, card);
 	dev++;
 
+	err = 0;
+	goto out;
+	
+out_err:
+	snd_card_free(card);
+	
+out:
 	snd_azf3328_dbgcallleave();
-	return 0;
+	return err;
 }
 
-static void __devexit snd_azf3328_remove(struct pci_dev *pci)
+static void __devexit
+snd_azf3328_remove(struct pci_dev *pci)
 {
 	snd_azf3328_dbgcallenter();
 	snd_card_free(pci_get_drvdata(pci));
@@ -1517,7 +1844,8 @@
 	.remove = __devexit_p(snd_azf3328_remove),
 };
 
-static int __init alsa_card_azf3328_init(void)
+static int __init
+alsa_card_azf3328_init(void)
 {
 	int err;
 	snd_azf3328_dbgcallenter();
@@ -1526,7 +1854,8 @@
 	return err;
 }
 
-static void __exit alsa_card_azf3328_exit(void)
+static void __exit
+alsa_card_azf3328_exit(void)
 {
 	snd_azf3328_dbgcallenter();
 	pci_unregister_driver(&driver);
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 7e0e791..f489bda 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,19 +1,17 @@
-#ifndef __SOUND_AZF3328_H
-#define __SOUND_AZF3328_H
+#ifndef __SOUND_AZT3328_H
+#define __SOUND_AZT3328_H
 
-/* type argument to use for the I/O functions */
-#define WORD_VALUE      0x1000
-#define DWORD_VALUE     0x2000
-#define BYTE_VALUE      0x4000
+/* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
 
 /*** main I/O area port indices ***/
 /* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
-/* the driver initialisation suggests a layout of 3 main areas:
- * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX
- * timer ???). and probably another area from 0x60 to 0x6f
- * (IRQ management, power management etc. ???). */
-/* playback area */
-#define IDX_IO_PLAY_FLAGS       0x00
+/* the driver initialisation suggests a layout of 4 main areas:
+ * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
+ * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
+ * power management etc.???). */
+
+/** playback area **/
+#define IDX_IO_PLAY_FLAGS       0x00 /* PU:0x0000 */
      /* able to reactivate output after output muting due to 8/16bit
       * output change, just like 0x0002.
       * 0x0001 is the only bit that's able to start the DMA counter */
@@ -29,7 +27,7 @@
   #define DMA_EPILOGUE_SOMETHING	0x0010
   #define DMA_SOMETHING_ELSE		0x0020 /* ??? */
   #define SOMETHING_UNMODIFIABLE	0xffc0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_IRQMASK     0x02
+#define IDX_IO_PLAY_IRQTYPE     0x02 /* PU:0x0001 */
   /* write back to flags in case flags are set, in order to ACK IRQ in handler
    * (bit 1 of port 0x64 indicates interrupt for one of these three types)
    * sometimes in this case it just writes 0xffff to globally ACK all IRQs
@@ -41,36 +39,39 @@
   #define IRQMASK_SOME_STATUS_1		0x0008 /* \ related bits */
   #define IRQMASK_SOME_STATUS_2		0x0010 /* / (checked together in loop) */
   #define IRQMASK_UNMODIFIABLE		0xffe0 /* unused ? not modifiable */
-#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_1   0x0c /* length of 1st DMA play area */
-#define IDX_IO_PLAY_DMA_LEN_2   0x0e /* length of 2nd DMA play area */
-#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position  */
-#define IDX_IO_PLAY_DMA_CURROFS	0x14 /* offset within current DMA play area */
-#define IDX_IO_PLAY_SOUNDFORMAT 0x16
+#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_LEN_1   0x0c /* length of 1st DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_LEN_2   0x0e /* length of 2nd DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
+#define IDX_IO_PLAY_DMA_CURROFS	0x14 /* offset within current DMA play area, PU:0x0000 */
+#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */
   /* all unspecified bits can't be modified */
   #define SOUNDFORMAT_FREQUENCY_MASK	0x000f
+  #define SOUNDFORMAT_XTAL1		0x00
+  #define SOUNDFORMAT_XTAL2		0x01
     /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
      * have any hard facts, only rough measurements */
-    #define SOUNDFORMAT_FREQ_SUSPECTED_4000	0x0c
-    #define SOUNDFORMAT_FREQ_SUSPECTED_4800	0x0a
-    #define SOUNDFORMAT_FREQ_5510		0x0d
-    #define SOUNDFORMAT_FREQ_6620		0x0b
-    #define SOUNDFORMAT_FREQ_8000		0x00 /* also 0x0e ? */
-    #define SOUNDFORMAT_FREQ_9600		0x08
-    #define SOUNDFORMAT_FREQ_SUSPECTED_12000	0x09
-    #define SOUNDFORMAT_FREQ_11025		0x01 /* also 0x0f ? */
-    #define SOUNDFORMAT_FREQ_16000		0x02
-    #define SOUNDFORMAT_FREQ_22050		0x03
-    #define SOUNDFORMAT_FREQ_32000		0x04
-    #define SOUNDFORMAT_FREQ_44100		0x05
-    #define SOUNDFORMAT_FREQ_48000		0x06
-    #define SOUNDFORMAT_FREQ_SUSPECTED_64000	0x07
+    #define SOUNDFORMAT_FREQ_SUSPECTED_4000	0x0c | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_SUSPECTED_4800	0x0a | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_5510		0x0c | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_6620		0x0a | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_8000		0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
+    #define SOUNDFORMAT_FREQ_9600		0x08 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_11025		0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
+    #define SOUNDFORMAT_FREQ_SUSPECTED_13240	0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
+    #define SOUNDFORMAT_FREQ_16000		0x02 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_22050		0x02 | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_32000		0x04 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_44100		0x04 | SOUNDFORMAT_XTAL2
+    #define SOUNDFORMAT_FREQ_48000		0x06 | SOUNDFORMAT_XTAL1
+    #define SOUNDFORMAT_FREQ_SUSPECTED_66200	0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
   #define SOUNDFORMAT_FLAG_16BIT	0x0010
   #define SOUNDFORMAT_FLAG_2CHANNELS	0x0020
-/* recording area (see also: playback bit flag definitions) */
-#define IDX_IO_REC_FLAGS	0x20 /* ?? */
-#define IDX_IO_REC_IRQMASK	0x22 /* ?? */
+
+/** recording area (see also: playback bit flag definitions) **/
+#define IDX_IO_REC_FLAGS	0x20 /* ??, PU:0x0000 */
+#define IDX_IO_REC_IRQTYPE	0x22 /* ??, PU:0x0000 */
   #define IRQ_REC_SOMETHING		0x0001 /* something & ACK */
   #define IRQ_FINISHED_RECBUF_1		0x0002 /* 1st dmabuf finished & ACK */
   #define IRQ_FINISHED_RECBUF_2		0x0004 /* 2nd dmabuf finished & ACK */
@@ -78,39 +79,47 @@
    * but OTOH they are most likely at port 0x22 instead */
   #define IRQMASK_SOME_STATUS_1		0x0008 /* \ related bits */
   #define IRQMASK_SOME_STATUS_2		0x0010 /* / (checked together in loop) */
-#define IDX_IO_REC_DMA_START_1  0x24
-#define IDX_IO_REC_DMA_START_2  0x28
-#define IDX_IO_REC_DMA_LEN_1    0x2c
-#define IDX_IO_REC_DMA_LEN_2    0x2e
-#define IDX_IO_REC_DMA_CURRPOS  0x30
-#define IDX_IO_REC_DMA_CURROFS  0x34
-#define IDX_IO_REC_SOUNDFORMAT  0x36
-/* some third area ? (after playback and recording) */
-#define IDX_IO_SOMETHING_FLAGS	0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */
+#define IDX_IO_REC_DMA_START_1  0x24 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_START_2  0x28 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_LEN_1    0x2c /* PU:0x0000 */
+#define IDX_IO_REC_DMA_LEN_2    0x2e /* PU:0x0000 */
+#define IDX_IO_REC_DMA_CURRPOS  0x30 /* PU:0x00000000 */
+#define IDX_IO_REC_DMA_CURROFS  0x34 /* PU:0x00000000 */
+#define IDX_IO_REC_SOUNDFORMAT  0x36 /* PU:0x0000 */
+
+/** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/
+#define IDX_IO_SOMETHING_FLAGS	0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
 /* general */
-#define IDX_IO_60H		0x60 /* writing 0xffff returns 0xffff */
-#define IDX_IO_62H		0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
-#define IDX_IO_IRQ63H		0x63 /* FIXME !! */
-  #define IO_IRQ63H_SOMETHING		0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */
+#define IDX_IO_42H		0x42 /* PU:0x0001 */
+
+/** DirectX timer, main interrupt area (FIXME: and something else?) **/ 
+#define IDX_IO_TIMER_VALUE	0x60 /* found this timer area by pure luck :-) */
+  #define TIMER_VALUE_MASK		0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
+  #define TIMER_ENABLE_COUNTDOWN	0x01000000UL /* activate the timer countdown */
+  #define TIMER_ENABLE_IRQ		0x02000000UL /* trigger timer IRQ on zero transition */
+  #define TIMER_ACK_IRQ			0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
 #define IDX_IO_IRQSTATUS        0x64
   #define IRQ_PLAYBACK			0x0001
   #define IRQ_RECORDING			0x0002
   #define IRQ_MPU401			0x0010
-  #define IRQ_SOMEIRQ			0x0020 /* ???? */
-  #define IRQ_WHO_KNOWS_UNUSED		0x00e0 /* probably unused */
+  #define IRQ_TIMER			0x0020 /* DirectX timer */
+  #define IRQ_UNKNOWN1			0x0040 /* probably unused */
+  #define IRQ_UNKNOWN2			0x0080 /* probably unused */
 #define IDX_IO_66H		0x66    /* writing 0xffff returns 0x0000 */
-#define IDX_IO_SOME_VALUE	0x68	/* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */
-#define IDX_IO_6AH		0x6A	/* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */
-#define IDX_IO_6CH		0x6C	/* this WORD can have all its bits activated ? */
+#define IDX_IO_SOME_VALUE	0x68	/* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
+#define IDX_IO_6AH		0x6A	/* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */
+#define IDX_IO_6CH		0x6C
 #define IDX_IO_6EH		0x6E	/* writing 0xffff returns 0x83fe */
 /* further I/O indices not saved/restored, so probably not used */
 
+
 /*** I/O 2 area port indices ***/
 /* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 
 #define IDX_IO2_LEGACY_ADDR	0x04
-  #define LEGACY_SOMETHING		0x01 /* OPL3 ?? */
+  #define LEGACY_SOMETHING		0x01 /* OPL3?? */
   #define LEGACY_JOY			0x08
 
+
 /*** mixer I/O area port indices ***/
 /* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
  * generally spoken: AC97 register index = AZF3328 mixer reg index + 2
@@ -148,18 +157,18 @@
   /* unlisted bits are unmodifiable */
   #define MIXER_ADVCTL1_3DWIDTH_MASK	0x000e
   #define MIXER_ADVCTL1_HIFI3D_MASK	0x0300
-#define IDX_MIXER_ADVCTL2       0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */
+#define IDX_MIXER_ADVCTL2       0x20 /* resembles AC97_GENERAL_PURPOSE reg! */
   /* unlisted bits are unmodifiable */
-  #define MIXER_ADVCTL2_BIT7		0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */
-  #define MIXER_ADVCTL2_BIT8		0x0100 /* is this Modem Out Select ? */
-  #define MIXER_ADVCTL2_BIT9		0x0200 /* Mono Select Source ? */
-  #define MIXER_ADVCTL2_BIT13		0x2000 /* 3D enable ? */
+  #define MIXER_ADVCTL2_BIT7		0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */
+  #define MIXER_ADVCTL2_BIT8		0x0100 /* is this Modem Out Select? */
+  #define MIXER_ADVCTL2_BIT9		0x0200 /* Mono Select Source? */
+  #define MIXER_ADVCTL2_BIT13		0x2000 /* 3D enable? */
   #define MIXER_ADVCTL2_BIT15		0x8000 /* unknown */
   
-#define IDX_MIXER_SOMETHING30H	0x30 /* used, but unknown ??? */
+#define IDX_MIXER_SOMETHING30H	0x30 /* used, but unknown??? */
 
 /* driver internal flags */
 #define SET_CHAN_LEFT	1
 #define SET_CHAN_RIGHT	2
 
-#endif /* __SOUND_AZF3328_H  */
+#endif /* __SOUND_AZT3328_H  */
diff --git a/sound/pci/ca0106/Makefile b/sound/pci/ca0106/Makefile
index 89c6cee..dcbae7b 100644
--- a/sound/pci/ca0106/Makefile
+++ b/sound/pci/ca0106/Makefile
@@ -1,3 +1,3 @@
-snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o
+snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
 
 obj-$(CONFIG_SND_CA0106) += snd-ca0106.o
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index da09cab..9a4b640 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -399,10 +399,24 @@
 #define PLAYBACK_VOLUME2        0x6a            /* Playback Analog volume per channel. Does not effect AC3 output */
 						/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
 #define UNKNOWN6b               0x6b            /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
-#define UART_A_DATA		0x6c            /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_A_CMD		0x6d            /* Uart, used in setting sample rates, bits per sample etc. */
-#define UART_B_DATA		0x6e            /* Uart, Unknown. */
-#define UART_B_CMD		0x6f            /* Uart, Unknown. */
+#define MIDI_UART_A_DATA		0x6c            /* Midi Uart A Data */
+#define MIDI_UART_A_CMD		0x6d            /* Midi Uart A Command/Status */
+#define MIDI_UART_B_DATA		0x6e            /* Midi Uart B Data (currently unused) */
+#define MIDI_UART_B_CMD		0x6f            /* Midi Uart B Command/Status (currently unused) */
+
+/* unique channel identifier for midi->channel */
+
+#define CA0106_MIDI_CHAN_A		0x1
+#define CA0106_MIDI_CHAN_B		0x2
+
+/* from mpu401 */
+
+#define CA0106_MIDI_INPUT_AVAIL 	0x80
+#define CA0106_MIDI_OUTPUT_READY	0x40
+#define CA0106_MPU401_RESET		0xff
+#define CA0106_MPU401_ENTER_UART	0x3f
+#define CA0106_MPU401_ACK		0xfe
+
 #define SAMPLE_RATE_TRACKER_STATUS 0x70         /* Readonly. Default 00108000 00108000 00500000 00500000 */
 						/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 =  1.0
 						 * Rate Locked [20]
@@ -538,6 +552,8 @@
 #define CONTROL_CENTER_LFE_CHANNEL 1
 #define CONTROL_UNKNOWN_CHANNEL 2
 
+#include "ca_midi.h"
+
 typedef struct snd_ca0106_channel ca0106_channel_t;
 typedef struct snd_ca0106 ca0106_t;
 typedef struct snd_ca0106_pcm ca0106_pcm_t;
@@ -592,6 +608,9 @@
 	int capture_mic_line_in;
 
 	struct snd_dma_buffer buffer;
+
+	ca_midi_t midi;
+	ca_midi_t midi2;
 };
 
 int __devinit snd_ca0106_mixer(ca0106_t *emu);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index ba07960..ee58d16 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -281,7 +281,7 @@
 	int retry;
 	if ((reg > 0x7f) || (value > 0x1ff))
 	{
-                snd_printk("i2c_write: invalid values.\n");
+		snd_printk(KERN_ERR "i2c_write: invalid values.\n");
 		return -EINVAL;
 	}
 
@@ -319,7 +319,7 @@
 
 	if(retry==10)
 	{
-                snd_printk("Writing to ADC failed!\n");
+		snd_printk(KERN_ERR "Writing to ADC failed!\n");
 		return -EINVAL;
 	}
     
@@ -338,6 +338,18 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
+static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb)
+{
+	unsigned long flags;
+	unsigned int enable;
+  
+	spin_lock_irqsave(&emu->emu_lock, flags);
+	enable = inl(emu->port + INTE) & ~intrenb;
+	outl(enable, emu->port + INTE);
+	spin_unlock_irqrestore(&emu->emu_lock, flags);
+}
+
+
 static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
 	kfree(runtime->private_data);
@@ -421,7 +433,7 @@
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL) {
-                snd_printk("open_capture_channel: failed epcm alloc\n");
+		snd_printk(KERN_ERR "open_capture_channel: failed epcm alloc\n");
 		return -ENOMEM;
         }
 	epcm->emu = chip;
@@ -969,10 +981,8 @@
 #endif
 
 	// release the i/o port
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
+
 	// release the irq
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -1042,6 +1052,15 @@
 
         snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
 	spin_lock(&chip->emu_lock);
+
+	if (chip->midi.dev_id &&
+	  (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
+		if (chip->midi.interrupt)
+			chip->midi.interrupt(&chip->midi, status);
+		else
+			chip->midi.interrupt_disable(&chip->midi, chip->midi.tx_enable | chip->midi.rx_enable);
+	}
+
 	// acknowledge the interrupt if necessary
 	outl(status, chip->port+IPR);
 
@@ -1311,6 +1330,88 @@
 	return 0;
 }
 
+
+static void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr)
+{
+	snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr)
+{
+	snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr);
+}
+
+static unsigned char ca0106_midi_read(ca_midi_t *midi, int idx)
+{
+	return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0);
+}
+
+static void ca0106_midi_write(ca_midi_t *midi, int data, int idx)
+{
+	snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data);
+}
+
+static snd_card_t *ca0106_dev_id_card(void *dev_id)
+{
+	return ((ca0106_t *)dev_id)->card;
+}
+
+static int ca0106_dev_id_port(void *dev_id)
+{
+	return ((ca0106_t *)dev_id)->port;
+}
+
+static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel)
+{
+	ca_midi_t *midi;
+	char *name;
+	int err;
+
+        if(channel==CA0106_MIDI_CHAN_B) {
+		name = "CA0106 MPU-401 (UART) B";
+		midi =  &chip->midi2;
+		midi->tx_enable = INTE_MIDI_TX_B;
+		midi->rx_enable = INTE_MIDI_RX_B;
+		midi->ipr_tx = IPR_MIDI_TX_B;
+		midi->ipr_rx = IPR_MIDI_RX_B;
+		midi->port = MIDI_UART_B_DATA;
+	} else {
+		name = "CA0106 MPU-401 (UART)";
+		midi =  &chip->midi;
+		midi->tx_enable = INTE_MIDI_TX_A;
+		midi->rx_enable = INTE_MIDI_TX_B;
+		midi->ipr_tx = IPR_MIDI_TX_A;
+		midi->ipr_rx = IPR_MIDI_RX_A;
+		midi->port = MIDI_UART_A_DATA;
+	}
+
+	midi->reset = CA0106_MPU401_RESET;
+	midi->enter_uart = CA0106_MPU401_ENTER_UART;
+	midi->ack = CA0106_MPU401_ACK;
+
+	midi->input_avail = CA0106_MIDI_INPUT_AVAIL;
+	midi->output_ready = CA0106_MIDI_OUTPUT_READY;
+
+	midi->channel = channel;
+
+	midi->interrupt_enable = ca0106_midi_interrupt_enable;
+	midi->interrupt_disable = ca0106_midi_interrupt_disable;
+
+	midi->read = ca0106_midi_read;
+	midi->write = ca0106_midi_write;
+
+	midi->get_dev_id_card = ca0106_dev_id_card;
+	midi->get_dev_id_port = ca0106_dev_id_port;
+
+	midi->dev_id = chip;
+	
+	if ((err = ca_midi_init(chip, midi, 0, name)) < 0)
+		return err;
+
+	return 0;
+}
+
+
 static int __devinit snd_ca0106_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
@@ -1362,6 +1463,14 @@
 		return err;
 	}
 
+	snd_printdd("ca0106: probe for MIDI channel A ...");
+	if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) {
+		snd_card_free(card);
+		snd_printdd(" failed, err=0x%x\n",err);
+		return err;
+	}
+	snd_printdd(" done.\n");
+
 	snd_ca0106_proc_init(chip);
 
 	if ((err = snd_card_register(card)) < 0) {
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
new file mode 100644
index 0000000..2e08b27
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.c
@@ -0,0 +1,306 @@
+/* 
+ *  Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ *  Creative Audio MIDI, for the CA0106 Driver
+ *  Version: 0.0.1
+ *
+ *  Changelog:
+ *    Implementation is based on mpu401 and emu10k1x and
+ *    tested with ca0106.
+ *    mpu401: Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *    emu10k1x: Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ *
+ */
+
+#include <linux/spinlock.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "ca_midi.h"
+
+#define ca_midi_write_data(midi, data)	midi->write(midi, data, 0)
+#define ca_midi_write_cmd(midi, data)	midi->write(midi, data, 1)
+#define ca_midi_read_data(midi)		midi->read(midi, 0)
+#define ca_midi_read_stat(midi)		midi->read(midi, 1)
+#define ca_midi_input_avail(midi)	(!(ca_midi_read_stat(midi) & midi->input_avail))
+#define ca_midi_output_ready(midi)	(!(ca_midi_read_stat(midi) & midi->output_ready))
+
+static void ca_midi_clear_rx(ca_midi_t *midi)
+{
+	int timeout = 100000;
+	for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
+		ca_midi_read_data(midi);
+#ifdef CONFIG_SND_DEBUG
+	if (timeout <= 0)
+		snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n", ca_midi_read_stat(midi));
+#endif
+}
+
+static void ca_midi_interrupt(ca_midi_t *midi, unsigned int status) {
+	unsigned char byte;
+
+	if (midi->rmidi == NULL) {
+		midi->interrupt_disable(midi,midi->tx_enable | midi->rx_enable);
+		return;
+	}
+
+	spin_lock(&midi->input_lock);
+	if ((status & midi->ipr_rx) && ca_midi_input_avail(midi)) {
+		if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+			ca_midi_clear_rx(midi);
+		} else {
+			byte = ca_midi_read_data(midi);
+			if(midi->substream_input)
+				snd_rawmidi_receive(midi->substream_input, &byte, 1);
+
+
+		}
+	}
+	spin_unlock(&midi->input_lock);
+
+	spin_lock(&midi->output_lock);
+	if ((status & midi->ipr_tx) && ca_midi_output_ready(midi)) {
+		if (midi->substream_output &&
+		    snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
+			ca_midi_write_data(midi, byte);
+		} else {
+			midi->interrupt_disable(midi,midi->tx_enable);
+		}
+	}
+	spin_unlock(&midi->output_lock);
+
+}
+
+static void ca_midi_cmd(ca_midi_t *midi, unsigned char cmd, int ack)
+{
+	unsigned long flags;
+	int timeout, ok;
+
+	spin_lock_irqsave(&midi->input_lock, flags);
+	ca_midi_write_data(midi, 0x00);
+	/* ca_midi_clear_rx(midi); */
+
+	ca_midi_write_cmd(midi, cmd);
+	if (ack) {
+		ok = 0;
+		timeout = 10000;
+		while (!ok && timeout-- > 0) {
+			if (ca_midi_input_avail(midi)) {
+				if (ca_midi_read_data(midi) == midi->ack)
+					ok = 1;
+			}
+		}
+		if (!ok && ca_midi_read_data(midi) == midi->ack)
+			ok = 1;
+	} else {
+		ok = 1;
+	}
+	spin_unlock_irqrestore(&midi->input_lock, flags);
+	if (!ok)
+		snd_printk(KERN_ERR "ca_midi_cmd: 0x%x failed at 0x%x (status = 0x%x, data = 0x%x)!!!\n",
+			   cmd,
+			   midi->get_dev_id_port(midi->dev_id),
+			   ca_midi_read_stat(midi),
+			   ca_midi_read_data(midi));
+}
+
+static int ca_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+	
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= CA_MIDI_MODE_INPUT;
+	midi->substream_input = substream;
+	if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 1);
+		ca_midi_cmd(midi, midi->enter_uart, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->midi_mode |= CA_MIDI_MODE_OUTPUT;
+	midi->substream_output = substream;
+	if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 1);
+		ca_midi_cmd(midi, midi->enter_uart, 1);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return -ENXIO);
+	spin_lock_irqsave(&midi->open_lock, flags);
+	midi->interrupt_disable(midi,midi->rx_enable);
+	midi->midi_mode &= ~CA_MIDI_MODE_INPUT;
+	midi->substream_input = NULL;
+	if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static int ca_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+	snd_assert(midi->dev_id, return -ENXIO);
+	
+	spin_lock_irqsave(&midi->open_lock, flags);
+
+	midi->interrupt_disable(midi,midi->tx_enable);
+	midi->midi_mode &= ~CA_MIDI_MODE_OUTPUT;
+	midi->substream_output = NULL;
+	
+	if (!(midi->midi_mode & CA_MIDI_MODE_INPUT)) {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+		ca_midi_cmd(midi, midi->reset, 0);
+	} else {
+		spin_unlock_irqrestore(&midi->open_lock, flags);
+	}
+	return 0;
+}
+
+static void ca_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	snd_assert(midi->dev_id, return);
+
+	if (up) {
+		midi->interrupt_enable(midi,midi->rx_enable);
+	} else {
+		midi->interrupt_disable(midi, midi->rx_enable);
+	}
+}
+
+static void ca_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	unsigned long flags;
+
+	snd_assert(midi->dev_id, return);
+
+	if (up) {
+		int max = 4;
+		unsigned char byte;
+
+		spin_lock_irqsave(&midi->output_lock, flags);
+	
+		/* try to send some amount of bytes here before interrupts */
+		while (max > 0) {
+			if (ca_midi_output_ready(midi)) {
+				if (!(midi->midi_mode & CA_MIDI_MODE_OUTPUT) ||
+				    snd_rawmidi_transmit(substream, &byte, 1) != 1) {
+					/* no more data */
+					spin_unlock_irqrestore(&midi->output_lock, flags);
+					return;
+				}
+				ca_midi_write_data(midi, byte);
+				max--;
+			} else {
+				break;
+			}
+		}
+
+		spin_unlock_irqrestore(&midi->output_lock, flags);
+		midi->interrupt_enable(midi,midi->tx_enable);
+
+	} else {
+		midi->interrupt_disable(midi,midi->tx_enable);
+	}
+}
+
+static snd_rawmidi_ops_t ca_midi_output =
+{
+	.open =		ca_midi_output_open,
+	.close =	ca_midi_output_close,
+	.trigger =	ca_midi_output_trigger,
+};
+
+static snd_rawmidi_ops_t ca_midi_input =
+{
+	.open =		ca_midi_input_open,
+	.close =	ca_midi_input_close,
+	.trigger =	ca_midi_input_trigger,
+};
+
+static void ca_midi_free(ca_midi_t *midi) {
+	midi->interrupt = NULL;
+	midi->interrupt_enable = NULL;
+	midi->interrupt_disable = NULL;
+	midi->read = NULL;
+	midi->write = NULL;
+	midi->get_dev_id_card = NULL;
+	midi->get_dev_id_port = NULL;
+	midi->rmidi = NULL;
+}
+
+static void ca_rmidi_free(snd_rawmidi_t *rmidi)
+{
+	ca_midi_free((ca_midi_t *)rmidi->private_data);
+}
+
+int __devinit ca_midi_init(void *dev_id, ca_midi_t *midi, int device, char *name)
+{
+	snd_rawmidi_t *rmidi;
+	int err;
+
+	if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
+		return err;
+
+	midi->dev_id = dev_id;
+	midi->interrupt = ca_midi_interrupt;
+
+	spin_lock_init(&midi->open_lock);
+	spin_lock_init(&midi->input_lock);
+	spin_lock_init(&midi->output_lock);
+
+	strcpy(rmidi->name, name);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &ca_midi_output);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &ca_midi_input);
+	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+	                     SNDRV_RAWMIDI_INFO_INPUT |
+	                     SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->private_data = midi;
+	rmidi->private_free = ca_rmidi_free;
+	
+	midi->rmidi = rmidi;
+	return 0;
+}
+
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
new file mode 100644
index 0000000..b452cec
--- /dev/null
+++ b/sound/pci/ca0106/ca_midi.h
@@ -0,0 +1,69 @@
+/* 
+ *  Copyright 10/16/2005 Tilman Kranz <tilde@tk-sls.de>
+ *  Creative Audio MIDI, for the CA0106 Driver
+ *  Version: 0.0.1
+ *
+ *  Changelog:
+ *    See ca_midi.c
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#include<linux/spinlock.h>
+#include<sound/rawmidi.h>
+#include<sound/mpu401.h>
+
+#define CA_MIDI_MODE_INPUT	MPU401_MODE_INPUT
+#define CA_MIDI_MODE_OUTPUT	MPU401_MODE_OUTPUT
+
+typedef struct ca_midi ca_midi_t;
+struct ca_midi {
+
+	snd_rawmidi_t *rmidi;
+	snd_rawmidi_substream_t *substream_input;
+	snd_rawmidi_substream_t *substream_output;
+
+	void *dev_id;
+
+	spinlock_t input_lock;
+	spinlock_t output_lock;
+	spinlock_t open_lock;
+
+	unsigned int channel;
+
+	unsigned int midi_mode;
+	int port;
+	int tx_enable, rx_enable;
+	int ipr_tx, ipr_rx;            
+	
+	int input_avail, output_ready;
+	int ack, reset, enter_uart;
+
+	void (*interrupt)(ca_midi_t *midi, unsigned int status);
+	void (*interrupt_enable)(ca_midi_t *midi, int intr);
+	void (*interrupt_disable)(ca_midi_t *midi, int intr);
+
+	unsigned char (*read)(ca_midi_t *midi, int idx);
+	void (*write)(ca_midi_t *midi, int data, int idx);
+
+	/* get info from dev_id */
+	snd_card_t *(*get_dev_id_card)(void *dev_id);
+	int (*get_dev_id_port)(void *dev_id);
+};
+
+int __devinit ca_midi_init(void *card, ca_midi_t *midi, int device, char *name);
+
+
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 1eb3315..57e8e43 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -446,9 +446,6 @@
 	snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
 	int mixer_res_status[CM_SAVED_MIXERS];
 
-	opl3_t *opl3;
-	snd_hwdep_t *opl3hwdep;
-
 	cmipci_pcm_t channel[2];	/* ch0 - DAC, ch1 - ADC or 2nd DAC */
 
 	/* external MIDI */
@@ -2686,8 +2683,7 @@
 	cm->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 	gameport_set_name(gp, "C-Media Gameport");
@@ -2712,8 +2708,7 @@
 		cm->gameport = NULL;
 
 		snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -2753,6 +2748,51 @@
 	return snd_cmipci_free(cm);
 }
 
+static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port)
+{
+	long iosynth;
+	unsigned int val;
+	opl3_t *opl3;
+	int err;
+
+	/* first try FM regs in PCI port range */
+	iosynth = cm->iobase + CM_REG_FM_PCI;
+	err = snd_opl3_create(cm->card, iosynth, iosynth + 2,
+			      OPL3_HW_OPL3, 1, &opl3);
+	if (err < 0) {
+		/* then try legacy ports */
+		val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
+		iosynth = fm_port;
+		switch (iosynth) {
+		case 0x3E8: val |= CM_FMSEL_3E8; break;
+		case 0x3E0: val |= CM_FMSEL_3E0; break;
+		case 0x3C8: val |= CM_FMSEL_3C8; break;
+		case 0x388: val |= CM_FMSEL_388; break;
+		default:
+			    return 0;
+		}
+		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+		/* enable FM */
+		snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+
+		if (snd_opl3_create(cm->card, iosynth, iosynth + 2,
+				    OPL3_HW_OPL3, 0, &opl3) < 0) {
+			printk(KERN_ERR "cmipci: no OPL device at %#lx, "
+			       "skipping...\n", iosynth);
+			/* disable FM */
+			snd_cmipci_write(cm, CM_REG_LEGACY_CTRL,
+					 val & ~CM_FMSEL_MASK);
+			snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+			return 0;
+		}
+	}
+	if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+		printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
+		return err;
+	}
+	return 0;
+}
+
 static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
 				       int dev, cmipci_t **rcmipci)
 {
@@ -2762,8 +2802,8 @@
 		.dev_free =	snd_cmipci_dev_free,
 	};
 	unsigned int val = 0;
-	long iomidi = mpu_port[dev];
-	long iosynth = fm_port[dev];
+	long iomidi;
+	int integrated_midi;
 	int pcm_index, pcm_spdif_index;
 	static struct pci_device_id intel_82437vx[] = {
 		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
@@ -2799,7 +2839,7 @@
 	cm->iobase = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cmipci_free(cm);
 		return -EBUSY;
 	}
@@ -2867,52 +2907,28 @@
 		return err;
 	}
 
-	/* set MPU address */
-	switch (iomidi) {
-	case 0x320: val = CM_VMPU_320; break;
-	case 0x310: val = CM_VMPU_310; break;
-	case 0x300: val = CM_VMPU_300; break;
-	case 0x330: val = CM_VMPU_330; break;
-	default:
-		iomidi = 0; break;
-	}
-	if (iomidi > 0) {
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
-		/* enable UART */
-		snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
-	}
-
-	/* set FM address */
-	val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL) & ~CM_FMSEL_MASK;
-	switch (iosynth) {
-	case 0x3E8: val |= CM_FMSEL_3E8; break;
-	case 0x3E0: val |= CM_FMSEL_3E0; break;
-	case 0x3C8: val |= CM_FMSEL_3C8; break;
-	case 0x388: val |= CM_FMSEL_388; break;
-	default:
-		iosynth = 0; break;
-	}
-	if (iosynth > 0) {
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
-		/* enable FM */
-		snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-
-		if (snd_opl3_create(card, iosynth, iosynth + 2,
-				    OPL3_HW_OPL3, 0, &cm->opl3) < 0) {
-			printk(KERN_ERR "cmipci: no OPL device at 0x%lx, skipping...\n", iosynth);
-			iosynth = 0;
-		} else {
-			if ((err = snd_opl3_hwdep_new(cm->opl3, 0, 1, &cm->opl3hwdep)) < 0) {
-				printk(KERN_ERR "cmipci: cannot create OPL3 hwdep\n");
-				return err;
-			}
+	integrated_midi = snd_cmipci_read_b(cm, CM_REG_MPU_PCI) != 0xff;
+	if (integrated_midi)
+		iomidi = cm->iobase + CM_REG_MPU_PCI;
+	else {
+		iomidi = mpu_port[dev];
+		switch (iomidi) {
+		case 0x320: val = CM_VMPU_320; break;
+		case 0x310: val = CM_VMPU_310; break;
+		case 0x300: val = CM_VMPU_300; break;
+		case 0x330: val = CM_VMPU_330; break;
+		default:
+			    iomidi = 0; break;
+		}
+		if (iomidi > 0) {
+			snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val);
+			/* enable UART */
+			snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_UART_EN);
 		}
 	}
-	if (! iosynth) {
-		/* disable FM */
-		snd_cmipci_write(cm, CM_REG_LEGACY_CTRL, val & ~CM_FMSEL_MASK);
-		snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
-	}
+
+	if ((err = snd_cmipci_create_fm(cm, fm_port[dev])) < 0)
+		return err;
 
 	/* reset mixer */
 	snd_cmipci_mixer_write(cm, 0, 0);
@@ -2941,7 +2957,7 @@
 
 	if (iomidi > 0) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
-					       iomidi, 0,
+					       iomidi, integrated_midi,
 					       cm->irq, 0, &cm->rmidi)) < 0) {
 			printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi);
 		}
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index dc87e01..aea2c47 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -523,8 +523,7 @@
 			delay = 1;
 		end_time = jiffies + delay;
 		do {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	} else {
 		udelay(delay);
@@ -533,8 +532,7 @@
 
 static inline void snd_cs4281_delay_long(void)
 {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 }
 
 static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 6e3855b..9b8af5b 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -163,7 +163,7 @@
 			goto ok1;
 	}
 
-	snd_printk("AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
+	snd_printk(KERN_ERR "AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
 	result = 0xffff;
 	goto end;
 	
@@ -182,7 +182,7 @@
 		udelay(10);
 	}
 	
-	snd_printk("AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
+	snd_printk(KERN_ERR "AC'97 read problem (ACSTS_VSTS), codec_index %d, reg = 0x%x\n", codec_index, reg);
 	result = 0xffff;
 	goto end;
 
@@ -281,7 +281,7 @@
 			goto end;
 		}
 	}
-	snd_printk("AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
+	snd_printk(KERN_ERR "AC'97 write problem, codec_index = %d, reg = 0x%x, val = 0x%x\n", codec_index, reg, val);
  end:
 	chip->active_ctrl(chip, -1);
 }
@@ -510,7 +510,7 @@
 	}
 
 	if (snd_cs46xx_peek(chip, BA1_SPCR) & SPCR_RUNFR)
-		snd_printk("SPCR_RUNFR never reset\n");
+		snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
 }
 
 static void snd_cs46xx_proc_stop(cs46xx_t *chip)
@@ -2403,7 +2403,7 @@
 		msleep(10);
 	} while (time_after_eq(end_time, jiffies));
 
-	snd_printk("CS46xx secondary codec dont respond!\n");  
+	snd_printk(KERN_ERR "CS46xx secondary codec doesn't respond!\n");  
 }
 #endif
 
@@ -2906,10 +2906,7 @@
 		snd_cs46xx_region_t *region = &chip->region.idx[idx];
 		if (region->remap_addr)
 			iounmap(region->remap_addr);
-		if (region->resource) {
-			release_resource(region->resource);
-			kfree_nocheck(region->resource);
-		}
+		release_and_free_resource(region->resource);
 	}
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
@@ -3075,8 +3072,8 @@
 	}
 
 
-	snd_printk("create - never read codec ready from AC'97\n");
-	snd_printk("it is not probably bug, try to use CS4236 driver\n");
+	snd_printk(KERN_ERR "create - never read codec ready from AC'97\n");
+	snd_printk(KERN_ERR "it is not probably bug, try to use CS4236 driver\n");
 	return -EIO;
  ok1:
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3124,17 +3121,17 @@
 	}
 
 #ifndef CONFIG_SND_CS46XX_NEW_DSP
-	snd_printk("create - never read ISV3 & ISV4 from AC'97\n");
+	snd_printk(KERN_ERR "create - never read ISV3 & ISV4 from AC'97\n");
 	return -EIO;
 #else
 	/* This may happen on a cold boot with a Terratec SiXPack 5.1.
 	   Reloading the driver may help, if there's other soundcards 
 	   with the same problem I would like to know. (Benny) */
 
-	snd_printk("ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
-	snd_printk("       Try reloading the ALSA driver, if you find something\n");
-        snd_printk("       broken or not working on your soundcard upon\n");
-	snd_printk("       this message please report to alsa-devel@lists.sourceforge.net\n");
+	snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n");
+	snd_printk(KERN_ERR "       Try reloading the ALSA driver, if you find something\n");
+        snd_printk(KERN_ERR "       broken or not working on your soundcard upon\n");
+	snd_printk(KERN_ERR "       this message please report to alsa-devel@lists.sourceforge.net\n");
 
 	return -EIO;
 #endif
@@ -3215,7 +3212,7 @@
 #else
 	/* old image */
 	if (snd_cs46xx_download_image(chip) < 0) {
-		snd_printk("image download error\n");
+		snd_printk(KERN_ERR "image download error\n");
 		return -EIO;
 	}
 
@@ -3790,7 +3787,7 @@
 	chip->ba1_addr = pci_resource_start(pci, 1);
 	if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
 	    chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
-	    	snd_printk("wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
+	    	snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
 	    	snd_cs46xx_free(chip);
 	    	return -ENOMEM;
 	}
@@ -3839,12 +3836,12 @@
 	}
 
 	if (external_amp) {
-		snd_printk("Crystal EAPD support forced on.\n");
+		snd_printk(KERN_INFO "Crystal EAPD support forced on.\n");
 		chip->amplifier_ctrl = amp_voyetra;
 	}
 
 	if (thinkpad) {
-		snd_printk("Activating CLKRUN hack for Thinkpad.\n");
+		snd_printk(KERN_INFO "Activating CLKRUN hack for Thinkpad.\n");
 		chip->active_ctrl = clkrun_hack;
 		clkrun_init(chip);
 	}
@@ -3861,20 +3858,20 @@
 	for (idx = 0; idx < 5; idx++) {
 		region = &chip->region.idx[idx];
 		if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
-			snd_printk("unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+			snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
 			snd_cs46xx_free(chip);
 			return -EBUSY;
 		}
 		region->remap_addr = ioremap_nocache(region->base, region->size);
 		if (region->remap_addr == NULL) {
-			snd_printk("%s ioremap problem\n", region->name);
+			snd_printk(KERN_ERR "%s ioremap problem\n", region->name);
 			snd_cs46xx_free(chip);
 			return -ENOMEM;
 		}
 	}
 
 	if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs46xx_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index b0e00f0..dd1ea9d 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -188,7 +188,7 @@
 	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
 			       sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
 	    wave == NULL) {
-		snd_printk("can't initialize Emu10k1 wavetable synth\n");
+		snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
 	} else {
 		snd_emu10k1_synth_arg_t *arg;
 		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 7cf2f90..6589bf2 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -241,7 +241,7 @@
 		else if (state == SNDRV_EMUX_ST_RELEASED ||
 			 state == SNDRV_EMUX_ST_PENDING) {
 			bp = best + V_RELEASED;
-#if 0
+#if 1
 			val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
 			if (! val)
 				bp = best + V_OFF;
@@ -349,7 +349,7 @@
 	}
 
 	/* channel to be silent and idle */
-	snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
+	snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0000);
 	snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
 	snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
 	snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index ad15755..cbb6894 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -759,10 +759,8 @@
 	outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
 
 	// release the i/o port
-	if (chip->res_port) {
-		release_resource(chip->res_port);
-		kfree_nocheck(chip->res_port);
-	}
+	release_and_free_resource(chip->res_port);
+
 	// release the irq
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 646b5d9..03e8c16 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -364,12 +364,18 @@
 			snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
 			break;
 		case EMU10K1_GPR_TRANSLATION_BASS:
-			snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+			if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+				change = -EIO;
+				goto __error;
+			}
 			for (j = 0; j < 5; j++)
 				snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
 			break;
 		case EMU10K1_GPR_TRANSLATION_TREBLE:
-			snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
+			if ((ctl->count % 5) != 0 || (ctl->count / 5) != ctl->vcount) {
+				change = -EIO;
+				goto __error;
+			}
 			for (j = 0; j < 5; j++)
 				snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
 			break;
@@ -412,8 +418,6 @@
 	snd_emu10k1_fx8010_irq_t *irq;
 	unsigned long flags;
 	
-	snd_runtime_check(emu, return -EINVAL);
-	snd_runtime_check(handler, return -EINVAL);
 	irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
 	if (irq == NULL)
 		return -ENOMEM;
@@ -442,7 +446,6 @@
 	snd_emu10k1_fx8010_irq_t *tmp;
 	unsigned long flags;
 	
-	snd_runtime_check(irq, return -EINVAL);
 	spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
 	if ((tmp = emu->fx8010.irq_handlers) == irq) {
 		emu->fx8010.irq_handlers = tmp->next;
@@ -717,9 +720,15 @@
 			err = -EFAULT;
 			goto __error;
 		}
-		snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
-		                  gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
-		snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
+		if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+		    gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+			err = -EINVAL;
+			goto __error;
+		}
+		if (! gctl->id.name[0]) {
+			err = -EINVAL;
+			goto __error;
+		}
 		ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
 		memset(&knew, 0, sizeof(knew));
 		knew.iface = gctl->id.iface;
@@ -783,7 +792,8 @@
 	
 	for (i = 0, _id = icode->gpr_del_controls;
 	     i < icode->gpr_del_control_count; i++, _id++) {
-	     	snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
+	     	if (copy_from_user(&id, _id, sizeof(id)))
+			return -EFAULT;
 		down_write(&card->controls_rwsem);
 		ctl = snd_emu10k1_look_for_ctl(emu, &id);
 		if (ctl)
@@ -964,8 +974,8 @@
 	return err;
 }
 
-#define SND_EMU10K1_GPR_CONTROLS	41
-#define SND_EMU10K1_INPUTS		10
+#define SND_EMU10K1_GPR_CONTROLS	44
+#define SND_EMU10K1_INPUTS		12
 #define SND_EMU10K1_PLAYBACK_CHANNELS	8
 #define SND_EMU10K1_CAPTURE_CHANNELS	4
 
@@ -1382,7 +1392,7 @@
 		A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
 		if ((z==1) && (emu->card_capabilities->spdif_bug)) {
 			/* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
-			snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
+			snd_printk(KERN_INFO "Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
 			A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
 			A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
 		} else {
@@ -1527,7 +1537,7 @@
 
 	strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
 	ptr = 0; i = 0;
-	/* we have 10 inputs */
+	/* we have 12 inputs */
 	playback = SND_EMU10K1_INPUTS;
 	/* we have 6 playback channels and tone control doubles */
 	capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
@@ -1551,6 +1561,8 @@
 	OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
 	OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000);	/* S/PDIF left */
 	OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000);	/* S/PDIF right */
+	OP(icode, &ptr, iMACINT0, GPR(10), C_00000000, FXBUS(FXBUS_PCM_LEFT_FRONT), C_00000004);
+	OP(icode, &ptr, iMACINT0, GPR(11), C_00000000, FXBUS(FXBUS_PCM_RIGHT_FRONT), C_00000004);
 
 	/* Raw S/PDIF PCM */
 	ipcm->substream = 0;
@@ -1697,6 +1709,21 @@
 	VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
 	snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
 
+	/* Front Playback Volume */
+	for (z = 0; z < 2; z++)
+		VOLUME_ADD(icode, &ptr, playback + z, 10 + z, gpr + z);
+	snd_emu10k1_init_stereo_control(controls + i++, "Front Playback Volume", gpr, 100);
+	gpr += 2;
+
+	/* Front Capture Volume + Switch */
+	for (z = 0; z < 2; z++) {
+		SWITCH(icode, &ptr, tmp + 0, 10 + z, gpr + 2);
+		VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
+	}
+	snd_emu10k1_init_stereo_control(controls + i++, "Front Capture Volume", gpr, 0);
+	snd_emu10k1_init_mono_onoff_control(controls + i++, "Front Capture Switch", gpr + 2, 0);
+	gpr += 3;
+
 	/*
 	 *  Process inputs
 	 */
@@ -2058,14 +2085,16 @@
 #if 0 // FIXME: who use them?
 int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
 {
-	snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+	if (output < 0 || output >= 6)
+		return -EINVAL;
 	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
 	return 0;
 }
 
 int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
 {
-	snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
+	if (output < 0 || output >= 6)
+		return -EINVAL;
 	snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
 	return 0;
 }
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 66ba27a..bf7490d 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -965,7 +965,8 @@
 {
 	snd_ctl_elem_id_t id;
 
-	snd_runtime_check(kctl != NULL, return);
+	if (! kctl)
+		return;
 	if (activate)
 		kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 	else
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index cd8460d..594ea06 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -41,7 +41,7 @@
 		orig_status = status;
 		handled = 1;
 		if (status & IPR_PCIERROR) {
-			snd_printk("interrupt: PCI error\n");
+			snd_printk(KERN_ERR "interrupt: PCI error\n");
 			snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
 			status &= ~IPR_PCIERROR;
 		}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 6afeaea..d42e4ae 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -232,11 +232,11 @@
 static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
 {
 	if (addr & ~emu->dma_mask) {
-		snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
+		snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
 		return 0;
 	}
 	if (addr & (EMUPAGESIZE-1)) {
-		snd_printk("page is not aligned\n");
+		snd_printk(KERN_ERR "page is not aligned\n");
 		return 0;
 	}
 	return 1;
@@ -501,7 +501,7 @@
 	snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
 	ptr = emu->page_ptr_table[page];
 	if (! ptr) {
-		printk("emu10k1: access to NULL ptr: page = %d\n", page);
+		printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page);
 		return NULL;
 	}
 	ptr += offset & (PAGE_SIZE - 1);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index d59c7f3..e27ebb9 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -546,7 +546,7 @@
 	ptr=ptr2;
 	if (ptr >= runtime->buffer_size) {
 		ptr -= runtime->buffer_size;
-		printk("buffer capture limited!\n");
+		printk(KERN_WARNING "buffer capture limited!\n");
 	}
 	//printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index bef9a59..92ff7c5 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -508,7 +508,7 @@
 			return r;
 		cond_resched();
 	}
-	snd_printk("wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
+	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
 	return 0;
 }
 
@@ -576,10 +576,9 @@
 			outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
 			return;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(end_time, jiffies));
-	snd_printk("codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
+	snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
 }
 
 #endif /* CHIP1370 */
@@ -620,7 +619,7 @@
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk("codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 }
 
 static unsigned short snd_es1371_codec_read(ac97_t *ac97,
@@ -667,14 +666,14 @@
 			}
 			up(&ensoniq->src_mutex);
 			if (++fail > 10) {
-				snd_printk("codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
+				snd_printk(KERN_ERR "codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
 				return 0;
 			}
 			goto __again;
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk("es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 	return 0;
 }
 
@@ -1960,7 +1959,7 @@
 	}
 	ensoniq->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ensoniq_free(ensoniq);
 		return -EBUSY;
 	}
@@ -1968,7 +1967,7 @@
 #ifdef CHIP1370
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				16, &ensoniq->dma_bug) < 0) {
-		snd_printk("unable to allocate space for phantom area - dma_bug\n");
+		snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
 		snd_ensoniq_free(ensoniq);
 		return -EBUSY;
 	}
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 17fa80c..78f90de 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -267,7 +267,7 @@
 	outb(val, SLSB_REG(chip, MIXERDATA));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x set to %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, val);
 #endif
 }
 
@@ -283,7 +283,7 @@
 	data = inb(SLSB_REG(chip, MIXERDATA));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Mixer reg %02x now is %02x\n", reg, data);
+	snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
 #endif
 	return data;
 }
@@ -303,7 +303,8 @@
 		new = (old & ~mask) | (val & mask);
 		outb(new, SLSB_REG(chip, MIXERDATA));
 #ifdef REG_DEBUG
-		snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
@@ -323,7 +324,7 @@
 			return;
 		}
 	}
-	printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
+	printk(KERN_ERR "snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
 }
 
 /* -----------------------------------------------------------------
@@ -336,7 +337,7 @@
 	for (i = GET_LOOP_TIMEOUT; i; i--)
 		if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
 			return inb(SLSB_REG(chip, READDATA));
-	snd_printk("get_byte timeout: status 0x02%x\n", v);
+	snd_printk(KERN_ERR "get_byte timeout: status 0x02%x\n", v);
 	return -ENODEV;
 }
 
@@ -351,7 +352,7 @@
 	snd_es1938_write_cmd(chip, val);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x set to %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, val);
 #endif
 }
 
@@ -368,7 +369,7 @@
 	val = snd_es1938_get_byte(chip);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 #ifdef REG_DEBUG
-	snd_printk("Reg %02x now is %02x\n", reg, val);
+	snd_printk(KERN_DEBUG "Reg %02x now is %02x\n", reg, val);
 #endif
 	return val;
 }
@@ -390,7 +391,8 @@
 		new = (old & ~mask) | (val & mask);
 		snd_es1938_write_cmd(chip, new);
 #ifdef REG_DEBUG
-		snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
+		snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x\n",
+			   reg, old, new);
 #endif
 	}
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
@@ -413,7 +415,7 @@
 				goto __next;
 		}
 	}
-	snd_printk("ESS Solo-1 reset failed\n");
+	snd_printk(KERN_ERR "ESS Solo-1 reset failed\n");
 
      __next:
 	snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
@@ -543,10 +545,12 @@
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		val = 0x0f;
 		chip->active |= ADC1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		val = 0x00;
 		chip->active &= ~ADC1;
 		break;
@@ -563,6 +567,7 @@
 	es1938_t *chip = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		/* According to the documentation this should be:
 		   0x13 but that value may randomly swap stereo channels */
                 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
@@ -575,6 +580,7 @@
 		chip->active |= DAC2;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		outb(0, SLIO_REG(chip, AUDIO2MODE));
 		snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
 		chip->active &= ~DAC2;
@@ -592,10 +598,12 @@
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		val = 5;
 		chip->active |= DAC1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		val = 0;
 		chip->active &= ~DAC1;
 		break;
@@ -1390,7 +1398,8 @@
 		*d = snd_es1938_reg_read(chip, *s);
 
 	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
-
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);  
 	pci_disable_device(chip->pci);
 	return 0;
 }
@@ -1401,6 +1410,9 @@
 	unsigned char *s, *d;
 
 	pci_enable_device(chip->pci);
+	request_irq(chip->pci->irq, snd_es1938_interrupt,
+		    SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
+	chip->irq = chip->pci->irq;
 	snd_es1938_chip_init(chip);
 
 	/* restore mixer-related registers */
@@ -1489,7 +1501,7 @@
         /* check, if we can restrict PCI DMA transfers to 24 bits */
 	if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-                snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
                 return -ENXIO;
         }
@@ -1514,13 +1526,13 @@
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->game_port = pci_resource_start(pci, 4);
 	if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1938_free(chip);
 		return -EBUSY;
 	}
 	chip->irq = pci->irq;
 #ifdef ES1938_DDEBUG
-	snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
+	snd_printk(KERN_DEBUG "create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
 		   chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
 #endif
 
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index ecdcada..ac8294e 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1462,13 +1462,13 @@
 						   snd_dma_pci_data(chip->pci),
 						   chip->total_bufsize, &chip->dma);
 		if (err < 0 || ! chip->dma.area) {
-			snd_printk("es1968: can't allocate dma pages for size %d\n",
+			snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
 				   chip->total_bufsize);
 			return -ENOMEM;
 		}
 		if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
 			snd_dma_free_pages(&chip->dma);
-			snd_printk("es1968: DMA buffer beyond 256MB.\n");
+			snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
 			return -ENOMEM;
 		}
 	}
@@ -1741,11 +1741,11 @@
 
 	/* search 2 APUs (although one apu is enough) */
 	if ((apu = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_PLAY)) < 0) {
-		snd_printk("Hmm, cannot find empty APU pair!?\n");
+		snd_printk(KERN_ERR "Hmm, cannot find empty APU pair!?\n");
 		return;
 	}
 	if ((memory = snd_es1968_new_memory(chip, CLOCK_MEASURE_BUFSIZE)) == NULL) {
-		snd_printk("cannot allocate dma buffer - using default clock %d\n", chip->clock);
+		snd_printk(KERN_ERR "cannot allocate dma buffer - using default clock %d\n", chip->clock);
 		snd_es1968_free_apu_pair(chip, apu);
 		return;
 	}
@@ -1806,7 +1806,7 @@
 	else
 		t += stop_time.tv_usec - start_time.tv_usec;
 	if (t == 0) {
-		snd_printk("?? calculation error..\n");
+		snd_printk(KERN_ERR "?? calculation error..\n");
 	} else {
 		offset *= 1000;
 		offset = (offset / t) * 1000 + ((offset % t) * 1000) / t;
@@ -2090,7 +2090,7 @@
 	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
 
 #if 0				/* the loop here needs to be much better if we want it.. */
-	snd_printk("trying software reset\n");
+	snd_printk(KERN_INFO "trying software reset\n");
 	/* try and do a software reset */
 	outb(0x80 | 0x7c, ioaddr + 0x30);
 	for (w = 0;; w++) {
@@ -2461,8 +2461,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "es1968: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -2488,8 +2487,7 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -2564,7 +2562,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2599,7 +2597,7 @@
 	chip->io_port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_es1968_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			"ESS Maestro", (void*)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1968_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index e5cfa2a..4c7c8d2 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -237,7 +237,7 @@
 			goto ok1;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface is busy (1)\n");
+	snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
 	return;
 
  ok1:
@@ -252,7 +252,7 @@
 			return;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
 }
 
 static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
@@ -268,7 +268,7 @@
 			goto ok1;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface is busy (1)\n");
+	snd_printk(KERN_ERR "AC'97 interface is busy (1)\n");
 	return 0;
 
  ok1:
@@ -279,7 +279,7 @@
 			goto ok2;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is busy (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
 	return 0;
 
  ok2:
@@ -288,7 +288,7 @@
 			goto ok3;
 		udelay(10);
 	}
-	snd_printk("AC'97 interface #%d is not valid (2)\n", ac97->num);
+	snd_printk(KERN_ERR "AC'97 interface #%d is not valid (2)\n", ac97->num);
 	return 0;
 
  ok3:
@@ -1279,7 +1279,7 @@
 	}
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", chip->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 		snd_fm801_free(chip);
 		return -EBUSY;
 	}
@@ -1303,10 +1303,9 @@
 	do {
 		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
 			goto __ac97_secondary;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(timeout, jiffies));
-	snd_printk("Primary AC'97 codec not found\n");
+	snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
 	snd_fm801_free(chip);
 	return -EIO;
 
@@ -1329,8 +1328,7 @@
 					goto __ac97_ok;
 				}
 			}
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after(timeout, jiffies));
 	}
 
@@ -1343,10 +1341,9 @@
 	do {
 		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
 			goto __ac97_ok;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after(timeout, jiffies));
-	snd_printk("Primary AC'97 codec not responding\n");
+	snd_printk(KERN_ERR "Primary AC'97 codec not responding\n");
 	snd_fm801_free(chip);
 	return -EIO;
 
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3815403..0dbeeaf 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -518,6 +518,13 @@
 		return -ENODEV;
 	}
 
+	if (! codec->subsystem_id) {
+		hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
+		codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
+							 AC_VERB_GET_SUBSYSTEM_ID,
+							 0);
+	}
+
 	codec->preset = find_codec_preset(codec);
 	if (! *bus->card->mixername)
 		snd_hda_get_codec_name(codec, bus->card->mixername,
@@ -814,6 +821,51 @@
 }
 
 /*
+ * bound volume controls
+ *
+ * bind multiple volumes (# indices, from 0)
+ */
+
+#define AMP_VAL_IDX_SHIFT	19
+#define AMP_VAL_IDX_MASK	(0x0f<<19)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned long pval;
+	int err;
+
+	down(&codec->spdif_mutex); /* reuse spdif_mutex */
+	pval = kcontrol->private_value;
+	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+	err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+	kcontrol->private_value = pval;
+	up(&codec->spdif_mutex);
+	return err;
+}
+
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned long pval;
+	int i, indices, err = 0, change = 0;
+
+	down(&codec->spdif_mutex); /* reuse spdif_mutex */
+	pval = kcontrol->private_value;
+	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
+	for (i = 0; i < indices; i++) {
+		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+		err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+		if (err < 0)
+			break;
+		change |= err;
+	}
+	kcontrol->private_value = pval;
+	up(&codec->spdif_mutex);
+	return err < 0 ? err : change;
+}
+
+/*
  * SPDIF out controls
  */
 
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index bb53bcf..1179d6c 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -79,6 +79,8 @@
 #define AC_VERB_GET_GPIO_MASK			0x0f16
 #define AC_VERB_GET_GPIO_DIRECTION		0x0f17
 #define AC_VERB_GET_CONFIG_DEFAULT		0x0f1c
+/* f20: AFG/MFG */
+#define AC_VERB_GET_SUBSYSTEM_ID		0x0f20
 
 /*
  * SET verbs
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 6fe696e..9d1412a 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -47,23 +47,24 @@
 #include "hda_codec.h"
 
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+static char *model;
+static int position_fix;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
-module_param_array(model, charp, NULL, 0444);
+module_param(model, charp, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
-module_param_array(position_fix, int, NULL, 0444);
+module_param(position_fix, int, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
 			 "{Intel, ICH6M},"
@@ -223,6 +224,9 @@
 #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
 #define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
 
+/* Defines for Nvidia HDA support */
+#define NVIDIA_HDA_TRANSREG_ADDR      0x4e
+#define NVIDIA_HDA_ENABLE_COHBITS     0x0f
 
 /*
  * Use CORB/RIRB for communication from/to codecs.
@@ -328,6 +332,7 @@
 	AZX_DRIVER_VIA,
 	AZX_DRIVER_SIS,
 	AZX_DRIVER_ULI,
+	AZX_DRIVER_NVIDIA,
 };
 
 static char *driver_short_names[] __devinitdata = {
@@ -335,7 +340,8 @@
 	[AZX_DRIVER_ATI] = "HDA ATI SB",
 	[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
 	[AZX_DRIVER_SIS] = "HDA SIS966",
-	[AZX_DRIVER_ULI] = "HDA ULI M5461"
+	[AZX_DRIVER_ULI] = "HDA ULI M5461",
+	[AZX_DRIVER_NVIDIA] = "HDA NVidia",
 };
 
 /*
@@ -710,14 +716,14 @@
  */
 static void azx_init_chip(azx_t *chip)
 {
-	unsigned char tcsel_reg, ati_misc_cntl2;
+	unsigned char reg;
 
 	/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
 	 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
 	 * Ensuring these bits are 0 clears playback static on some HD Audio codecs
 	 */
-	pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &tcsel_reg);
-	pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, tcsel_reg & 0xf8);
+	pci_read_config_byte (chip->pci, ICH6_PCIREG_TCSEL, &reg);
+	pci_write_config_byte(chip->pci, ICH6_PCIREG_TCSEL, reg & 0xf8);
 
 	/* reset controller */
 	azx_reset(chip);
@@ -733,13 +739,21 @@
 	azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
 	azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
 
-	/* For ATI SB450 azalia HD audio, we need to enable snoop */
-	if (chip->driver_type == AZX_DRIVER_ATI) {
+	switch (chip->driver_type) {
+	case AZX_DRIVER_ATI:
+		/* For ATI SB450 azalia HD audio, we need to enable snoop */
 		pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-				     &ati_misc_cntl2);
+				     &reg);
 		pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
-				      (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
-	}
+				      (reg & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+		break;
+	case AZX_DRIVER_NVIDIA:
+		/* For NVIDIA HDA, enable snoop */
+		pci_read_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR, &reg);
+		pci_write_config_byte(chip->pci,NVIDIA_HDA_TRANSREG_ADDR,
+				      (reg & 0xf0) | NVIDIA_HDA_ENABLE_COHBITS);
+		break;
+        }
 }
 
 
@@ -1264,6 +1278,7 @@
 			err = create_codec_pcm(chip, codec, &codec->pcm_info[c], pcm_dev);
 			if (err < 0)
 				return err;
+			chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
 			pcm_dev++;
 		}
 	}
@@ -1530,32 +1545,24 @@
 
 static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	azx_t *chip;
 	int err = 0;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (! enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (NULL == card) {
 		snd_printk(KERN_ERR SFX "Error creating card!\n");
 		return -ENOMEM;
 	}
 
-	if ((err = azx_create(card, pci, position_fix[dev], pci_id->driver_data,
+	if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
 			      &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
 	/* create codec instances */
-	if ((err = azx_codec_create(chip, model[dev])) < 0) {
+	if ((err = azx_codec_create(chip, model)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1581,7 +1588,6 @@
 	}
 
 	pci_set_drvdata(pci, card);
-	dev++;
 
 	return err;
 }
@@ -1601,6 +1607,8 @@
 	{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */
 	{ 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */
 	{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */
+	{ 0x10de, 0x026c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 026c */
+	{ 0x10de, 0x0371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_NVIDIA }, /* NVIDIA 0371 */
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 810cfd2..f51a56f 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -27,28 +27,36 @@
  * for mixer controls
  */
 #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
+/* mono volume with index (index=0,1,...) (channel=1,2) */
 #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx,  \
 	  .info = snd_hda_mixer_amp_volume_info, \
 	  .get = snd_hda_mixer_amp_volume_get, \
 	  .put = snd_hda_mixer_amp_volume_put, \
 	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo volume with index */
 #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono volume */
 #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo volume */
 #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
 	HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
+/* mono mute switch with index (index=0,1,...) (channel=1,2) */
 #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
 	  .info = snd_hda_mixer_amp_switch_info, \
 	  .get = snd_hda_mixer_amp_switch_get, \
 	  .put = snd_hda_mixer_amp_switch_put, \
 	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
+/* stereo mute switch with index */
 #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
 	HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
+/* mono mute switch */
 #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
 	HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
+/* stereo mute switch */
 #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
 	HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
 
@@ -59,6 +67,20 @@
 int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
 int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
 
+/* mono switch binding multiple inputs */
+#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = snd_hda_mixer_amp_switch_info, \
+	  .get = snd_hda_mixer_bind_switch_get, \
+	  .put = snd_hda_mixer_bind_switch_put, \
+	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
+
+/* stereo switch binding multiple inputs */
+#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+
 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
 
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 08f6a6e..39ddf1c 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -281,6 +281,11 @@
 			print_pcm_caps(buffer, codec, nid);
 		}
 
+		if (wid_caps & AC_WCAP_POWER)
+			snd_iprintf(buffer, "  Power: 0x%x\n",
+				    snd_hda_codec_read(codec, nid, 0,
+						       AC_VERB_GET_POWER_STATE, 0));
+
 		if (wid_caps & AC_WCAP_CONN_LIST) {
 			int c, curr = -1;
 			if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index da6874d..d7d636d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -28,15 +28,38 @@
 #include "hda_local.h"
 
 struct ad198x_spec {
-	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
-	struct hda_multi_out multiout;	/* playback */
-	hda_nid_t adc_nid;
+	snd_kcontrol_new_t *mixers[5];
+	int num_mixers;
+
+	const struct hda_verb *init_verbs[3];	/* initialization verbs
+						 * don't forget NULL termination!
+						 */
+	unsigned int num_init_verbs;
+
+	/* playback */
+	struct hda_multi_out multiout;	/* playback set-up
+					 * max_channels, dacs must be set
+					 * dig_out_nid and hp_nid are optional
+					 */
+
+	/* capture */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
+
+	/* capture source */
 	const struct hda_input_mux *input_mux;
-	unsigned int cur_mux;		/* capture source */
+	unsigned int cur_mux[3];
+
+	/* channel model */
+	const struct alc_channel_mode *channel_mode;
+	int num_channel_mode;
+
+	/* PCM information */
+	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
+
+	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
 	unsigned int spdif_route;
-	snd_kcontrol_new_t *mixers;
-	const struct hda_verb *init_verbs;
-	struct hda_pcm pcm_rec[2];	/* PCM information */
 };
 
 /*
@@ -54,8 +77,9 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
-	ucontrol->value.enumerated.item[0] = spec->cur_mux;
+	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 	return 0;
 }
 
@@ -63,9 +87,10 @@
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
-				     spec->adc_nid, &spec->cur_mux);
+				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
 }
 
 /*
@@ -74,22 +99,34 @@
 static int ad198x_init(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_sequence_write(codec, spec->init_verbs);
+	int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++)
+		snd_hda_sequence_write(codec, spec->init_verbs[i]);
 	return 0;
 }
 
 static int ad198x_build_controls(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
+	unsigned int i;
 	int err;
 
-	err = snd_hda_add_new_ctls(codec, spec->mixers);
-	if (err < 0)
-		return err;
-	if (spec->multiout.dig_out_nid)
+	for (i = 0; i < spec->num_mixers; i++) {
+		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+		if (err < 0)
+			return err;
+	}
+	if (spec->multiout.dig_out_nid) {
 		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
-	if (err < 0)
-		return err;
+		if (err < 0)
+			return err;
+	} 
+	if (spec->dig_in_nid) {
+		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+		if (err < 0)
+			return err;
+	}
 	return 0;
 }
 
@@ -152,7 +189,8 @@
 				      snd_pcm_substream_t *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   stream_tag, 0, format);
 	return 0;
 }
 
@@ -161,7 +199,8 @@
 				      snd_pcm_substream_t *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
-	snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   0, 0, 0);
 	return 0;
 }
 
@@ -171,7 +210,7 @@
 static struct hda_pcm_stream ad198x_pcm_analog_playback = {
 	.substreams = 1,
 	.channels_min = 2,
-	.channels_max = 6,
+	.channels_max = 6, /* changed later */
 	.nid = 0, /* fill later */
 	.ops = {
 		.open = ad198x_playback_pcm_open,
@@ -181,7 +220,7 @@
 };
 
 static struct hda_pcm_stream ad198x_pcm_analog_capture = {
-	.substreams = 2,
+	.substreams = 1,
 	.channels_min = 2,
 	.channels_max = 2,
 	.nid = 0, /* fill later */
@@ -202,6 +241,13 @@
 	},
 };
 
+static struct hda_pcm_stream ad198x_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+};
+
 static int ad198x_build_pcms(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
@@ -215,7 +261,8 @@
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
 	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
-	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 
 	if (spec->multiout.dig_out_nid) {
 		info++;
@@ -223,6 +270,10 @@
 		info->name = "AD198x Digital";
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
 	}
 
 	return 0;
@@ -237,10 +288,15 @@
 static int ad198x_resume(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec = codec->spec;
+	int i;
 
 	ad198x_init(codec);
-	snd_hda_resume_ctls(codec, spec->mixers);
-	snd_hda_resume_spdif_out(codec);
+	for (i = 0; i < spec->num_mixers; i++)
+		snd_hda_resume_ctls(codec, spec->mixers[i]);
+	if (spec->multiout.dig_out_nid)
+		snd_hda_resume_spdif_out(codec);
+	if (spec->dig_in_nid)
+		snd_hda_resume_spdif_in(codec);
 	return 0;
 }
 #endif
@@ -269,6 +325,7 @@
 static hda_nid_t ad1986a_dac_nids[3] = {
 	AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
 };
+static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
 
 static struct hda_input_mux ad1986a_capture_source = {
 	.num_items = 7,
@@ -476,10 +533,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
 	spec->multiout.dac_nids = ad1986a_dac_nids;
 	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
-	spec->adc_nid = AD1986A_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1986a_adc_nids;
 	spec->input_mux = &ad1986a_capture_source;
-	spec->mixers = ad1986a_mixers;
-	spec->init_verbs = ad1986a_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1986a_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1986a_init_verbs;
 
 	codec->patch_ops = ad198x_patch_ops;
 
@@ -495,6 +555,7 @@
 #define AD1983_ADC		0x04
 
 static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
+static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
 
 static struct hda_input_mux ad1983_capture_source = {
 	.num_items = 4,
@@ -619,6 +680,7 @@
 	{ } /* end */
 };
 
+
 static int patch_ad1983(struct hda_codec *codec)
 {
 	struct ad198x_spec *spec;
@@ -634,10 +696,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
 	spec->multiout.dac_nids = ad1983_dac_nids;
 	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
-	spec->adc_nid = AD1983_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1983_adc_nids;
 	spec->input_mux = &ad1983_capture_source;
-	spec->mixers = ad1983_mixers;
-	spec->init_verbs = ad1983_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1983_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1983_init_verbs;
 	spec->spdif_route = 0;
 
 	codec->patch_ops = ad198x_patch_ops;
@@ -655,6 +720,7 @@
 #define AD1981_ADC		0x04
 
 static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
+static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
 
 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
 static struct hda_input_mux ad1981_capture_source = {
@@ -775,10 +841,13 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
 	spec->multiout.dac_nids = ad1981_dac_nids;
 	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
-	spec->adc_nid = AD1981_ADC;
+	spec->num_adc_nids = 1;
+	spec->adc_nids = ad1981_adc_nids;
 	spec->input_mux = &ad1981_capture_source;
-	spec->mixers = ad1981_mixers;
-	spec->init_verbs = ad1981_init_verbs;
+	spec->num_mixers = 1;
+	spec->mixers[0] = ad1981_mixers;
+	spec->num_init_verbs = 1;
+	spec->init_verbs[0] = ad1981_init_verbs;
 	spec->spdif_route = 0;
 
 	codec->patch_ops = ad198x_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7327deb..cffb83f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -57,6 +57,7 @@
 enum {
 	ALC260_BASIC,
 	ALC260_HP,
+	ALC260_FUJITSU_S702x,
 	ALC260_MODEL_LAST /* last tag */
 };
 
@@ -72,6 +73,7 @@
 #define PIN_VREF50	0x21
 #define PIN_OUT		0x40
 #define PIN_HP		0xc0
+#define PIN_HP_AMP	0x80
 
 struct alc_spec {
 	/* codec parameterization */
@@ -113,8 +115,6 @@
 	/* PCM information */
 	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
 
-	struct semaphore bind_mutex;	/* for bound controls */
-
 	/* dynamic controls, init_verbs and input_mux */
 	struct auto_pin_cfg autocfg;
 	unsigned int num_kctl_alloc, num_kctl_used;
@@ -218,72 +218,53 @@
 
 
 /*
- * bound volume controls
- *
- * bind multiple volumes (# indices, from 0)
+ * Control of pin widget settings via the mixer.  Only boolean settings are
+ * supported, so VrefEn can't be controlled using these functions as they
+ * stand.
  */
-
-#define AMP_VAL_IDX_SHIFT	19
-#define AMP_VAL_IDX_MASK	(0x0f<<19)
-
-static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
-
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
-	snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
 	return 0;
 }
 
-static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	long mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
 
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
-	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	*valp = 0;
+	if (snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00) & mask)
+		*valp = 1;
 	return 0;
 }
 
-static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	unsigned long pval;
-	int i, indices, change = 0;
+	hda_nid_t nid = kcontrol->private_value & 0xffff;
+	long mask = (kcontrol->private_value >> 16) & 0xff;
+	long *valp = ucontrol->value.integer.value;
+	unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
+	int change = ((pinctl & mask)!=0) != *valp;
 
-	down(&spec->bind_mutex);
-	pval = kcontrol->private_value;
-	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
-	for (i = 0; i < indices; i++) {
-		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
-		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
-	}
-	kcontrol->private_value = pval;
-	up(&spec->bind_mutex);
+	if (change)
+		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
+			*valp?(pinctl|mask):(pinctl&~mask));
 	return change;
 }
 
-#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+#define ALC_PINCTL_SWITCH(xname, nid, mask) \
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .info = alc_bind_switch_info, \
-	  .get = alc_bind_switch_get, \
-	  .put = alc_bind_switch_put, \
-	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
-
-#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
-
+	  .info = alc_pinctl_switch_info, \
+	  .get = alc_pinctl_switch_get, \
+	  .put = alc_pinctl_switch_put, \
+	  .private_value = (nid) | (mask<<16) }
 
 /*
  * ALC880 3-stack model
@@ -354,13 +335,13 @@
 
 static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -441,7 +422,7 @@
 /* additional mixers to alc880_three_stack_mixer */
 static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
 	{ } /* end */
 };
 
@@ -498,15 +479,15 @@
 
 static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -566,13 +547,13 @@
 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
 static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	{ } /* end */
 };
@@ -597,9 +578,9 @@
 
 static snd_kcontrol_new_t alc880_z71v_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -623,9 +604,9 @@
 
 static snd_kcontrol_new_t alc880_f1734_mixer[] = {
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -648,13 +629,13 @@
 
 static snd_kcontrol_new_t alc880_asus_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -1383,10 +1364,10 @@
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	PIN_CTL_TEST("Front Pin Mode", 0x14),
 	PIN_CTL_TEST("Surround Pin Mode", 0x15),
 	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
@@ -1769,7 +1750,7 @@
 static snd_kcontrol_new_t alc880_control_templates[] = {
 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
-	ALC_BIND_MUTE(NULL, 0, 0, 0),
+	HDA_BIND_MUTE(NULL, 0, 0, 0),
 };
 
 /* add dynamic controls */
@@ -2087,7 +2068,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
@@ -2205,6 +2185,17 @@
 	},
 };
 
+/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack
+ * and the internal CD lines.
+ */
+static struct hda_input_mux alc260_fujitsu_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "Mic/Line", 0x0 },
+		{ "CD", 0x4 },
+	},
+};
+
 /*
  * This is just place-holder, so there's something for alc_build_pcms to look
  * at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -2217,7 +2208,7 @@
 
 static snd_kcontrol_new_t alc260_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2229,9 +2220,9 @@
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
 	{
@@ -2246,7 +2237,7 @@
 
 static snd_kcontrol_new_t alc260_hp_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2256,9 +2247,9 @@
 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
 	{
@@ -2271,6 +2262,30 @@
 	{ } /* end */
 };
 
+static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
+	ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
 static struct hda_verb alc260_init_verbs[] = {
 	/* Line In pin widget for input */
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -2332,6 +2347,60 @@
 	{ }
 };
 
+/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
+ * laptops.
+ */
+static struct hda_verb alc260_fujitsu_init_verbs[] = {
+	/* Disable all GPIOs */
+	{0x01, AC_VERB_SET_GPIO_MASK, 0},
+	/* Internal speaker is connected to headphone pin */
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+        /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
+        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+        /* Ensure all other unused pins are disabled and muted.
+	 * Note: trying to set widget 0x15 to anything blocks all audio
+	 * output for some reason, so just leave that at the default.
+	 */
+        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
+        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+        /* Disable digital (SPDIF) pins */
+        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
+        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
+
+        /* Start with mixer outputs muted */
+        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+        /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
+        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+        /* Unmute Line1 pin widget amp left and right (no equiv mixer ctrl) */
+        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Unmute pin widget used for Line-in (no equiv mixer ctrl) */
+        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+        /* Mute capture amp left and right */
+        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+        /* Set ADC connection select to line in (on mic1 pin) */
+        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+        /* Mute all inputs to mixer widget (even unconnected ones) */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
+        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+};
+
 static struct hda_pcm_stream alc260_pcm_analog_playback = {
 	.substreams = 1,
 	.channels_min = 2,
@@ -2347,6 +2416,8 @@
 static struct hda_board_config alc260_cfg_tbl[] = {
 	{ .modelname = "hp", .config = ALC260_HP },
 	{ .pci_subvendor = 0x103c, .config = ALC260_HP },
+	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x },
+	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x },
 	{}
 };
 
@@ -2359,7 +2430,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
@@ -2373,14 +2443,23 @@
 		spec->mixers[spec->num_mixers] = alc260_hp_mixer;
 		spec->num_mixers++;
 		break;
+	case ALC260_FUJITSU_S702x:
+		spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer;
+		spec->num_mixers++;
+		break;
 	default:
 		spec->mixers[spec->num_mixers] = alc260_base_mixer;
 		spec->num_mixers++;
 		break;
 	}
 
-	spec->init_verbs[0] = alc260_init_verbs;
-	spec->num_init_verbs = 1;
+	if (board_config != ALC260_FUJITSU_S702x) {
+		spec->init_verbs[0] = alc260_init_verbs;
+		spec->num_init_verbs = 1;
+	} else {
+		spec->init_verbs[0] = alc260_fujitsu_init_verbs;
+		spec->num_init_verbs = 1;
+	}
 
 	spec->channel_mode = alc260_modes;
 	spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
@@ -2393,7 +2472,11 @@
 	spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
 	spec->multiout.dac_nids = alc260_dac_nids;
 
-	spec->input_mux = &alc260_capture_source;
+	if (board_config != ALC260_FUJITSU_S702x) {
+		spec->input_mux = &alc260_capture_source;
+	} else {
+		spec->input_mux = &alc260_fujitsu_capture_source;
+	}
 	switch (board_config) {
 	case ALC260_HP:
 		spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
@@ -2483,15 +2566,15 @@
  */
 static snd_kcontrol_new_t alc882_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -2609,7 +2692,6 @@
 	if (spec == NULL)
 		return -ENOMEM;
 
-	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	spec->mixers[spec->num_mixers] = alc882_base_mixer;
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index d014b7b..9c7fe0b 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -3,7 +3,7 @@
  *
  * HD audio interface patch for Silicon Labs 3054/5 modem codec
  *
- * Copyright (c) 2005 Sasha Khapyorsky <sashak@smlink.com>
+ * Copyright (c) 2005 Sasha Khapyorsky <sashak@alsa-project.org>
  *                    Takashi Iwai <tiwai@suse.de>
  *
  *
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 2e0a316..db12b03 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -960,7 +960,7 @@
 	if (change)
 		wm_put(ice, WM_ADC_MUX, nval);
 	snd_ice1712_restore_gpio_status(ice);
-	return 0;
+	return change;
 }
 
 /*
@@ -1672,9 +1672,9 @@
 		snd_ice1712_save_gpio_status(ice);
 		id = aureon_cs8415_get(ice, CS8415_ID);
 		if (id != 0x41)
-			snd_printk("No CS8415 chip. Skipping CS8415 controls.\n");
+			snd_printk(KERN_INFO "No CS8415 chip. Skipping CS8415 controls.\n");
 		else if ((id & 0x0F) != 0x01)
-			snd_printk("Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
+			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
 		else {
 			for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
 				snd_kcontrol_t *kctl;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 39fbe66..576f69d 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -546,7 +546,7 @@
 	case ICE1712_SUBDEVICE_DELTA1010LT:
 	case ICE1712_SUBDEVICE_VX442:
 		if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
-			snd_printk("unable to create I2C bus\n");
+			snd_printk(KERN_ERR "unable to create I2C bus\n");
 			return err;
 		}
 		ice->i2c->private_data = ice;
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index e36efa1..c8ec5ca 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -438,7 +438,7 @@
 
 	/* create i2c */
 	if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
-		snd_printk("unable to create I2C bus\n");
+		snd_printk(KERN_ERR "unable to create I2C bus\n");
 		return err;
 	}
 	ice->i2c->private_data = ice;
@@ -448,7 +448,7 @@
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DMX6FIRE:
 		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
-			snd_printk("PCF9554 initialization failed\n");
+			snd_printk(KERN_ERR "PCF9554 initialization failed\n");
 			return err;
 		}
 		snd_ice1712_6fire_write_pca(ice, PCF9554_REG_CONFIG, 0x80);
@@ -791,7 +791,7 @@
 	byte = 0;
 	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
-		printk("cannot read pca\n");
+		printk(KERN_ERR "cannot read pca\n");
 		return -EIO;
 	}
 	snd_i2c_unlock(ice->i2c);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index a6d9801..5aca377 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -387,7 +387,7 @@
 	if ((err = snd_cs8427_create(ice->i2c, addr,
 				     (ice->cs8427_timeout * HZ) / 1000,
 				     &ice->cs8427)) < 0) {
-		snd_printk("CS8427 initialization failed\n");
+		snd_printk(KERN_ERR "CS8427 initialization failed\n");
 		return err;
 	}
 	ice->spdif.ops.open = open_cs8427;
@@ -2348,12 +2348,12 @@
 	if (ice->eeprom.size < 6)
 		ice->eeprom.size = 32; /* FIXME: any cards without the correct size? */
 	else if (ice->eeprom.size > 32) {
-		snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
+		snd_printk(KERN_ERR "invalid EEPROM (size = %i)\n", ice->eeprom.size);
 		return -EIO;
 	}
 	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
 	if (ice->eeprom.version != 1) {
-		snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
+		snd_printk(KERN_ERR "invalid EEPROM version %i\n", ice->eeprom.version);
 		/* return -EIO; */
 	}
 	size = ice->eeprom.size - 6;
@@ -2524,7 +2524,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2573,7 +2573,7 @@
 	ice->profi_port = pci_resource_start(pci, 3);
 
 	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ice1712_free(ice);
 		return -EIO;
 	}
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c3ce8f9..5b4293f 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -675,9 +675,12 @@
 				 SNDRV_PCM_INFO_MMAP_VALID |
 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
 	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =	        SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+	.rates =	        (SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100|
+				 SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_88200|
+				 SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_176400|
+				 SNDRV_PCM_RATE_192000),
 	.rate_min =		32000,
-	.rate_max =		48000,
+	.rate_max =		192000,
 	.channels_min =		2,
 	.channels_max =		2,
 	.buffer_bytes_max =	(1UL << 18),	/* 16bits dword */
@@ -905,6 +908,10 @@
 	case 44100: break;
 	case 48000: nval |= 2 << 12; break;
 	case 32000: nval |= 3 << 12; break;
+	case 88200: nval |= 4 << 12; break;
+	case 96000: nval |= 5 << 12; break;
+	case 192000: nval |= 6 << 12; break;
+	case 176400: nval |= 7 << 12; break;
 	}
 	if (val != nval)
 		update_spdif_bits(ice, nval);
@@ -1292,22 +1299,32 @@
 
 static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
 {
-	unsigned int val;
+	unsigned int val, rbits;
 
 	val = diga->status[0] & 0x03; /* professional, non-audio */
 	if (val & 0x01) {
 		/* professional */
 		if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
 			val |= 1U << 3;
-		switch (diga->status[0] & IEC958_AES0_PRO_FS) {
-		case IEC958_AES0_PRO_FS_44100:
-			break;
-		case IEC958_AES0_PRO_FS_32000:
-			val |= 3U << 12;
-			break;
-		default:
-			val |= 2U << 12;
-			break;
+		rbits = (diga->status[4] >> 3) & 0x0f;
+		if (rbits) {
+			switch (rbits) {
+			case 2: val |= 5 << 12; break; /* 96k */
+			case 3: val |= 6 << 12; break; /* 192k */
+			case 10: val |= 4 << 12; break; /* 88.2k */
+			case 11: val |= 7 << 12; break; /* 176.4k */
+			}
+		} else {
+			switch (diga->status[0] & IEC958_AES0_PRO_FS) {
+			case IEC958_AES0_PRO_FS_44100:
+				break;
+			case IEC958_AES0_PRO_FS_32000:
+				val |= 3U << 12;
+				break;
+			default:
+				val |= 2U << 12;
+				break;
+			}
 		}
 	} else {
 		/* consumer */
@@ -2154,7 +2171,7 @@
 	ice->profi_port = pci_resource_start(pci, 1);
 
 	if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vt1724_free(ice);
 		return -EIO;
 	}
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index a5f852b..773a1ec 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -794,8 +794,7 @@
 	/* initialize WM8776 codec */
 	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
 		wm_put(ice, wm_inits[i], wm_inits[i+1]);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 	for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
 		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
 
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index d48d425..1fe2100 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -128,17 +128,6 @@
 	.mask_flags = 0,
 };
 
-static unsigned int rates[] = {
-	32000, 44100, 48000, 64000, 88200, 96000,
-	176400, 192000,
-};
-
-static snd_pcm_hw_constraint_list_t revo_rates = {
-	.count = ARRAY_SIZE(rates),
-	.list = rates,
-	.mask = 0,
-};
-
 static int __devinit revo_init(ice1712_t *ice)
 {
 	akm4xxx_t *ak;
@@ -173,8 +162,6 @@
 		break;
 	}
 
-	ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
-
 	return 0;
 }
 
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index ab61e38..90c85cd 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -71,6 +71,22 @@
 	0x00,	/* - */
 };
 
+static unsigned char sn25p_eeprom[] __devinitdata = {
+	0x01,	/* SYSCONF: clock 256, 1ADC, 2DACs */
+	0x02,	/* ACLINK: ACLINK, packed */
+	0x00,	/* I2S: - */
+	0x41,	/* SPDIF: - */
+	0xff,	/* GPIO_DIR */
+	0xff,	/* GPIO_DIR1 */
+	0x00,	/* - */
+	0xff,	/* GPIO_MASK */
+	0xff,	/* GPIO_MASK1 */
+	0x00,	/* - */
+	0x00,	/* GPIO_STATE */
+	0x00,	/* GPIO_STATE1 */
+	0x00,	/* - */
+};
+
 
 /* entry point */
 struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
@@ -113,11 +129,11 @@
 	{
 		.subvendor = VT1720_SUBDEVICE_SN25P,
 		.name = "Shuttle SN25P",
-		/* identical with k8x800 */
+		.model = "sn25p",
 		.chip_init = k8x800_init,
 		.build_controls = k8x800_add_controls,
 		.eeprom_size = sizeof(k8x800_eeprom),
-		.eeprom_data = k8x800_eeprom,
+		.eeprom_data = sn25p_eeprom,
 	},
 	{ } /* terminator */
 };
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 1a96198..0801083 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -64,36 +64,35 @@
 		"{AMD,AMD8111},"
 	        "{ALI,M5455}}");
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
-static char *ac97_quirk[SNDRV_CARDS];
-static int buggy_semaphore[SNDRV_CARDS];
-static int buggy_irq[SNDRV_CARDS];
-static int xbox[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 0;
+static char *ac97_quirk;
+static int buggy_semaphore;
+static int buggy_irq = -1; /* auto-check */
+static int xbox;
 
-#ifdef SUPPORT_MIDI
-static int mpu_port[SNDRV_CARDS]; /* disabled */
-#endif
-
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 soundcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(buggy_semaphore, bool, NULL, 0444);
+module_param(buggy_semaphore, bool, 0444);
 MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param_array(buggy_irq, bool, NULL, 0444);
+module_param(buggy_irq, bool, 0444);
 MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
-module_param_array(xbox, bool, NULL, 0444);
+module_param(xbox, bool, 0444);
 MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+static int joystick;
+module_param(joystick, int, 0444);
+
 /*
  *  Direct registers
  */
@@ -539,7 +538,7 @@
 	/* access to some forbidden (non existant) ac97 registers will not
 	 * reset the semaphore. So even if you don't get the semaphore, still
 	 * continue the access. We don't need the semaphore anyway. */
-	snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+	snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
 			igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
 	iagetword(chip, 0);	/* clear semaphore flag */
 	/* I don't care about the semaphore */
@@ -554,7 +553,7 @@
 	
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
@@ -568,7 +567,7 @@
 
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 		res = 0xffff;
 	} else {
 		res = iagetword(chip, reg + ac97->num * 0x80);
@@ -576,7 +575,7 @@
 			/* reset RCS and preserve other R/WC bits */
 			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
-				snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
 		}
 	}
@@ -607,16 +606,19 @@
 		if (val & mask)
 			return 0;
 	}
-	snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
+	if (! chip->in_ac97_init)
+		snd_printd(KERN_WARNING "intel8x0: AC97 codec ready timeout.\n");
 	return -EBUSY;
 }
 
 static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
 {
 	int time = 100;
+	if (chip->buggy_semaphore)
+		return 0; /* just ignore ... */
 	while (time-- && (igetdword(chip, ICHREG(ALI_CAS)) & ALI_CAS_SEM_BUSY))
 		udelay(1);
-	if (! time)
+	if (! time && ! chip->in_ac97_init)
 		snd_printk(KERN_WARNING "ali_codec_semaphore timeout\n");
 	return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
 }
@@ -1716,6 +1718,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x1025,
+		.subdevice = 0x0083,
+		.name = "Acer Aspire 3003LCi",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.subvendor = 0x1028,
 		.subdevice = 0x00d8,
 		.name = "Dell Precision 530",	/* AD1885 */
@@ -1758,6 +1766,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x1028,
+		.subdevice = 0x0191,
+		.name = "Dell Inspiron 8600",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
 		.subvendor = 0x103c,
 		.subdevice = 0x006d,
 		.name = "HP zv5000",
@@ -2022,7 +2036,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, ops, chip, &pbus)) < 0)
 		goto __err;
 	pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
-	pbus->shared_type = AC97_SHARED_TYPE_ICH;	/* shared with modem driver */
 	if (ac97_clock >= 8000 && ac97_clock <= 48000)
 		pbus->clock = ac97_clock;
 	/* FIXME: my test board doesn't work well with VRA... */
@@ -2131,14 +2144,13 @@
 	iputdword(chip, ICHREG(ALI_FIFOCR2), 0x83838383);
 	iputdword(chip, ICHREG(ALI_FIFOCR3), 0x83838383);
 	iputdword(chip, ICHREG(ALI_INTERFACECR),
-		  ICH_ALI_IF_MC|ICH_ALI_IF_PI|ICH_ALI_IF_PO);
+		  ICH_ALI_IF_PI|ICH_ALI_IF_PO);
 	iputdword(chip, ICHREG(ALI_INTERRUPTCR), 0x00000000);
 	iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
 }
 
 #define do_delay(chip) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(1);\
+	schedule_timeout_uninterruptible(1);\
 } while (0)
 
 static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
@@ -2166,7 +2178,7 @@
 			goto __ok;
 		do_delay(chip);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -2441,7 +2453,7 @@
 
 	subs = chip->pcm[0]->streams[0].substream;
 	if (! subs || subs->dma_buffer.bytes < INTEL8X0_TESTBUF_SIZE) {
-		snd_printk("no playback buffer allocated - aborting measure ac97 clock\n");
+		snd_printk(KERN_WARNING "no playback buffer allocated - aborting measure ac97 clock\n");
 		return;
 	}
 	ichdev = &chip->ichd[ICHD_PCMOUT];
@@ -2477,7 +2489,7 @@
 	do_gettimeofday(&stop_time);
 	/* stop */
 	if (chip->device_type == DEVICE_ALI) {
-		iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 8));
+		iputdword(chip, ICHREG(ALI_DMACR), 1 << (ichdev->ali_slot + 16));
 		iputbyte(chip, port + ICH_REG_OFF_CR, 0);
 		while (igetbyte(chip, port + ICH_REG_OFF_CR))
 			;
@@ -2556,7 +2568,6 @@
 static int __devinit snd_intel8x0_create(snd_card_t * card,
 					 struct pci_dev *pci,
 					 unsigned long device_type,
-					 int buggy_sem,
 					 intel8x0_t ** r_intel8x0)
 {
 	intel8x0_t *chip;
@@ -2614,18 +2625,17 @@
 	chip->card = card;
 	chip->pci = pci;
 	chip->irq = -1;
-	chip->buggy_semaphore = buggy_sem;
+
+	/* module parameters */
+	chip->buggy_irq = buggy_irq;
+	chip->buggy_semaphore = buggy_semaphore;
+	if (xbox)
+		chip->xbox = 1;
 
 	if (pci->vendor == PCI_VENDOR_ID_INTEL &&
 	    pci->device == PCI_DEVICE_ID_INTEL_440MX)
 		chip->fix_nocache = 1; /* enable workaround */
 
-	/* some Nforce[2] and ICH boards have problems with IRQ handling.
-	 * Needs to return IRQ_HANDLED for unknown irqs.
-	 */
-	if (device_type == DEVICE_NFORCE)
-		chip->buggy_irq = 1;
-
 	if ((err = pci_request_regions(pci, card->shortname)) < 0) {
 		kfree(chip);
 		pci_disable_device(pci);
@@ -2644,7 +2654,7 @@
 		chip->remap_addr = ioremap_nocache(chip->addr,
 						   pci_resource_len(pci, 2));
 		if (chip->remap_addr == NULL) {
-			snd_printk("AC'97 space ioremap problem\n");
+			snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -2657,7 +2667,7 @@
 		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
 						     pci_resource_len(pci, 3));
 		if (chip->remap_bmaddr == NULL) {
-			snd_printk("Controller space ioremap problem\n");
+			snd_printk(KERN_ERR "Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -2666,15 +2676,6 @@
 	}
 
  port_inited:
-	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		snd_intel8x0_free(chip);
-		return -EBUSY;
-	}
-	chip->irq = pci->irq;
-	pci_set_master(pci);
-	synchronize_irq(chip->irq);
-
 	chip->bdbars_count = bdbars[device_type];
 
 	/* initialize offsets */
@@ -2725,13 +2726,27 @@
 	int_sta_masks = 0;
 	for (i = 0; i < chip->bdbars_count; i++) {
 		ichdev = &chip->ichd[i];
-		ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
-		ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
+		ichdev->bdbar = ((u32 *)chip->bdbars.area) +
+			(i * ICH_MAX_FRAGS * 2);
+		ichdev->bdbar_addr = chip->bdbars.addr +
+			(i * sizeof(u32) * ICH_MAX_FRAGS * 2);
 		int_sta_masks |= ichdev->int_sta_mask;
 	}
-	chip->int_sta_reg = device_type == DEVICE_ALI ? ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
+	chip->int_sta_reg = device_type == DEVICE_ALI ?
+		ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA;
 	chip->int_sta_mask = int_sta_masks;
 
+	/* request irq after initializaing int_sta_mask, etc */
+	if (request_irq(pci->irq, snd_intel8x0_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		snd_intel8x0_free(chip);
+		return -EBUSY;
+	}
+	chip->irq = pci->irq;
+	pci_set_master(pci);
+	synchronize_irq(chip->irq);
+
 	if ((err = snd_intel8x0_chip_init(chip, 1)) < 0) {
 		snd_intel8x0_free(chip);
 		return err;
@@ -2782,20 +2797,12 @@
 static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	intel8x0_t *chip;
 	int err;
 	struct shortname_table *name;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -2819,17 +2826,23 @@
 		}
 	}
 
+	if (buggy_irq < 0) {
+		/* some Nforce[2] and ICH boards have problems with IRQ handling.
+		 * Needs to return IRQ_HANDLED for unknown irqs.
+		 */
+		if (pci_id->driver_data == DEVICE_NFORCE)
+			buggy_irq = 1;
+		else
+			buggy_irq = 0;
+	}
+
 	if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data,
-				       buggy_semaphore[dev], &chip)) < 0) {
+				       &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	if (buggy_irq[dev])
-		chip->buggy_irq = 1;
-	if (xbox[dev])
-		chip->xbox = 1;
 
-	if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) {
+	if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2844,7 +2857,7 @@
 		 "%s with %s at %#lx, irq %i", card->shortname,
 		 snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq);
 
-	if (! ac97_clock[dev])
+	if (! ac97_clock)
 		intel8x0_measure_ac97_clock(chip);
 
 	if ((err = snd_card_register(card)) < 0) {
@@ -2852,7 +2865,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 9e2060d..acfb197 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -3,7 +3,7 @@
  *
  *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
  *
- *   This is modified (by Sasha Khapyorsky <sashak@smlink.com>) version
+ *   This is modified (by Sasha Khapyorsky <sashak@alsa-project.org>) version
  *   of ALSA ICH sound driver intel8x0.c .
  *
  *
@@ -56,20 +56,21 @@
 		"{NVidia,NForce3 Modem},"
 		"{AMD,AMD768}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 0;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel i8x0 modemcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel i8x0 modemcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Intel i8x0 modemcard.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 /*
  *  Direct registers
  */
@@ -362,7 +363,7 @@
 	/* access to some forbidden (non existant) ac97 registers will not
 	 * reset the semaphore. So even if you don't get the semaphore, still
 	 * continue the access. We don't need the semaphore anyway. */
-	snd_printk("codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
+	snd_printk(KERN_ERR "codec_semaphore: semaphore is not ready [0x%x][0x%x]\n",
 			igetbyte(chip, ICHREG(ACC_SEMA)), igetdword(chip, ICHREG(GLOB_STA)));
 	iagetword(chip, 0);	/* clear semaphore flag */
 	/* I don't care about the semaphore */
@@ -377,7 +378,7 @@
 	
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_write %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 	}
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
@@ -391,7 +392,7 @@
 
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
-			snd_printk("codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
+			snd_printk(KERN_ERR "codec_read %d: semaphore is not ready for register 0x%x\n", ac97->num, reg);
 		res = 0xffff;
 	} else {
 		res = iagetword(chip, reg + ac97->num * 0x80);
@@ -399,7 +400,7 @@
 			/* reset RCS and preserve other R/WC bits */
 			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
-				snd_printk("codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
+				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
 		}
 	}
@@ -746,6 +747,7 @@
 
 	pcm->private_data = chip;
 	pcm->info_flags = 0;
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	if (rec->suffix)
 		sprintf(pcm->name, "%s - %s", chip->card->shortname, rec->suffix);
 	else
@@ -854,7 +856,6 @@
 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
 		goto __err;
 	pbus->private_free = snd_intel8x0_mixer_free_ac97_bus;
-	pbus->shared_type = AC97_SHARED_TYPE_ICH;	/* shared with audio driver */
 	if (ac97_clock >= 8000 && ac97_clock <= 48000)
 		pbus->clock = ac97_clock;
 	chip->ac97_bus = pbus;
@@ -889,8 +890,7 @@
  */
 
 #define do_delay(chip) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(1);\
+	schedule_timeout_uninterruptible(1);\
 } while (0)
 
 static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
@@ -916,7 +916,7 @@
 			goto __ok;
 		do_delay(chip);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -1142,7 +1142,7 @@
 		chip->remap_addr = ioremap_nocache(chip->addr,
 						   pci_resource_len(pci, 2));
 		if (chip->remap_addr == NULL) {
-			snd_printk("AC'97 space ioremap problem\n");
+			snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -1155,7 +1155,7 @@
 		chip->remap_bmaddr = ioremap_nocache(chip->bmaddr,
 						     pci_resource_len(pci, 3));
 		if (chip->remap_bmaddr == NULL) {
-			snd_printk("Controller space ioremap problem\n");
+			snd_printk(KERN_ERR "Controller space ioremap problem\n");
 			snd_intel8x0_free(chip);
 			return -EIO;
 		}
@@ -1165,7 +1165,7 @@
 
  port_inited:
 	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
 	}
@@ -1263,20 +1263,12 @@
 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	intel8x0_t *chip;
 	int err;
 	struct shortname_table *name;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1295,7 +1287,7 @@
 		return err;
 	}
 
-	if ((err = snd_intel8x0_mixer(chip, ac97_clock[dev])) < 0) {
+	if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1314,7 +1306,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 2693b6f..99eb76c5 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1492,7 +1492,7 @@
 	/* set buffer address */
 	s->buffer_addr = substream->runtime->dma_addr;
 	if (s->buffer_addr & 0x3) {
-		snd_printk("oh my, not aligned\n");
+		snd_printk(KERN_ERR "oh my, not aligned\n");
 		s->buffer_addr = s->buffer_addr & ~0x3;
 	}
 	return 0;
@@ -1942,7 +1942,7 @@
 			return 0;
 	} while (i-- > 0);
 
-	snd_printk("ac97 serial bus busy\n");
+	snd_printk(KERN_ERR "ac97 serial bus busy\n");
 	return 1;
 }
 
@@ -2046,8 +2046,7 @@
 		outw(0, io + GPIO_DATA);
 		outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION);
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((delay1 * HZ) / 1000);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(delay1));
 
 		outw(GPO_PRIMARY_AC97, io + GPIO_DATA);
 		udelay(5);
@@ -2055,8 +2054,7 @@
 		outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A);
 		outw(~0, io + GPIO_MASK);
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((delay2 * HZ) / 1000);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(delay2));
 
 		if (! snd_m3_try_read_vendor(chip))
 			break;
@@ -2101,8 +2099,7 @@
 
 	/* seems ac97 PCM needs initialization.. hack hack.. */
 	snd_ac97_write(chip->ac97, AC97_PCM, 0x8000 | (15 << 8) | 15);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 10);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(100));
 	snd_ac97_write(chip->ac97, AC97_PCM, 0);
 
 	memset(&id, 0, sizeof(id));
@@ -2367,7 +2364,7 @@
 	address = 0x1100 + ((data_bytes/2) * index);
 
 	if ((address + (data_bytes/2)) >= 0x1c00) {
-		snd_printk("no memory for %d bytes at ind %d (addr 0x%x)\n",
+		snd_printk(KERN_ERR "no memory for %d bytes at ind %d (addr 0x%x)\n",
 			   data_bytes, index, address);
 		return -ENOMEM;
 	}
@@ -2476,6 +2473,7 @@
 	t |= ASSP_0_WS_ENABLE; 
 	outb(t, chip->iobase + ASSP_CONTROL_A);
 
+	snd_m3_assp_init(chip); /* download DSP code before starting ASSP below */
 	outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B); 
 
 	outb(0x00, io + HARDWARE_VOL_CTRL);
@@ -2655,7 +2653,7 @@
 	/* check, if we can restrict PCI DMA transfers to 28 bits */
 	if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 28bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -2734,14 +2732,13 @@
 
 	snd_m3_ac97_reset(chip);
 
-	snd_m3_assp_init(chip);
 	snd_m3_amp_enable(chip, 1);
 
 	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
 
 	if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_m3_free(chip);
 		return -ENOMEM;
 	}
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 1a62c7f..c341c99 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -451,8 +451,7 @@
 			snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
 			return -EBUSY;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 	return 0;
 }
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 5c55a3b..e7aa151 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -52,37 +52,43 @@
  * some compile conditions.
  */
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static int playback_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int capture_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 16};
-static int force_ac97[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled as default */
-static int buffer_top[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* not specified */
-static int use_cache[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int vaio_hack[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* disabled */
-static int reset_workaround[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int playback_bufsize = 16;
+static int capture_bufsize = 16;
+static int force_ac97;			/* disabled as default */
+static int buffer_top;			/* not specified */
+static int use_cache;			/* disabled */
+static int vaio_hack;			/* disabled */
+static int reset_workaround;
+static int reset_workaround_2;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable this soundcard.");
-module_param_array(playback_bufsize, int, NULL, 0444);
+module_param(playback_bufsize, int, 0444);
 MODULE_PARM_DESC(playback_bufsize, "DAC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(capture_bufsize, int, NULL, 0444);
+module_param(capture_bufsize, int, 0444);
 MODULE_PARM_DESC(capture_bufsize, "ADC frame size in kB for " CARD_NAME " soundcard.");
-module_param_array(force_ac97, bool, NULL, 0444);
+module_param(force_ac97, bool, 0444);
 MODULE_PARM_DESC(force_ac97, "Force to use AC97 codec for " CARD_NAME " soundcard.");
-module_param_array(buffer_top, int, NULL, 0444);
+module_param(buffer_top, int, 0444);
 MODULE_PARM_DESC(buffer_top, "Set the top address of audio buffer for " CARD_NAME " soundcard.");
-module_param_array(use_cache, bool, NULL, 0444);
+module_param(use_cache, bool, 0444);
 MODULE_PARM_DESC(use_cache, "Enable the cache for coefficient table access.");
-module_param_array(vaio_hack, bool, NULL, 0444);
+module_param(vaio_hack, bool, 0444);
 MODULE_PARM_DESC(vaio_hack, "Enable workaround for Sony VAIO notebooks.");
-module_param_array(reset_workaround, bool, NULL, 0444);
+module_param(reset_workaround, bool, 0444);
 MODULE_PARM_DESC(reset_workaround, "Enable AC97 RESET workaround for some laptops.");
+module_param(reset_workaround_2, bool, 0444);
+MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops.");
+
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
+
 
 /*
  * hw definitions
@@ -226,6 +232,7 @@
 	unsigned int coeffs_current: 1;	/* coeff. table is loaded? */
 	unsigned int use_cache: 1;	/* use one big coef. table */
 	unsigned int reset_workaround: 1; /* Workaround for some laptops to avoid freeze */
+	unsigned int reset_workaround_2: 1; /* Extended workaround for some other laptops to avoid freeze */
 
 	int mixer_base;			/* register offset of ac97 mixer */
 	int mixer_status_offset;	/* offset of mixer status reg. */
@@ -313,9 +320,9 @@
 snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
 {
 	offset -= chip->buffer_start;
-#ifdef SNDRV_CONFIG_DEBUG
+#ifdef CONFIG_SND_DEBUG
 	if (offset < 0 || offset >= chip->buffer_size) {
-		snd_printk("write_buffer invalid offset = %d size = %d\n", offset, size);
+		snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size);
 		return;
 	}
 #endif
@@ -459,7 +466,7 @@
 	if (chip->irq < 0) {
 		if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
 				chip->card->driver, (void*)chip)) {
-			snd_printk("unable to grab IRQ %d\n", chip->pci->irq);
+			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			up(&chip->irq_mutex);
 			return -EBUSY;
 		}
@@ -1199,8 +1206,11 @@
 		/* Dell latitude LS will lock up by this */
 		snd_nm256_writeb(chip, 0x6cc, 0x87);
 	}
-	snd_nm256_writeb(chip, 0x6cc, 0x80);
-	snd_nm256_writeb(chip, 0x6cc, 0x0);
+	if (! chip->reset_workaround_2) {
+		/* Dell latitude CSx will lock up by this */
+		snd_nm256_writeb(chip, 0x6cc, 0x80);
+		snd_nm256_writeb(chip, 0x6cc, 0x0);
+	}
 }
 
 /* create an ac97 mixer interface */
@@ -1263,7 +1273,7 @@
 
 	temp = ioremap_nocache(chip->buffer_addr + chip->buffer_end - 0x400, 16);
 	if (temp == NULL) {
-		snd_printk("Unable to scan for card signature in video RAM\n");
+		snd_printk(KERN_ERR "Unable to scan for card signature in video RAM\n");
 		return -EBUSY;
 	}
 
@@ -1277,7 +1287,7 @@
 		if (pointer == 0xffffffff ||
 		    pointer < chip->buffer_size ||
 		    pointer > chip->buffer_end) {
-			snd_printk("invalid signature found: 0x%x\n", pointer);
+			snd_printk(KERN_ERR "invalid signature found: 0x%x\n", pointer);
 			iounmap(temp);
 			return -ENODEV;
 		} else {
@@ -1347,14 +1357,8 @@
 		iounmap(chip->cport);
 	if (chip->buffer)
 		iounmap(chip->buffer);
-	if (chip->res_cport) {
-		release_resource(chip->res_cport);
-		kfree_nocheck(chip->res_cport);
-	}
-	if (chip->res_buffer) {
-		release_resource(chip->res_buffer);
-		kfree_nocheck(chip->res_buffer);
-	}
+	release_and_free_resource(chip->res_cport);
+	release_and_free_resource(chip->res_buffer);
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void*)chip);
 
@@ -1420,14 +1424,14 @@
 	chip->res_cport = request_mem_region(chip->cport_addr, NM_PORT2_SIZE,
 					     card->driver);
 	if (chip->res_cport == NULL) {
-		snd_printk("memory region 0x%lx (size 0x%x) busy\n",
+		snd_printk(KERN_ERR "memory region 0x%lx (size 0x%x) busy\n",
 			   chip->cport_addr, NM_PORT2_SIZE);
 		err = -EBUSY;
 		goto __error;
 	}
 	chip->cport = ioremap_nocache(chip->cport_addr, NM_PORT2_SIZE);
 	if (chip->cport == NULL) {
-		snd_printk("unable to map control port %lx\n", chip->cport_addr);
+		snd_printk(KERN_ERR "unable to map control port %lx\n", chip->cport_addr);
 		err = -ENOMEM;
 		goto __error;
 	}
@@ -1485,7 +1489,7 @@
 					      chip->buffer_size,
 					      card->driver);
 	if (chip->res_buffer == NULL) {
-		snd_printk("nm256: buffer 0x%lx (size 0x%x) busy\n",
+		snd_printk(KERN_ERR "nm256: buffer 0x%lx (size 0x%x) busy\n",
 			   chip->buffer_addr, chip->buffer_size);
 		err = -EBUSY;
 		goto __error;
@@ -1493,7 +1497,7 @@
 	chip->buffer = ioremap_nocache(chip->buffer_addr, chip->buffer_size);
 	if (chip->buffer == NULL) {
 		err = -ENOMEM;
-		snd_printk("unable to map ring buffer at %lx\n", chip->buffer_addr);
+		snd_printk(KERN_ERR "unable to map ring buffer at %lx\n", chip->buffer_addr);
 		goto __error;
 	}
 
@@ -1542,7 +1546,7 @@
 	int type;
 };
 
-enum { NM_BLACKLISTED, NM_RESET_WORKAROUND };
+enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
 
 static struct nm256_quirk nm256_quirks[] __devinitdata = {
 	/* HP omnibook 4150 has cs4232 codec internally */
@@ -1551,6 +1555,8 @@
 	{ .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND },
 	/* Dell Latitude LS */
 	{ .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND },
+	/* Dell Latitude CSx */
+	{ .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
 	{ } /* terminator */
 };
 
@@ -1558,7 +1564,6 @@
 static int __devinit snd_nm256_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	nm256_t *chip;
 	int err;
@@ -1566,13 +1571,6 @@
 	struct nm256_quirk *q;
 	u16 subsystem_vendor, subsystem_device;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
 	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
 
@@ -1582,14 +1580,17 @@
 			case NM_BLACKLISTED:
 				printk(KERN_INFO "nm256: The device is blacklisted.  Loading stopped\n");
 				return -ENODEV;
+			case NM_RESET_WORKAROUND_2:
+				reset_workaround_2 = 1;
+				/* Fall-through */
 			case NM_RESET_WORKAROUND:
-				reset_workaround[dev] = 1;
+				reset_workaround = 1;
 				break;
 			}
 		}
 	}
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1604,40 +1605,45 @@
 		strcpy(card->driver, "NM256XL+");
 		break;
 	default:
-		snd_printk("invalid device id 0x%x\n", pci->device);
+		snd_printk(KERN_ERR "invalid device id 0x%x\n", pci->device);
 		snd_card_free(card);
 		return -EINVAL;
 	}
 
-	if (vaio_hack[dev])
+	if (vaio_hack)
 		xbuffer_top = 0x25a800;	/* this avoids conflicts with XFree86 server */
 	else
-		xbuffer_top = buffer_top[dev];
+		xbuffer_top = buffer_top;
 
-	if (playback_bufsize[dev] < 4)
-		playback_bufsize[dev] = 4;
-	if (playback_bufsize[dev] > 128)
-		playback_bufsize[dev] = 128;
-	if (capture_bufsize[dev] < 4)
-		capture_bufsize[dev] = 4;
-	if (capture_bufsize[dev] > 128)
-		capture_bufsize[dev] = 128;
+	if (playback_bufsize < 4)
+		playback_bufsize = 4;
+	if (playback_bufsize > 128)
+		playback_bufsize = 128;
+	if (capture_bufsize < 4)
+		capture_bufsize = 4;
+	if (capture_bufsize > 128)
+		capture_bufsize = 128;
 	if ((err = snd_nm256_create(card, pci,
-				    playback_bufsize[dev] * 1024, /* in bytes */
-				    capture_bufsize[dev] * 1024,  /* in bytes */
-				    force_ac97[dev],
+				    playback_bufsize * 1024, /* in bytes */
+				    capture_bufsize * 1024,  /* in bytes */
+				    force_ac97,
 				    xbuffer_top,
-				    use_cache[dev],
+				    use_cache,
 				    &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
-	if (reset_workaround[dev]) {
+	if (reset_workaround) {
 		snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
 		chip->reset_workaround = 1;
 	}
 
+	if (reset_workaround_2) {
+		snd_printdd(KERN_INFO "nm256: reset_workaround_2 activated\n");
+		chip->reset_workaround_2 = 1;
+	}
+
 	if ((err = snd_nm256_pcm(chip, 0)) < 0 ||
 	    (err = snd_nm256_mixer(chip)) < 0) {
 		snd_card_free(card);
@@ -1655,7 +1661,6 @@
 	}
 
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 }
 
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cd313af..e6627b0 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1369,13 +1369,13 @@
 	rme32->port = pci_resource_start(rme32->pci, 0);
 
 	if (request_irq(pci->irq, snd_rme32_interrupt, SA_INTERRUPT | SA_SHIRQ, "RME32", (void *) rme32)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme32->irq = pci->irq;
 
 	if ((rme32->iobase = ioremap_nocache(rme32->port, RME32_IO_SIZE)) == 0) {
-		snd_printk("unable to remap memory region 0x%lx-0x%lx\n",
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n",
 			   rme32->port, rme32->port + RME32_IO_SIZE - 1);
 		return -ENOMEM;
 	}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index c495cae..0eddeb1 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1570,13 +1570,13 @@
 	rme96->port = pci_resource_start(rme96->pci, 0);
 
 	if (request_irq(pci->irq, snd_rme96_interrupt, SA_INTERRUPT|SA_SHIRQ, "RME96", (void *)rme96)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme96->irq = pci->irq;
 
 	if ((rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE)) == 0) {
-		snd_printk("unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
+		snd_printk(KERN_ERR "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1);
 		return -ENOMEM;
 	}
 
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 52525eb..845158b 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -671,11 +671,7 @@
 			}
 		}
 
-		if ((1000 / HZ) < 3000) {
-			ssleep(3);
-		} else {
-			mdelay(3000);
-		}
+		ssleep(3);
 		
 		if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
 			snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
@@ -692,7 +688,7 @@
 		
 	}
 	if (hdsp->state & HDSP_InitializationComplete) {
-		snd_printk("Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
+		snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
 		spin_lock_irqsave(&hdsp->lock, flags);
 		snd_hdsp_set_defaults(hdsp);
 		spin_unlock_irqrestore(&hdsp->lock, flags); 
@@ -709,9 +705,8 @@
 	
 		hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
 		hdsp_write (hdsp, HDSP_fifoData, 0);
-		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
 			return -EIO;
-		}
 
 		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
 		hdsp_write (hdsp, HDSP_fifoData, 0);
@@ -726,22 +721,30 @@
 		} 
 	} else {
 		/* firmware was already loaded, get iobox type */
-		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
 			hdsp->io_type = Multiface;
-		} else {
+		else
 			hdsp->io_type = Digiface;
-		}
 	}
 	return 0;
 }
 
 
-static int hdsp_check_for_firmware (hdsp_t *hdsp)
+static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
 {
 	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
-		snd_printk("Hammerfall-DSP: firmware not present.\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");
 		hdsp->state &= ~HDSP_FirmwareLoaded;
+		if (! show_err)
+			return -EIO;
+		/* try to load firmware */
+		if (hdsp->state & HDSP_FirmwareCached) {
+			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)
+				snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
+		} else {
+			snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
+		}
 		return -EIO;
 	}
 	return 0;
@@ -775,9 +778,9 @@
 
 static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
 {
-	if (addr >= HDSP_MATRIX_MIXER_SIZE) {
+	if (addr >= HDSP_MATRIX_MIXER_SIZE)
 		return 0;
-	}
+
 	return hdsp->mixer_matrix[addr];
 }
 
@@ -802,13 +805,11 @@
 		   memory."
 		*/
 
-		if (hdsp->io_type == H9632 && addr >= 512) {
+		if (hdsp->io_type == H9632 && addr >= 512)
 			return 0;
-		}
 
-		if (hdsp->io_type == H9652 && addr >= 1352) {
+		if (hdsp->io_type == H9652 && addr >= 1352)
 			return 0;
-		}
 
 		hdsp->mixer_matrix[addr] = data;
 
@@ -832,9 +833,8 @@
 
 		ad = (addr << 16) + data;
 		
-		if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT)) {
+		if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))
 			return -1;
-		}
 
 		hdsp_write (hdsp, HDSP_fifoData, ad);
 		hdsp->mixer_matrix[addr] = data;
@@ -851,9 +851,8 @@
 
 	spin_lock_irqsave(&hdsp->lock, flags);
 	if ((hdsp->playback_pid != hdsp->capture_pid) &&
-	    (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0)) {
+	    (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))
 		ret = 0;
-	}
 	spin_unlock_irqrestore(&hdsp->lock, flags);
 	return ret;
 }
@@ -880,9 +879,8 @@
 	unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
 	unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
 
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		return 0;
-	}
 	
 	switch (rate_bits) {
 	case HDSP_spdifFrequency32KHz: return 32000;
@@ -918,9 +916,8 @@
 
 	position = hdsp_read(hdsp, HDSP_statusRegister);
 
-	if (!hdsp->precise_ptr) {
+	if (!hdsp->precise_ptr)
 		return (position & HDSP_BufferID) ? (hdsp->period_bytes / 4) : 0;
-	}
 
 	position &= HDSP_BufferPositionMask;
 	position /= 4;
@@ -989,19 +986,19 @@
 	if (!(hdsp->control_register & HDSP_ClockModeMaster)) {	
 		if (called_internally) {
 			/* request from ctl or card initialization */
-			snd_printk("Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: device is not running as a clock master: cannot set sample rate.\n");
 			return -1;
 		} else {		
 			/* hw_param request while in AutoSync mode */
 			int external_freq = hdsp_external_sample_rate(hdsp);
 			int spdif_freq = hdsp_spdif_sample_rate(hdsp);
 		
-			if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
-				snd_printk("Hammerfall-DSP: Detected ADAT in double speed mode\n");
-			} else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1)) {
-				snd_printk("Hammerfall-DSP: Detected ADAT in quad speed mode\n");			
-			} else if (rate != external_freq) {
-				snd_printk("Hammerfall-DSP: No AutoSync source for requested rate\n");
+			if ((spdif_freq == external_freq*2) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+				snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in double speed mode\n");
+			else if (hdsp->io_type == H9632 && (spdif_freq == external_freq*4) && (hdsp_autosync_ref(hdsp) >= HDSP_AUTOSYNC_FROM_ADAT1))
+				snd_printk(KERN_INFO "Hammerfall-DSP: Detected ADAT in quad speed mode\n");			
+			else if (rate != external_freq) {
+				snd_printk(KERN_INFO "Hammerfall-DSP: No AutoSync source for requested rate\n");
 				return -1;
 			}		
 		}	
@@ -1019,63 +1016,53 @@
 	   exists for externally-driven rate changes. All we can do
 	   is to flag rate changes in the read/write routines.  */
 
-	if (rate > 96000 && hdsp->io_type != H9632) {
+	if (rate > 96000 && hdsp->io_type != H9632)
 		return -EINVAL;
-	}
 	
 	switch (rate) {
 	case 32000:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency32KHz;
 		break;
 	case 44100:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency44_1KHz;
 		break;
 	case 48000:
-		if (current_rate > 48000) {
+		if (current_rate > 48000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency48KHz;
 		break;
 	case 64000:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency64KHz;
 		break;
 	case 88200:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency88_2KHz;
 		break;
 	case 96000:
-		if (current_rate <= 48000 || current_rate > 96000) {
+		if (current_rate <= 48000 || current_rate > 96000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency96KHz;
 		break;
 	case 128000:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency128KHz;
 		break;
 	case 176400:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency176_4KHz;
 		break;
 	case 192000:
-		if (current_rate < 128000) {
+		if (current_rate < 128000)
 			reject_if_open = 1;
-		}
 		rate_bits = HDSP_Frequency192KHz;
 		break;
 	default:
@@ -1096,11 +1083,10 @@
 	if (rate >= 128000) {
 		hdsp->channel_map = channel_map_H9632_qs;
 	} else if (rate > 48000) {
-		if (hdsp->io_type == H9632) {
+		if (hdsp->io_type == H9632)
 			hdsp->channel_map = channel_map_H9632_ds;
-		} else {
+		else
 			hdsp->channel_map = channel_map_ds;
-		}
 	} else {
 		switch (hdsp->io_type) {
 		case Multiface:
@@ -1131,54 +1117,48 @@
 static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
-	if (id) {
+	if (id)
 		return hdsp_read(hdsp, HDSP_midiDataIn1);
-	} else {
+	else
 		return hdsp_read(hdsp, HDSP_midiDataIn0);
-	}
 }
 
 static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
-	if (id) {
+	if (id)
 		hdsp_write(hdsp, HDSP_midiDataOut1, val);
-	} else {
+	else
 		hdsp_write(hdsp, HDSP_midiDataOut0, val);
-	}
 }
 
 static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
 {
-	if (id) {
+	if (id)
 		return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
-	} else {
+	else
 		return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
-	}
 }
 
 static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
 {
 	int fifo_bytes_used;
 
-	if (id) {
+	if (id)
 		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut1) & 0xff;
-	} else {
+	else
 		fifo_bytes_used = hdsp_read(hdsp, HDSP_midiStatusOut0) & 0xff;
-	}
 
-	if (fifo_bytes_used < 128) {
+	if (fifo_bytes_used < 128)
 		return  128 - fifo_bytes_used;
-	} else {
+	else
 		return 0;
-	}
 }
 
 static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
 {
-	while (snd_hdsp_midi_input_available (hdsp, id)) {
+	while (snd_hdsp_midi_input_available (hdsp, id))
 		snd_hdsp_midi_read_byte (hdsp, id);
-	}
 }
 
 static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
@@ -1219,28 +1199,23 @@
 	spin_lock_irqsave (&hmidi->lock, flags);
 	if ((n_pending = snd_hdsp_midi_input_available (hmidi->hdsp, hmidi->id)) > 0) {
 		if (hmidi->input) {
-			if (n_pending > (int)sizeof (buf)) {
+			if (n_pending > (int)sizeof (buf))
 				n_pending = sizeof (buf);
-			}
-			for (i = 0; i < n_pending; ++i) {
+			for (i = 0; i < n_pending; ++i)
 				buf[i] = snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
-			}
-			if (n_pending) {
+			if (n_pending)
 				snd_rawmidi_receive (hmidi->input, buf, n_pending);
-			}
 		} else {
 			/* flush the MIDI input FIFO */
-			while (--n_pending) {
+			while (--n_pending)
 				snd_hdsp_midi_read_byte (hmidi->hdsp, hmidi->id);
-			}
 		}
 	}
 	hmidi->pending = 0;
-	if (hmidi->id) {
+	if (hmidi->id)
 		hmidi->hdsp->control_register |= HDSP_Midi1InterruptEnable;
-	} else {
+	else
 		hmidi->hdsp->control_register |= HDSP_Midi0InterruptEnable;
-	}
 	hdsp_write(hmidi->hdsp, HDSP_controlRegister, hmidi->hdsp->control_register);
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 	return snd_hdsp_midi_output_write (hmidi);
@@ -1310,9 +1285,8 @@
 			hmidi->istimer++;
 		}
 	} else {
-		if (hmidi->istimer && --hmidi->istimer <= 0) {
+		if (hmidi->istimer && --hmidi->istimer <= 0)
 			del_timer (&hmidi->timer);
-		}
 	}
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 	if (up)
@@ -1400,9 +1374,8 @@
 	spin_lock_init (&hdsp->midi[id].lock);
 
 	sprintf (buf, "%s MIDI %d", card->shortname, id+1);
-	if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) {
+	if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
 		return -1;
-	}
 
 	sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
 	hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
@@ -1588,11 +1561,10 @@
 
 static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
 {
-	if (out) {
+	if (out)
 		hdsp->control_register |= HDSP_SPDIFOpticalOut;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFOpticalOut;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1642,11 +1614,10 @@
 
 static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFProfessional;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFProfessional;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1687,11 +1658,10 @@
 
 static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFEmphasis;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFEmphasis;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1732,11 +1702,10 @@
 
 static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
 {
-	if (val) {
+	if (val)
 		hdsp->control_register |= HDSP_SPDIFNonAudio;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_SPDIFNonAudio;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -1921,11 +1890,10 @@
 
 static int hdsp_system_clock_mode(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_ClockModeMaster) {
+	if (hdsp->control_register & HDSP_ClockModeMaster)
 		return 0;
-	} else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate) {
+	else if (hdsp_external_sample_rate(hdsp) != hdsp->system_sample_rate)
 			return 0;
-	}
 	return 1;
 }
 
@@ -2074,16 +2042,17 @@
 	val = ucontrol->value.enumerated.item[0];
 	if (val < 0) val = 0;
 	if (hdsp->io_type == H9632) {
-	    if (val > 9) val = 9;
+		if (val > 9)
+			val = 9;
 	} else {
-	    if (val > 6) val = 6;
+		if (val > 6)
+			val = 6;
 	}
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_clock_source(hdsp)) {
+	if (val != hdsp_clock_source(hdsp))
 		change = (hdsp_set_clock_source(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2193,11 +2162,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_da_gain(hdsp)) {
+	if (val != hdsp_da_gain(hdsp))
 		change = (hdsp_set_da_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2279,11 +2247,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_ad_gain(hdsp)) {
+	if (val != hdsp_ad_gain(hdsp))
 		change = (hdsp_set_ad_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2365,11 +2332,10 @@
 	if (val < 0) val = 0;
 	if (val > 2) val = 2;
 	spin_lock_irq(&hdsp->lock);
-	if (val != hdsp_phone_gain(hdsp)) {
+	if (val != hdsp_phone_gain(hdsp))
 		change = (hdsp_set_phone_gain(hdsp, val) == 0) ? 1 : 0;
-	} else {
+	else
 		change = 0;
-	}
 	spin_unlock_irq(&hdsp->lock);
 	return change;
 }
@@ -2385,19 +2351,17 @@
 
 static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_XLRBreakoutCable) {
+	if (hdsp->control_register & HDSP_XLRBreakoutCable)
 		return 1;
-	}
 	return 0;
 }
 
 static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
 {
-	if (mode) {
+	if (mode)
 		hdsp->control_register |= HDSP_XLRBreakoutCable;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_XLRBreakoutCable;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2450,19 +2414,17 @@
 
 static int hdsp_aeb(hdsp_t *hdsp)
 {
-	if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+	if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 		return 1;
-	}
 	return 0;
 }
 
 static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
 {
-	if (mode) {
+	if (mode)
 		hdsp->control_register |= HDSP_AnalogExtensionBoard;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_AnalogExtensionBoard;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2705,11 +2667,10 @@
 
 static int hdsp_set_line_output(hdsp_t *hdsp, int out)
 {
-	if (out) {
+	if (out)
 		hdsp->control_register |= HDSP_LineOut;
-	} else {
+	else
 		hdsp->control_register &= ~HDSP_LineOut;
-	}
 	hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
 	return 0;
 }
@@ -2760,11 +2721,10 @@
 
 static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
 {
-	if (precise) {
+	if (precise)
 		hdsp->precise_ptr = 1;
-	} else {
+	else
 		hdsp->precise_ptr = 0;
-	}
 	return 0;
 }
 
@@ -2814,11 +2774,10 @@
 
 static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
 {
-	if (use_tasklet) {
+	if (use_tasklet)
 		hdsp->use_midi_tasklet = 1;
-	} else {
+	else
 		hdsp->use_midi_tasklet = 0;
-	}
 	return 0;
 }
 
@@ -2889,11 +2848,10 @@
 	source = ucontrol->value.integer.value[0];
 	destination = ucontrol->value.integer.value[1];
 	
-	if (source >= hdsp->max_channels) {
+	if (source >= hdsp->max_channels)
 		addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels,destination);
-	} else {
+	else
 		addr = hdsp_input_to_output_key(hdsp,source, destination);
-	}
 	
 	spin_lock_irq(&hdsp->lock);
 	ucontrol->value.integer.value[2] = hdsp_read_gain (hdsp, addr);
@@ -2916,11 +2874,10 @@
 	source = ucontrol->value.integer.value[0];
 	destination = ucontrol->value.integer.value[1];
 
-	if (source >= hdsp->max_channels) {
+	if (source >= hdsp->max_channels)
 		addr = hdsp_playback_to_output_key(hdsp,source-hdsp->max_channels, destination);
-	} else {
+	else
 		addr = hdsp_input_to_output_key(hdsp,source, destination);
-	}
 
 	gain = ucontrol->value.integer.value[2];
 
@@ -2957,14 +2914,12 @@
 {
 	int status2 = hdsp_read(hdsp, HDSP_status2Register);
 	if (status2 & HDSP_wc_lock) {
-		if (status2 & HDSP_wc_sync) {
+		if (status2 & HDSP_wc_sync)
 			return 2;
-		} else {
+		else
 			 return 1;
-		}
-	} else {		
+	} else
 		return 0;
-	}
 	return 0;
 }
 
@@ -2988,14 +2943,13 @@
 static int hdsp_spdif_sync_check(hdsp_t *hdsp)
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		return 0;
-	} else {	
-		if (status & HDSP_SPDIFSync) {
+	else {	
+		if (status & HDSP_SPDIFSync)
 			return 2;
-		} else {
+		else
 			return 1;
-		}
 	}
 	return 0;
 }
@@ -3021,14 +2975,12 @@
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	if (status & HDSP_TimecodeLock) {
-		if (status & HDSP_TimecodeSync) {
+		if (status & HDSP_TimecodeSync)
 			return 2;
-		} else {
+		else
 			return 1;
-		}
-	} else {
+	} else
 		return 0;
-	}
 }	
 
 static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3051,14 +3003,12 @@
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	
 	if (status & (HDSP_Lock0>>idx)) {
-		if (status & (HDSP_Sync0>>idx)) {
+		if (status & (HDSP_Sync0>>idx))
 			return 2;
-		} else {
+		else
 			return 1;		
-		}
-	} else {
+	} else
 		return 0;
-	}		
 } 
 
 static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
@@ -3171,9 +3121,8 @@
 	snd_kcontrol_t *kctl;
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
-		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) {
+		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
 			return err;
-		}
 		if (idx == 1)	/* IEC958 (S/PDIF) Stream */
 			hdsp->spdif_ctl = kctl;
 	}
@@ -3181,32 +3130,28 @@
 	/* ADAT SyncCheck status */
 	snd_hdsp_adat_sync_check.name = "ADAT Lock Status";
 	snd_hdsp_adat_sync_check.index = 1;
-	if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+	if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
 		return err;
-	}	
 	if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
 		for (idx = 1; idx < 3; ++idx) {
 			snd_hdsp_adat_sync_check.index = idx+1;
-			if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp)))) {
+			if ((err = snd_ctl_add (card, kctl = snd_ctl_new1(&snd_hdsp_adat_sync_check, hdsp))))
 				return err;
-			}
 		}
 	}
 	
 	/* DA, AD and Phone gain and XLR breakout cable controls for H9632 cards */
 	if (hdsp->io_type == H9632) {
 		for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_9632_controls); idx++) {
-			if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0) {
+			if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_9632_controls[idx], hdsp))) < 0)
 				return err;
-			}
 		}
 	}
 
 	/* AEB control for H96xx card */
 	if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
-		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0) {
+		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_96xx_aeb, hdsp))) < 0)
 				return err;
-		}	
 	}
 
 	return 0;
@@ -3228,12 +3173,11 @@
 	char *clock_source;
 	int x;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n");
 		return;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
+	if (hdsp_check_for_firmware(hdsp, 0)) {
 		if (hdsp->state & HDSP_FirmwareCached) {
 			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
 				snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n");
@@ -3314,11 +3258,10 @@
 	}
 	snd_iprintf (buffer, "Sample Clock Source: %s\n", clock_source);
 			
-	if (hdsp_system_clock_mode(hdsp)) {
+	if (hdsp_system_clock_mode(hdsp))
 		system_clock_mode = "Slave";
-	} else {
+	else
 		system_clock_mode = "Master";
-	}
 	
 	switch (hdsp_pref_sync_ref (hdsp)) {
 	case HDSP_SYNC_FROM_WORD:
@@ -3400,85 +3343,75 @@
 		break;
 	}
 	
-	if (hdsp->control_register & HDSP_SPDIFOpticalOut) {
+	if (hdsp->control_register & HDSP_SPDIFOpticalOut)
 		snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFProfessional) {
+	if (hdsp->control_register & HDSP_SPDIFProfessional)
 		snd_iprintf(buffer, "IEC958 quality: Professional\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 quality: Consumer\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFEmphasis) {
+	if (hdsp->control_register & HDSP_SPDIFEmphasis)
 		snd_iprintf(buffer, "IEC958 emphasis: on\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 emphasis: off\n");
-	}
 
-	if (hdsp->control_register & HDSP_SPDIFNonAudio) {
+	if (hdsp->control_register & HDSP_SPDIFNonAudio)
 		snd_iprintf(buffer, "IEC958 NonAudio: on\n");
-	} else {
+	else
 		snd_iprintf(buffer, "IEC958 NonAudio: off\n");
-	}
-	if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) {
+	if ((x = hdsp_spdif_sample_rate (hdsp)) != 0)
 		snd_iprintf (buffer, "IEC958 sample rate: %d\n", x);
-	} else {
+	else
 		snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n");
-	}
 
 	snd_iprintf(buffer, "\n");
 
 	/* Sync Check */
 	x = status & HDSP_Sync0;
-	if (status & HDSP_Lock0) {
+	if (status & HDSP_Lock0)
 		snd_iprintf(buffer, "ADAT1: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf(buffer, "ADAT1: No Lock\n");
-	}
 
 	switch (hdsp->io_type) {
 	case Digiface:
 	case H9652:
 		x = status & HDSP_Sync1;
-		if (status & HDSP_Lock1) {
+		if (status & HDSP_Lock1)
 			snd_iprintf(buffer, "ADAT2: %s\n", x ? "Sync" : "Lock");
-		} else {
+		else
 			snd_iprintf(buffer, "ADAT2: No Lock\n");
-		}
 		x = status & HDSP_Sync2;
-		if (status & HDSP_Lock2) {
+		if (status & HDSP_Lock2)
 			snd_iprintf(buffer, "ADAT3: %s\n", x ? "Sync" : "Lock");
-		} else {
+		else
 			snd_iprintf(buffer, "ADAT3: No Lock\n");
-		}
+		break;
 	default:
 		/* relax */
 		break;
 	}
 
 	x = status & HDSP_SPDIFSync;
-	if (status & HDSP_SPDIFErrorFlag) {
+	if (status & HDSP_SPDIFErrorFlag)
 		snd_iprintf (buffer, "SPDIF: No Lock\n");
-	} else {
+	else
 		snd_iprintf (buffer, "SPDIF: %s\n", x ? "Sync" : "Lock");
-	}
 	
 	x = status2 & HDSP_wc_sync;
-	if (status2 & HDSP_wc_lock) {
+	if (status2 & HDSP_wc_lock)
 		snd_iprintf (buffer, "Word Clock: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf (buffer, "Word Clock: No Lock\n");
-	}
 	
 	x = status & HDSP_TimecodeSync;
-	if (status & HDSP_TimecodeLock) {
+	if (status & HDSP_TimecodeLock)
 		snd_iprintf(buffer, "ADAT Sync: %s\n", x ? "Sync" : "Lock");
-	} else {
+	else
 		snd_iprintf(buffer, "ADAT Sync: No Lock\n");
-	}
 
 	snd_iprintf(buffer, "\n");
 	
@@ -3527,11 +3460,10 @@
 
 		snd_iprintf(buffer, "XLR Breakout Cable : %s\n", hdsp_xlr_breakout_cable(hdsp) ? "yes" : "no");	
 		
-		if (hdsp->control_register & HDSP_AnalogExtensionBoard) {
+		if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 			snd_iprintf(buffer, "AEB : on (ADAT1 internal)\n");
-		} else {
+		else
 			snd_iprintf(buffer, "AEB : off (ADAT1 external)\n");
-		}
 		snd_iprintf(buffer, "\n");
 	}
 
@@ -3610,25 +3542,22 @@
 #else
 	hdsp->control2_register = 0;
 #endif
-	if (hdsp->io_type == H9652) {
+	if (hdsp->io_type == H9652)
 	        snd_hdsp_9652_enable_mixer (hdsp);
-	} else {
-	    hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
-	} 
+	else
+		hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
 
 	hdsp_reset_hw_pointer(hdsp);
 	hdsp_compute_period_size(hdsp);
 
 	/* silence everything */
 	
-	for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i) {
+	for (i = 0; i < HDSP_MATRIX_MIXER_SIZE; ++i)
 		hdsp->mixer_matrix[i] = MINUS_INFINITY_GAIN;
-	}
 
 	for (i = 0; i < ((hdsp->io_type == H9652 || hdsp->io_type == H9632) ? 1352 : HDSP_MATRIX_MIXER_SIZE); ++i) {
-		if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN)) {
+		if (hdsp_write_gain (hdsp, i, MINUS_INFINITY_GAIN))
 			return -EIO;
-		}
 	}
 	
 	/* H9632 specific defaults */
@@ -3649,12 +3578,10 @@
 {
 	hdsp_t *hdsp = (hdsp_t *)arg;
 	
-	if (hdsp->midi[0].pending) {
+	if (hdsp->midi[0].pending)
 		snd_hdsp_midi_input_read (&hdsp->midi[0]);
-	}
-	if (hdsp->midi[1].pending) {
+	if (hdsp->midi[1].pending)
 		snd_hdsp_midi_input_read (&hdsp->midi[1]);
-	}
 } 
 
 static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -3674,9 +3601,8 @@
 	midi0 = status & HDSP_midi0IRQPending;
 	midi1 = status & HDSP_midi1IRQPending;
 
-	if (!audio && !midi0 && !midi1) {
+	if (!audio && !midi0 && !midi1)
 		return IRQ_NONE;
-	}
 
 	hdsp_write(hdsp, HDSP_interruptConfirmation, 0);
 
@@ -3684,13 +3610,11 @@
 	midi1status = hdsp_read (hdsp, HDSP_midiStatusIn1) & 0xff;
 	
 	if (audio) {
-		if (hdsp->capture_substream) {
+		if (hdsp->capture_substream)
 			snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
-		}
 		
-		if (hdsp->playback_substream) {
+		if (hdsp->playback_substream)
 			snd_pcm_period_elapsed(hdsp->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
-		}
 	}
 	
 	if (midi0 && midi0status) {
@@ -3735,15 +3659,13 @@
 
         snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL);
         
-	if ((mapped_channel = hdsp->channel_map[channel]) < 0) {
+	if ((mapped_channel = hdsp->channel_map[channel]) < 0)
 		return NULL;
-	}
 	
-	if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+	if (stream == SNDRV_PCM_STREAM_CAPTURE)
 		return hdsp->capture_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
-	} else {
+	else
 		return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
-	}
 }
 
 static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
@@ -3824,20 +3746,11 @@
 	pid_t this_pid;
 	pid_t other_pid;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -3908,9 +3821,8 @@
 
 	snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
 
-	if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) {
+	if ((mapped_channel = hdsp->channel_map[info->channel]) < 0)
 		return -EINVAL;
-	}
 
 	info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES;
 	info->first = 0;
@@ -3923,14 +3835,9 @@
 {
 	switch (cmd) {
 	case SNDRV_PCM_IOCTL1_RESET:
-	{
 		return snd_hdsp_reset(substream);
-	}
 	case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
-	{
-		snd_pcm_channel_info_t *info = arg;
-		return snd_hdsp_channel_info(substream, info);
-	}
+		return snd_hdsp_channel_info(substream, arg);
 	default:
 		break;
 	}
@@ -3944,20 +3851,11 @@
 	snd_pcm_substream_t *other;
 	int running;
 	
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock(&hdsp->lock);
 	running = hdsp->running;
@@ -4022,20 +3920,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	int result = 0;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 	if (!hdsp->running)
@@ -4285,20 +4174,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4367,20 +4247,11 @@
 	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	if (hdsp_check_for_iobox (hdsp)) {
+	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
-	}
 
-	if (hdsp_check_for_firmware(hdsp)) {
-		if (hdsp->state & HDSP_FirmwareCached) {
-			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
-				snd_printk("Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");
-			}
-		} else {
-			snd_printk("Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");
-		}
+	if (hdsp_check_for_firmware(hdsp, 1))
 		return -EIO;
-	}
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4589,19 +4460,17 @@
 		int i;
 		
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
-			snd_printk("Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");	
+			snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");	
 			return -EINVAL;
 		}
 		spin_lock_irqsave(&hdsp->lock, flags);
 		info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
 		info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
-		if (hdsp->io_type != H9632) {
+		if (hdsp->io_type != H9632)
 		    info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
-		}
 		info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
-		for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) {
+		for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i)
 			info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
-		}
 		info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
 		info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
 		info.spdif_professional = (unsigned char)hdsp_spdif_professional(hdsp);
@@ -4621,9 +4490,8 @@
 			info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
 		
 		}
-		if (hdsp->io_type == H9632 || hdsp->io_type == H9652) {
+		if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
 			info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
-		}
 		spin_unlock_irqrestore(&hdsp->lock, flags);
 		if (copy_to_user(argp, &info, sizeof(info)))
 			return -EFAULT;
@@ -4645,15 +4513,13 @@
 		
 		if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
 		if (hdsp->io_type == Undefined) {
-			if ((err = hdsp_get_iobox_version(hdsp)) < 0) {
+			if ((err = hdsp_get_iobox_version(hdsp)) < 0)
 				return err;
-			}
 		}
 		hdsp_version.io_type = hdsp->io_type;
 		hdsp_version.firmware_rev = hdsp->firmware_rev;
-		if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version)))) {
+		if ((err = copy_to_user(argp, &hdsp_version, sizeof(hdsp_version))))
 		    	return -EFAULT;
-		}
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
@@ -4668,38 +4534,33 @@
 		if (hdsp->state & (HDSP_FirmwareCached | HDSP_FirmwareLoaded))
 			return -EBUSY;
 
-		snd_printk("Hammerfall-DSP: initializing firmware upload\n");
+		snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
 		firmware = (hdsp_firmware_t __user *)argp;
 
-		if (get_user(firmware_data, &firmware->firmware_data)) {
+		if (get_user(firmware_data, &firmware->firmware_data))
 			return -EFAULT;
-		}
 		
-		if (hdsp_check_for_iobox (hdsp)) {
+		if (hdsp_check_for_iobox (hdsp))
 			return -EIO;
-		}
 
-		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0) {
+		if (copy_from_user(hdsp->firmware_cache, firmware_data, sizeof(hdsp->firmware_cache)) != 0)
 			return -EFAULT;
-		}
 		
 		hdsp->state |= HDSP_FirmwareCached;
 
-		if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0) {
+		if ((err = snd_hdsp_load_firmware_from_cache(hdsp)) < 0)
 			return err;
-		}
 		
 		if (!(hdsp->state & HDSP_InitializationComplete)) {
-			if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+			if ((err = snd_hdsp_enable_io(hdsp)) < 0)
 				return err;
-			}
 			
 			snd_hdsp_initialize_channels(hdsp);		
 			snd_hdsp_initialize_midi_flush(hdsp);
 	    
 			if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
-				snd_printk("Hammerfall-DSP: error creating alsa devices\n");
-			    return err;
+				snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
+				return err;
 			}
 		}
 		break;
@@ -4790,7 +4651,7 @@
 	int i;
 	
 	if (hdsp_fifo_wait (hdsp, 0, 100)) {
-		snd_printk("Hammerfall-DSP: enable_io fifo_wait failed\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: enable_io fifo_wait failed\n");
 		return -EIO;
 	}
 	
@@ -4856,25 +4717,25 @@
 	int err;
 	
 	if ((err = snd_hdsp_create_pcm(card, hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating pcm interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating pcm interface\n");
 		return err;
 	}
 	
 
 	if ((err = snd_hdsp_create_midi(card, hdsp, 0)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating first midi interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating first midi interface\n");
 		return err;
 	}
 
 	if (hdsp->io_type == Digiface || hdsp->io_type == H9652) {
 		if ((err = snd_hdsp_create_midi(card, hdsp, 1)) < 0) {
-			snd_printk("Hammerfall-DSP: Error creating second midi interface\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: Error creating second midi interface\n");
 			return err;
 		}
 	}
 
 	if ((err = snd_hdsp_create_controls(card, hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error creating ctl interface\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error creating ctl interface\n");
 		return err;
 	}
 
@@ -4887,7 +4748,7 @@
 	hdsp->playback_substream = NULL;
 
 	if ((err = snd_hdsp_set_defaults(hdsp)) < 0) {
-		snd_printk("Hammerfall-DSP: Error setting default values\n");
+		snd_printk(KERN_ERR "Hammerfall-DSP: Error setting default values\n");
 		return err;
 	}
 	
@@ -4897,7 +4758,7 @@
 			hdsp->port, hdsp->irq);
 	    
 		if ((err = snd_card_register(card)) < 0) {
-			snd_printk("Hammerfall-DSP: error registering card\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error registering card\n");
 			return err;
 		}
 		hdsp->state |= HDSP_InitializationComplete;
@@ -4963,18 +4824,17 @@
 		return err;
 		
 	if (!(hdsp->state & HDSP_InitializationComplete)) {
-		if ((err = snd_hdsp_enable_io(hdsp)) < 0) {
+		if ((err = snd_hdsp_enable_io(hdsp)) < 0)
 			return err;
-		}
 
 		if ((err = snd_hdsp_create_hwdep(hdsp->card, hdsp)) < 0) {
-			snd_printk("Hammerfall-DSP: error creating hwdep device\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error creating hwdep device\n");
 			return err;
 		}
 		snd_hdsp_initialize_channels(hdsp);
 		snd_hdsp_initialize_midi_flush(hdsp);
 		if ((err = snd_hdsp_create_alsa_devices(hdsp->card, hdsp)) < 0) {
-			snd_printk("Hammerfall-DSP: error creating alsa devices\n");
+			snd_printk(KERN_ERR "Hammerfall-DSP: error creating alsa devices\n");
 			return err;
 		}
 	}
@@ -5029,11 +4889,11 @@
 	strcpy(card->driver, "H-DSP");
 	strcpy(card->mixername, "Xilinx FPGA");
 
-	if (hdsp->firmware_rev < 0xa) {
+	if (hdsp->firmware_rev < 0xa)
 		return -ENODEV;
-	} else if (hdsp->firmware_rev < 0x64) {
+	else if (hdsp->firmware_rev < 0x64)
 		hdsp->card_name = "RME Hammerfall DSP";
-	} else if (hdsp->firmware_rev < 0x96) {
+	else if (hdsp->firmware_rev < 0x96) {
 		hdsp->card_name = "RME HDSP 9652";
 		is_9652 = 1;
 	} else {
@@ -5042,9 +4902,8 @@
 		is_9632 = 1;	
 	}
 
-	if ((err = pci_enable_device(pci)) < 0) {
+	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	}
 
 	pci_set_master(hdsp->pci);
 
@@ -5052,12 +4911,12 @@
 		return err;
 	hdsp->port = pci_resource_start(pci, 0);
 	if ((hdsp->iobase = ioremap_nocache(hdsp->port, HDSP_IO_EXTENT)) == NULL) {
-		snd_printk("Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
+		snd_printk(KERN_ERR "Hammerfall-DSP: unable to remap region 0x%lx-0x%lx\n", hdsp->port, hdsp->port + HDSP_IO_EXTENT - 1);
 		return -EBUSY;
 	}
 
 	if (request_irq(pci->irq, snd_hdsp_interrupt, SA_INTERRUPT|SA_SHIRQ, "hdsp", (void *)hdsp)) {
-		snd_printk("Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 
@@ -5065,71 +4924,58 @@
 	hdsp->precise_ptr = 1;
 	hdsp->use_midi_tasklet = 1;
 
-	if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) {
+	if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
 		return err;
-	}
 	
 	if (!is_9652 && !is_9632) {
 		/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
- 		if ((1000 / HZ) < 2000) {
-			ssleep(2);
-		} else {
-			mdelay(2000);
-		}
+		ssleep(2);
 
 		if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 #ifdef HDSP_FW_LOADER
-			if ((err = hdsp_request_fw_loader(hdsp)) < 0) {
+			if ((err = hdsp_request_fw_loader(hdsp)) < 0)
 				/* we don't fail as this can happen
 				   if userspace is not ready for
 				   firmware upload
 				*/
-				snd_printk("Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
-			} else {
+				snd_printk(KERN_ERR "Hammerfall-DSP: couldn't get firmware from userspace. try using hdsploader\n");
+			else
 				/* init is complete, we return */
 				return 0;
-			}
 #endif
 			/* no iobox connected, we defer initialization */
-			snd_printk("Hammerfall-DSP: card initialization pending : waiting for firmware\n");
-			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+			snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
+			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
 				return err;
-			}
 			return 0;
 		} else {
-			snd_printk("Hammerfall-DSP: Firmware already present, initializing card.\n");	    
-			if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) {
+			snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");	    
+			if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
 				hdsp->io_type = Multiface;
-			} else {
+			else 
 				hdsp->io_type = Digiface;
-			}
 		}
 	}
 	
-	if ((err = snd_hdsp_enable_io(hdsp)) != 0) {
+	if ((err = snd_hdsp_enable_io(hdsp)) != 0)
 		return err;
-	}
 	
-	if (is_9652) {
+	if (is_9652)
 	        hdsp->io_type = H9652;
-	}
 	
-	if (is_9632) {
+	if (is_9632)
 		hdsp->io_type = H9632;
-	}
 
-	if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) {
+	if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
 		return err;
-	}
 	
 	snd_hdsp_initialize_channels(hdsp);
 	snd_hdsp_initialize_midi_flush(hdsp);
 
 	hdsp->state |= HDSP_FirmwareLoaded;	
 
-	if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0) {
+	if ((err = snd_hdsp_create_alsa_devices(card, hdsp)) < 0)
 		return err;
-	}
 
 	return 0;	
 }
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index fc3f328..60a1141 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3563,8 +3563,7 @@
 		free_irq(hdspm->irq, (void *) hdspm);
 
 
-	if (hdspm->mixer)
-		kfree(hdspm->mixer);
+	kfree(hdspm->mixer);
 
 	if (hdspm->iobase)
 		iounmap(hdspm->iobase);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index b600f45..59fcef9 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -779,7 +779,7 @@
 		break;
 
 	default:
-		snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+		snd_printk(KERN_ERR "%s: unknown S/PDIF input rate (bits = 0x%x)\n",
 			   s->card_name, rate_bits);
 		return 0;
 		break;
@@ -2496,12 +2496,12 @@
 	rme9652->port = pci_resource_start(pci, 0);
 	rme9652->iobase = ioremap_nocache(rme9652->port, RME9652_IO_EXTENT);
 	if (rme9652->iobase == NULL) {
-		snd_printk("unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
+		snd_printk(KERN_ERR "unable to remap region 0x%lx-0x%lx\n", rme9652->port, rme9652->port + RME9652_IO_EXTENT - 1);
 		return -EBUSY;
 	}
 	
 	if (request_irq(pci->irq, snd_rme9652_interrupt, SA_INTERRUPT|SA_SHIRQ, "rme9652", (void *)rme9652)) {
-		snd_printk("unable to request IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
 		return -EBUSY;
 	}
 	rme9652->irq = pci->irq;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 1f6c2bf..9a35474 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -591,7 +591,7 @@
 		return IRQ_NONE;
 	if (status == 0xff) {	/* failure */
 		outb(sonic->irqmask = ~0, SV_REG(sonic, IRQMASK));
-		snd_printk("IRQ failure - interrupts disabled!!\n");
+		snd_printk(KERN_ERR "IRQ failure - interrupts disabled!!\n");
 		return IRQ_HANDLED;
 	}
 	if (sonic->pcm) {
@@ -1205,14 +1205,8 @@
 	pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port);
 	if (sonic->irq >= 0)
 		free_irq(sonic->irq, (void *)sonic);
-	if (sonic->res_dmaa) {
-		release_resource(sonic->res_dmaa);
-		kfree_nocheck(sonic->res_dmaa);
-	}
-	if (sonic->res_dmac) {
-		release_resource(sonic->res_dmac);
-		kfree_nocheck(sonic->res_dmac);
-	}
+	release_and_free_resource(sonic->res_dmaa);
+	release_and_free_resource(sonic->res_dmac);
 	pci_release_regions(sonic->pci);
 	pci_disable_device(sonic->pci);
 	kfree(sonic);
@@ -1245,7 +1239,7 @@
 	/* check, if we can restrict PCI DMA transfers to 24 bits */
         if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
-                snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
                 return -ENXIO;
         }
@@ -1273,7 +1267,7 @@
 	sonic->game_port = pci_resource_start(pci, 4);
 
 	if (request_irq(pci->irq, snd_sonicvibes_interrupt, SA_INTERRUPT|SA_SHIRQ, "S3 SonicVibes", (void *)sonic)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_sonicvibes_free(sonic);
 		return -EBUSY;
 	}
@@ -1287,24 +1281,24 @@
 	if (!dmaa) {
 		dmaa = dmaio;
 		dmaio += 0x10;
-		snd_printk("BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
+		snd_printk(KERN_INFO "BIOS did not allocate DDMA channel A i/o, allocated at 0x%x\n", dmaa);
 	}
 	if (!dmac) {
 		dmac = dmaio;
 		dmaio += 0x10;
-		snd_printk("BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
+		snd_printk(KERN_INFO "BIOS did not allocate DDMA channel C i/o, allocated at 0x%x\n", dmac);
 	}
 	pci_write_config_dword(pci, 0x40, dmaa);
 	pci_write_config_dword(pci, 0x48, dmac);
 
 	if ((sonic->res_dmaa = request_region(dmaa, 0x10, "S3 SonicVibes DDMA-A")) == NULL) {
 		snd_sonicvibes_free(sonic);
-		snd_printk("unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
+		snd_printk(KERN_ERR "unable to grab DDMA-A port at 0x%x-0x%x\n", dmaa, dmaa + 0x10 - 1);
 		return -EBUSY;
 	}
 	if ((sonic->res_dmac = request_region(dmac, 0x10, "S3 SonicVibes DDMA-C")) == NULL) {
 		snd_sonicvibes_free(sonic);
-		snd_printk("unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
+		snd_printk(KERN_ERR "unable to grab DDMA-C port at 0x%x-0x%x\n", dmac, dmac + 0x10 - 1);
 		return -EBUSY;
 	}
 
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 777da9a..b9b93c7 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -153,7 +153,7 @@
 	}
 
 	if (count == 0 && !trident->ac97_detect) {
-		snd_printk("ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+		snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
 		data = 0;
 	}
 
@@ -2893,7 +2893,8 @@
 {
 	snd_ctl_elem_id_t id;
 
-	snd_runtime_check(kctl != NULL, return);
+	if (! kctl)
+		return;
 	if (activate)
 		kctl->vd[num].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
 	else
@@ -2989,13 +2990,13 @@
 		_ac97.num = 1;
 		err = snd_ac97_mixer(trident->ac97_bus, &_ac97, &trident->ac97_sec);
 		if (err < 0)
-			snd_printk("SI7018: the secondary codec - invalid access\n");
+			snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
 #if 0	// only for my testing purpose --jk
 		{
 			ac97_t *mc97;
 			err = snd_ac97_modem(trident->card, &_ac97, &mc97);
 			if (err < 0)
-				snd_printk("snd_ac97_modem returned error %i\n", err);
+				snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
 		}
 #endif
 	}
@@ -3206,8 +3207,7 @@
  */
 static inline void do_delay(trident_t *chip)
 {
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
+	schedule_timeout_uninterruptible(1);
 }
 
 /*
@@ -3243,7 +3243,7 @@
 			goto __si7018_ok;
 		do_delay(trident);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk("AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
+	snd_printk(KERN_ERR "AC'97 codec ready error [0x%x]\n", inl(TRID_REG(trident, SI_SERIAL_INTF_CTRL)));
 	if (r-- > 0) {
 		end_time = jiffies + HZ;
 		do {
@@ -3541,7 +3541,7 @@
 	/* check, if we can restrict PCI DMA transfers to 30 bits */
 	if (pci_set_dma_mask(pci, 0x3fffffff) < 0 ||
 	    pci_set_consistent_dma_mask(pci, 0x3fffffff) < 0) {
-		snd_printk("architecture does not support 30bit PCI busmaster DMA\n");
+		snd_printk(KERN_ERR "architecture does not support 30bit PCI busmaster DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
 	}
@@ -3578,7 +3578,7 @@
 	trident->port = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_trident_free(trident);
 		return -EBUSY;
 	}
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index 333d379..f3e6c54 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -170,11 +170,11 @@
 static int is_valid_page(unsigned long ptr)
 {
 	if (ptr & ~0x3fffffffUL) {
-		snd_printk("max memory size is 1GB!!\n");
+		snd_printk(KERN_ERR "max memory size is 1GB!!\n");
 		return 0;
 	}
 	if (ptr & (SNDRV_TRIDENT_PAGE_SIZE-1)) {
-		snd_printk("page is not aligned\n");
+		snd_printk(KERN_ERR "page is not aligned\n");
 		return 0;
 	}
 	return 1;
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 3c0205b..523eace 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -41,6 +41,9 @@
  *	  device for applications.
  *	- clean up the code, separate low-level initialization
  *	  routines for each chipset.
+ *
+ * Sep. 26, 2005	Karsten Wiese <annabellesgarden@yahoo.de>
+ *	- Optimize position calculation for the 823x chips. 
  */
 
 #include <sound/driver.h>
@@ -73,36 +76,37 @@
 #define SUPPORT_JOYSTICK 1
 #endif
 
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static long mpu_port[SNDRV_CARDS];
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static long mpu_port;
 #ifdef SUPPORT_JOYSTICK
-static int joystick[SNDRV_CARDS];
+static int joystick;
 #endif
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
-static char *ac97_quirk[SNDRV_CARDS];
-static int dxs_support[SNDRV_CARDS];
+static int ac97_clock = 48000;
+static char *ac97_quirk;
+static int dxs_support;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable audio part of VIA 82xx bridge.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param(mpu_port, long, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port. (VT82C686x only)");
 #ifdef SUPPORT_JOYSTICK
-module_param_array(joystick, bool, NULL, 0444);
+module_param(joystick, bool, 0444);
 MODULE_PARM_DESC(joystick, "Enable joystick. (VT82C686x only)");
 #endif
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
-module_param_array(ac97_quirk, charp, NULL, 0444);
+module_param(ac97_quirk, charp, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
-module_param_array(dxs_support, int, NULL, 0444);
+module_param(dxs_support, int, 0444);
 MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /* revision numbers for via686 */
 #define VIA_REV_686_A		0x10
@@ -130,6 +134,7 @@
 /* common offsets */
 #define VIA_REG_OFFSET_STATUS		0x00	/* byte - channel status */
 #define   VIA_REG_STAT_ACTIVE		0x80	/* RO */
+#define   VIA8233_SHADOW_STAT_ACTIVE	0x08	/* RO */
 #define   VIA_REG_STAT_PAUSED		0x40	/* RO */
 #define   VIA_REG_STAT_TRIGGER_QUEUED	0x08	/* RO */
 #define   VIA_REG_STAT_STOPPED		0x04	/* RWC */
@@ -328,6 +333,9 @@
 	unsigned int fragsize;
 	unsigned int bufsize;
 	unsigned int bufsize2;
+	int hwptr_done;		/* processed frame position in the buffer */
+	int in_interrupt;
+	int shadow_shift;
 };
 
 
@@ -360,7 +368,8 @@
 	unsigned int mpu_port_saved;
 #endif
 
-	unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
+	unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
+	unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */
 
 	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
 
@@ -393,8 +402,10 @@
 };
 
 static struct pci_device_id snd_via82xx_ids[] = {
-	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
-	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
+	/* 0x1106, 0x3058 */
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
+	/* 0x1106, 0x3059 */
+	{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
 	{ 0, }
 };
 
@@ -548,7 +559,7 @@
 {
 	via82xx_t *chip = ac97->private_data;
 	unsigned int xval;
-	
+
 	xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
 	xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
 	xval |= reg << VIA_REG_AC97_CMD_SHIFT;
@@ -596,14 +607,15 @@
 	outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
 	// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
 	viadev->lastpos = 0;
+	viadev->hwptr_done = 0;
 }
 
 
 /*
  *  Interrupt handler
+ *  Used for 686 and 8233A
  */
-
-static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	via82xx_t *chip = dev_id;
 	unsigned int status;
@@ -622,13 +634,23 @@
 	for (i = 0; i < chip->num_devs; i++) {
 		viadev_t *viadev = &chip->devs[i];
 		unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
-		c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
-		if (! c_status)
+		if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
 			continue;
 		if (viadev->substream && viadev->running) {
+			/*
+			 * Update hwptr_done based on 'period elapsed'
+			 * interrupts. We'll use it, when the chip returns 0 
+			 * for OFFSET_CURR_COUNT.
+			 */
+			if (c_status & VIA_REG_STAT_EOL)
+				viadev->hwptr_done = 0;
+			else
+				viadev->hwptr_done += viadev->fragsize;
+			viadev->in_interrupt = c_status;
 			spin_unlock(&chip->reg_lock);
 			snd_pcm_period_elapsed(viadev->substream);
 			spin_lock(&chip->reg_lock);
+			viadev->in_interrupt = 0;
 		}
 		outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
 	}
@@ -637,6 +659,60 @@
 }
 
 /*
+ *  Interrupt handler
+ */
+static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	via82xx_t *chip = dev_id;
+	unsigned int status;
+	unsigned int i;
+	int irqreturn = 0;
+
+	/* check status for each stream */
+	spin_lock(&chip->reg_lock);
+	status = inl(VIAREG(chip, SGD_SHADOW));
+
+	for (i = 0; i < chip->num_devs; i++) {
+		viadev_t *viadev = &chip->devs[i];
+		snd_pcm_substream_t *substream;
+		unsigned char c_status, shadow_status;
+
+		shadow_status = (status >> viadev->shadow_shift) &
+			(VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
+			 VIA_REG_STAT_FLAG);
+		c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
+		if (!c_status)
+			continue;
+
+		substream = viadev->substream;
+		if (substream && viadev->running) {
+			/*
+			 * Update hwptr_done based on 'period elapsed'
+			 * interrupts. We'll use it, when the chip returns 0 
+			 * for OFFSET_CURR_COUNT.
+			 */
+			if (c_status & VIA_REG_STAT_EOL)
+				viadev->hwptr_done = 0;
+			else
+				viadev->hwptr_done += viadev->fragsize;
+			viadev->in_interrupt = c_status;
+			if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
+				viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
+			spin_unlock(&chip->reg_lock);
+
+			snd_pcm_period_elapsed(substream);
+
+			spin_lock(&chip->reg_lock);
+			viadev->in_interrupt = 0;
+		}
+		outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
+		irqreturn = 1;
+	}
+	spin_unlock(&chip->reg_lock);
+	return IRQ_RETVAL(irqreturn);
+}
+
+/*
  *  PCM callbacks
  */
 
@@ -699,6 +775,8 @@
 	size = viadev->idx_table[idx].size;
 	base = viadev->idx_table[idx].offset;
 	res = base + size - count;
+	if (res >= viadev->bufsize)
+		res -= viadev->bufsize;
 
 	/* check the validity of the calculated position */
 	if (size < count) {
@@ -728,9 +806,6 @@
 			}
 		}
 	}
-	viadev->lastpos = res; /* remember the last position */
-	if (res >= viadev->bufsize)
-		res -= viadev->bufsize;
 	return res;
 }
 
@@ -758,6 +833,7 @@
 	else /* CURR_PTR holds the address + 8 */
 		idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
 	res = calc_linear_pos(viadev, idx, count);
+	viadev->lastpos = res; /* remember the last position */
 	spin_unlock(&chip->reg_lock);
 
 	return bytes_to_frames(substream->runtime, res);
@@ -771,30 +847,44 @@
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
 	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	unsigned int idx, count, res;
-	int timeout = 5000;
+	int status;
 	
 	snd_assert(viadev->tbl_entries, return 0);
-	if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
-		return 0;
+
 	spin_lock(&chip->reg_lock);
-	do {
-		count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
-		/* some mobos read 0 count */
-		if ((count & 0xffffff) || ! viadev->running)
-			break;
-	} while (--timeout);
-	if (! timeout)
-		snd_printd(KERN_ERR "zero position is read\n");
-	idx = count >> 24;
-	if (idx >= viadev->tbl_entries) {
-#ifdef POINTER_DEBUG
-		printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
-#endif
-		res = viadev->lastpos;
-	} else {
-		count &= 0xffffff;
-		res = calc_linear_pos(viadev, idx, count);
+	count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
+	status = viadev->in_interrupt;
+	if (!status)
+		status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+
+	if (!(status & VIA_REG_STAT_ACTIVE)) {
+		res = 0;
+		goto unlock;
 	}
+	if (count & 0xffffff) {
+		idx = count >> 24;
+		if (idx >= viadev->tbl_entries) {
+#ifdef POINTER_DEBUG
+			printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+#endif
+			res = viadev->lastpos;
+		} else {
+			count &= 0xffffff;
+			res = calc_linear_pos(viadev, idx, count);
+		}
+	} else {
+		res = viadev->hwptr_done;
+		if (!viadev->in_interrupt) {
+			if (status & VIA_REG_STAT_EOL) {
+				res = 0;
+			} else
+				if (status & VIA_REG_STAT_FLAG) {
+					res += viadev->fragsize;
+				}
+		}
+	}			    
+unlock:
+	viadev->lastpos = res;
 	spin_unlock(&chip->reg_lock);
 
 	return bytes_to_frames(substream->runtime, res);
@@ -936,8 +1026,8 @@
 	snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
 	snd_via82xx_channel_reset(chip, viadev);
 	snd_via82xx_set_table_ptr(chip, viadev);
-	outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
-	outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
 	outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
 	     (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
 	     rbits | /* rate */
@@ -1239,9 +1329,10 @@
 };
 
 
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
 {
 	chip->devs[idx].reg_offset = reg_offset;
+	chip->devs[idx].shadow_shift = shadow_pos * 4;
 	chip->devs[idx].direction = direction;
 	chip->devs[idx].port = chip->port + reg_offset;
 }
@@ -1271,9 +1362,9 @@
 	chip->pcms[0] = pcm;
 	/* set up playbacks */
 	for (i = 0; i < 4; i++)
-		init_viadev(chip, i, 0x10 * i, 0);
+		init_viadev(chip, i, 0x10 * i, i, 0);
 	/* capture */
-	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1289,9 +1380,9 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[1] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
 	/* set up capture */
-	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
+	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 						         snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1324,9 +1415,9 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
+	init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
 	/* capture */
-	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
+	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1345,7 +1436,7 @@
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[1] = pcm;
 	/* set up playback */
-	init_viadev(chip, chip->playback_devno, 0x30, 0);
+	init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1375,8 +1466,8 @@
 	pcm->private_data = chip;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
-	init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
-	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
+	init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
+	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
@@ -1497,14 +1588,46 @@
 static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
-	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
+	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+
+	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
+	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
+	return 0;
+}
+
+static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
+	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
 	return 0;
 }
 
 static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
+	unsigned long port = chip->port + 0x10 * idx;
+	unsigned char val;
+	int i, change = 0;
+
+	for (i = 0; i < 2; i++) {
+		val = ucontrol->value.integer.value[i];
+		if (val > VIA_DXS_MAX_VOLUME)
+			val = VIA_DXS_MAX_VOLUME;
+		val = VIA_DXS_MAX_VOLUME - val;
+		change |= val != chip->playback_volume[idx][i];
+		if (change) {
+			chip->playback_volume[idx][i] = val;
+			outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+		}
+	}
+	return change;
+}
+
+static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int idx;
 	unsigned char val;
 	int i, change = 0;
@@ -1514,11 +1637,12 @@
 		if (val > VIA_DXS_MAX_VOLUME)
 			val = VIA_DXS_MAX_VOLUME;
 		val = VIA_DXS_MAX_VOLUME - val;
-		if (val != chip->playback_volume[i]) {
+		if (val != chip->playback_volume_c[i]) {
 			change = 1;
-			chip->playback_volume[i] = val;
+			chip->playback_volume_c[i] = val;
 			for (idx = 0; idx < 4; idx++) {
 				unsigned long port = chip->port + 0x10 * idx;
+				chip->playback_volume[idx][i] = val;
 				outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
 			}
 		}
@@ -1526,10 +1650,19 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = {
 	.name = "PCM Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_dxs_volume_info,
+	.get = snd_via8233_pcmdxs_volume_get,
+	.put = snd_via8233_pcmdxs_volume_put,
+};
+
+static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+	.name = "VIA DXS Playback Volume",
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.count = 4,
+	.info = snd_via8233_dxs_volume_info,
 	.get = snd_via8233_dxs_volume_get,
 	.put = snd_via8233_dxs_volume_put,
 };
@@ -1616,12 +1749,12 @@
 		return err;
 	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
 	chip->ac97_bus->clock = chip->ac97_clock;
-	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_via82xx_mixer_free_ac97;
 	ac97.pci = chip->pci;
+	ac97.scaps = AC97_SCAP_SKIP_MODEM;
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
 		return err;
 
@@ -1637,12 +1770,12 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static int __devinit snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
 {
 	struct gameport *gp;
 	struct resource *r;
 
-	if (!joystick[dev])
+	if (!joystick)
 		return -ENODEV;
 
 	r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
@@ -1654,8 +1787,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -1681,12 +1813,11 @@
 
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
-static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+static inline int snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
 {
 	return -ENOSYS;
 }
@@ -1698,7 +1829,7 @@
  *
  */
 
-static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via8233_init_misc(via82xx_t *chip)
 {
 	int i, err, caps;
 	unsigned char val;
@@ -1724,12 +1855,19 @@
 		strcpy(sid.name, "PCM Playback Volume");
 		sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		if (! snd_ctl_find_id(chip->card, &sid)) {
+			snd_printd(KERN_INFO "Using DXS as PCM Playback\n");
+			err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip));
+			if (err < 0)
+				return err;
+		}
+		else /* Using DXS when PCM emulation is enabled is really weird */
+		{
+			/* Standalone DXS controls */
 			err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
 			if (err < 0)
 				return err;
 		}
 	}
-
 	/* select spdif data slot 10/11 */
 	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
 	val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011;
@@ -1739,7 +1877,7 @@
 	return 0;
 }
 
-static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via686_init_misc(via82xx_t *chip)
 {
 	unsigned char legacy, legacy_cfg;
 	int rev_h = 0;
@@ -1750,32 +1888,33 @@
 	legacy &= ~VIA_FUNC_ENABLE_GAME;	/* disable joystick */
 	if (chip->revision >= VIA_REV_686_H) {
 		rev_h = 1;
-		if (mpu_port[dev] >= 0x200) {	/* force MIDI */
-			mpu_port[dev] &= 0xfffc;
-			pci_write_config_dword(chip->pci, 0x18, mpu_port[dev] | 0x01);
+		if (mpu_port >= 0x200) {	/* force MIDI */
+			mpu_port &= 0xfffc;
+			pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
 #ifdef CONFIG_PM
-			chip->mpu_port_saved = mpu_port[dev];
+			chip->mpu_port_saved = mpu_port;
 #endif
 		} else {
-			mpu_port[dev] = pci_resource_start(chip->pci, 2);
+			mpu_port = pci_resource_start(chip->pci, 2);
 		}
 	} else {
-		switch (mpu_port[dev]) {	/* force MIDI */
+		switch (mpu_port) {	/* force MIDI */
 		case 0x300:
 		case 0x310:
 		case 0x320:
 		case 0x330:
 			legacy_cfg &= ~(3 << 2);
-			legacy_cfg |= (mpu_port[dev] & 0x0030) >> 2;
+			legacy_cfg |= (mpu_port & 0x0030) >> 2;
 			break;
 		default:			/* no, use BIOS settings */
 			if (legacy & VIA_FUNC_ENABLE_MIDI)
-				mpu_port[dev] = 0x300 + ((legacy_cfg & 0x000c) << 2);
+				mpu_port = 0x300 + ((legacy_cfg & 0x000c) << 2);
 			break;
 		}
 	}
-	if (mpu_port[dev] >= 0x200 &&
-	    (chip->mpu_res = request_region(mpu_port[dev], 2, "VIA82xx MPU401")) != NULL) {
+	if (mpu_port >= 0x200 &&
+	    (chip->mpu_res = request_region(mpu_port, 2, "VIA82xx MPU401"))
+	    != NULL) {
 		if (rev_h)
 			legacy |= VIA_FUNC_MIDI_PNP;	/* enable PCI I/O 2 */
 		legacy |= VIA_FUNC_ENABLE_MIDI;
@@ -1783,16 +1922,17 @@
 		if (rev_h)
 			legacy &= ~VIA_FUNC_MIDI_PNP;	/* disable PCI I/O 2 */
 		legacy &= ~VIA_FUNC_ENABLE_MIDI;
-		mpu_port[dev] = 0;
+		mpu_port = 0;
 	}
 
 	pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
 	pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
 	if (chip->mpu_res) {
 		if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A,
-					mpu_port[dev], 1,
+					mpu_port, 1,
 					chip->irq, 0, &chip->rmidi) < 0) {
-			printk(KERN_WARNING "unable to initialize MPU-401 at 0x%lx, skipping\n", mpu_port[dev]);
+			printk(KERN_WARNING "unable to initialize MPU-401"
+			       " at 0x%lx, skipping\n", mpu_port);
 			legacy &= ~VIA_FUNC_ENABLE_MIDI;
 		} else {
 			legacy &= ~VIA_FUNC_MIDI_IRQMASK;	/* enable MIDI interrupt */
@@ -1800,7 +1940,7 @@
 		pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
 	}
 
-	snd_via686_create_gameport(chip, dev, &legacy);
+	snd_via686_create_gameport(chip, &legacy);
 
 #ifdef CONFIG_PM
 	chip->legacy_saved = legacy;
@@ -1887,12 +2027,11 @@
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
-		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+		snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
 
 #if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
@@ -1907,8 +2046,7 @@
 			chip->ac97_secondary = 1;
 			goto __ac97_ok2;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
@@ -1940,8 +2078,10 @@
 		int i, idx;
 		for (idx = 0; idx < 4; idx++) {
 			unsigned long port = chip->port + 0x10 * idx;
-			for (i = 0; i < 2; i++)
-				outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+			for (i = 0; i < 2; i++) {
+				chip->playback_volume[idx][i]=chip->playback_volume_c[i];
+				outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+			}
 		}
 	}
 
@@ -2020,10 +2160,7 @@
       __end_hw:
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->mpu_res) {
-		release_resource(chip->mpu_res);
-		kfree_nocheck(chip->mpu_res);
-	}
+	release_and_free_resource(chip->mpu_res);
 	pci_release_regions(chip->pci);
 
 	if (chip->chip_type == TYPE_VIA686) {
@@ -2084,9 +2221,12 @@
 		return err;
 	}
 	chip->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+	if (request_irq(pci->irq,
+			chip_type == TYPE_VIA8233 ?
+			snd_via8233_interrupt :	snd_via686_interrupt,
+			SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 	}
@@ -2178,6 +2318,7 @@
 		{ .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
 		{ .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
 		{ .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
+		{ .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */
 		{ .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
 		{ .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
 		{ .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
@@ -2221,7 +2362,6 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	via82xx_t *chip;
 	unsigned char revision;
@@ -2229,14 +2369,7 @@
 	unsigned int i;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -2259,12 +2392,12 @@
 			}
 		}
 		if (chip_type != TYPE_VIA8233A) {
-			if (dxs_support[dev] == VIA_DXS_AUTO)
-				dxs_support[dev] = check_dxs_list(pci);
+			if (dxs_support == VIA_DXS_AUTO)
+				dxs_support = check_dxs_list(pci);
 			/* force to use VIA8233 or 8233A model according to
 			 * dxs_support module option
 			 */
-			if (dxs_support[dev] == VIA_DXS_DISABLE)
+			if (dxs_support == VIA_DXS_DISABLE)
 				chip_type = TYPE_VIA8233A;
 			else
 				chip_type = TYPE_VIA8233;
@@ -2282,14 +2415,15 @@
 		goto __error;
 	}
 		
-	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+				      ac97_clock, &chip)) < 0)
 		goto __error;
-	if ((err = snd_via82xx_mixer_new(chip, ac97_quirk[dev])) < 0)
+	if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
 		goto __error;
 
 	if (chip_type == TYPE_VIA686) {
 		if ((err = snd_via686_pcm_new(chip)) < 0 ||
-		    (err = snd_via686_init_misc(chip, dev)) < 0)
+		    (err = snd_via686_init_misc(chip)) < 0)
 			goto __error;
 	} else {
 		if (chip_type == TYPE_VIA8233A) {
@@ -2299,16 +2433,16 @@
 		} else {
 			if ((err = snd_via8233_pcm_new(chip)) < 0)
 				goto __error;
-			if (dxs_support[dev] == VIA_DXS_48K)
+			if (dxs_support == VIA_DXS_48K)
 				chip->dxs_fixed = 1;
-			else if (dxs_support[dev] == VIA_DXS_NO_VRA)
+			else if (dxs_support == VIA_DXS_NO_VRA)
 				chip->no_vra = 1;
-			else if (dxs_support[dev] == VIA_DXS_SRC) {
+			else if (dxs_support == VIA_DXS_SRC) {
 				chip->no_vra = 1;
 				chip->dxs_src = 1;
 			}
 		}
-		if ((err = snd_via8233_init_misc(chip, dev)) < 0)
+		if ((err = snd_via8233_init_misc(chip)) < 0)
 			goto __error;
 	}
 
@@ -2329,7 +2463,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 7eac6f6..011f0fb 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -26,7 +26,7 @@
 /*
  * Changes:
  *
- * Sep. 2,  2004  Sasha Khapyorsky <sashak@smlink.com>
+ * Sep. 2,  2004  Sasha Khapyorsky <sashak@alsa-project.org>
  *      Modified from original audio driver 'via82xx.c' to support AC97
  *      modems.
  */
@@ -55,20 +55,21 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{VIA,VT82C686A/B/C modem,pci}}");
 
-static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
-static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
+static int index = -2; /* Exclude the first card */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+static int ac97_clock = 48000;
 
-module_param_array(index, int, NULL, 0444);
+module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for VIA 82xx bridge.");
-module_param_array(id, charp, NULL, 0444);
+module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for VIA 82xx bridge.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable modem part of VIA 82xx bridge.");
-module_param_array(ac97_clock, int, NULL, 0444);
+module_param(ac97_clock, int, 0444);
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 
+/* just for backward compatibility */
+static int enable;
+module_param(enable, bool, 0444);
+
 
 /*
  *  Direct registers
@@ -569,7 +570,7 @@
 		res = viadev->lastpos;
 	} else if (check_invalid_pos(viadev, res)) {
 #ifdef POINTER_DEBUG
-		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+		printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
 #endif
 		if (count && size < count) {
 			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
@@ -832,6 +833,7 @@
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_via686_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_via686_capture_ops);
+	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
 	pcm->private_data = chip;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcms[0] = pcm;
@@ -878,7 +880,6 @@
 		return err;
 	chip->ac97_bus->private_free = snd_via82xx_mixer_free_ac97_bus;
 	chip->ac97_bus->clock = chip->ac97_clock;
-	chip->ac97_bus->shared_type = AC97_SHARED_TYPE_VIA;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -967,12 +968,11 @@
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
-		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
+		snd_printk(KERN_ERR "AC'97 codec is not ready [0x%x]\n", val);
 
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
@@ -986,8 +986,7 @@
 			chip->ac97_secondary = 1;
 			goto __ac97_ok2;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
@@ -1101,7 +1100,7 @@
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 	}
@@ -1135,7 +1134,6 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	static int dev;
 	snd_card_t *card;
 	via82xx_t *chip;
 	unsigned char revision;
@@ -1143,14 +1141,7 @@
 	unsigned int i;
 	int err;
 
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -1167,7 +1158,8 @@
 		goto __error;
 	}
 		
-	if ((err = snd_via82xx_create(card, pci, chip_type, revision, ac97_clock[dev], &chip)) < 0)
+	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
+				      ac97_clock, &chip)) < 0)
 		goto __error;
 	if ((err = snd_via82xx_mixer_new(chip)) < 0)
 		goto __error;
@@ -1191,7 +1183,6 @@
 		return err;
 	}
 	pci_set_drvdata(pci, card);
-	dev++;
 	return 0;
 
  __error:
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 2e69abe..1bbba32 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -130,8 +130,7 @@
 	chip->gameport = gp = gameport_allocate_port();
 	if (!gp) {
 		printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n");
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 		return -ENOMEM;
 	}
 
@@ -161,8 +160,7 @@
 		gameport_unregister_port(chip->gameport);
 		chip->gameport = NULL;
 
-		release_resource(r);
-		kfree_nocheck(r);
+		release_and_free_resource(r);
 	}
 }
 #else
@@ -267,14 +265,8 @@
 				     old_legacy_ctrl,
 			 	     &chip)) < 0) {
 		snd_card_free(card);
-		if (mpu_res) {
-			release_resource(mpu_res);
-			kfree_nocheck(mpu_res);
-		}
-		if (fm_res) {
-			release_resource(fm_res);
-			kfree_nocheck(fm_res);
-		}
+		release_and_free_resource(mpu_res);
+		release_and_free_resource(fm_res);
 		return err;
 	}
 	chip->fm_res = fm_res;
@@ -328,7 +320,7 @@
 			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
 		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
 			snd_card_free(card);
-			snd_printk("cannot create opl3 hwdep\n");
+			snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
 			return err;
 		}
 	}
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 27fa523..88a43e0 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -92,9 +92,9 @@
 		if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
 			return 0;
 		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
-	snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
+	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
 	return -EBUSY;
 }
 
@@ -728,8 +728,7 @@
 		init_waitqueue_entry(&wait, current);
 		add_wait_queue(&chip->interrupt_sleep, &wait);
 		atomic_inc(&chip->interrupt_sleep_count);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/20);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(50));
 		remove_wait_queue(&chip->interrupt_sleep, &wait);
 	}
 }
@@ -1421,15 +1420,18 @@
  *  Mixer controls
  */
 
-#define YMFPCI_SINGLE(xname, xindex, reg) \
+#define YMFPCI_SINGLE(xname, xindex, reg, shift) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
   .info = snd_ymfpci_info_single, \
   .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
-  .private_value = reg }
+  .private_value = ((reg) | ((shift) << 16)) }
 
-static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol,
+				  snd_ctl_elem_info_t *uinfo)
 {
-	switch (kcontrol->private_value) {
+	int reg = kcontrol->private_value & 0xffff;
+
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
@@ -1441,30 +1443,35 @@
 	return 0;
 }
 
-static int snd_ymfpci_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_single(snd_kcontrol_t *kcontrol,
+				 snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1;
+	int reg = kcontrol->private_value & 0xffff;
+	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+	unsigned int mask = 1;
 	
-	switch (kcontrol->private_value) {
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
 	}
-	ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
+	ucontrol->value.integer.value[0] =
+		(snd_ymfpci_readl(chip, reg) >> shift) & mask;
 	return 0;
 }
 
-static int snd_ymfpci_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_single(snd_kcontrol_t *kcontrol,
+				 snd_ctl_elem_value_t *ucontrol)
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
-	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1;
+	int reg = kcontrol->private_value & 0xffff;
+	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
+ 	unsigned int mask = 1;
 	int change;
 	unsigned int val, oval;
 	
-	switch (kcontrol->private_value) {
+	switch (reg) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
@@ -1583,8 +1590,9 @@
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL),
 YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL),
-YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),
+YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4),
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "4ch Duplication",
@@ -1842,9 +1850,7 @@
 	unsigned int count;
 
 	chip = snd_timer_chip(timer);
-	count = timer->sticks - 1;
-	if (count == 0) /* minimum time is 20.8 us */
-		count = 1;
+	count = (timer->sticks << 1) - 1;
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_ymfpci_writew(chip, YDSXGR_TIMERCOUNT, count);
 	snd_ymfpci_writeb(chip, YDSXGR_TIMERCTRL, 0x03);
@@ -1868,14 +1874,14 @@
 					       unsigned long *num, unsigned long *den)
 {
 	*num = 1;
-	*den = 96000;
+	*den = 48000;
 	return 0;
 }
 
 static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
 	.flags = SNDRV_TIMER_HW_AUTO,
-	.resolution = 10417, /* 1/2fs = 10.41666...us */
-	.ticks = 65536,
+	.resolution = 20833, /* 1/fs = 20.8333...us */
+	.ticks = 0x8000,
 	.start = snd_ymfpci_timer_start,
 	.stop = snd_ymfpci_timer_stop,
 	.precise_resolution = snd_ymfpci_timer_precise_resolution,
@@ -2142,14 +2148,8 @@
 #ifdef CONFIG_PM
 	vfree(chip->saved_regs);
 #endif
-	if (chip->mpu_res) {
-		release_resource(chip->mpu_res);
-		kfree_nocheck(chip->mpu_res);
-	}
-	if (chip->fm_res) {
-		release_resource(chip->fm_res);
-		kfree_nocheck(chip->fm_res);
-	}
+	release_and_free_resource(chip->mpu_res);
+	release_and_free_resource(chip->fm_res);
 	snd_ymfpci_free_gameport(chip);
 	if (chip->reg_area_virt)
 		iounmap(chip->reg_area_virt);
@@ -2158,10 +2158,7 @@
 	
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
-	if (chip->res_reg_area) {
-		release_resource(chip->res_reg_area);
-		kfree_nocheck(chip->res_reg_area);
-	}
+	release_and_free_resource(chip->res_reg_area);
 
 	pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
 	
@@ -2290,12 +2287,12 @@
 	pci_set_master(pci);
 
 	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
-		snd_printk("unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
+		snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 	}
 	if (request_irq(pci->irq, snd_ymfpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "YMFPCI", (void *) chip)) {
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 	}
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 0a954dc..20b86d8 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -50,9 +50,9 @@
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already enough large */
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 	}
-	runtime->dma_area = vmalloc_nocheck(size);
+	runtime->dma_area = vmalloc_32(size);
 	if (! runtime->dma_area)
 		return -ENOMEM;
 	runtime->dma_bytes = size;
@@ -67,7 +67,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 1681ee1..d4ec6cc 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -171,8 +171,6 @@
  * beep volume mixer
  */
 
-#define chip_t pmac_t
-
 static int snd_pmac_info_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 392b2ab..db2f1815 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -220,7 +220,8 @@
 
 	/* set up constraints */
 	astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
-	snd_runtime_check(astr, return -EINVAL);
+	if (! astr)
+		return -EINVAL;
 	astr->cur_freqs = 1 << rate_index;
 	astr->cur_formats = 1 << runtime->format;
 	chip->rate_index = rate_index;
@@ -467,7 +468,8 @@
 	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 	int i, freq_table[8], num_freqs;
 
-	snd_runtime_check(rec, return -EINVAL);
+	if (! rec)
+		return -EINVAL;
 	num_freqs = 0;
 	for (i = chip->num_freqs - 1; i >= 0; i--) {
 		if (rec->cur_freqs & (1 << i))
@@ -484,7 +486,8 @@
 	pmac_t *chip = rule->private;
 	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 
-	snd_runtime_check(rec, return -EINVAL);
+	if (! rec)
+		return -EINVAL;
 	return snd_mask_refine_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
 				   rec->cur_formats);
 }
@@ -569,7 +572,8 @@
 	snd_pmac_dma_stop(rec);
 
 	astr = snd_pmac_get_stream(chip, another_stream(rec->stream));
-	snd_runtime_check(astr, return -EINVAL);
+	if (! astr)
+		return -EINVAL;
 
 	/* reset constraints */
 	astr->cur_freqs = chip->freqs_ok;
@@ -1158,7 +1162,6 @@
 		.dev_free =	snd_pmac_dev_free,
 	};
 
-	snd_runtime_check(chip_return, return -EINVAL);
 	*chip_return = NULL;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1382,7 +1385,8 @@
 	pmac_t *chip;
 
 	chip = sleeping_pmac;
-	snd_runtime_check(chip, return 0);
+	if (! chip)
+		return 0;
 
 	switch (when) {
 	case PBOOK_SLEEP_NOW:
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index b5c4c15..59a77129 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -343,9 +343,6 @@
 	struct snd_dbri *next;
 } snd_dbri_t;
 
-/* Needed for the ALSA macros to work */
-#define chip_t snd_dbri_t
-
 #define DBRI_MAX_VOLUME		63	/* Output volume */
 #define DBRI_MAX_GAIN		15	/* Input gain */
 #define DBRI_RIGHT_BALANCE	255
@@ -1767,7 +1764,7 @@
 	spin_unlock_irqrestore(&dbri->lock, flags);
 }
 
-DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
+static DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
 
 /* transmission_complete_intr()
  *
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 751bf12..bd71b73 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -171,7 +171,6 @@
 		vp = &emu->voices[ch];
 		if (STATE_IS_PLAYING(vp->state) &&
 		    vp->chan == chan && vp->key == note) {
-			vp->time = emu->use_time++;
 			vp->state = SNDRV_EMUX_ST_RELEASED;
 			if (vp->ontime == jiffies) {
 				/* if note-off is sent too shortly after
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 2ead878..99dae02 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -41,7 +41,6 @@
 #include <sound/driver.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -185,7 +184,6 @@
 	unsigned int num_formats;		/* number of supported audio formats (list) */
 	struct list_head fmt_list;	/* format list */
 	spinlock_t lock;
-	struct tasklet_struct start_period_elapsed;	/* for start trigger */
 
 	struct snd_urb_ops ops;		/* callbacks (must be filled at init) */
 };
@@ -480,6 +478,28 @@
 }
 
 /*
+ * Prepare urb for streaming before playback starts.
+ *
+ * We don't care about (or have) any data, so we just send a transfer delimiter.
+ */
+static int prepare_startup_playback_urb(snd_usb_substream_t *subs,
+					snd_pcm_runtime_t *runtime,
+					struct urb *urb)
+{
+	unsigned int i;
+	snd_urb_ctx_t *ctx = urb->context;
+
+	urb->dev = ctx->subs->dev;
+	urb->number_of_packets = subs->packs_per_ms;
+	for (i = 0; i < subs->packs_per_ms; ++i) {
+		urb->iso_frame_desc[i].offset = 0;
+		urb->iso_frame_desc[i].length = 0;
+	}
+	urb->transfer_buffer_length = 0;
+	return 0;
+}
+
+/*
  * prepare urb for playback data pipe
  *
  * Since a URB can handle only a single linear buffer, we must use double
@@ -568,12 +588,8 @@
 		subs->hwptr_done -= runtime->buffer_size;
 	spin_unlock_irqrestore(&subs->lock, flags);
 	urb->transfer_buffer_length = offs * stride;
-	if (period_elapsed) {
-		if (likely(subs->running))
-			snd_pcm_period_elapsed(subs->pcm_substream);
-		else
-			tasklet_hi_schedule(&subs->start_period_elapsed);
-	}
+	if (period_elapsed)
+		snd_pcm_period_elapsed(subs->pcm_substream);
 	return 0;
 }
 
@@ -588,22 +604,12 @@
 	return 0;
 }
 
-/*
- * Delay the snd_pcm_period_elapsed() call until after the start trigger
- * callback so that we're not longer in the substream's lock.
- */
-static void start_period_elapsed(unsigned long data)
-{
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)data;
-	snd_pcm_period_elapsed(subs->pcm_substream);
-}
-
 
 /*
  */
 static struct snd_urb_ops audio_urb_ops[2] = {
 	{
-		.prepare =	prepare_playback_urb,
+		.prepare =	prepare_startup_playback_urb,
 		.retire =	retire_playback_urb,
 		.prepare_sync =	prepare_playback_sync_urb,
 		.retire_sync =	retire_playback_sync_urb,
@@ -618,7 +624,7 @@
 
 static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
 	{
-		.prepare =	prepare_playback_urb,
+		.prepare =	prepare_startup_playback_urb,
 		.retire =	retire_playback_urb,
 		.prepare_sync =	prepare_playback_sync_urb_hs,
 		.retire_sync =	retire_playback_sync_urb_hs,
@@ -692,9 +698,9 @@
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already large enough */
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 	}
-	runtime->dma_area = vmalloc_nocheck(size);
+	runtime->dma_area = vmalloc(size);
 	if (! runtime->dma_area)
 		return -ENOMEM;
 	runtime->dma_bytes = size;
@@ -706,7 +712,7 @@
 {
 	snd_pcm_runtime_t *runtime = subs->runtime;
 	if (runtime->dma_area) {
-		vfree_nocheck(runtime->dma_area);
+		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
 	}
 	return 0;
@@ -838,8 +844,7 @@
 		}
 		if (! alive)
 			break;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_before(jiffies, end_time));
 	if (alive)
 		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
@@ -864,25 +869,40 @@
 
 
 /*
- * start/stop substream
+ * start/stop playback substream
  */
-static int snd_usb_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_usb_pcm_playback_trigger(snd_pcm_substream_t *substream,
+					int cmd)
 {
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data;
-	int err;
+	snd_usb_substream_t *subs = substream->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		err = start_urbs(subs, substream->runtime);
-		break;
+		subs->ops.prepare = prepare_playback_urb;
+		return 0;
 	case SNDRV_PCM_TRIGGER_STOP:
-		err = deactivate_urbs(subs, 0, 0);
-		break;
+		return deactivate_urbs(subs, 0, 0);
 	default:
-		err = -EINVAL;
-		break;
+		return -EINVAL;
 	}
-	return err < 0 ? err : 0;
+}
+
+/*
+ * start/stop capture substream
+ */
+static int snd_usb_pcm_capture_trigger(snd_pcm_substream_t *substream,
+				       int cmd)
+{
+	snd_usb_substream_t *subs = substream->runtime->private_data;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		return start_urbs(subs, substream->runtime);
+	case SNDRV_PCM_TRIGGER_STOP:
+		return deactivate_urbs(subs, 0, 0);
+	default:
+		return -EINVAL;
+	}
 }
 
 
@@ -1044,7 +1064,7 @@
 		u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 		u->urb->interval = 1 << subs->datainterval;
 		u->urb->context = u;
-		u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
+		u->urb->complete = snd_complete_urb;
 	}
 
 	if (subs->syncpipe) {
@@ -1070,7 +1090,7 @@
 			u->urb->number_of_packets = 1;
 			u->urb->interval = 1 << subs->syncinterval;
 			u->urb->context = u;
-			u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb);
+			u->urb->complete = snd_complete_sync_urb;
 		}
 	}
 	return 0;
@@ -1414,7 +1434,7 @@
 static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)runtime->private_data;
+	snd_usb_substream_t *subs = runtime->private_data;
 
 	if (! subs->cur_audiofmt) {
 		snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -1434,7 +1454,13 @@
 	deactivate_urbs(subs, 0, 1);
 	wait_clear_urbs(subs);
 
-	return 0;
+	/* for playback, submit the URBs now; otherwise, the first hwptr_done
+	 * updates for all URBs would happen at the same time when starting */
+	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
+		subs->ops.prepare = prepare_startup_playback_urb;
+		return start_urbs(subs, runtime);
+	} else
+		return 0;
 }
 
 static snd_pcm_hardware_t snd_usb_playback =
@@ -1848,7 +1874,7 @@
 	.hw_params =	snd_usb_hw_params,
 	.hw_free =	snd_usb_hw_free,
 	.prepare =	snd_usb_pcm_prepare,
-	.trigger =	snd_usb_pcm_trigger,
+	.trigger =	snd_usb_pcm_playback_trigger,
 	.pointer =	snd_usb_pcm_pointer,
 	.page =		snd_pcm_get_vmalloc_page,
 };
@@ -1860,7 +1886,7 @@
 	.hw_params =	snd_usb_hw_params,
 	.hw_free =	snd_usb_hw_free,
 	.prepare =	snd_usb_pcm_prepare,
-	.trigger =	snd_usb_pcm_trigger,
+	.trigger =	snd_usb_pcm_capture_trigger,
 	.pointer =	snd_usb_pcm_pointer,
 	.page =		snd_pcm_get_vmalloc_page,
 };
@@ -2079,9 +2105,6 @@
 
 	INIT_LIST_HEAD(&subs->fmt_list);
 	spin_lock_init(&subs->lock);
-	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
-		tasklet_init(&subs->start_period_elapsed, start_period_elapsed,
-			     (unsigned long)subs);
 
 	subs->stream = as;
 	subs->direction = stream;
@@ -2755,9 +2778,9 @@
 /*
  * create a stream for an interface with proper descriptors
  */
-static int create_standard_interface_quirk(snd_usb_audio_t *chip,
-					   struct usb_interface *iface,
-					   const snd_usb_audio_quirk_t *quirk)
+static int create_standard_audio_quirk(snd_usb_audio_t *chip,
+				       struct usb_interface *iface,
+				       const snd_usb_audio_quirk_t *quirk)
 {
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
@@ -2765,24 +2788,14 @@
 
 	alts = &iface->altsetting[0];
 	altsd = get_iface_desc(alts);
-	switch (quirk->type) {
-	case QUIRK_AUDIO_STANDARD_INTERFACE:
-		err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
-		if (!err)
-			usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0); /* reset the current interface */
-		break;
-	case QUIRK_MIDI_STANDARD_INTERFACE:
-		err = snd_usb_create_midi_interface(chip, iface, NULL);
-		break;
-	default:
-		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
-		return -ENXIO;
-	}
+	err = parse_audio_endpoints(chip, altsd->bInterfaceNumber);
 	if (err < 0) {
 		snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
 			   altsd->bInterfaceNumber, err);
 		return err;
 	}
+	/* reset the current interface */
+	usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
 	return 0;
 }
 
@@ -3044,7 +3057,7 @@
 		[QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
 		[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
 		[QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface,
-		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk,
+		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
 		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
 		[QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
 		[QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
@@ -3222,7 +3235,6 @@
 				 struct usb_interface *intf,
 				 const struct usb_device_id *usb_id)
 {
-	struct usb_host_config *config = dev->actconfig;
 	const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info;
 	int i, err;
 	snd_usb_audio_t *chip;
@@ -3243,7 +3255,6 @@
 	if (id == USB_ID(0x041e, 0x3000)) {
 		if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
 			goto __err_val;
-		config = dev->actconfig;
 	}
 	/* SB Audigy 2 NX needs its own boot-up magic, too */
 	if (id == USB_ID(0x041e, 0x3020)) {
@@ -3272,11 +3283,6 @@
 		/* it's a fresh one.
 		 * now look for an empty slot and create a new card instance
 		 */
-		/* first, set the current configuration for this device */
-		if (usb_reset_configuration(dev) < 0) {
-			snd_printk(KERN_ERR "cannot reset configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue);
-			goto __error;
-		}
 		for (i = 0; i < SNDRV_CARDS; i++)
 			if (enable[i] && ! usb_chip[i] &&
 			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index ad9eab2..b580202 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -249,14 +249,6 @@
 #define get_cfg_desc(cfg)	(&(cfg)->desc)
 #endif
 
-#ifndef usb_pipe_needs_resubmit
-#define usb_pipe_needs_resubmit(pipe) 1
-#endif
-
-#ifndef snd_usb_complete_callback
-#define snd_usb_complete_callback(x) (x)
-#endif
-
 #ifndef snd_usb_get_speed
 #define snd_usb_get_speed(dev) ((dev)->speed)
 #endif
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index f1a2e2c..f8aa662 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -47,7 +47,6 @@
 #include <linux/timer.h>
 #include <linux/usb.h>
 #include <sound/core.h>
-#include <sound/minors.h>
 #include <sound/rawmidi.h>
 #include "usbaudio.h"
 
@@ -246,10 +245,8 @@
 		}
 	}
 
-	if (usb_pipe_needs_resubmit(urb->pipe)) {
-		urb->dev = ep->umidi->chip->dev;
-		snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
-	}
+	urb->dev = ep->umidi->chip->dev;
+	snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
 }
 
 static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
@@ -863,13 +860,12 @@
 		return -ENOMEM;
 	}
 	if (ep_info->in_interval)
-		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				 snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
-				 ep, ep_info->in_interval);
+		usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+				 length, snd_usbmidi_in_urb_complete, ep,
+				 ep_info->in_interval);
 	else
-		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length,
-				  snd_usb_complete_callback(snd_usbmidi_in_urb_complete),
-				  ep);
+		usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
+				  length, snd_usbmidi_in_urb_complete, ep);
 	ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
 	rep->in = ep;
@@ -933,8 +929,7 @@
 		return -ENOMEM;
 	}
 	usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer,
-			  ep->max_transfer,
-			  snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep);
+			  ep->max_transfer, snd_usbmidi_out_urb_complete, ep);
 	ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 
 	spin_lock_init(&ep->buffer_lock);
@@ -1550,46 +1545,45 @@
 
 	/* detect the endpoint(s) to use */
 	memset(endpoints, 0, sizeof(endpoints));
-	if (!quirk) {
+	switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
+	case QUIRK_MIDI_STANDARD_INTERFACE:
 		err = snd_usbmidi_get_ms_info(umidi, endpoints);
-	} else {
-		switch (quirk->type) {
-		case QUIRK_MIDI_FIXED_ENDPOINT:
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
-			break;
-		case QUIRK_MIDI_YAMAHA:
-			err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
-			break;
-		case QUIRK_MIDI_MIDIMAN:
-			umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = 0;
-			break;
-		case QUIRK_MIDI_NOVATION:
-			umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		case QUIRK_MIDI_RAW:
-			umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		case QUIRK_MIDI_EMAGIC:
-			umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
-			memcpy(&endpoints[0], quirk->data,
-			       sizeof(snd_usb_midi_endpoint_info_t));
-			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
-			break;
-		case QUIRK_MIDI_MIDITECH:
-			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
-			break;
-		default:
-			snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
-			err = -ENXIO;
-			break;
-		}
+		break;
+	case QUIRK_MIDI_FIXED_ENDPOINT:
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+		break;
+	case QUIRK_MIDI_YAMAHA:
+		err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
+		break;
+	case QUIRK_MIDI_MIDIMAN:
+		umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = 0;
+		break;
+	case QUIRK_MIDI_NOVATION:
+		umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	case QUIRK_MIDI_RAW:
+		umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	case QUIRK_MIDI_EMAGIC:
+		umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
+		memcpy(&endpoints[0], quirk->data,
+		       sizeof(snd_usb_midi_endpoint_info_t));
+		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
+		break;
+	case QUIRK_MIDI_MIDITECH:
+		err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+		break;
+	default:
+		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
+		err = -ENXIO;
+		break;
 	}
 	if (err < 0) {
 		kfree(umidi);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index c3c08c9..e570d14 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -911,7 +911,7 @@
 	case USB_ID(0x0672, 0x1041):
 		if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
 		    cval->min == -15616) {
-			snd_printk("using volume control quirk for the UDA1321/N101 chip\n");
+			snd_printk(KERN_INFO "using volume control quirk for the UDA1321/N101 chip\n");
 			cval->max = -256;
 		}
 	}
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 948759d..ba506c3 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -294,6 +294,7 @@
 	}
 },
 {
+	/* a later revision uses ID 0x0099 */
 	USB_DEVICE(0x0582, 0x0005),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -384,6 +385,7 @@
 	}
 },
 {
+	/* a later revision uses ID 0x009d */
 	USB_DEVICE(0x0582, 0x0009),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -532,6 +534,7 @@
 	}
 },
 {
+	/* has ID 0x0013 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0012),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -545,6 +548,7 @@
 	}
 },
 {
+	/* has ID 0x0015 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0014),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -558,6 +562,7 @@
 	}
 },
 {
+	/* has ID 0x0017 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0016),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -588,6 +593,7 @@
 	}
 },
 {
+	/* has ID 0x001c when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001b),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -618,6 +624,7 @@
 	}
 },
 {
+	/* has ID 0x001e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -631,6 +638,7 @@
 	}
 },
 {
+	/* has ID 0x0024 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0023),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -675,6 +683,7 @@
 	}
 },
 {
+	/* has ID 0x0028 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0027),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -688,6 +697,7 @@
 	}
 },
 {
+	/* has ID 0x002a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0029),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -732,6 +742,7 @@
 	}
 },
 {
+	/* has ID 0x002e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -745,6 +756,7 @@
 	}
 },
 {
+	/* has ID 0x0030 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002f),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -758,6 +770,7 @@
 	}
 },
 {
+	/* has ID 0x0034 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0033),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -770,7 +783,12 @@
 		}
 	}
 },
+	/* TODO: add Roland M-1000 support */
 {
+	/*
+	 * Has ID 0x0038 when not in "Advanced Driver" mode;
+	 * later revisions use IDs 0x0054 and 0x00a2.
+	 */
 	USB_DEVICE(0x0582, 0x0037),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -815,6 +833,7 @@
 	}
 },
 {
+	/* has ID 0x0041 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0040),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -828,6 +847,7 @@
 	}
 },
 {
+	/* has ID 0x0043 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0042),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -871,6 +891,7 @@
 	}
 },
 {
+	/* has ID 0x004a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0048),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -883,7 +904,9 @@
 		}
 	}
 },
+	/* TODO: add Edirol M-100FX support */
 {
+	/* has ID 0x004f when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x004d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -931,7 +954,9 @@
 		.type = QUIRK_MIDI_STANDARD_INTERFACE
 	}
 },
+	/* TODO: add Roland EXR support */
 {
+	/* has ID 0x0067 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0065),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
@@ -945,6 +970,7 @@
 	}
 },
 {
+	/* has ID 0x006b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -958,6 +984,7 @@
 	}
 },
 {
+	/* has ID 0x006e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x006d),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
@@ -1002,6 +1029,7 @@
 	}
 },
 {
+	/* has ID 0x0076 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0075),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "BOSS",
@@ -1015,10 +1043,11 @@
 	}
 },
 {
+	/* has ID 0x007b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
-		/* RD-700SX, RD-300SX */
+		/* "RD" or "RD-700SX"? */
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = & (const snd_usb_midi_endpoint_info_t) {
@@ -1048,6 +1077,15 @@
 		}
 	}
 },
+	/* TODO: add Edirol UA-101 support */
+	/* TODO: add Roland G-70 support */
+	/* TODO: add Roland V-SYNTH XT support */
+	/* TODO: add BOSS GT-PRO support */
+	/* TODO: add Edirol PC-50 support */
+	/* TODO: add Edirol PC-80 support */
+	/* TODO: add Edirol UA-1EX support */
+	/* TODO: add Edirol UM-3 support */
+	/* TODO: add Edirol MD-P1 support */
 
 /* Midiman/M-Audio devices */
 {
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 0281a36..8abe086 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -193,7 +193,7 @@
 
 	do {
 		if ((err = usX2Y_create_usbmidi(card)) < 0) {
-			snd_printk("usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
+			snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
 			break;
 		}
 		if ((err = usX2Y_audio_create(card)) < 0) 
@@ -224,7 +224,7 @@
 		}
 		err = usb_set_interface(dev, 0, 1);
 		if (err)
-			snd_printk("usb_set_interface error \n");
+			snd_printk(KERN_ERR "usb_set_interface error \n");
 		else
 			err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
 		kfree(buf);
@@ -235,17 +235,17 @@
 		msleep(250);				// give the device some time
 		err = usX2Y_AsyncSeq04_init(priv);
 		if (err) {
-			snd_printk("usX2Y_AsyncSeq04_init error \n");
+			snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
 			return err;
 		}
 		err = usX2Y_In04_init(priv);
 		if (err) {
-			snd_printk("usX2Y_In04_init error \n");
+			snd_printk(KERN_ERR "usX2Y_In04_init error \n");
 			return err;
 		}
 		err = usX2Y_create_alsa_devices(hw->card);
 		if (err) {
-			snd_printk("usX2Y_create_alsa_devices error %i \n", err);
+			snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
 			snd_card_free(hw->card);
 			return err;
 		}
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index e6e6da1..cf77313 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -251,9 +251,8 @@
 			}
 		}
 
-	if (err) {
-		snd_printk("In04Int() usb_submit_urb err=%i\n", err);
-	}
+	if (err)
+		snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
 
 	urb->dev = usX2Y->chip.dev;
 	usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 0f09e0d..affda97 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -78,7 +78,7 @@
 	for (i = 0; i < nr_of_packs(); i++) {
 		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -134,7 +134,7 @@
 		counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
 		count += counts;
 		if (counts < 43 || counts > 50) {
-			snd_printk("should not be here with counts=%i\n", counts);
+			snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
 			return -EPIPE;
 		}
 		/* set up descriptor */
@@ -196,7 +196,7 @@
 	urb->hcpriv = NULL;
 	urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */
 	if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-		snd_printk("usb_submit_urb() returned %i\n", err);
+		snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
 		return err;
 	}
 	return 0;
@@ -283,16 +283,16 @@
 
 static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
 {
-	snd_printk("ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
+	snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
 	urb->status = 0;
 	usX2Y_clients_stop(usX2Y);
 }
 
 static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
 {
-	snd_printk("Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-		   "Most propably some urb of usb-frame %i is still missing.\n"
-		   "Cause could be too long delays in usb-hcd interrupt handling.\n",
+	snd_printk(KERN_ERR "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+		   KERN_ERR "Most propably some urb of usb-frame %i is still missing.\n"
+		   KERN_ERR "Cause could be too long delays in usb-hcd interrupt handling.\n",
 		   usb_get_current_frame_number(usX2Y->chip.dev),
 		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
 	usX2Y_clients_stop(usX2Y);
@@ -653,9 +653,8 @@
 {
 	usX2Ydev_t*	usX2Y = urb->context;
 	
-	if (urb->status) {
-		snd_printk("snd_usX2Y_04Int() urb->status=%i\n", urb->status);
-	}
+	if (urb->status)
+		snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
 	if (0 == --usX2Y->US04->len)
 		wake_up(&usX2Y->In04WaitQueue);
 }
@@ -740,7 +739,7 @@
 	}
 	usb_kill_urb(usX2Y->In04urb);
 	if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) {
-		snd_printk("usb_set_interface error \n");
+		snd_printk(KERN_ERR "usb_set_interface error \n");
 		return err;
 	}
 	usX2Y->In04urb->dev = usX2Y->chip.dev;
@@ -787,7 +786,7 @@
 		}
 	}
 	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
-		snd_printk("snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
+		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
 		return err;
 	}
 	return 0;
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index d0199c4..0dc828f 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -73,7 +73,7 @@
 	}
 	for (i = 0; i < nr_of_packs(); i++) {
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk("activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -126,7 +126,7 @@
 		/* calculate the size of a packet */
 		counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
 		if (counts < 43 || counts > 50) {
-			snd_printk("should not be here with counts=%i\n", counts);
+			snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
 			return -EPIPE;
 		}
 		/* set up descriptor */