Merge branch 'fix/opl3sa2-suspend' into topic/isa-misc
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 841a936..a763b76 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -346,6 +346,9 @@
     sbirq	- IRQ # for CMI8330 chip (SB16)
     sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
     sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
+    fmport	- (optional) OPL3 I/O port
+    mpuport	- (optional) MPU401 I/O port
+    mpuirq	- (optional) MPU401 irq #
 
     This module supports multiple cards and autoprobe.
 
@@ -606,6 +609,7 @@
     Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
 
     port	- port # for ES-1688 chip (0x220,0x240,0x260)
+    fm_port	- port # for OPL3 (option; share the same port as default)
     mpu_port	- port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
     irq		- IRQ # for ES-1688 chip (5,7,9,10)
     mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
index b3aa62e..d010858 100644
--- a/include/sound/ad1816a.h
+++ b/include/sound/ad1816a.h
@@ -169,5 +169,7 @@
 
 extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
 extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
+extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
+			     struct snd_timer **rtimer);
 
 #endif	/* __SOUND_AD1816A_H */
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 85f93c5..4e62ee1 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -249,6 +249,7 @@
 #define SB_ALS4000_3D_AUTO_MUTE	0x52
 #define SB_ALS4000_ANALOG_BLOCK_CTRL 0x53
 #define SB_ALS4000_3D_DELAYLINE_PATTERN 0x54
+#define SB_ALS4000_CR3_CONFIGURATION	0xc3 /* bit 7 is Digital Loop Enable */
 #define SB_ALS4000_QSOUND	0xdb
 
 /* IRQ setting bitmap */
@@ -330,7 +331,8 @@
 	SB_MIX_DOUBLE,
 	SB_MIX_INPUT_SW,
 	SB_MIX_CAPTURE_PRO,
-	SB_MIX_CAPTURE_DT019X
+	SB_MIX_CAPTURE_DT019X,
+	SB_MIX_MONO_CAPTURE_ALS4K
 };
 
 #define SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) \
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index ce0aa04..5915dc4 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -94,6 +94,8 @@
 	tristate "C-Media CMI8330"
 	select SND_WSS_LIB
 	select SND_SB16_DSP
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
 	help
 	  Say Y here to include support for soundcards based on the
 	  C-Media CMI8330 chip.
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 7752424..15f6010 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -156,6 +156,7 @@
 	struct snd_card_ad1816a *acard;
 	struct snd_ad1816a *chip;
 	struct snd_opl3 *opl3;
+	struct snd_timer *timer;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_ad1816a))) == NULL)
@@ -194,6 +195,12 @@
 		return error;
 	}
 
+	error = snd_ad1816a_timer(chip, 0, &timer);
+	if (error < 0) {
+		snd_card_free(card);
+		return error;
+	}
+
 	if (mpu_port[dev] > 0) {
 		if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 					mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED,
@@ -207,11 +214,8 @@
 				    OPL3_HW_AUTO, 0, &opl3) < 0) {
 			printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2);
 		} else {
-			if ((error = snd_opl3_timer_new(opl3, 1, 2)) < 0) {
-				snd_card_free(card);
-				return error;
-			}
-			if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+			error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+			if (error < 0) {
 				snd_card_free(card);
 				return error;
 			}
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 3bfca7c..05aef8b 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -37,7 +37,7 @@
 		if (inb(AD1816A_REG(AD1816A_CHIP_STATUS)) & AD1816A_READY)
 			return 0;
 
-	snd_printk("chip busy.\n");
+	snd_printk(KERN_WARNING "chip busy.\n");
 	return -EBUSY;
 }
 
@@ -196,7 +196,7 @@
 		spin_unlock(&chip->lock);
 		break;
 	default:
-		snd_printk("invalid trigger mode 0x%x.\n", what);
+		snd_printk(KERN_WARNING "invalid trigger mode 0x%x.\n", what);
 		error = -EINVAL;
 	}
 
@@ -377,7 +377,6 @@
 	.fifo_size =		0,
 };
 
-#if 0 /* not used now */
 static int snd_ad1816a_timer_close(struct snd_timer *timer)
 {
 	struct snd_ad1816a *chip = snd_timer_chip(timer);
@@ -442,8 +441,6 @@
 	.start =	snd_ad1816a_timer_start,
 	.stop =		snd_ad1816a_timer_stop,
 };
-#endif /* not used now */
-
 
 static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
 {
@@ -568,7 +565,7 @@
 	case AD1816A_HW_AD1815:	return "AD1815";
 	case AD1816A_HW_AD18MAX10: return "AD18max10";
 	default:
-		snd_printk("Unknown chip version %d:%d.\n",
+		snd_printk(KERN_WARNING "Unknown chip version %d:%d.\n",
 			chip->version, chip->hardware);
 		return "AD1816A - unknown";
 	}
@@ -687,7 +684,6 @@
 	return 0;
 }
 
-#if 0 /* not used now */
 int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer)
 {
 	struct snd_timer *timer;
@@ -709,7 +705,6 @@
 		*rtimer = timer;
 	return 0;
 }
-#endif /* not used now */
 
 /*
  *
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index e49aec7..9ca8122 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -31,11 +31,11 @@
  *  To quickly load the module,
  *
  *  modprobe -a snd-cmi8330 sbport=0x220 sbirq=5 sbdma8=1
- *    sbdma16=5 wssport=0x530 wssirq=11 wssdma=0
+ *    sbdma16=5 wssport=0x530 wssirq=11 wssdma=0 fmport=0x388
  *
  *  This card has two mixers and two PCM devices.  I've cheesed it such
  *  that recording and playback can be done through the same device.
- *  The driver "magically" routes the capturing to the AD1848 codec,
+ *  The driver "magically" routes the capturing to the CMI8330 codec,
  *  and playback to the SB16 codec.  This allows for full-duplex mode
  *  to some extent.
  *  The utilities in alsa-utils are aware of both devices, so passing
@@ -51,6 +51,8 @@
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/wss.h>
+#include <sound/opl3.h>
+#include <sound/mpu401.h>
 #include <sound/sb.h>
 #include <sound/initval.h>
 
@@ -79,6 +81,9 @@
 static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 static int wssirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 static int wssdma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
+static long fmport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
+static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
+static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard.");
@@ -107,6 +112,12 @@
 module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
+module_param_array(fmport, long, NULL, 0444);
+MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver.");
+module_param_array(mpuport, long, NULL, 0444);
+MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver.");
+module_param_array(mpuirq, int, NULL, 0444);
+MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port.");
 #ifdef CONFIG_PNP
 static int isa_registered;
 static int pnp_registered;
@@ -149,6 +160,7 @@
 #ifdef CONFIG_PNP
 	struct pnp_dev *cap;
 	struct pnp_dev *play;
+	struct pnp_dev *mpu;
 #endif
 	struct snd_card *card;
 	struct snd_wss *wss;
@@ -165,7 +177,7 @@
 #ifdef CONFIG_PNP
 
 static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
-	{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" } } },
+	{ .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
 	{ .id = "" }
 };
 
@@ -219,8 +231,10 @@
 		CMI8330_RMUX3D, 5, 1, 1),
 WSS_SINGLE("PC Speaker Playback Volume", 0,
 		CMI8330_OUTPUTVOL, 3, 3, 0),
-WSS_SINGLE("FM Playback Switch", 0,
-		CMI8330_RECMUX, 3, 1, 1),
+WSS_DOUBLE("FM Playback Switch", 0,
+		CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
+WSS_DOUBLE("FM Playback Volume", 0,
+		CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
 WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", CAPTURE, SWITCH), 0,
 		CMI8330_RMUX3D, 7, 1, 1),
 WSS_SINGLE(SNDRV_CTL_NAME_IEC958("Input ", PLAYBACK, SWITCH), 0,
@@ -323,16 +337,21 @@
 	if (acard->play == NULL)
 		return -EBUSY;
 
+	acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
+	if (acard->play == NULL)
+		return -EBUSY;
+
 	pdev = acard->cap;
 
 	err = pnp_activate_dev(pdev);
 	if (err < 0) {
-		snd_printk(KERN_ERR "CMI8330/C3D (AD1848) PnP configure failure\n");
+		snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n");
 		return -EBUSY;
 	}
 	wssport[dev] = pnp_port_start(pdev, 0);
 	wssdma[dev] = pnp_dma(pdev, 0);
 	wssirq[dev] = pnp_irq(pdev, 0);
+	fmport[dev] = pnp_port_start(pdev, 1);
 
 	/* allocate SB16 resources */
 	pdev = acard->play;
@@ -347,6 +366,17 @@
 	sbdma16[dev] = pnp_dma(pdev, 1);
 	sbirq[dev] = pnp_irq(pdev, 0);
 
+	/* allocate MPU-401 resources */
+	pdev = acard->mpu;
+
+	err = pnp_activate_dev(pdev);
+	if (err < 0) {
+		snd_printk(KERN_ERR
+			   "CMI8330/C3D (MPU-401) PnP configure failure\n");
+		return -EBUSY;
+	}
+	mpuport[dev] = pnp_port_start(pdev, 0);
+	mpuirq[dev] = pnp_irq(pdev, 0);
 	return 0;
 }
 #endif
@@ -487,6 +517,7 @@
 {
 	struct snd_cmi8330 *acard;
 	int i, err;
+	struct snd_opl3 *opl3;
 
 	acard = card->private_data;
 	err = snd_wss_create(card, wssport[dev] + 4, -1,
@@ -494,11 +525,11 @@
 			     wssdma[dev], -1,
 			     WSS_HW_DETECT, 0, &acard->wss);
 	if (err < 0) {
-		snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
+		snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n");
 		return err;
 	}
 	if (acard->wss->hardware != WSS_HW_CMI8330) {
-		snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
+		snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n");
 		return -ENODEV;
 	}
 
@@ -530,6 +561,27 @@
 		snd_printk(KERN_ERR PFX "failed to create pcms\n");
 		return err;
 	}
+	if (fmport[dev] != SNDRV_AUTO_PORT) {
+		if (snd_opl3_create(card,
+				    fmport[dev], fmport[dev] + 2,
+				    OPL3_HW_AUTO, 0, &opl3) < 0) {
+			snd_printk(KERN_ERR PFX
+				   "no OPL device at 0x%lx-0x%lx ?\n",
+				   fmport[dev], fmport[dev] + 2);
+		} else {
+			err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	if (mpuport[dev] != SNDRV_AUTO_PORT) {
+		if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
+					mpuport[dev], 0, mpuirq[dev],
+					IRQF_DISABLED, NULL) < 0)
+			printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
+				mpuport[dev]);
+	}
 
 	strcpy(card->driver, "CMI8330/C3D");
 	strcpy(card->shortname, "C-Media CMI8330/C3D");
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 6a85fdc..2406efd 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -286,7 +286,8 @@
 	if (hardware == WSS_HW_DETECT)
 		hardware = WSS_HW_DETECT3;
 	if (cport < 0x100) {
-		snd_printk("please, specify control port for CS4236+ chips\n");
+		snd_printk(KERN_ERR "please, specify control port "
+			   "for CS4236+ chips\n");
 		return -ENODEV;
 	}
 	err = snd_wss_create(card, port, cport,
@@ -295,7 +296,8 @@
 		return err;
 
 	if (!(chip->hardware & WSS_HW_CS4236B_MASK)) {
-	        snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware);
+		snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers "
+			   "not available, hardware=0x%x\n", chip->hardware);
 		snd_device_free(card, chip);
 		return -ENODEV;
 	}
@@ -303,16 +305,19 @@
 	{
 		int idx;
 		for (idx = 0; idx < 8; idx++)
-			snd_printk("CD%i = 0x%x\n", idx, inb(chip->cport + idx));
+			snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
+				   idx, inb(chip->cport + idx));
 		for (idx = 0; idx < 9; idx++)
-			snd_printk("C%i = 0x%x\n", idx, snd_cs4236_ctrl_in(chip, idx));
+			snd_printk(KERN_DEBUG "C%i = 0x%x\n",
+				   idx, snd_cs4236_ctrl_in(chip, idx));
 	}
 #endif
 	ver1 = snd_cs4236_ctrl_in(chip, 1);
 	ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
 	snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
 	if (ver1 != ver2) {
-		snd_printk("CS4236+ chip detected, but control port 0x%lx is not valid\n", cport);
+		snd_printk(KERN_ERR "CS4236+ chip detected, but "
+			   "control port 0x%lx is not valid\n", cport);
 		snd_device_free(card, chip);
 		return -ENODEV;
 	}
@@ -883,7 +888,8 @@
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 1 : 0;
 #if 0
-	printk("get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
+	printk(KERN_DEBUG "get valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, "
+	       "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
 			snd_wss_in(chip, CS4231_ALT_FEATURE_1),
 			snd_cs4236_ctrl_in(chip, 3),
 			snd_cs4236_ctrl_in(chip, 4),
@@ -920,7 +926,8 @@
 	mutex_unlock(&chip->mce_mutex);
 
 #if 0
-	printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
+	printk(KERN_DEBUG "set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, "
+	       "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
 			snd_wss_in(chip, CS4231_ALT_FEATURE_1),
 			snd_cs4236_ctrl_in(chip, 3),
 			snd_cs4236_ctrl_in(chip, 4),
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index b463771..b0eb0cf 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -49,6 +49,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x220,0x240,0x260 */
+static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* Usually 0x388 */
 static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 5,7,9,10 */
 static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 5,7,9,10 */
@@ -65,6 +66,8 @@
 module_param_array(mpu_port, long, NULL, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
+module_param_array(fm_port, long, NULL, 0444);
+MODULE_PARM_DESC(fm_port, "FM port # for ES1688 driver.");
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(mpu_irq, int, NULL, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
@@ -143,13 +146,19 @@
 	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
 		chip->port, chip->irq, chip->dma8);
 
-	if (snd_opl3_create(card, chip->port, chip->port + 2,
-			OPL3_HW_OPL3, 0, &opl3) < 0)
-		dev_warn(dev, "opl3 not detected at 0x%lx\n", chip->port);
-	else {
-		error =	snd_opl3_hwdep_new(opl3, 0, 1, NULL);
-		if (error < 0)
-			goto out;
+	if (fm_port[n] == SNDRV_AUTO_PORT)
+		fm_port[n] = port[n];	/* share the same port */
+
+	if (fm_port[n] > 0) {
+		if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
+				OPL3_HW_OPL3, 0, &opl3) < 0)
+			dev_warn(dev,
+				 "opl3 not detected at 0x%lx\n", fm_port[n]);
+		else {
+			error =	snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+			if (error < 0)
+				goto out;
+		}
 	}
 
 	if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 4fbb508..4c6e14f 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -45,7 +45,7 @@
 			return 1;
 		}
 #ifdef CONFIG_SND_DEBUG
-	printk("snd_es1688_dsp_command: timeout (0x%x)\n", val);
+	printk(KERN_DEBUG "snd_es1688_dsp_command: timeout (0x%x)\n", val);
 #endif
 	return 0;
 }
@@ -167,13 +167,16 @@
 	hw = ES1688_HW_AUTO;
 	switch (chip->version & 0xfff0) {
 	case 0x4880:
-		snd_printk("[0x%lx] ESS: AudioDrive ES488 detected, but driver is in another place\n", chip->port);
+		snd_printk(KERN_ERR "[0x%lx] ESS: AudioDrive ES488 detected, "
+			   "but driver is in another place\n", chip->port);
 		return -ENODEV;
 	case 0x6880:
 		hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688;
 		break;
 	default:
-		snd_printk("[0x%lx] ESS: unknown AudioDrive chip with version 0x%x (Jazz16 soundcard?)\n", chip->port, chip->version);
+		snd_printk(KERN_ERR "[0x%lx] ESS: unknown AudioDrive chip "
+			   "with version 0x%x (Jazz16 soundcard?)\n",
+			   chip->port, chip->version);
 		return -ENODEV;
 	}
 
@@ -223,7 +226,7 @@
 		}
 	}
 #if 0
-	snd_printk("mpu cfg = 0x%x\n", cfg);
+	snd_printk(KERN_DEBUG "mpu cfg = 0x%x\n", cfg);
 #endif
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_es1688_mixer_write(chip, 0x40, cfg);
@@ -237,7 +240,9 @@
 		cfg = 0xf0;	/* enable only DMA counter interrupt */
 		irq_bits = irqs[chip->irq & 0x0f];
 		if (irq_bits < 0) {
-			snd_printk("[0x%lx] ESS: bad IRQ %d for ES1688 chip!!\n", chip->port, chip->irq);
+			snd_printk(KERN_ERR "[0x%lx] ESS: bad IRQ %d "
+				   "for ES1688 chip!!\n",
+				   chip->port, chip->irq);
 #if 0
 			irq_bits = 0;
 			cfg = 0x10;
@@ -250,7 +255,8 @@
 		cfg = 0xf0;	/* extended mode DMA enable */
 		dma = chip->dma8;
 		if (dma > 3 || dma == 2) {
-			snd_printk("[0x%lx] ESS: bad DMA channel %d for ES1688 chip!!\n", chip->port, dma);
+			snd_printk(KERN_ERR "[0x%lx] ESS: bad DMA channel %d "
+				   "for ES1688 chip!!\n", chip->port, dma);
 #if 0
 			dma_bits = 0;
 			cfg = 0x00;	/* disable all DMA */
@@ -341,8 +347,9 @@
 		return -EINVAL;	/* something is wrong */
 	}
 #if 0
-	printk("trigger: val = 0x%x, value = 0x%x\n", val, value);
-	printk("trigger: pointer = 0x%x\n", snd_dma_pointer(chip->dma8, chip->dma_size));
+	printk(KERN_DEBUG "trigger: val = 0x%x, value = 0x%x\n", val, value);
+	printk(KERN_DEBUG "trigger: pointer = 0x%x\n",
+	       snd_dma_pointer(chip->dma8, chip->dma_size));
 #endif
 	snd_es1688_write(chip, 0xb8, (val & 0xf0) | value);
 	spin_unlock(&chip->reg_lock);
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index f45f611..36c27c8 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -45,7 +45,8 @@
 	unsigned char dma_cmd;
 	unsigned int address_high;
 
-	// snd_printk("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n", addr, (long) buf, count);
+	snd_printdd("dma_transfer: addr=0x%x, buf=0x%lx, count=0x%x\n",
+		    addr, buf_addr, count);
 
 	if (gus->gf1.dma1 > 3) {
 		if (gus->gf1.enh_mode) {
@@ -77,7 +78,8 @@
 	snd_gf1_dma_ack(gus);
 	snd_dma_program(gus->gf1.dma1, buf_addr, count, dma_cmd & SNDRV_GF1_DMA_READ ? DMA_MODE_READ : DMA_MODE_WRITE);
 #if 0
-	snd_printk("address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n", address << 1, count, dma_cmd);
+	snd_printk(KERN_DEBUG "address = 0x%x, count = 0x%x, dma_cmd = 0x%x\n",
+		   address << 1, count, dma_cmd);
 #endif
 	spin_lock_irqsave(&gus->reg_lock, flags);
 	if (gus->gf1.enh_mode) {
@@ -142,7 +144,9 @@
 	snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd);
 	kfree(block);
 #if 0
-	printk("program dma (IRQ) - addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", addr, (long) buffer, count, cmd);
+	snd_printd(KERN_DEBUG "program dma (IRQ) - "
+		   "addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
+		   block->addr, block->buf_addr, block->count, block->cmd);
 #endif
 }
 
@@ -203,13 +207,16 @@
 	}
 	*block = *__block;
 	block->next = NULL;
-#if 0
-	printk("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n", block->addr, (long) block->buffer, block->count, block->cmd);
-#endif
-#if 0
-	printk("gus->gf1.dma_data_pcm_last = 0x%lx\n", (long)gus->gf1.dma_data_pcm_last);
-	printk("gus->gf1.dma_data_pcm = 0x%lx\n", (long)gus->gf1.dma_data_pcm);
-#endif
+
+	snd_printdd("addr = 0x%x, buffer = 0x%lx, count = 0x%x, cmd = 0x%x\n",
+		    block->addr, (long) block->buffer, block->count,
+		    block->cmd);
+
+	snd_printdd("gus->gf1.dma_data_pcm_last = 0x%lx\n",
+		    (long)gus->gf1.dma_data_pcm_last);
+	snd_printdd("gus->gf1.dma_data_pcm = 0x%lx\n",
+		    (long)gus->gf1.dma_data_pcm);
+
 	spin_lock_irqsave(&gus->dma_lock, flags);
 	if (synth) {
 		if (gus->gf1.dma_data_synth_last) {
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index 041894d..2055aff 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -41,7 +41,7 @@
 	if (status == 0)
 		return IRQ_RETVAL(handled);
 	handled = 1;
-	// snd_printk("IRQ: status = 0x%x\n", status);
+	/* snd_printk(KERN_DEBUG "IRQ: status = 0x%x\n", status); */
 	if (status & 0x02) {
 		STAT_ADD(gus->gf1.interrupt_stat_midi_in);
 		if (gus->gf1.interrupt_handler_midi_in)
@@ -65,7 +65,9 @@
 				continue;	/* multi request */
 			already |= _current_;	/* mark request */
 #if 0
-			printk("voice = %i, voice_status = 0x%x, voice_verify = %i\n", voice, voice_status, inb(GUSP(gus, GF1PAGE)));
+			printk(KERN_DEBUG "voice = %i, voice_status = 0x%x, "
+			       "voice_verify = %i\n",
+			       voice, voice_status, inb(GUSP(gus, GF1PAGE)));
 #endif
 			pvoice = &gus->gf1.voices[voice]; 
 			if (pvoice->use) {
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 38510ae..edb11ee 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -82,7 +82,10 @@
 
 	count += offset & 31;
 	offset &= ~31;
-	// snd_printk("block change - offset = 0x%x, count = 0x%x\n", offset, count);
+	/*
+	snd_printk(KERN_DEBUG "block change - offset = 0x%x, count = 0x%x\n",
+		   offset, count);
+	*/
 	memset(&block, 0, sizeof(block));
 	block.cmd = SNDRV_GF1_DMA_IRQ;
 	if (snd_pcm_format_unsigned(runtime->format))
@@ -135,7 +138,11 @@
 		curr = begin + (pcmp->bpos * pcmp->block_size) / runtime->channels;
 		end = curr + (pcmp->block_size / runtime->channels);
 		end -= snd_pcm_format_width(runtime->format) == 16 ? 2 : 1;
-		// snd_printk("init: curr=0x%x, begin=0x%x, end=0x%x, ctrl=0x%x, ramp=0x%x, rate=0x%x\n", curr, begin, end, voice_ctrl, ramp_ctrl, rate);
+		/*
+		snd_printk(KERN_DEBUG "init: curr=0x%x, begin=0x%x, end=0x%x, "
+			   "ctrl=0x%x, ramp=0x%x, rate=0x%x\n",
+			   curr, begin, end, voice_ctrl, ramp_ctrl, rate);
+		*/
 		pan = runtime->channels == 2 ? (!voice ? 1 : 14) : 8;
 		vol = !voice ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right;
 		spin_lock_irqsave(&gus->reg_lock, flags);
@@ -205,9 +212,11 @@
 	ramp_ctrl = (snd_gf1_read8(gus, SNDRV_GF1_VB_VOLUME_CONTROL) & ~0xa4) | 0x03;
 #if 0
 	snd_gf1_select_voice(gus, pvoice->number);
-	printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
+	printk(KERN_DEBUG "position = 0x%x\n",
+	       (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
 	snd_gf1_select_voice(gus, pcmp->pvoices[1]->number);
-	printk("position = 0x%x\n", (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
+	printk(KERN_DEBUG "position = 0x%x\n",
+	       (snd_gf1_read_addr(gus, SNDRV_GF1_VA_CURRENT, voice_ctrl & 4) >> 4));
 	snd_gf1_select_voice(gus, pvoice->number);
 #endif
 	pcmp->bpos++;
@@ -299,7 +308,11 @@
 	unsigned int len;
 	unsigned long flags;
 
-	// printk("poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n", (int)buf, pos, count, gus->gf1.port);
+	/*
+	printk(KERN_DEBUG
+	       "poke block; buf = 0x%x, pos = %i, count = %i, port = 0x%x\n",
+	       (int)buf, pos, count, gus->gf1.port);
+	*/
 	while (count > 0) {
 		len = count;
 		if (len > 512)		/* limit, to allow IRQ */
@@ -680,7 +693,8 @@
 	runtime->private_free = snd_gf1_pcm_playback_free;
 
 #if 0
-	printk("playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n", (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer);
+	printk(KERN_DEBUG "playback.buffer = 0x%lx, gf1.pcm_buffer = 0x%lx\n",
+	       (long) pcm->playback.buffer, (long) gus->gf1.pcm_buffer);
 #endif
 	if ((err = snd_gf1_dma_init(gus)) < 0)
 		return err;
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index f0af3f7..21cc42e 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -129,8 +129,14 @@
 	}
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 #if 0
-	snd_printk("read init - enable = %i, cmd = 0x%x, stat = 0x%x\n", gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
-	snd_printk("[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x (page = 0x%x)\n", gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100), inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102));
+	snd_printk(KERN_DEBUG
+		   "read init - enable = %i, cmd = 0x%x, stat = 0x%x\n",
+		   gus->uart_enable, gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
+	snd_printk(KERN_DEBUG
+		   "[0x%x] reg (ctrl/status) = 0x%x, reg (data) = 0x%x "
+		   "(page = 0x%x)\n",
+		   gus->gf1.port + 0x100, inb(gus->gf1.port + 0x100),
+		   inb(gus->gf1.port + 0x101), inb(gus->gf1.port + 0x102));
 #endif
 	return 0;
 }
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 5faecfb..418d49e 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -170,7 +170,7 @@
 	unsigned long port = bus->private_value;
 
 #if 0
-	printk("i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);
+	printk(KERN_DEBUG "i2c_setlines - 0x%lx <- %i,%i\n", port, ctrl, data);
 #endif
 	outb((data << 1) | ctrl, port);
 	udelay(10);
@@ -183,7 +183,7 @@
 
 	res = inb(port) & 1;
 #if 0
-	printk("i2c_getclockline - 0x%lx -> %i\n", port, res);
+	printk(KERN_DEBUG "i2c_getclockline - 0x%lx -> %i\n", port, res);
 #endif
 	return res;
 }
@@ -197,7 +197,7 @@
 		udelay(10);
 	res = (inb(port) & 2) >> 1;
 #if 0
-	printk("i2c_getdataline - 0x%lx -> %i\n", port, res);
+	printk(KERN_DEBUG "i2c_getdataline - 0x%lx -> %i\n", port, res);
 #endif
 	return res;
 }
@@ -342,7 +342,8 @@
 			snd_gf1_poke(gus, local, d);
 			snd_gf1_poke(gus, local + 1, d + 1);
 #if 0
-			printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n",
+			printk(KERN_DEBUG "d = 0x%x, local = 0x%x, "
+			       "local + 1 = 0x%x, idx << 22 = 0x%x\n",
 			       d,
 			       snd_gf1_peek(gus, local),
 			       snd_gf1_peek(gus, local + 1),
@@ -356,7 +357,8 @@
 		}
 	}
 #if 0
-	printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]);
+	printk(KERN_DEBUG "sizes: %i %i %i %i\n",
+	       sizes[0], sizes[1], sizes[2], sizes[3]);
 #endif
 }
 
@@ -410,12 +412,12 @@
 		lmct = (psizes[3] << 24) | (psizes[2] << 16) |
 		    (psizes[1] << 8) | psizes[0];
 #if 0
-		printk("lmct = 0x%08x\n", lmct);
+		printk(KERN_DEBUG "lmct = 0x%08x\n", lmct);
 #endif
 		for (i = 0; i < ARRAY_SIZE(lmc); i++)
 			if (lmct == lmc[i]) {
 #if 0
-				printk("found !!! %i\n", i);
+				printk(KERN_DEBUG "found !!! %i\n", i);
 #endif
 				snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i);
 				snd_interwave_bank_sizes(gus, psizes);
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index b848d10..3f0b877 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -179,12 +179,13 @@
 	unsigned char result;
 #if 0
 	outb(0x1d, port);	/* password */
-	printk("read [0x%lx] = 0x%x\n", port, inb(port));
+	printk(KERN_DEBUG "read [0x%lx] = 0x%x\n", port, inb(port));
 #endif
 	outb(reg, chip->port);	/* register */
 	result = inb(chip->port + 1);
 #if 0
-	printk("read [0x%lx] = 0x%x [0x%x]\n", port, result, inb(port));
+	printk(KERN_DEBUG "read [0x%lx] = 0x%x [0x%x]\n",
+	       port, result, inb(port));
 #endif
 	return result;
 }
@@ -233,7 +234,10 @@
 		snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
 		return -EBUSY;
 	}
-	// snd_printk("REG 0A = 0x%x\n", snd_opl3sa2_read(chip, 0x0a));
+	/*
+	snd_printk(KERN_DEBUG "REG 0A = 0x%x\n",
+		   snd_opl3sa2_read(chip, 0x0a));
+	*/
 	chip->version = 0;
 	tmp = snd_opl3sa2_read(chip, OPL3SA2_MISC);
 	if (tmp == 0xff) {
@@ -619,7 +623,7 @@
 {
 	struct snd_opl3sa2 *chip = card->private_data;
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, card);
 	release_and_free_resource(chip->res_port);
 }
 
@@ -632,7 +636,7 @@
 	if (card == NULL)
 		return NULL;
 	strcpy(card->driver, "OPL3SA2");
-	strcpy(card->shortname, "Yamaha OPL3-SA2");
+	strcpy(card->shortname, "Yamaha OPL3-SA");
 	chip = card->private_data;
 	spin_lock_init(&chip->reg_lock);
 	chip->irq = -1;
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 19706b0..d5bc0e0 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -252,7 +252,7 @@
 #endif	/* OPTi93X */
 
 	default:
-		snd_printk("chip %d not supported\n", hardware);
+		snd_printk(KERN_ERR "chip %d not supported\n", hardware);
 		return -ENODEV;
 	}
 	return 0;
@@ -294,7 +294,7 @@
 #endif	/* OPTi93X */
 
 	default:
-		snd_printk("chip %d not supported\n", chip->hardware);
+		snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
 	}
 
 	spin_unlock_irqrestore(&chip->lock, flags);
@@ -336,7 +336,7 @@
 #endif	/* OPTi93X */
 
 	default:
-		snd_printk("chip %d not supported\n", chip->hardware);
+		snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
 	}
 
 	spin_unlock_irqrestore(&chip->lock, flags);
@@ -412,7 +412,7 @@
 #endif	/* OPTi93X */
 
 	default:
-		snd_printk("chip %d not supported\n", chip->hardware);
+		snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
 		return -EINVAL;
 	}
 
@@ -430,7 +430,8 @@
 		wss_base_bits = 0x02;
 		break;
 	default:
-		snd_printk("WSS port 0x%lx not valid\n", chip->wss_base);
+		snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n",
+			   chip->wss_base);
 		goto __skip_base;
 	}
 	snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
@@ -455,7 +456,7 @@
 		irq_bits = 0x04;
 		break;
 	default:
-		snd_printk("WSS irq # %d not valid\n", chip->irq);
+		snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq);
 		goto __skip_resources;
 	}
 
@@ -470,13 +471,14 @@
 		dma_bits = 0x03;
 		break;
 	default:
-		snd_printk("WSS dma1 # %d not valid\n", chip->dma1);
+		snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n",
+			   chip->dma1);
 		goto __skip_resources;
 	}
 
 #if defined(CS4231) || defined(OPTi93X)
 	if (chip->dma1 == chip->dma2) {
-		snd_printk("don't want to share dmas\n");
+		snd_printk(KERN_ERR "don't want to share dmas\n");
 		return -EBUSY;
 	}
 
@@ -485,7 +487,8 @@
 	case 1:
 		break;
 	default:
-		snd_printk("WSS dma2 # %d not valid\n", chip->dma2);
+		snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n",
+			   chip->dma2);
 		goto __skip_resources;
 	}
 	dma_bits |= 0x04;
@@ -516,7 +519,8 @@
 			mpu_port_bits = 0x00;
 			break;
 		default:
-			snd_printk("MPU-401 port 0x%lx not valid\n",
+			snd_printk(KERN_WARNING
+				   "MPU-401 port 0x%lx not valid\n",
 				chip->mpu_port);
 			goto __skip_mpu;
 		}
@@ -535,7 +539,7 @@
 			mpu_irq_bits = 0x01;
 			break;
 		default:
-			snd_printk("MPU-401 irq # %d not valid\n",
+			snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
 				chip->mpu_irq);
 			goto __skip_mpu;
 		}
@@ -726,7 +730,7 @@
 	if (chip->wss_base == SNDRV_AUTO_PORT) {
 		chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4);
 		if (chip->wss_base < 0) {
-			snd_printk("unable to find a free WSS port\n");
+			snd_printk(KERN_ERR "unable to find a free WSS port\n");
 			return -EBUSY;
 		}
 	}
@@ -815,14 +819,8 @@
 				   chip->fm_port, chip->fm_port + 4 - 1);
 		}
 		if (opl3) {
-#ifdef CS4231
-			const int t1dev = 1;
-#else
-			const int t1dev = 0;
-#endif
-			if ((error = snd_opl3_timer_new(opl3, t1dev, t1dev+1)) < 0)
-				return error;
-			if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0)
+			error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
+			if (error < 0)
 				return error;
 		}
 	}
@@ -897,7 +895,7 @@
 #if defined(CS4231) || defined(OPTi93X)
 	if (dma2 == SNDRV_AUTO_DMA) {
 		if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) {
-			snd_printk("unable to find a free DMA2\n");
+			snd_printk(KERN_ERR "unable to find a free DMA2\n");
 			return -EBUSY;
 		}
 	}
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 406a431..475220b 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -182,7 +182,7 @@
 
 static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[5] = {
+	static const char *texts[5] = {
 		"CD", "Mic", "Line", "Synth", "Master"
 	};
 
@@ -269,12 +269,73 @@
 }
 
 /*
+ * ALS4000 mono recording control switch
+ */
+
+static int snd_als4k_mono_capture_route_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
+{
+	static const char *texts[3] = {
+		"L chan only", "R chan only", "L ch/2 + R ch/2"
+	};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item > 2)
+		uinfo->value.enumerated.item = 2;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_als4k_mono_capture_route_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
+	unsigned long flags;
+	unsigned char oval;
+
+	spin_lock_irqsave(&sb->mixer_lock, flags);
+	oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
+	spin_unlock_irqrestore(&sb->mixer_lock, flags);
+	oval >>= 6;
+	if (oval > 2)
+		oval = 2;
+
+	ucontrol->value.enumerated.item[0] = oval;
+	return 0;
+}
+
+static int snd_als4k_mono_capture_route_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
+	unsigned long flags;
+	int change;
+	unsigned char nval, oval;
+
+	if (ucontrol->value.enumerated.item[0] > 2)
+		return -EINVAL;
+	spin_lock_irqsave(&sb->mixer_lock, flags);
+	oval = snd_sbmixer_read(sb, SB_ALS4000_MONO_IO_CTRL);
+
+	nval = (oval & ~(3 << 6))
+	     | (ucontrol->value.enumerated.item[0] << 6);
+	change = nval != oval;
+	if (change)
+		snd_sbmixer_write(sb, SB_ALS4000_MONO_IO_CTRL, nval);
+	spin_unlock_irqrestore(&sb->mixer_lock, flags);
+	return change;
+}
+
+/*
  * SBPRO input multiplexer
  */
 
 static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	static char *texts[3] = {
+	static const char *texts[3] = {
 		"Mic", "CD", "Line"
 	};
 
@@ -442,6 +503,12 @@
 			.get = snd_dt019x_input_sw_get,
 			.put = snd_dt019x_input_sw_put,
 		},
+		[SB_MIX_MONO_CAPTURE_ALS4K] = {
+			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+			.info = snd_als4k_mono_capture_route_info,
+			.get = snd_als4k_mono_capture_route_get,
+			.put = snd_als4k_mono_capture_route_put,
+		},
 	};
 	struct snd_kcontrol *ctl;
 	int err;
@@ -636,6 +703,8 @@
 	};
 
 static struct sbmix_elem *snd_dt019x_controls[] = {
+	/* ALS4000 below has some parts which we might be lacking,
+	 * e.g. snd_als4000_ctl_mono_playback_switch - check it! */
 	&snd_dt019x_ctl_master_play_vol,
 	&snd_dt019x_ctl_pcm_play_vol,
 	&snd_dt019x_ctl_synth_play_vol,
@@ -666,18 +735,21 @@
 /*
  * ALS4000 specific mixer elements
  */
-/* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl! */
 static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch =
 	SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1);
-static struct sbmix_elem snd_als4000_ctl_master_mono_capture_route =
-	SB_SINGLE("Master Mono Capture Route", SB_ALS4000_MONO_IO_CTRL, 6, 0x03);
-/* FIXME: mono playback switch also available on DT019X? */
+static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = {
+		.name = "Master Mono Capture Route",
+		.type = SB_MIX_MONO_CAPTURE_ALS4K
+	};
 static struct sbmix_elem snd_als4000_ctl_mono_playback_switch =
 	SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
 static struct sbmix_elem snd_als4000_ctl_mic_20db_boost =
 	SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
-static struct sbmix_elem snd_als4000_ctl_mixer_loopback =
-	SB_SINGLE("Analog Loopback", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
+static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback =
+	SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
+static struct sbmix_elem snd_als4000_ctl_mixer_digital_loopback =
+	SB_SINGLE("Digital Loopback Switch",
+		  SB_ALS4000_CR3_CONFIGURATION, 7, 0x01);
 /* FIXME: functionality of 3D controls might be swapped, I didn't find
  * a description of how to identify what is supposed to be what */
 static struct sbmix_elem snd_als4000_3d_control_switch =
@@ -694,6 +766,9 @@
 	SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
 static struct sbmix_elem snd_als4000_3d_control_poweroff_switch =
 	SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
+static struct sbmix_elem snd_als4000_ctl_3db_freq_control_switch =
+	SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch",
+		  SB_ALS4000_FMDAC, 5, 0x01);
 #ifdef NOT_AVAILABLE
 static struct sbmix_elem snd_als4000_ctl_fmdac =
 	SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
@@ -702,35 +777,37 @@
 #endif
 
 static struct sbmix_elem *snd_als4000_controls[] = {
-	&snd_sb16_ctl_master_play_vol,
-	&snd_dt019x_ctl_pcm_play_switch,
-	&snd_sb16_ctl_pcm_play_vol,
-	&snd_sb16_ctl_synth_capture_route,
-	&snd_dt019x_ctl_synth_play_switch,
-	&snd_sb16_ctl_synth_play_vol,
-	&snd_sb16_ctl_cd_capture_route,
-	&snd_sb16_ctl_cd_play_switch,
-	&snd_sb16_ctl_cd_play_vol,
-	&snd_sb16_ctl_line_capture_route,
-	&snd_sb16_ctl_line_play_switch,
-	&snd_sb16_ctl_line_play_vol,
-	&snd_sb16_ctl_mic_capture_route,
-	&snd_als4000_ctl_mic_20db_boost,
-	&snd_sb16_ctl_auto_mic_gain,
-	&snd_sb16_ctl_mic_play_switch,
-	&snd_sb16_ctl_mic_play_vol,
-	&snd_sb16_ctl_pc_speaker_vol,
-	&snd_sb16_ctl_capture_vol,
-	&snd_sb16_ctl_play_vol,
-	&snd_als4000_ctl_master_mono_playback_switch,
-	&snd_als4000_ctl_master_mono_capture_route,
-	&snd_als4000_ctl_mono_playback_switch,
-	&snd_als4000_ctl_mixer_loopback,
-	&snd_als4000_3d_control_switch,
-	&snd_als4000_3d_control_ratio,
-	&snd_als4000_3d_control_freq,
-	&snd_als4000_3d_control_delay,
-	&snd_als4000_3d_control_poweroff_switch,
+						/* ALS4000a.PDF regs page */
+	&snd_sb16_ctl_master_play_vol,		/* MX30/31 12 */
+	&snd_dt019x_ctl_pcm_play_switch,	/* MX4C    16 */
+	&snd_sb16_ctl_pcm_play_vol,		/* MX32/33 12 */
+	&snd_sb16_ctl_synth_capture_route,	/* MX3D/3E 14 */
+	&snd_dt019x_ctl_synth_play_switch,	/* MX4C    16 */
+	&snd_sb16_ctl_synth_play_vol,		/* MX34/35 12/13 */
+	&snd_sb16_ctl_cd_capture_route,		/* MX3D/3E 14 */
+	&snd_sb16_ctl_cd_play_switch,		/* MX3C    14 */
+	&snd_sb16_ctl_cd_play_vol,		/* MX36/37 13 */
+	&snd_sb16_ctl_line_capture_route,	/* MX3D/3E 14 */
+	&snd_sb16_ctl_line_play_switch,		/* MX3C    14 */
+	&snd_sb16_ctl_line_play_vol,		/* MX38/39 13 */
+	&snd_sb16_ctl_mic_capture_route,	/* MX3D/3E 14 */
+	&snd_als4000_ctl_mic_20db_boost,	/* MX4D    16 */
+	&snd_sb16_ctl_mic_play_switch,		/* MX3C    14 */
+	&snd_sb16_ctl_mic_play_vol,		/* MX3A    13 */
+	&snd_sb16_ctl_pc_speaker_vol,		/* MX3B    14 */
+	&snd_sb16_ctl_capture_vol,		/* MX3F/40 15 */
+	&snd_sb16_ctl_play_vol,			/* MX41/42 15 */
+	&snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */
+	&snd_als4k_ctl_master_mono_capture_route, /* MX4B  16 */
+	&snd_als4000_ctl_mono_playback_switch,	/* MX4C    16 */
+	&snd_als4000_ctl_mixer_analog_loopback, /* MX4D    16 */
+	&snd_als4000_ctl_mixer_digital_loopback, /* CR3    21 */
+	&snd_als4000_3d_control_switch,		 /* MX50   17 */
+	&snd_als4000_3d_control_ratio,		 /* MX50   17 */
+	&snd_als4000_3d_control_freq,		 /* MX50   17 */
+	&snd_als4000_3d_control_delay,		 /* MX51   18 */
+	&snd_als4000_3d_control_poweroff_switch,	/* MX51    18 */
+	&snd_als4000_ctl_3db_freq_control_switch,	/* MX4F    17 */
 #ifdef NOT_AVAILABLE
 	&snd_als4000_ctl_fmdac,
 	&snd_als4000_ctl_qsound,
@@ -905,13 +982,14 @@
 };
 
 static unsigned char als4000_saved_regs[] = {
+	/* please verify in dsheet whether regs to be added
+	   are actually real H/W or just dummy */
 	SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
 	SB_DSP4_OUTPUT_SW,
 	SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
 	SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
 	SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
 	SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
-	SB_DSP4_MIC_AGC,
 	SB_DSP4_MIC_DEV,
 	SB_DSP4_SPEAKER_DEV,
 	SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
@@ -919,8 +997,10 @@
 	SB_DT019X_OUTPUT_SW2,
 	SB_ALS4000_MONO_IO_CTRL,
 	SB_ALS4000_MIC_IN_GAIN,
+	SB_ALS4000_FMDAC,
 	SB_ALS4000_3D_SND_FX,
 	SB_ALS4000_3D_TIME_DELAY,
+	SB_ALS4000_CR3_CONFIGURATION,
 };
 
 static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index ca35924..bbc5369 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -576,10 +576,6 @@
 		snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n",
 			   0x388, 0x388 + 2);
 	} else {
-		err = snd_opl3_timer_new(opl3, 0, 1);
-		if (err < 0)
-			goto err_unmap2;
-
 		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
 		if (err < 0)
 			goto err_unmap2;
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 4c095bc..c280e62 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -551,11 +551,11 @@
 		return 0;
 #endif
 	if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk("specify CS4232 port\n");
+		snd_printk(KERN_ERR "specify CS4232 port\n");
 		return 0;
 	}
 	if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk("specify ICS2115 port\n");
+		snd_printk(KERN_ERR "specify ICS2115 port\n");
 		return 0;
 	}
 	return 1;
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 4c41082..beb312c 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -633,7 +633,7 @@
 		wbuf[1] = i >> 7;
 
 		if (snd_wavefront_cmd (dev, WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) {
-			snd_printk("cannot identify sample "
+			snd_printk(KERN_WARNING "cannot identify sample "
 				   "type of slot %d\n", i);
 			dev->sample_status[i] = WF_ST_EMPTY;
 			continue;
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 3d6c5f2..8de5ded 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -219,7 +219,8 @@
 	snd_wss_wait(chip);
 #ifdef CONFIG_SND_DEBUG
 	if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
-		snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+		snd_printk(KERN_DEBUG "out: auto calibration time out "
+			   "- reg = 0x%x, value = 0x%x\n", reg, value);
 #endif
 	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
 	wss_outb(chip, CS4231P(REG), value);
@@ -235,7 +236,8 @@
 	snd_wss_wait(chip);
 #ifdef CONFIG_SND_DEBUG
 	if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
-		snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
+		snd_printk(KERN_DEBUG "in: auto calibration time out "
+			   "- reg = 0x%x\n", reg);
 #endif
 	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
 	mb();
@@ -252,7 +254,7 @@
 	wss_outb(chip, CS4231P(REG), val);
 	chip->eimage[CS4236_REG(reg)] = val;
 #if 0
-	printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val);
+	printk(KERN_DEBUG "ext out : reg = 0x%x, val = 0x%x\n", reg, val);
 #endif
 }
 EXPORT_SYMBOL(snd_cs4236_ext_out);
@@ -268,7 +270,8 @@
 	{
 		unsigned char res;
 		res = wss_inb(chip, CS4231P(REG));
-		printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res);
+		printk(KERN_DEBUG "ext in : reg = 0x%x, val = 0x%x\n",
+		       reg, res);
 		return res;
 	}
 #endif
@@ -394,13 +397,16 @@
 	snd_wss_wait(chip);
 #ifdef CONFIG_SND_DEBUG
 	if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
-		snd_printk("mce_up - auto calibration time out (0)\n");
+		snd_printk(KERN_DEBUG
+			   "mce_up - auto calibration time out (0)\n");
 #endif
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit |= CS4231_MCE;
 	timeout = wss_inb(chip, CS4231P(REGSEL));
 	if (timeout == 0x80)
-		snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_DEBUG "mce_up [0x%lx]: "
+			   "serious init problem - codec still busy\n",
+			   chip->port);
 	if (!(timeout & CS4231_MCE))
 		wss_outb(chip, CS4231P(REGSEL),
 			 chip->mce_bit | (timeout & 0x1f));
@@ -419,7 +425,9 @@
 
 #ifdef CONFIG_SND_DEBUG
 	if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
-		snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL));
+		snd_printk(KERN_DEBUG "mce_down [0x%lx] - "
+			   "auto calibration time out (0)\n",
+			   (long)CS4231P(REGSEL));
 #endif
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	chip->mce_bit &= ~CS4231_MCE;
@@ -427,7 +435,9 @@
 	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	if (timeout == 0x80)
-		snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_DEBUG "mce_down [0x%lx]: "
+			   "serious init problem - codec still busy\n",
+			   chip->port);
 	if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask))
 		return;
 
@@ -565,7 +575,7 @@
 	if (channels > 1)
 		rformat |= CS4231_STEREO;
 #if 0
-	snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
+	snd_printk(KERN_DEBUG "get_format: 0x%x (mode=0x%x)\n", format, mode);
 #endif
 	return rformat;
 }
@@ -774,7 +784,7 @@
 	snd_wss_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-	snd_printk("init: (1)\n");
+	snd_printk(KERN_DEBUG "init: (1)\n");
 #endif
 	snd_wss_mce_up(chip);
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -789,7 +799,7 @@
 	snd_wss_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-	snd_printk("init: (2)\n");
+	snd_printk(KERN_DEBUG "init: (2)\n");
 #endif
 
 	snd_wss_mce_up(chip);
@@ -800,7 +810,7 @@
 	snd_wss_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-	snd_printk("init: (3) - afei = 0x%x\n",
+	snd_printk(KERN_DEBUG "init: (3) - afei = 0x%x\n",
 		   chip->image[CS4231_ALT_FEATURE_1]);
 #endif
 
@@ -817,7 +827,7 @@
 	snd_wss_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-	snd_printk("init: (4)\n");
+	snd_printk(KERN_DEBUG "init: (4)\n");
 #endif
 
 	snd_wss_mce_up(chip);
@@ -829,7 +839,7 @@
 	snd_wss_mce_down(chip);
 
 #ifdef SNDRV_DEBUG_MCE
-	snd_printk("init: (5)\n");
+	snd_printk(KERN_DEBUG "init: (5)\n");
 #endif
 }
 
@@ -1278,7 +1288,8 @@
 		} else if (rev == 0x03) {
 			chip->hardware = WSS_HW_CS4236B;
 		} else {
-			snd_printk("unknown CS chip with version 0x%x\n", rev);
+			snd_printk(KERN_ERR
+				   "unknown CS chip with version 0x%x\n", rev);
 			return -ENODEV;		/* unknown CS4231 chip? */
 		}
 	}
@@ -1342,7 +1353,10 @@
 				case 6:
 					break;
 				default:
-					snd_printk("unknown CS4235 chip (enhanced version = 0x%x)\n", id);
+					snd_printk(KERN_WARNING
+						"unknown CS4235 chip "
+						"(enhanced version = 0x%x)\n",
+						id);
 				}
 			} else if ((id & 0x1f) == 0x0b) {	/* CS4236/B */
 				switch (id >> 5) {
@@ -1353,7 +1367,10 @@
 					chip->hardware = WSS_HW_CS4236B;
 					break;
 				default:
-					snd_printk("unknown CS4236 chip (enhanced version = 0x%x)\n", id);
+					snd_printk(KERN_WARNING
+						"unknown CS4236 chip "
+						"(enhanced version = 0x%x)\n",
+						id);
 				}
 			} else if ((id & 0x1f) == 0x08) {	/* CS4237B */
 				chip->hardware = WSS_HW_CS4237B;
@@ -1364,7 +1381,10 @@
 				case 7:
 					break;
 				default:
-					snd_printk("unknown CS4237B chip (enhanced version = 0x%x)\n", id);
+					snd_printk(KERN_WARNING
+						"unknown CS4237B chip "
+						"(enhanced version = 0x%x)\n",
+						id);
 				}
 			} else if ((id & 0x1f) == 0x09) {	/* CS4238B */
 				chip->hardware = WSS_HW_CS4238B;
@@ -1374,7 +1394,10 @@
 				case 7:
 					break;
 				default:
-					snd_printk("unknown CS4238B chip (enhanced version = 0x%x)\n", id);
+					snd_printk(KERN_WARNING
+						"unknown CS4238B chip "
+						"(enhanced version = 0x%x)\n",
+						id);
 				}
 			} else if ((id & 0x1f) == 0x1e) {	/* CS4239 */
 				chip->hardware = WSS_HW_CS4239;
@@ -1384,10 +1407,15 @@
 				case 6:
 					break;
 				default:
-					snd_printk("unknown CS4239 chip (enhanced version = 0x%x)\n", id);
+					snd_printk(KERN_WARNING
+						"unknown CS4239 chip "
+						"(enhanced version = 0x%x)\n",
+						id);
 				}
 			} else {
-				snd_printk("unknown CS4236/CS423xB chip (enhanced version = 0x%x)\n", id);
+				snd_printk(KERN_WARNING
+					   "unknown CS4236/CS423xB chip "
+					   "(enhanced version = 0x%x)\n", id);
 			}
 		}
 	}
@@ -1618,7 +1646,8 @@
 	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	if (timeout == 0x80)
-		snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port);
+		snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
+			   "- codec still busy\n", chip->port);
 	if ((timeout & CS4231_MCE) == 0 ||
 	    !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
 		return;
@@ -1820,7 +1849,8 @@
 #if 0
 	if (chip->hardware & WSS_HW_CS4232_MASK) {
 		if (chip->res_cport == NULL)
-			snd_printk("CS4232 control port features are not accessible\n");
+			snd_printk(KERN_ERR "CS4232 control port features are "
+				   "not accessible\n");
 	}
 #endif