Преглед изворни кода

Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa

* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (122 commits)
  [ALSA] version 1.0.14rc4
  [ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config()
  [ALSA] hda-codec - Add ALC861VD Lenovo support
  [ALSA] hda-codec - Fix connection list in generic parser
  [ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U
  [ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware
  [ALSA] usb-audio: explicitly match Logitech QuickCam
  [ALSA] hda-codec - Fix a typo
  [ALSA] hda-codec - Fix ALC880 uniwill auto-mutes
  [ALSA] hda-codec - Fix AD1988 SPDIF playback route control
  [ALSA] wm8750 typo fix
  [ALSA] wavefront: only declare isapnp on CONFIG_PNP
  [ALSA] hda-codec - bug fixes for stac92xx HDA codecs.
  [ALSA] add MODULE_FIRMWARE entries
  [ALSA] do not depend on FW_LOADER when internal firmware images are used
  [ALSA] hda-codec - Fix resume of STAC92xx codecs
  [ALSA] usbaudio - Revert the minimal period size fix patch
  [ALSA] hda-codec - Add support for new HP DV series laptops
  [ALSA] usb-audio - Fix the minimum period size per transfer mode
  [ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition
  ...
Linus Torvalds пре 18 година
родитељ
комит
0a3fd051c7
100 измењених фајлова са 4916 додато и 5114 уклоњено
  1. 20 1
      Documentation/sound/alsa/ALSA-Configuration.txt
  2. 2 2
      Documentation/sound/alsa/Bt87x.txt
  3. 3 3
      MAINTAINERS
  4. 1 0
      include/linux/i2c-id.h
  5. 2 2
      include/sound/ak4114.h
  6. 1 0
      include/sound/mpu401.h
  7. 2 5
      include/sound/pcm.h
  8. 2 2
      include/sound/version.h
  9. 2 2
      sound/aoa/codecs/snd-aoa-codec-onyx.c
  10. 2 2
      sound/aoa/codecs/snd-aoa-codec-tas.c
  11. 0 2
      sound/aoa/soundbus/core.c
  12. 2 3
      sound/aoa/soundbus/i2sbus/i2sbus-core.c
  13. 2 0
      sound/aoa/soundbus/soundbus.h
  14. 12 18
      sound/core/pcm_native.c
  15. 2 1
      sound/core/rtctimer.c
  16. 8 4
      sound/drivers/mpu401/mpu401.c
  17. 12 6
      sound/drivers/mpu401/mpu401_uart.c
  18. 2 2
      sound/drivers/mts64.c
  19. 2 2
      sound/drivers/portman2x4.c
  20. 14 0
      sound/drivers/vx/vx_hwdep.c
  21. 77 37
      sound/i2c/other/ak4114.c
  22. 20 2
      sound/isa/Kconfig
  23. 6 2
      sound/isa/ad1816a/ad1816a.c
  24. 67 100
      sound/isa/ad1848/ad1848.c
  25. 44 78
      sound/isa/adlib.c
  26. 43 72
      sound/isa/cmi8330.c
  27. 91 122
      sound/isa/cs423x/cs4231.c
  28. 1 3
      sound/isa/cs423x/cs4231_lib.c
  29. 57 74
      sound/isa/cs423x/cs4236.c
  30. 111 140
      sound/isa/es1688/es1688.c
  31. 39 71
      sound/isa/es18xx.c
  32. 130 162
      sound/isa/gus/gusclassic.c
  33. 183 196
      sound/isa/gus/gusextreme.c
  34. 18 53
      sound/isa/gus/gusmax.c
  35. 37 64
      sound/isa/gus/interwave.c
  36. 50 77
      sound/isa/opl3sa2.c
  37. 36 44
      sound/isa/opti9xx/miro.c
  38. 45 63
      sound/isa/opti9xx/opti92x-ad1848.c
  39. 38 75
      sound/isa/sb/sb16.c
  40. 18 12
      sound/isa/sb/sb16_csp.c
  41. 33 57
      sound/isa/sb/sb8.c
  42. 38 69
      sound/isa/sgalaxy.c
  43. 40 80
      sound/isa/sscape.c
  44. 42 71
      sound/isa/wavefront/wavefront.c
  45. 12 11
      sound/isa/wavefront/wavefront_fx.c
  46. 30 3
      sound/pci/Kconfig
  47. 1 1
      sound/pci/ac97/Makefile
  48. 27 16
      sound/pci/ac97/ac97_codec.c
  49. 2 53
      sound/pci/ac97/ac97_local.h
  50. 139 55
      sound/pci/ac97/ac97_patch.c
  51. 69 41
      sound/pci/ac97/ac97_patch.h
  52. 0 1
      sound/pci/ac97/ac97_pcm.c
  53. 421 448
      sound/pci/ali5451/ali5451.c
  54. 0 40
      sound/pci/au88x0/au88x0_sb.h
  55. 23 11
      sound/pci/azt3328.c
  56. 2 2
      sound/pci/azt3328.h
  57. 3 1
      sound/pci/bt87x.c
  58. 1 3
      sound/pci/ca0106/ca0106_main.c
  59. 1 1
      sound/pci/cs46xx/cs46xx_lib.c
  60. 0 1607
      sound/pci/cs46xx/imgs/cwcemb80.h
  61. 2 0
      sound/pci/echoaudio/darla20.c
  62. 2 0
      sound/pci/echoaudio/darla24.c
  63. 4 0
      sound/pci/echoaudio/echo3g.c
  64. 1 3
      sound/pci/echoaudio/echoaudio.c
  65. 2 2
      sound/pci/echoaudio/echoaudio_3g.c
  66. 2 0
      sound/pci/echoaudio/gina20.c
  67. 6 0
      sound/pci/echoaudio/gina24.c
  68. 3 0
      sound/pci/echoaudio/indigo.c
  69. 3 0
      sound/pci/echoaudio/indigodj.c
  70. 3 0
      sound/pci/echoaudio/indigoio.c
  71. 3 0
      sound/pci/echoaudio/layla20.c
  72. 6 0
      sound/pci/echoaudio/layla24.c
  73. 3 0
      sound/pci/echoaudio/mia.c
  74. 9 0
      sound/pci/echoaudio/mona.c
  75. 19 5
      sound/pci/emu10k1/emu10k1_main.c
  76. 1 3
      sound/pci/emu10k1/p16v.c
  77. 2 6
      sound/pci/ens1370.c
  78. 3 8
      sound/pci/es1968.c
  79. 6 3
      sound/pci/hda/Makefile
  80. 420 309
      sound/pci/hda/hda_codec.c
  81. 1 1
      sound/pci/hda/hda_codec.h
  82. 1 1
      sound/pci/hda/hda_generic.c
  83. 25 6
      sound/pci/hda/hda_intel.c
  84. 12 0
      sound/pci/hda/hda_local.h
  85. 48 37
      sound/pci/hda/patch_analog.c
  86. 15 2
      sound/pci/hda/patch_atihdmi.c
  87. 13 1
      sound/pci/hda/patch_cmedia.c
  88. 118 192
      sound/pci/hda/patch_conexant.c
  89. 1909 362
      sound/pci/hda/patch_realtek.c
  90. 127 51
      sound/pci/hda/patch_sigmatel.c
  91. 13 1
      sound/pci/hda/patch_via.c
  92. 1 1
      sound/pci/ice1712/amp.c
  93. 1 1
      sound/pci/ice1712/amp.h
  94. 9 9
      sound/pci/ice1712/aureon.c
  95. 1 1
      sound/pci/ice1712/aureon.h
  96. 17 17
      sound/pci/ice1712/delta.c
  97. 1 1
      sound/pci/ice1712/delta.h
  98. 12 12
      sound/pci/ice1712/ews.c
  99. 1 1
      sound/pci/ice1712/ews.h
  100. 3 3
      sound/pci/ice1712/hoontech.c

+ 20 - 1
Documentation/sound/alsa/ALSA-Configuration.txt

@@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  6stack-dig	6-jack digital with SPDIF I/O
 	  arima		Arima W820Di1
 	  macpro	MacPro support
+	  w2jc		ASUS W2JC
 	  auto		auto-config reading BIOS (default)
 
 	ALC883/888
@@ -852,6 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  3stack-dig	3-jack with SPDIF OUT
 	  6stack-dig	6-jack with SPDIF OUT
 	  3stack-660	3-jack (for ALC660VD)
+	  lenovo	Lenovo 3000 C200
 	  auto		auto-config reading BIOS (default)
 
 	CMI9880
@@ -909,6 +911,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  macbook	Intel Mac Book
 	  macbook-pro-v1 Intel Mac Book Pro 1st generation
 	  macbook-pro	Intel Mac Book Pro 2nd generation
+	  imac-intel	Intel iMac
 
 	STAC9202/9250/9251
 	  ref		Reference board, base config
@@ -924,6 +927,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  vaio		Setup for VAIO FE550G/SZ110
 	  vaio-ar Setup for VAIO AR
 
+    The model name "genric" is treated as a special case.  When this
+    model is given, the driver uses the generic codec parser without
+    "codec-patch".  It's sometimes good for testing and debugging.
+
     If the default configuration doesn't work and one of the above
     matches with your device, report it together with the PCI
     subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
@@ -1278,6 +1285,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
     port	- port number or -1 (disable)
     irq		- IRQ number or -1 (disable)
     pnp		- PnP detection - 0 = disable, 1 = enable (default)
+    uart_enter	- Issue UART_ENTER command at open - bool, default = on
 
     This module supports multiple devices and PnP.
     
@@ -1692,6 +1700,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 
     This module supports multiple devices, autoprobe and hotplugging.
 
+  Module snd-usb-caiaq
+  --------------------
+
+    Module for caiaq UB audio interfaces,
+	    * Native Instruments RigKontrol2
+	    * Native Instruments Kore Controller
+	    * Native Instruments Audio Kontrol 1
+	    * Native Instruments Audio 8 DJ
+
+    This module supports multiple devices, autoprobe and hotplugging.
+
   Module snd-usb-usx2y
   --------------------
 
@@ -2046,4 +2065,4 @@ Links and Addresses
        https://bugtrack.alsa-project.org/bugs/
 
   ALSA Developers ML
-       mailto:alsa-devel@lists.sourceforge.net
+       mailto:alsa-devel@alsa-project.org

+ 2 - 2
Documentation/sound/alsa/Bt87x.txt

@@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with
 other values than the default 32000 (often it's 44100 or 64000).
 
 If you have an unknown card, please mail the ID and board name to
-<alsa-devel@lists.sf.net>, regardless of whether audio capture works or
-not, so that future versions of this driver know about your card.
+<alsa-devel@alsa-project.org>, regardless of whether audio capture works
+or not, so that future versions of this driver know about your card.
 
 
 Audio modes

+ 3 - 3
MAINTAINERS

@@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER
 P:	Johannes Berg
 M:	johannes@sipsolutions.net
 L:	linuxppc-dev@ozlabs.org
-L:	alsa-devel@alsa-project.org
+L:	alsa-devel@alsa-project.org (subscribers-only)
 S:	Maintained
 
 APM DRIVER
@@ -3239,13 +3239,13 @@ S:	Maintained
 SOUND
 P:	Jaroslav Kysela
 M:	perex@suse.cz
-L:	alsa-devel@alsa-project.org
+L:	alsa-devel@alsa-project.org (subscribers-only)
 S:	Maintained
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
 P:	Liam Girdwood
 M:	liam.girdwood@wolfsonmicro.com
-L:	alsa-devel@alsa-project.org
+L:	alsa-devel@alsa-project.org (subscribers-only)
 S:	Supported
 
 SPI SUBSYSTEM

+ 1 - 0
include/linux/i2c-id.h

@@ -117,6 +117,7 @@
 #define I2C_DRIVERID_ISL1208	88	/* Intersil ISL1208 RTC		*/
 #define I2C_DRIVERID_WM8731		89	/* Wolfson WM8731 audio codec */
 #define I2C_DRIVERID_WM8750		90	/* Wolfson WM8750 audio codec */
+#define I2C_DRIVERID_WM8753		91	/* Wolfson WM8753 audio codec */
 
 #define I2C_DRIVERID_I2CDEV	900
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */

+ 2 - 2
include/sound/ak4114.h

@@ -73,7 +73,7 @@
 
 /* AK4114_REQ_FORMAT bits */
 #define AK4114_MONO		(1<<7)	/* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */
-#define AK4114_DIF2		(1<<5)	/* Audio Data Control */
+#define AK4114_DIF2		(1<<6)	/* Audio Data Control */
 #define AK4114_DIF1		(1<<5)	/* Audio Data Control */
 #define AK4114_DIF0		(1<<4)	/* Audio Data Control */
 #define AK4114_DIF_16R		(0)				/* STDO: 16-bit, right justified */
@@ -158,7 +158,7 @@
 #define AK4114_CHECK_NO_STAT	(1<<0)	/* no statistics */
 #define AK4114_CHECK_NO_RATE	(1<<1)	/* no rate check */
 
-#define AK4114_CONTROLS		14
+#define AK4114_CONTROLS		15
 
 typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
 typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);

+ 1 - 0
include/sound/mpu401.h

@@ -50,6 +50,7 @@
 #define MPU401_INFO_INTEGRATED	(1 << 2)	/* integrated h/w port */
 #define MPU401_INFO_MMIO	(1 << 3)	/* MMIO access */
 #define MPU401_INFO_TX_IRQ	(1 << 4)	/* independent TX irq */
+#define MPU401_INFO_UART_ONLY	(1 << 5)	/* No ENTER_UART cmd needed */
 
 #define MPU401_MODE_BIT_INPUT		0
 #define MPU401_MODE_BIT_OUTPUT		1

+ 2 - 5
include/sound/pcm.h

@@ -603,11 +603,8 @@ do { \
 	read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
 } while (0)
 
-#define snd_pcm_group_for_each(pos, substream) \
-	list_for_each(pos, &substream->group->substreams)
-
-#define snd_pcm_group_substream_entry(pos) \
-	list_entry(pos, struct snd_pcm_substream, link_list)
+#define snd_pcm_group_for_each_entry(s, substream) \
+	list_for_each_entry(s, &substream->group->substreams, link_list)
 
 static inline int snd_pcm_running(struct snd_pcm_substream *substream)
 {

+ 2 - 2
include/sound/version.h

@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
-#define CONFIG_SND_VERSION "1.0.14rc3"
-#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)"
+#define CONFIG_SND_VERSION "1.0.14rc4"
+#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"

+ 2 - 2
sound/aoa/codecs/snd-aoa-codec-onyx.c

@@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter,
 	onyx->i2c.driver = &onyx_driver;
 	onyx->i2c.adapter = adapter;
 	onyx->i2c.addr = addr & 0x7f;
-	strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1);
+	strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE);
 
 	if (i2c_attach_client(&onyx->i2c)) {
 		printk(KERN_ERR PFX "failed to attach to i2c\n");
@@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter,
 		goto fail;
 	}
 
-	strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1);
+	strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN);
 	onyx->codec.owner = THIS_MODULE;
 	onyx->codec.init = onyx_init_codec;
 	onyx->codec.exit = onyx_exit_codec;

+ 2 - 2
sound/aoa/codecs/snd-aoa-codec-tas.c

@@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter,
 	tas->i2c.addr = addr;
 	/* seems that half is a saner default */
 	tas->drc_range = TAS3004_DRC_MAX / 2;
-	strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1);
+	strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE);
 
 	if (i2c_attach_client(&tas->i2c)) {
 		printk(KERN_ERR PFX "failed to attach to i2c\n");
 		goto fail;
 	}
 
-	strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1);
+	strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN);
 	tas->codec.owner = THIS_MODULE;
 	tas->codec.init = tas_init_codec;
 	tas->codec.exit = tas_exit_codec;

+ 0 - 2
sound/aoa/soundbus/core.c

@@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev)
 
 #endif /* CONFIG_PM */
 
-extern struct device_attribute soundbus_dev_attrs[];
-
 static struct bus_type soundbus_bus_type = {
 	.name		= "aoa-soundbus",
 	.probe		= soundbus_probe,

+ 2 - 3
sound/aoa/soundbus/i2sbus/i2sbus-core.c

@@ -23,9 +23,6 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
 MODULE_DESCRIPTION("Apple Soundbus: I2S support");
-/* for auto-loading, declare that we handle this weird
- * string that macio puts into the relevant device */
-MODULE_ALIAS("of:Ni2sTi2sC");
 
 static int force;
 module_param(force, int, 0444);
@@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = {
 	{ }
 };
 
+MODULE_DEVICE_TABLE(of, i2sbus_match);
+
 static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
 				       struct dbdma_command_mem *r,
 				       int numcmds)

+ 2 - 0
sound/aoa/soundbus/soundbus.h

@@ -199,4 +199,6 @@ struct soundbus_driver {
 extern int soundbus_register_driver(struct soundbus_driver *drv);
 extern void soundbus_unregister_driver(struct soundbus_driver *drv);
 
+extern struct device_attribute soundbus_dev_attrs[];
+
 #endif /* __SOUNDBUS_H */

+ 12 - 18
sound/core/pcm_native.c

@@ -712,26 +712,23 @@ static int snd_pcm_action_group(struct action_ops *ops,
 				struct snd_pcm_substream *substream,
 				int state, int do_lock)
 {
-	struct list_head *pos;
 	struct snd_pcm_substream *s = NULL;
 	struct snd_pcm_substream *s1;
 	int res = 0;
 
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		if (do_lock && s != substream)
-			spin_lock(&s->self_group.lock);
+			spin_lock_nested(&s->self_group.lock,
+					 SINGLE_DEPTH_NESTING);
 		res = ops->pre_action(s, state);
 		if (res < 0)
 			goto _unlock;
 	}
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		res = ops->do_action(s, state);
 		if (res < 0) {
 			if (ops->undo_action) {
-				snd_pcm_group_for_each(pos, substream) {
-					s1 = snd_pcm_group_substream_entry(pos);
+				snd_pcm_group_for_each_entry(s1, substream) {
 					if (s1 == s) /* failed stream */
 						break;
 					ops->undo_action(s1, state);
@@ -741,15 +738,13 @@ static int snd_pcm_action_group(struct action_ops *ops,
 			goto _unlock;
 		}
 	}
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		ops->post_action(s, state);
 	}
  _unlock:
 	if (do_lock) {
 		/* unlock streams */
-		snd_pcm_group_for_each(pos, substream) {
-			s1 = snd_pcm_group_substream_entry(pos);
+		snd_pcm_group_for_each_entry(s1, substream) {
 			if (s1 != substream)
 				spin_unlock(&s1->self_group.lock);
 			if (s1 == s)	/* end */
@@ -1438,7 +1433,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
 {
 	struct snd_card *card;
 	struct snd_pcm_runtime *runtime;
-	struct list_head *pos;
+	struct snd_pcm_substream *s;
 	int result = 0;
 	int i, num_drecs;
 	struct drain_rec *drec, drec_tmp, *d;
@@ -1473,8 +1468,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream)
 
 	/* count only playback streams */
 	num_drecs = 0;
-	snd_pcm_group_for_each(pos, substream) {
-		struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		runtime = s->runtime;
 		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			d = &drec[num_drecs++];
@@ -1674,7 +1668,7 @@ static void relink_to_local(struct snd_pcm_substream *substream)
 
 static int snd_pcm_unlink(struct snd_pcm_substream *substream)
 {
-	struct list_head *pos;
+	struct snd_pcm_substream *s;
 	int res = 0;
 
 	down_write(&snd_pcm_link_rwsem);
@@ -1686,8 +1680,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
 	list_del(&substream->link_list);
 	substream->group->count--;
 	if (substream->group->count == 1) {	/* detach the last stream, too */
-		snd_pcm_group_for_each(pos, substream) {
-			relink_to_local(snd_pcm_group_substream_entry(pos));
+		snd_pcm_group_for_each_entry(s, substream) {
+			relink_to_local(s);
 			break;
 		}
 		kfree(substream->group);

+ 2 - 1
sound/core/rtctimer.c

@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/log2.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 
@@ -129,7 +130,7 @@ static int __init rtctimer_init(void)
 	struct snd_timer *timer;
 
 	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
-	    (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
+	    !is_power_of_2(rtctimer_freq)) {
 		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
 			   rtctimer_freq);
 		return -EINVAL;

+ 8 - 4
sound/drivers/mpu401/mpu401.c

@@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* MPU-401 port number */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* MPU-401 IRQ */
+static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for MPU-401 device.");
@@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444);
 MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
 module_param_array(irq, int, NULL, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
+module_param_array(uart_enter, bool, NULL, 0444);
+MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
 
 static struct platform_device *platform_devices[SNDRV_CARDS];
 static int pnp_registered;
@@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
 		strcat(card->longname, "polled");
 	}
 
-	if ((err = snd_mpu401_uart_new(card, 0,
-				       MPU401_HW_MPU401,
-				       port[dev], 0,
-				       irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) {
+	err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev],
+				  uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY,
+				  irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
+				  NULL);
+	if (err < 0) {
 		printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
 		goto _err;
 	}

+ 12 - 6
sound/drivers/mpu401/mpu401_uart.c

@@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
 	return 0;
 }
 
+static int snd_mpu401_do_reset(struct snd_mpu401 *mpu)
+{
+	if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
+		return -EIO;
+	if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) &&
+	    snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+		return -EIO;
+	return 0;
+}
+
 /*
  * input/output open/close - protected by open_mutex in rawmidi.c
  */
@@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
 	if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
 		return err;
 	if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
-		if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
-			goto error_out;
-		if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+		if (snd_mpu401_do_reset(mpu) < 0)
 			goto error_out;
 	}
 	mpu->substream_input = substream;
@@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
 	if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
 		return err;
 	if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
-		if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
-			goto error_out;
-		if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+		if (snd_mpu401_do_reset(mpu) < 0)
 			goto error_out;
 	}
 	mpu->substream_output = substream;

+ 2 - 2
sound/drivers/mts64.c

@@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p)
 	struct platform_device *device;
 
 	device = platform_device_alloc(PLATFORM_DRIVER, device_count);
-	if (!device) 
+	if (!device)
 		return;
 
 	/* Temporary assignment to forward the parport */
 	platform_set_drvdata(device, p);
 
-	if (platform_device_register(device) < 0) {
+	if (platform_device_add(device) < 0) {
 		platform_device_put(device);
 		return;
 	}

+ 2 - 2
sound/drivers/portman2x4.c

@@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p)
 	struct platform_device *device;
 
 	device = platform_device_alloc(PLATFORM_DRIVER, device_count);
-	if (!device) 
+	if (!device)
 		return;
 
 	/* Temporary assignment to forward the parport */
 	platform_set_drvdata(device, p);
 
-	if (platform_device_register(device) < 0) {
+	if (platform_device_add(device) < 0) {
 		platform_device_put(device);
 		return;
 	}

+ 14 - 0
sound/drivers/vx/vx_hwdep.c

@@ -30,6 +30,20 @@
 
 #ifdef SND_VX_FW_LOADER
 
+MODULE_FIRMWARE("vx/bx_1_vxp.b56");
+MODULE_FIRMWARE("vx/bx_1_vp4.b56");
+MODULE_FIRMWARE("vx/x1_1_vx2.xlx");
+MODULE_FIRMWARE("vx/x1_2_v22.xlx");
+MODULE_FIRMWARE("vx/x1_1_vxp.xlx");
+MODULE_FIRMWARE("vx/x1_1_vp4.xlx");
+MODULE_FIRMWARE("vx/bd56002.boot");
+MODULE_FIRMWARE("vx/bd563v2.boot");
+MODULE_FIRMWARE("vx/bd563s3.boot");
+MODULE_FIRMWARE("vx/l_1_vx2.d56");
+MODULE_FIRMWARE("vx/l_1_v22.d56");
+MODULE_FIRMWARE("vx/l_1_vxp.d56");
+MODULE_FIRMWARE("vx/l_1_vp4.d56");
+
 int snd_vx_setup_firmware(struct vx_core *chip)
 {
 	static char *fw_files[VX_TYPE_NUMS][4] = {

+ 77 - 37
sound/i2c/other/ak4114.c

@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
 #define AK4114_ADDR			0x00 /* fixed address */
 
 static void ak4114_stats(struct work_struct *work);
+static void ak4114_init_regs(struct ak4114 *chip);
 
 static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
 {
@@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card,
 	for (reg = 0; reg < 5; reg++)
 		chip->txcsb[reg] = txcsb[reg];
 
-	snd_ak4114_reinit(chip);
+	ak4114_init_regs(chip);
 
 	chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
 	chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
@@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char
 			  (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val);
 }
 
-void snd_ak4114_reinit(struct ak4114 *chip)
+static void ak4114_init_regs(struct ak4114 *chip)
 {
 	unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
 
-	chip->init = 1;
-	mb();
-	flush_scheduled_work();
 	/* bring the chip to reset state and powerdown state */
 	reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN));
 	udelay(200);
@@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip)
 		reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]);
 	/* release powerdown, everything is initialized now */
 	reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN);
+}
+
+void snd_ak4114_reinit(struct ak4114 *chip)
+{
+	chip->init = 1;
+	mb();
+	flush_scheduled_work();
+	ak4114_init_regs(chip);
 	/* bring up statistics / event queing */
 	chip->init = 0;
-	schedule_delayed_work(&chip->work, HZ / 10);
+	if (chip->kctls[0])
+		schedule_delayed_work(&chip->work, HZ / 10);
 }
 
 static unsigned int external_rate(unsigned char rcs1)
@@ -428,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_bit_info,
 	.get =		snd_ak4114_in_bit_get,
-	.private_value = (6<<8) | AK4114_REG_RCS1,
+	.private_value = (6<<8) | AK4114_REG_RCS0,
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -436,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_bit_info,
 	.get =		snd_ak4114_in_bit_get,
-	.private_value = (3<<8) | AK4114_REG_RCS1,
+	.private_value = (3<<8) | AK4114_REG_RCS0,
+},
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =		"IEC958 PPL Lock Status",
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+	.info =		snd_ak4114_in_bit_info,
+	.get =		snd_ak4114_in_bit_get,
+	.private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0,
 }
 };
 
@@ -455,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114,
 		kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114);
 		if (kctl == NULL)
 			return -ENOMEM;
-		if (!strstr(kctl->id.name, "Playback")) {
+		if (strstr(kctl->id.name, "Playback")) {
 			if (ply_substream == NULL) {
 				snd_ctl_free_one(kctl);
 				ak4114->kctls[idx] = NULL;
@@ -472,9 +487,58 @@ int snd_ak4114_build(struct ak4114 *ak4114,
 			return err;
 		ak4114->kctls[idx] = kctl;
 	}
+	/* trigger workq */
+	schedule_delayed_work(&ak4114->work, HZ / 10);
 	return 0;
 }
 
+/* notify kcontrols if any parameters are changed */
+static void ak4114_notify(struct ak4114 *ak4114,
+			  unsigned char rcs0, unsigned char rcs1,
+			  unsigned char c0, unsigned char c1)
+{
+	if (!ak4114->kctls[0])
+		return;
+
+	if (rcs0 & AK4114_PAR)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[0]->id);
+	if (rcs0 & AK4114_V)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[1]->id);
+	if (rcs1 & AK4114_CCRC)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[2]->id);
+	if (rcs1 & AK4114_QCRC)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[3]->id);
+
+	/* rate change */
+	if (c1 & 0xf0)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[4]->id);
+
+	if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[9]->id);
+	if (c0 & AK4114_QINT)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[10]->id);
+
+	if (c0 & AK4114_AUDION)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[11]->id);
+	if (c0 & AK4114_AUTO)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[12]->id);
+	if (c0 & AK4114_DTSCD)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[13]->id);
+	if (c0 & AK4114_UNLCK)
+		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &ak4114->kctls[14]->id);
+}
+
 int snd_ak4114_external_rate(struct ak4114 *ak4114)
 {
 	unsigned char rcs1;
@@ -511,31 +575,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
 	ak4114->rcs1 = rcs1;
 	spin_unlock_irqrestore(&ak4114->lock, _flags);
 
-	if (rcs0 & AK4114_PAR)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id);
-	if (rcs0 & AK4114_V)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id);
-	if (rcs1 & AK4114_CCRC)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id);
-	if (rcs1 & AK4114_QCRC)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id);
-
-	/* rate change */
-	if (c1 & 0xf0)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id);
-
-	if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT))
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id);
-	if (c0 & AK4114_QINT)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id);
-
-	if (c0 & AK4114_AUDION)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id);
-	if (c0 & AK4114_AUTO)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id);
-	if (c0 & AK4114_DTSCD)
-		snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id);
-
+	ak4114_notify(ak4114, rcs0, rcs1, c0, c1);
 	if (ak4114->change_callback && (c0 | c1) != 0)
 		ak4114->change_callback(ak4114, c0, c1);
 
@@ -558,9 +598,9 @@ static void ak4114_stats(struct work_struct *work)
 {
 	struct ak4114 *chip = container_of(work, struct ak4114, work.work);
 
-	if (chip->init)
-		return;
-	snd_ak4114_check_rate_and_errors(chip, 0);
+	if (!chip->init)
+		snd_ak4114_check_rate_and_errors(chip, 0);
+
 	schedule_delayed_work(&chip->work, HZ / 10);
 }
 

+ 20 - 2
sound/isa/Kconfig

@@ -358,12 +358,21 @@ config SND_SBAWE
 config SND_SB16_CSP
 	bool "Sound Blaster 16/AWE CSP support"
 	depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
-	select FW_LOADER
+	select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL
 	help
 	  Say Y here to include support for the CSP core.  This special
 	  coprocessor can do variable tasks like various compression and
 	  decompression algorithms.
 
+config SND_SB16_CSP_FIRMWARE_IN_KERNEL
+	bool "In-kernel firmware for SB16 CSP"
+	depends on SND_SB16_CSP
+	default y
+	help
+	  Say Y here to include the static firmware built in the kernel
+	  for the SB16 CSP controller.  If you choose N here, you need
+	  to install the firmware files from the alsa-firmware package.
+
 config SND_SGALAXY
 	tristate "Aztech Sound Galaxy"
 	depends on SND
@@ -391,7 +400,7 @@ config SND_SSCAPE
 config SND_WAVEFRONT
 	tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
 	depends on SND
-	select FW_LOADER
+	select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_CS4231_LIB
@@ -402,4 +411,13 @@ config SND_WAVEFRONT
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-wavefront.
 
+config SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+	bool "In-kernel firmware for Wavefront"
+	depends on SND_WAVEFRONT
+	default y
+	help
+	  Say Y here to include the static firmware built in the kernel
+	  for the Wavefront driver.  If you choose N here, you need to
+	  install the firmware files from the alsa-firmware package.
+
 endmenu

+ 6 - 2
sound/isa/ad1816a/ad1816a.c

@@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
 	}
 	acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
 	if (acard->devmpu == NULL) {
-		kfree(cfg);
-		return -EBUSY;
+		mpu_port[dev] = -1;
+		snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
 	}
 
 	pdev = acard->dev;
@@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar
 	dma2[dev] = pnp_dma(pdev, 1);
 	irq[dev] = pnp_irq(pdev, 0);
 
+	if (acard->devmpu == NULL) {
+		kfree(cfg);
+		return 0;
+	}
 	pdev = acard->devmpu;
 	pnp_init_resource_table(cfg);
 

+ 67 - 100
sound/isa/ad1848/ad1848.c

@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
@@ -32,8 +32,11 @@
 #include <sound/ad1848.h>
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic AD1848/AD1847/CS4248"
+#define DEV_NAME "ad1848"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Tugrul Galatali <galatalt@stuy.edu>, Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("AD1848/AD1847/CS4248");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
 	        "{Analog Devices,AD1847},"
@@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
 static int thinkpad[SNDRV_CARDS];			/* Thinkpad special case */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for AD1848 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for AD1848 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable AD1848 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for AD1848 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
+{
+	if (!enable[n])
+		return 0;
 
+	if (port[n] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+		return 0;
+	}
+	if (irq[n] == SNDRV_AUTO_IRQ) {
+		snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+		return 0;	
+	}
+	if (dma1[n] == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+		return 0;
+	}
+	return 1;
+}
 
-static int __devinit snd_ad1848_probe(struct platform_device *pdev)
+static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n)
 {
-	int dev = pdev->id;
 	struct snd_card *card;
 	struct snd_ad1848 *chip;
 	struct snd_pcm *pcm;
-	int err;
+	int error;
 
-	if (port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk(KERN_ERR "ad1848: specify port\n");
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+	if (!card)
 		return -EINVAL;
-	}
-	if (irq[dev] == SNDRV_AUTO_IRQ) {
-		snd_printk(KERN_ERR "ad1848: specify irq\n");
-		return -EINVAL;
-	}
-	if (dma1[dev] == SNDRV_AUTO_DMA) {
-		snd_printk(KERN_ERR "ad1848: specify dma1\n");
-		return -EINVAL;
-	}
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
+	error = snd_ad1848_create(card, port[n], irq[n], dma1[n],
+			thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip);
+	if (error < 0)
+		goto out;
 
-	if ((err = snd_ad1848_create(card, port[dev],
-				     irq[dev],
-				     dma1[dev],
-				     thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
-				     &chip)) < 0)
-		goto _err;
 	card->private_data = chip;
 
-	if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
-		goto _err;
+	error = snd_ad1848_pcm(chip, 0, &pcm);
+	if (error < 0)
+		goto out;
 
-	if ((err = snd_ad1848_mixer(chip)) < 0)
-		goto _err;
+	error = snd_ad1848_mixer(chip);
+	if (error < 0)
+		goto out;
 
 	strcpy(card->driver, "AD1848");
 	strcpy(card->shortname, pcm->name);
 
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-		pcm->name, chip->port, irq[dev], dma1[dev]);
-
-	if (thinkpad[dev])
+		pcm->name, chip->port, irq[n], dma1[n]);
+	if (thinkpad[n])
 		strcat(card->longname, " [Thinkpad]");
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, dev);
 
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+	error = snd_card_register(card);
+	if (error < 0)
+		goto out;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(dev, card);
 	return 0;
 
- _err:
-	snd_card_free(card);
-	return err;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_ad1848_remove(struct platform_device *devptr)
+static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state)
 {
-	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_card *card = dev_get_drvdata(dev);
 	struct snd_ad1848 *chip = card->private_data;
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int snd_ad1848_resume(struct platform_device *pdev)
+static int snd_ad1848_resume(struct device *dev, unsigned int n)
 {
-	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_card *card = dev_get_drvdata(dev);
 	struct snd_ad1848 *chip = card->private_data;
 
 	chip->resume(chip);
@@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev)
 }
 #endif
 
-#define SND_AD1848_DRIVER	"snd_ad1848"
-
-static struct platform_driver snd_ad1848_driver = {
+static struct isa_driver snd_ad1848_driver = {
+	.match		= snd_ad1848_match,
 	.probe		= snd_ad1848_probe,
 	.remove		= __devexit_p(snd_ad1848_remove),
 #ifdef CONFIG_PM
@@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = {
 	.resume		= snd_ad1848_resume,
 #endif
 	.driver		= {
-		.name	= SND_AD1848_DRIVER
-	},
+		.name	= DEV_NAME
+	}
 };
 
-static void __init_or_module snd_ad1848_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_ad1848_driver);
-}
-
 static int __init alsa_card_ad1848_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_ad1848_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(SND_AD1848_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
-#endif
-		snd_ad1848_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_ad1848_exit(void)
 {
-	snd_ad1848_unregister_all();
+	isa_unregister_driver(&snd_ad1848_driver);
 }
 
-module_init(alsa_card_ad1848_init)
-module_exit(alsa_card_ad1848_exit)
+module_init(alsa_card_ad1848_init);
+module_exit(alsa_card_ad1848_exit);

+ 44 - 78
sound/isa/adlib.c

@@ -5,13 +5,13 @@
 #include <sound/driver.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/opl3.h>
 
 #define CRD_NAME "AdLib FM"
-#define DRV_NAME "snd_adlib"
+#define DEV_NAME "adlib"
 
 MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Rene Herman");
@@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
+{
+	if (!enable[n])
+		return 0;
+
+	if (port[n] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+		return 0;
+	}
+	return 1;
+}
 
 static void snd_adlib_free(struct snd_card *card)
 {
 	release_and_free_resource(card->private_data);
 }
 
-static int __devinit snd_adlib_probe(struct platform_device *device)
+static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
 {
 	struct snd_card *card;
 	struct snd_opl3 *opl3;
+	int error;
 
-	int error, i = device->id;
-
-	if (port[i] == SNDRV_AUTO_PORT) {
-		snd_printk(KERN_ERR DRV_NAME ": please specify port\n");
-		error = -EINVAL;
-		goto out0;
-	}
-
-	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
 	if (!card) {
-		snd_printk(KERN_ERR DRV_NAME ": could not create card\n");
-		error = -EINVAL;
-		goto out0;
+		snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id);
+		return -EINVAL;
 	}
 
-	card->private_data = request_region(port[i], 4, CRD_NAME);
+	card->private_data = request_region(port[n], 4, CRD_NAME);
 	if (!card->private_data) {
-		snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n");
+		snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id);
 		error = -EBUSY;
-		goto out1;
+		goto out;
 	}
 	card->private_free = snd_adlib_free;
 
-	error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3);
+	strcpy(card->driver, DEV_NAME);
+	strcpy(card->shortname, CRD_NAME);
+	sprintf(card->longname, CRD_NAME " at %#lx", port[n]);
+
+	error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
 	if (error < 0) {
-		snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n");
-		goto out1;
+		snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id);
+		goto out;
 	}
 
 	error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
 	if (error < 0) {
-		snd_printk(KERN_ERR DRV_NAME ": could not create FM\n");
-		goto out1;
+		snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id);
+		goto out;
 	}
 
-	strcpy(card->driver, DRV_NAME);
-	strcpy(card->shortname, CRD_NAME);
-	sprintf(card->longname, CRD_NAME " at %#lx", port[i]);
-
-	snd_card_set_dev(card, &device->dev);
+	snd_card_set_dev(card, dev);
 
 	error = snd_card_register(card);
 	if (error < 0) {
-		snd_printk(KERN_ERR DRV_NAME ": could not register card\n");
-		goto out1;
+		snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id);
+		goto out;
 	}
 
-	platform_set_drvdata(device, card);
+	dev_set_drvdata(dev, card);
 	return 0;
 
-out1:	snd_card_free(card);
-out0:	return error;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_adlib_remove(struct platform_device *device)
+static int __devexit snd_adlib_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(device));
-	platform_set_drvdata(device, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
-static struct platform_driver snd_adlib_driver = {
+static struct isa_driver snd_adlib_driver = {
+	.match		= snd_adlib_match,
 	.probe		= snd_adlib_probe,
 	.remove		= __devexit_p(snd_adlib_remove),
 
 	.driver		= {
-		.name	= DRV_NAME
+		.name	= DEV_NAME
 	}
 };
 
 static int __init alsa_card_adlib_init(void)
 {
-	int i, cards;
-
-	if (platform_driver_register(&snd_adlib_driver) < 0) {
-		snd_printk(KERN_ERR DRV_NAME ": could not register driver\n");
-		return -ENODEV;
-	}
-
-	for (cards = 0, i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-
-		if (!enable[i])
-			continue;
-
-		device = platform_device_register_simple(DRV_NAME, i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-
-		devices[i] = device;
-		cards++;
-	}
-
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n");
-#endif
-		platform_driver_unregister(&snd_adlib_driver);
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_adlib_exit(void)
 {
-	int i;
-
-	for (i = 0; i < SNDRV_CARDS; i++)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_adlib_driver);
+	isa_unregister_driver(&snd_adlib_driver);
 }
 
 module_init(alsa_card_adlib_init);

+ 43 - 72
sound/isa/cmi8330.c

@@ -46,7 +46,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver.");
 module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 #endif
@@ -547,70 +546,78 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
 	return snd_card_register(card);
 }
 
-static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cmi8330_isa_match(struct device *pdev,
+					   unsigned int dev)
 {
-	struct snd_card *card;
-	int err;
-	int dev = pdev->id;
-
+	if (!enable[dev] || is_isapnp_selected(dev))
+		return 0;
 	if (wssport[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify wssport\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (sbport[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify sbport\n");
-		return -EINVAL;
+		return 0;
 	}
+	return 1;
+}
+
+static int __devinit snd_cmi8330_isa_probe(struct device *pdev,
+					   unsigned int dev)
+{
+	struct snd_card *card;
+	int err;
 
 	card = snd_cmi8330_card_new(dev);
 	if (! card)
 		return -ENOMEM;
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 	if ((err = snd_cmi8330_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
-static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cmi8330_isa_remove(struct device *devptr,
+					    unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
+				   pm_message_t state)
 {
-	return snd_cmi8330_suspend(platform_get_drvdata(dev));
+	return snd_cmi8330_suspend(dev_get_drvdata(dev));
 }
 
-static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
+static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
 {
-	return snd_cmi8330_resume(platform_get_drvdata(dev));
+	return snd_cmi8330_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define CMI8330_DRIVER	"snd_cmi8330"
+#define DEV_NAME	"cmi8330"
 
-static struct platform_driver snd_cmi8330_driver = {
-	.probe		= snd_cmi8330_nonpnp_probe,
-	.remove		= __devexit_p(snd_cmi8330_nonpnp_remove),
+static struct isa_driver snd_cmi8330_driver = {
+	.match		= snd_cmi8330_isa_match,
+	.probe		= snd_cmi8330_isa_probe,
+	.remove		= __devexit_p(snd_cmi8330_isa_remove),
 #ifdef CONFIG_PM
-	.suspend	= snd_cmi8330_nonpnp_suspend,
-	.resume		= snd_cmi8330_nonpnp_resume,
+	.suspend	= snd_cmi8330_isa_suspend,
+	.resume		= snd_cmi8330_isa_resume,
 #endif
 	.driver		= {
-		.name	= CMI8330_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata cmi8330_pnp_devices;
-
 static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
 					    const struct pnp_card_device_id *pid)
 {
@@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
 	}
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	cmi8330_pnp_devices++;
 	return 0;
 }
 
@@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_cmi8330_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnp_registered)
-		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_cmi8330_driver);
-}
-
 static int __init alsa_card_cmi8330_init(void)
 {
-	int i, err, cards = 0;
+	int err;
 
-	if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
+	err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i] || is_isapnp_selected(i))
-			continue;
-		device = platform_device_register_simple(CMI8330_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		cards++;
-	}
-
 #ifdef CONFIG_PNP
 	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
-	if (!err) {
+	if (!err)
 		pnp_registered = 1;
-		cards += cmi8330_pnp_devices;
-	}
 #endif
-
-	if (!cards) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
-#endif
-		snd_cmi8330_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_cmi8330_exit(void)
 {
-	snd_cmi8330_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+#endif
+	isa_unregister_driver(&snd_cmi8330_driver);
 }
 
 module_init(alsa_card_cmi8330_init)

+ 91 - 122
sound/isa/cs423x/cs4231.c

@@ -23,7 +23,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
@@ -32,8 +32,11 @@
 #include <sound/mpu401.h>
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic CS4231"
+#define DEV_NAME "cs4231"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Generic CS4231");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
 
@@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for CS4231 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for CS4231 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable CS4231 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for CS4231 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for CS4231 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 CS4231 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
+static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
+{
+	if (!enable[n])
+		return 0;
 
+	if (port[n] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id);
+		return 0;
+	}
+	if (irq[n] == SNDRV_AUTO_IRQ) {
+		snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id);
+		return 0;
+	}
+	if (dma1[n] == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id);
+		return 0;
+	}
+	return 1;
+}
 
-static int __init snd_cs4231_probe(struct platform_device *pdev)
+static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
 {
-	int dev = pdev->id;
 	struct snd_card *card;
-	struct snd_pcm *pcm;
 	struct snd_cs4231 *chip;
-	int err;
+	struct snd_pcm *pcm;
+	int error;
 
-	if (port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk(KERN_ERR "specify port\n");
-		return -EINVAL;
-	}
-	if (irq[dev] == SNDRV_AUTO_IRQ) {
-		snd_printk(KERN_ERR "specify irq\n");
-		return -EINVAL;
-	}
-	if (dma1[dev] == SNDRV_AUTO_DMA) {
-		snd_printk(KERN_ERR "specify dma1\n");
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+	if (!card)
 		return -EINVAL;
-	}
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
-	if ((err = snd_cs4231_create(card, port[dev], -1,
-				     irq[dev],
-				     dma1[dev],
-				     dma2[dev],
-				     CS4231_HW_DETECT,
-				     0, &chip)) < 0)
-		goto _err;
+
+	error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
+			CS4231_HW_DETECT, 0, &chip);
+	if (error < 0)
+		goto out;
+
 	card->private_data = chip;
 
-	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
-		goto _err;
+	error = snd_cs4231_pcm(chip, 0, &pcm);
+	if (error < 0)
+		goto out;
 
 	strcpy(card->driver, "CS4231");
 	strcpy(card->shortname, pcm->name);
+
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-		pcm->name, chip->port, irq[dev], dma1[dev]);
-	if (dma2[dev] >= 0)
-		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
-
-	if ((err = snd_cs4231_mixer(chip)) < 0)
-		goto _err;
-	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
-		goto _err;
-
-	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
-		if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
-			mpu_irq[dev] = -1;
+		pcm->name, chip->port, irq[n], dma1[n]);
+	if (dma2[n] >= 0)
+		sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]);
+
+	error = snd_cs4231_mixer(chip);
+	if (error < 0)
+		goto out;
+
+	error = snd_cs4231_timer(chip, 0, NULL);
+	if (error < 0)
+		goto out;
+
+	if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
+		if (mpu_irq[n] == SNDRV_AUTO_IRQ)
+			mpu_irq[n] = -1;
 		if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
-					mpu_port[dev], 0,
-					mpu_irq[dev],
-					mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
+					mpu_port[n], 0, mpu_irq[n],
+					mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
 					NULL) < 0)
-			printk(KERN_WARNING "cs4231: MPU401 not detected\n");
+			printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id);
 	}
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, dev);
 
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+	error = snd_card_register(card);
+	if (error < 0)
+		goto out;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(dev, card);
 	return 0;
 
- _err:
-	snd_card_free(card);
-	return err;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_cs4231_remove(struct platform_device *devptr)
+static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state)
 {
-	struct snd_card *card;
-	struct snd_cs4231 *chip;
-	card = platform_get_drvdata(dev);
+	struct snd_card *card = dev_get_drvdata(dev);
+	struct snd_cs4231 *chip = card->private_data;
+
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	chip = card->private_data;
 	chip->suspend(chip);
 	return 0;
 }
 
-static int snd_cs4231_resume(struct platform_device *dev)
+static int snd_cs4231_resume(struct device *dev, unsigned int n)
 {
-	struct snd_card *card;
-	struct snd_cs4231 *chip;
-	card = platform_get_drvdata(dev);
-	chip = card->private_data;
+	struct snd_card *card = dev_get_drvdata(dev);
+	struct snd_cs4231 *chip = card->private_data;
+
 	chip->resume(chip);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif
 
-#define SND_CS4231_DRIVER	"snd_cs4231"
-
-static struct platform_driver snd_cs4231_driver = {
+static struct isa_driver snd_cs4231_driver = {
+	.match		= snd_cs4231_match,
 	.probe		= snd_cs4231_probe,
 	.remove		= __devexit_p(snd_cs4231_remove),
 #ifdef CONFIG_PM
@@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = {
 	.resume		= snd_cs4231_resume,
 #endif
 	.driver		= {
-		.name	= SND_CS4231_DRIVER
-	},
+		.name	= DEV_NAME
+	}
 };
 
-static void __init_or_module snd_cs4231_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_cs4231_driver);
-}
-
 static int __init alsa_card_cs4231_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_cs4231_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(SND_CS4231_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "CS4231 soundcard not found or device busy\n");
-#endif
-		snd_cs4231_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_cs4231_exit(void)
 {
-	snd_cs4231_unregister_all();
+	isa_unregister_driver(&snd_cs4231_driver);
 }
 
-module_init(alsa_card_cs4231_init)
-module_exit(alsa_card_cs4231_exit)
+module_init(alsa_card_cs4231_init);
+module_exit(alsa_card_cs4231_exit);

+ 1 - 3
sound/isa/cs423x/cs4231_lib.c

@@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
 	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 	unsigned int what;
-	struct list_head *pos;
 	struct snd_pcm_substream *s;
 	int do_start;
 
@@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
 	}
 
 	what = 0;
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		if (s == chip->playback_substream) {
 			what |= CS4231_PLAYBACK_ENABLE;
 			snd_pcm_trigger_done(s, substream);

+ 57 - 74
sound/isa/cs423x/cs4236.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235},"
 
 #ifdef CS4232
 #define IDENT "CS4232"
-#define CS423X_DRIVER "snd_cs4232"
+#define DEV_NAME "cs4232"
 #else
 #define IDENT "CS4236+"
-#define CS423X_DRIVER "snd_cs4236"
+#define DEV_NAME "cs4236"
 #endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
@@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnpc_registered;
 #ifdef CS4232
 static int pnp_registered;
 #endif
 #endif /* CONFIG_PNP */
-static unsigned int snd_cs423x_devices;
 
 struct snd_card_cs4236 {
 	struct snd_cs4231 *chip;
@@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
 	return snd_card_register(card);
 }
 
-static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_cs423x_isa_match(struct device *pdev,
+					  unsigned int dev)
 {
-	int dev = pdev->id;
-	struct snd_card *card;
-	int err;
+	if (!enable[dev] || is_isapnp_selected(dev))
+		return 0;
 
 	if (port[dev] == SNDRV_AUTO_PORT) {
-		snd_printk(KERN_ERR "specify port\n");
-		return -EINVAL;
+		snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id);
+		return 0;
 	}
 	if (cport[dev] == SNDRV_AUTO_PORT) {
-		snd_printk(KERN_ERR "specify cport\n");
-		return -EINVAL;
+		snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id);
+		return 0;
+	}
+	if (irq[dev] == SNDRV_AUTO_IRQ) {
+		snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+		return 0;
 	}
+	if (dma1[dev] == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id);
+		return 0;
+	}
+	return 1;
+}
+
+static int __devinit snd_cs423x_isa_probe(struct device *pdev,
+					  unsigned int dev)
+{
+	struct snd_card *card;
+	int err;
 
 	card = snd_cs423x_card_new(dev);
 	if (! card)
 		return -ENOMEM;
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 	if ((err = snd_cs423x_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
-static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_cs423x_isa_remove(struct device *pdev,
+					   unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(pdev));
+	dev_set_drvdata(pdev, NULL);
 	return 0;
 }
 
@@ -594,26 +609,28 @@ static int snd_cs423x_resume(struct snd_card *card)
 	return 0;
 }
 
-static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n,
+				  pm_message_t state)
 {
-	return snd_cs423x_suspend(platform_get_drvdata(dev));
+	return snd_cs423x_suspend(dev_get_drvdata(dev));
 }
 
-static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
+static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
 {
-	return snd_cs423x_resume(platform_get_drvdata(dev));
+	return snd_cs423x_resume(dev_get_drvdata(dev));
 }
 #endif
 
-static struct platform_driver cs423x_nonpnp_driver = {
-	.probe		= snd_cs423x_nonpnp_probe,
-	.remove		= __devexit_p(snd_cs423x_nonpnp_remove),
+static struct isa_driver cs423x_isa_driver = {
+	.match		= snd_cs423x_isa_match,
+	.probe		= snd_cs423x_isa_probe,
+	.remove		= __devexit_p(snd_cs423x_isa_remove),
 #ifdef CONFIG_PM
-	.suspend	= snd_cs423x_nonpnp_suspend,
-	.resume		= snd_cs423x_nonpnp_resume,
+	.suspend	= snd_cs423x_isa_suspend,
+	.resume		= snd_cs423x_isa_resume,
 #endif
 	.driver		= {
-		.name	= CS423X_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
@@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
 	}
 	pnp_set_drvdata(pdev, card);
 	dev++;
-	snd_cs423x_devices++;
 	return 0;
 }
 
@@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
 	}
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	snd_cs423x_devices++;
 	return 0;
 }
 
@@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_cs423x_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnpc_registered)
-		pnp_unregister_card_driver(&cs423x_pnpc_driver);
-#ifdef CS4232
-	if (pnp_registered)
-		pnp_unregister_driver(&cs4232_pnp_driver);
-#endif
-#endif /* CONFIG_PNP */
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&cs423x_nonpnp_driver);
-}
-
 static int __init alsa_card_cs423x_init(void)
 {
-	int i, err;
+	int err;
 
-	if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
+	err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i] || is_isapnp_selected(i))
-			continue;
-		device = platform_device_register_simple(CS423X_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		snd_cs423x_devices++;
-	}
 #ifdef CONFIG_PNP
 #ifdef CS4232
 	err = pnp_register_driver(&cs4232_pnp_driver);
@@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void)
 	if (!err)
 		pnpc_registered = 1;
 #endif /* CONFIG_PNP */
-
-	if (!snd_cs423x_devices) {
-#ifdef MODULE
-		printk(KERN_ERR IDENT " soundcard not found or device busy\n");
-#endif
-		snd_cs423x_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_cs423x_exit(void)
 {
-	snd_cs423x_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+	if (pnp_registered)
+		pnp_unregister_driver(&cs4232_pnp_driver);
+#endif
+#endif /* CONFIG_PNP */
+	isa_unregister_driver(&cs423x_isa_driver);
 }
 
 module_init(alsa_card_cs423x_init)

+ 111 - 140
sound/isa/es1688/es1688.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
@@ -35,8 +35,11 @@
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive"
+#define DEV_NAME "es1688"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("ESS ESx688 AudioDrive");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
 	        "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102},"
@@ -53,189 +56,157 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 5,7,9,10 */
 static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3 */
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for ESx688 soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for ESx688 soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable ESx688 soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for ESx688 driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for ESx688 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 ESx688 driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
-
-static struct platform_device *devices[SNDRV_CARDS];
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
 
-#define PFX	"es1688: "
+static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
+{
+	return enable[n];
+}
 
-static int __devinit snd_es1688_probe(struct platform_device *pdev)
+static int __devinit snd_es1688_legacy_create(struct snd_card *card, 
+		struct device *dev, unsigned int n, struct snd_es1688 **rchip)
 {
-	int dev = pdev->id;
+	static long possible_ports[] = {0x220, 0x240, 0x260};
 	static int possible_irqs[] = {5, 9, 10, 7, -1};
 	static int possible_dmas[] = {1, 3, 0, -1};
-	int xirq, xdma, xmpu_irq;
-	struct snd_card *card;
-	struct snd_es1688 *chip;
-	struct snd_opl3 *opl3;
-	struct snd_pcm *pcm;
-	int err;
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
-
-	xirq = irq[dev];
-	if (xirq == SNDRV_AUTO_IRQ) {
-		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-			err = -EBUSY;
-			goto _err;
+
+	int i, error;
+
+	if (irq[n] == SNDRV_AUTO_IRQ) {
+		irq[n] = snd_legacy_find_free_irq(possible_irqs);
+		if (irq[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+				dev->bus_id);
+			return -EBUSY;
 		}
 	}
-	xmpu_irq = mpu_irq[dev];
-	xdma = dma8[dev];
-	if (xdma == SNDRV_AUTO_DMA) {
-		if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
-			err = -EBUSY;
-			goto _err;
+	if (dma8[n] == SNDRV_AUTO_DMA) {
+		dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+		if (dma8[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free DMA\n",
+				dev->bus_id);
+			return -EBUSY;
 		}
 	}
 
-	if (port[dev] != SNDRV_AUTO_PORT) {
-		if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
-					     xirq, xmpu_irq, xdma,
-					     ES1688_HW_AUTO, &chip)) < 0)
-			goto _err;
-	} else {
-		/* auto-probe legacy ports */
-		static unsigned long possible_ports[] = {
-			0x220, 0x240, 0x260,
-		};
-		int i;
-		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-			err = snd_es1688_create(card, possible_ports[i],
-						mpu_port[dev],
-						xirq, xmpu_irq, xdma,
-						ES1688_HW_AUTO, &chip);
-			if (err >= 0) {
-				port[dev] = possible_ports[i];
-				break;
-			}
-		}
-		if (i >= ARRAY_SIZE(possible_ports))
-			goto _err;
-	}
+	if (port[n] != SNDRV_AUTO_PORT)
+		return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+				mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+
+	i = 0;
+	do {
+		port[n] = possible_ports[i];
+		error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+				mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
+	} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
+
+	return error;
+}
+
+static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
+{
+	struct snd_card *card;
+	struct snd_es1688 *chip;
+	struct snd_opl3 *opl3;
+	struct snd_pcm *pcm;
+	int error;
+
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+	if (!card)
+		return -EINVAL;
+
+	error = snd_es1688_legacy_create(card, dev, n, &chip);
+	if (error < 0)
+		goto out;
 
-	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
-		goto _err;
+	error = snd_es1688_pcm(chip, 0, &pcm);
+	if (error < 0)
+		goto out;
 
-	if ((err = snd_es1688_mixer(chip)) < 0)
-		goto _err;
+	error = snd_es1688_mixer(chip);
+	if (error < 0)
+		goto out;
 
 	strcpy(card->driver, "ES1688");
 	strcpy(card->shortname, pcm->name);
-	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);
-
-	if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
-		printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
-	} else {
-		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
-			goto _err;
+	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)
+		printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n",
+			dev->bus_id, chip->port);
+	else {
+		error =	snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+		if (error < 0)
+			goto out;
 	}
 
-	if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
-		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
-					       chip->mpu_port, 0,
-					       xmpu_irq,
-					       IRQF_DISABLED,
-					       NULL)) < 0)
-			goto _err;
+	if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
+			chip->mpu_port > 0) {
+		error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+				chip->mpu_port, 0,
+				mpu_irq[n], IRQF_DISABLED, NULL);
+		if (error < 0)
+			goto out;
 	}
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, dev);
 
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+	error = snd_card_register(card);
+	if (error < 0)
+		goto out;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(dev, card);
 	return 0;
 
- _err:
-	snd_card_free(card);
-	return err;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_es1688_remove(struct platform_device *devptr)
+static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
-#define ES1688_DRIVER	"snd_es1688"
-
-static struct platform_driver snd_es1688_driver = {
+static struct isa_driver snd_es1688_driver = {
+	.match		= snd_es1688_match,
 	.probe		= snd_es1688_probe,
-	.remove		= __devexit_p(snd_es1688_remove),
-	/* FIXME: suspend/resume */
+	.remove		= snd_es1688_remove,
+#if 0	/* FIXME */
+	.suspend	= snd_es1688_suspend,
+	.resume		= snd_es1688_resume,
+#endif
 	.driver		= {
-		.name	= ES1688_DRIVER
-	},
+		.name	= DEV_NAME
+	}
 };
 
-static void __init_or_module snd_es1688_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_es1688_driver);
-}
-
 static int __init alsa_card_es1688_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_es1688_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(ES1688_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
-#endif
-		snd_es1688_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_es1688_exit(void)
 {
-	snd_es1688_unregister_all();
+	isa_unregister_driver(&snd_es1688_driver);
 }
 
-module_init(alsa_card_es1688_init)
-module_exit(alsa_card_es1688_exit)
+module_init(alsa_card_es1688_init);
+module_exit(alsa_card_es1688_exit);

+ 39 - 71
sound/isa/es18xx.c

@@ -80,7 +80,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
@@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
 #ifdef CONFIG_PNP
 static int pnp_registered, pnpc_registered;
 
@@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
 	return snd_card_register(card);
 }
 
-static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
+{
+	return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr)
 {
 	struct snd_card *card;
 	int err;
@@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d
 	card = snd_es18xx_card_new(dev);
 	if (! card)
 		return -ENOMEM;
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, devptr);
 	if ((err = snd_audiodrive_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(devptr, card);
 	return 0;
 }
 
-static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
 {
-	int dev = pdev->id;
 	int err;
 	static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
 	static int possible_dmas[] = {1, 0, 3, 5, -1};
@@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
 	}
 
 	if (port[dev] != SNDRV_AUTO_PORT) {
-		return snd_es18xx_nonpnp_probe1(dev, pdev);
+		return snd_es18xx_isa_probe1(dev, pdev);
 	} else {
 		static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
 		int i;
 		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
 			port[dev] = possible_ports[i];
-			err = snd_es18xx_nonpnp_probe1(dev, pdev);
+			err = snd_es18xx_isa_probe1(dev, pdev);
 			if (! err)
 				return 0;
 		}
@@ -2295,43 +2297,44 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev)
 	}
 }
 
-static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_es18xx_isa_remove(struct device *devptr,
+					   unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
+				  pm_message_t state)
 {
-	return snd_es18xx_suspend(platform_get_drvdata(dev), state);
+	return snd_es18xx_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_es18xx_nonpnp_resume(struct platform_device *dev)
+static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
 {
-	return snd_es18xx_resume(platform_get_drvdata(dev));
+	return snd_es18xx_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define ES18XX_DRIVER	"snd_es18xx"
+#define DEV_NAME "es18xx"
 
-static struct platform_driver snd_es18xx_nonpnp_driver = {
-	.probe		= snd_es18xx_nonpnp_probe,
-	.remove		= __devexit_p(snd_es18xx_nonpnp_remove),
+static struct isa_driver snd_es18xx_isa_driver = {
+	.match		= snd_es18xx_isa_match,
+	.probe		= snd_es18xx_isa_probe,
+	.remove		= __devexit_p(snd_es18xx_isa_remove),
 #ifdef CONFIG_PM
-	.suspend	= snd_es18xx_nonpnp_suspend,
-	.resume		= snd_es18xx_nonpnp_resume,
+	.suspend	= snd_es18xx_isa_suspend,
+	.resume		= snd_es18xx_isa_resume,
 #endif
 	.driver		= {
-		.name	= ES18XX_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata es18xx_pnp_devices;
-
 static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
 					    const struct pnp_device_id *id)
 {
@@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
 	}
 	pnp_set_drvdata(pdev, card);
 	dev++;
-	es18xx_pnp_devices++;
 	return 0;
 }
 
@@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
 
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	es18xx_pnp_devices++;
 	return 0;
 }
 
@@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_es18xx_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnpc_registered)
-		pnp_unregister_card_driver(&es18xx_pnpc_driver);
-	if (pnp_registered)
-		pnp_unregister_driver(&es18xx_pnp_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_es18xx_nonpnp_driver);
-}
-
 static int __init alsa_card_es18xx_init(void)
 {
-	int i, err, cards = 0;
+	int err;
 
-	if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
+	err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
 
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i] || is_isapnp_selected(i))
-			continue;
-		device = platform_device_register_simple(ES18XX_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-	       		continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		cards++;
-	}
-
 #ifdef CONFIG_PNP
 	err = pnp_register_driver(&es18xx_pnp_driver);
 	if (!err)
@@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void)
 	err = pnp_register_card_driver(&es18xx_pnpc_driver);
 	if (!err)
 		pnpc_registered = 1;
-	cards += es18xx_pnp_devices;
-#endif
-
-	if(!cards) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
 #endif
-		snd_es18xx_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_es18xx_exit(void)
 {
-	snd_es18xx_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&es18xx_pnpc_driver);
+	if (pnp_registered)
+		pnp_unregister_driver(&es18xx_pnp_driver);
+#endif
+	isa_unregister_driver(&snd_es18xx_isa_driver);
 }
 
 module_init(alsa_card_es18xx_init)

+ 130 - 162
sound/isa/gus/gusclassic.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
@@ -33,8 +33,11 @@
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Gravis UltraSound Classic"
+#define DEV_NAME "gusclassic"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Classic");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
 
@@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Classic driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver.");
+MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(dma2, int, NULL, 0444);
-MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver.");
+MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
 module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n)
+{
+	return enable[n];
+}
+
+static int __devinit snd_gusclassic_create(struct snd_card *card,
+		struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+	static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260};
+	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
+	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
+
+	int i, error;
+
+	if (irq[n] == SNDRV_AUTO_IRQ) {
+		irq[n] = snd_legacy_find_free_irq(possible_irqs);
+		if (irq[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free IRQ\n",
+				dev->bus_id);
+			return -EBUSY;
+		}
+	}
+	if (dma1[n] == SNDRV_AUTO_DMA) {
+		dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+		if (dma1[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free DMA1\n",
+				dev->bus_id);
+			return -EBUSY;
+		}
+	}
+	if (dma2[n] == SNDRV_AUTO_DMA) {
+		dma2[n] = snd_legacy_find_free_dma(possible_dmas);
+		if (dma2[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free DMA2\n",
+				dev->bus_id);
+			return -EBUSY;
+		}
+	}
 
-static struct platform_device *devices[SNDRV_CARDS];
+	if (port[n] != SNDRV_AUTO_PORT)
+		return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+				0, channels[n], pcm_channels[n], 0, rgus);
 
+	i = 0;
+	do {
+		port[n] = possible_ports[i];
+		error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n],
+				0, channels[n], pcm_channels[n], 0, rgus);
+	} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
 
-#define PFX	"gusclassic: "
+	return error;
+}
 
-static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
+static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus)
 {
 	unsigned char d;
 
@@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus)
 	return 0;
 }
 
-static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus)
-{
-	gus->equal_irq = 0;
-	gus->codec_flag = 0;
-	gus->max_flag = 0;
-	gus->joystick_dac = joystick_dac[dev];
-}
-
-static int __devinit snd_gusclassic_probe(struct platform_device *pdev)
+static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
 {
-	int dev = pdev->id;
-	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
-	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
-	int xirq, xdma1, xdma2;
 	struct snd_card *card;
-	struct snd_gus_card *gus = NULL;
-	int err;
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
-	if (pcm_channels[dev] < 2)
-		pcm_channels[dev] = 2;
-
-	xirq = irq[dev];
-	if (xirq == SNDRV_AUTO_IRQ) {
-		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
-	xdma1 = dma1[dev];
-	if (xdma1 == SNDRV_AUTO_DMA) {
-		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
-	xdma2 = dma2[dev];
-	if (xdma2 == SNDRV_AUTO_DMA) {
-		if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
+	struct snd_gus_card *gus;
+	int error;
 
-	if (port[dev] != SNDRV_AUTO_PORT) {
-		err = snd_gus_create(card,
-				     port[dev],
-				     xirq, xdma1, xdma2,
-				     0, channels[dev], pcm_channels[dev],
-				     0, &gus);
-	} else {
-		/* auto-probe legacy ports */
-		static unsigned long possible_ports[] = {
-			0x220, 0x230, 0x240, 0x250, 0x260,
-		};
-		int i;
-		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-			err = snd_gus_create(card,
-					     possible_ports[i],
-					     xirq, xdma1, xdma2,
-					     0, channels[dev], pcm_channels[dev],
-					     0, &gus);
-			if (err >= 0) {
-				port[dev] = possible_ports[i];
-				break;
-			}
-		}
-	}
-	if (err < 0)
-		goto _err;
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+	if (!card)
+		return -EINVAL;
 
-	if ((err = snd_gusclassic_detect(gus)) < 0)
-		goto _err;
+	if (pcm_channels[n] < 2)
+		pcm_channels[n] = 2;
 
-	snd_gusclassic_init(dev, gus);
-	if ((err = snd_gus_initialize(gus)) < 0)
-		goto _err;
+	error = snd_gusclassic_create(card, dev, n, &gus);
+	if (error < 0)
+		goto out;
 
+	error = snd_gusclassic_detect(gus);
+	if (error < 0)
+		goto out;
+
+	gus->joystick_dac = joystick_dac[n];
+
+	error = snd_gus_initialize(gus);
+	if (error < 0)
+		goto out;
+
+	error = -ENODEV;
 	if (gus->max_flag || gus->ess_flag) {
-		snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port);
-		err = -ENODEV;
-		goto _err;
+		snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was "
+			"not detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
+		goto out;
 	}
 
-	if ((err = snd_gf1_new_mixer(gus)) < 0)
-		goto _err;
+	error = snd_gf1_new_mixer(gus);
+	if (error < 0)
+		goto out;
 
-	if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0)
-		goto _err;
+	error = snd_gf1_pcm_new(gus, 0, 0, NULL);
+	if (error < 0)
+		goto out;
 
 	if (!gus->ace_flag) {
-		if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
-			goto _err;
+		error = snd_gf1_rawmidi_new(gus, 0, NULL);
+		if (error < 0)
+			goto out;
 	}
-	sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1);
-	if (xdma2 >= 0)
-		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-	snd_card_set_dev(card, &pdev->dev);
+	sprintf(card->longname + strlen(card->longname),
+		" at 0x%lx, irq %d, dma %d",
+		gus->gf1.port, gus->gf1.irq, gus->gf1.dma1);
 
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+	if (gus->gf1.dma2 >= 0)
+		sprintf(card->longname + strlen(card->longname),
+			"&%d", gus->gf1.dma2);
 
-	platform_set_drvdata(pdev, card);
+	snd_card_set_dev(card, dev);
+
+	error = snd_card_register(card);
+	if (error < 0)
+		goto out;
+
+	dev_set_drvdata(dev, card);
 	return 0;
 
- _err:
-	snd_card_free(card);
-	return err;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_gusclassic_remove(struct platform_device *devptr)
+static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
-#define GUSCLASSIC_DRIVER	"snd_gusclassic"
-
-static struct platform_driver snd_gusclassic_driver = {
+static struct isa_driver snd_gusclassic_driver = {
+	.match		= snd_gusclassic_match,
 	.probe		= snd_gusclassic_probe,
 	.remove		= __devexit_p(snd_gusclassic_remove),
-	/* FIXME: suspend/resume */
+#if 0	/* FIXME */
+	.suspend	= snd_gusclassic_suspend,
+	.remove		= snd_gusclassic_remove,
+#endif
 	.driver		= {
-		.name	= GUSCLASSIC_DRIVER
-	},
+		.name	= DEV_NAME
+	}
 };
 
-static void __init_or_module snd_gusclassic_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_gusclassic_driver);
-}
-
 static int __init alsa_card_gusclassic_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_gusclassic_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(GUSCLASSIC_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
-#endif
-		snd_gusclassic_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusclassic_exit(void)
 {
-	snd_gusclassic_unregister_all();
+	isa_unregister_driver(&snd_gusclassic_driver);
 }
 
-module_init(alsa_card_gusclassic_init)
-module_exit(alsa_card_gusclassic_exit)
+module_init(alsa_card_gusclassic_init);
+module_exit(alsa_card_gusclassic_exit);

+ 183 - 196
sound/isa/gus/gusextreme.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
@@ -37,8 +37,11 @@
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
+#define CRD_NAME "Gravis UltraSound Extreme"
+#define DEV_NAME "gusextreme"
+
+MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Gravis UltraSound Extreme");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
 
@@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard.");
+MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard.");
+MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard.");
+MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 module_param_array(port, long, NULL, 0444);
-MODULE_PARM_DESC(port, "Port # for GUS Extreme driver.");
+MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 module_param_array(gf1_port, long, NULL, 0444);
-MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional).");
+MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
 module_param_array(mpu_port, long, NULL, 0444);
-MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
 module_param_array(irq, int, NULL, 0444);
-MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme 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 GUS Extreme driver.");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
 module_param_array(gf1_irq, int, NULL, 0444);
-MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver.");
+MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
 module_param_array(dma8, int, NULL, 0444);
-MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
 module_param_array(dma1, int, NULL, 0444);
-MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver.");
+MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
-MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver.");
+MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
 module_param_array(channels, int, NULL, 0444);
-MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver.");
+MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
-MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
+MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver.");
+
+static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
+{
+	return enable[n];
+}
+
+static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
+		struct device *dev, unsigned int n, struct snd_es1688 **rchip)
+{
+	static long possible_ports[] = {0x220, 0x240, 0x260};
+	static int possible_irqs[] = {5, 9, 10, 7, -1};
+	static int possible_dmas[] = {1, 3, 0, -1};
+
+	int i, error;
+
+	if (irq[n] == SNDRV_AUTO_IRQ) {
+		irq[n] = snd_legacy_find_free_irq(possible_irqs);
+		if (irq[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+				"for ES1688\n", dev->bus_id);
+			return -EBUSY;
+		}
+	}
+	if (dma8[n] == SNDRV_AUTO_DMA) {
+		dma8[n] = snd_legacy_find_free_dma(possible_dmas);
+		if (dma8[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free DMA "
+				"for ES1688\n", dev->bus_id);
+			return -EBUSY;
+		}
+	}
 
-static struct platform_device *devices[SNDRV_CARDS];
+	if (port[n] != SNDRV_AUTO_PORT)
+		return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+				mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
 
+	i = 0;
+	do {
+		port[n] = possible_ports[i];
+		error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
+				mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
+	} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
 
-#define PFX	"gusextreme: "
+	return error;
+}
 
-static int __devinit snd_gusextreme_detect(int dev,
-					struct snd_card *card,
-					struct snd_gus_card * gus,
-					struct snd_es1688 *es1688)
+static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
+		struct device *dev, unsigned int n, struct snd_gus_card **rgus)
+{
+	static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1};
+	static int possible_dmas[] = {5, 6, 7, 3, 1, -1};
+
+	if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
+		gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
+		if (gf1_irq[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free IRQ "
+				"for GF1\n", dev->bus_id);
+			return -EBUSY;
+		}
+	}
+	if (dma1[n] == SNDRV_AUTO_DMA) {
+		dma1[n] = snd_legacy_find_free_dma(possible_dmas);
+		if (dma1[n] < 0) {
+			snd_printk(KERN_ERR "%s: unable to find a free DMA "
+				"for GF1\n", dev->bus_id);
+			return -EBUSY;
+		}
+	}
+	return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1,
+			0, channels[n], pcm_channels[n], 0, rgus);
+}
+
+static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
+	struct snd_es1688 *es1688)
 {
 	unsigned long flags;
 	unsigned char d;
@@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev,
 	spin_lock_irqsave(&es1688->mixer_lock, flags);
 	snd_es1688_mixer_write(es1688, 0x40, 0x0b);	/* don't change!!! */
 	spin_unlock_irqrestore(&es1688->mixer_lock, flags);
+
 	spin_lock_irqsave(&es1688->reg_lock, flags);
-	outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
+	outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1));
 	outb(0, 0x201);
-	outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
+	outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1));
 	outb(0, 0x201);
-	outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
+	outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1));
 	spin_unlock_irqrestore(&es1688->reg_lock, flags);
 
 	udelay(100);
@@ -139,253 +207,172 @@ static int __devinit snd_gusextreme_detect(int dev,
 		snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d);
 		return -EIO;
 	}
-	return 0;
-}
 
-static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus)
-{
-	gus->joystick_dac = joystick_dac[dev];
+	return 0;
 }
 
 static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id1, id2;
-	int err;
+	int error;
 
 	memset(&id1, 0, sizeof(id1));
 	memset(&id2, 0, sizeof(id2));
 	id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+
 	/* reassign AUX to SYNTHESIZER */
 	strcpy(id1.name, "Aux Playback Volume");
 	strcpy(id2.name, "Synth Playback Volume");
-	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-		return err;
+	error = snd_ctl_rename_id(card, &id1, &id2);
+	if (error < 0)
+		return error;
+
 	/* reassign Master Playback Switch to Synth Playback Switch */
 	strcpy(id1.name, "Master Playback Switch");
 	strcpy(id2.name, "Synth Playback Switch");
-	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-		return err;
+	error = snd_ctl_rename_id(card, &id1, &id2);
+	if (error < 0)
+		return error;
+
 	return 0;
 }
 
-static int __devinit snd_gusextreme_probe(struct platform_device *pdev)
+static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
 {
-	int dev = pdev->id;
-	static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
-	static int possible_ess_dmas[] = {1, 3, 0, -1};
-	static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
-	static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
-	int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
 	struct snd_card *card;
 	struct snd_gus_card *gus;
 	struct snd_es1688 *es1688;
 	struct snd_opl3 *opl3;
-	int err;
+	int error;
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
+	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
+	if (!card)
+		return -EINVAL;
 
-	xgf1_irq = gf1_irq[dev];
-	if (xgf1_irq == SNDRV_AUTO_IRQ) {
-		if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
-			err = -EBUSY;
-			goto out;
-		}
-	}
-	xess_irq = irq[dev];
-	if (xess_irq == SNDRV_AUTO_IRQ) {
-		if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
-			err = -EBUSY;
-			goto out;
-		}
-	}
-	if (mpu_port[dev] == SNDRV_AUTO_PORT)
-		mpu_port[dev] = 0;
-	xmpu_irq = mpu_irq[dev];
-	if (xmpu_irq > 15)
-		xmpu_irq = -1;
-	xgf1_dma = dma1[dev];
-	if (xgf1_dma == SNDRV_AUTO_DMA) {
-		if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
-			err = -EBUSY;
-			goto out;
-		}
-	}
-	xess_dma = dma8[dev];
-	if (xess_dma == SNDRV_AUTO_DMA) {
-		if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
-			err = -EBUSY;
-			goto out;
-		}
-	}
+	if (mpu_port[n] == SNDRV_AUTO_PORT)
+		mpu_port[n] = 0;
 
-	if (port[dev] != SNDRV_AUTO_PORT) {
-		err = snd_es1688_create(card, port[dev], mpu_port[dev],
-					xess_irq, xmpu_irq, xess_dma,
-					ES1688_HW_1688, &es1688);
-	} else {
-		/* auto-probe legacy ports */
-		static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
-		int i;
-		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
-			err = snd_es1688_create(card,
-						possible_ports[i],
-						mpu_port[dev],
-						xess_irq, xmpu_irq, xess_dma,
-						ES1688_HW_1688, &es1688);
-			if (err >= 0) {
-				port[dev] = possible_ports[i];
-				break;
-			}
-		}
-	}
-	if (err < 0)
+	if (mpu_irq[n] > 15)
+		mpu_irq[n] = -1;
+
+	error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
+	if (error < 0)
 		goto out;
 
-	if (gf1_port[dev] < 0)
-		gf1_port[dev] = port[dev] + 0x20;
-	if ((err = snd_gus_create(card,
-				  gf1_port[dev],
-				  xgf1_irq,
-				  xgf1_dma,
-				  -1,
-				  0, channels[dev],
-				  pcm_channels[dev], 0,
-				  &gus)) < 0)
+	if (gf1_port[n] < 0)
+		gf1_port[n] = es1688->port + 0x20;
+
+	error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
+	if (error < 0)
 		goto out;
 
-	if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
+	error = snd_gusextreme_detect(gus, es1688);
+	if (error < 0)
 		goto out;
 
-	snd_gusextreme_init(dev, gus);
-	if ((err = snd_gus_initialize(gus)) < 0)
+	gus->joystick_dac = joystick_dac[n];
+
+	error = snd_gus_initialize(gus);
+	if (error < 0)
 		goto out;
 
+	error = -ENODEV;
 	if (!gus->ess_flag) {
-		snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
-		err = -ENODEV;
+		snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not "
+			"detected at 0x%lx\n", dev->bus_id, gus->gf1.port);
 		goto out;
 	}
-	if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
+	gus->codec_flag = 1;
+
+	error = snd_es1688_pcm(es1688, 0, NULL);
+	if (error < 0)
 		goto out;
 
-	if ((err = snd_es1688_mixer(es1688)) < 0)
+	error = snd_es1688_mixer(es1688);
+	if (error < 0)
 		goto out;
 
 	snd_component_add(card, "ES1688");
-	if (pcm_channels[dev] > 0) {
-		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
+
+	if (pcm_channels[n] > 0) {
+		error = snd_gf1_pcm_new(gus, 1, 1, NULL);
+		if (error < 0)
 			goto out;
 	}
-	if ((err = snd_gf1_new_mixer(gus)) < 0)
+
+	error = snd_gf1_new_mixer(gus);
+	if (error < 0)
 		goto out;
 
-	if ((err = snd_gusextreme_mixer(es1688)) < 0)
+	error = snd_gusextreme_mixer(es1688);
+	if (error < 0)
 		goto out;
 
 	if (snd_opl3_create(card, es1688->port, es1688->port + 2,
-			    OPL3_HW_OPL3, 0, &opl3) < 0) {
-		printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
-	} else {
-		if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
+			OPL3_HW_OPL3, 0, &opl3) < 0)
+		printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n",
+			dev->bus_id, es1688->port);
+	else {
+		error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
+		if (error < 0)
 			goto out;
 	}
 
-	if (es1688->mpu_port >= 0x300 &&
-	    (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
-					       es1688->mpu_port, 0,
-					       xmpu_irq,
-					       IRQF_DISABLED,
-					       NULL)) < 0)
-		goto out;
+	if (es1688->mpu_port >= 0x300) {
+		error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
+				es1688->mpu_port, 0,
+				mpu_irq[n], IRQF_DISABLED, NULL);
+		if (error < 0)
+			goto out;
+	}
 
-	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
-		es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
+	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
+		"irq %i&%i, dma %i&%i", es1688->port,
+		gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, dev);
 
-	if ((err = snd_card_register(card)) < 0)
+	error = snd_card_register(card);
+	if (error < 0)
 		goto out;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(dev, card);
 	return 0;
 
-      out:
-	snd_card_free(card);
-	return err;
+out:	snd_card_free(card);
+	return error;
 }
 
-static int __devexit snd_gusextreme_remove(struct platform_device *devptr)
+static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(dev));
+	dev_set_drvdata(dev, NULL);
 	return 0;
 }
 
-#define GUSEXTREME_DRIVER	"snd_gusextreme"
-
-static struct platform_driver snd_gusextreme_driver = {
+static struct isa_driver snd_gusextreme_driver = {
+	.match		= snd_gusextreme_match,
 	.probe		= snd_gusextreme_probe,
-	.remove		= __devexit_p(snd_gusextreme_remove),
-	/* FIXME: suspend/resume */
+	.remove		= snd_gusextreme_remove,
+#if 0	/* FIXME */
+	.suspend	= snd_gusextreme_suspend,
+	.resume		= snd_gusextreme_resume,
+#endif
 	.driver		= {
-		.name	= GUSEXTREME_DRIVER
-	},
+		.name	= DEV_NAME
+	}
 };
 
-static void __init_or_module snd_gusextreme_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_gusextreme_driver);
-}
-
 static int __init alsa_card_gusextreme_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_gusextreme_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(GUSEXTREME_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
-#endif
-		snd_gusextreme_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusextreme_exit(void)
 {
-	snd_gusextreme_unregister_all();
+	isa_unregister_driver(&snd_gusextreme_driver);
 }
 
-module_init(alsa_card_gusextreme_init)
-module_exit(alsa_card_gusextreme_exit)
+module_init(alsa_card_gusextreme_init);
+module_exit(alsa_card_gusextreme_exit);

+ 18 - 53
sound/isa/gus/gusmax.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver.");
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 struct snd_gusmax {
 	int irq;
 	struct snd_card *card;
@@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card)
 		free_irq(maxcard->irq, (void *)maxcard);
 }
 
-static int __devinit snd_gusmax_probe(struct platform_device *pdev)
+static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev)
+{
+	return enable[dev];
+}
+
+static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
 {
-	int dev = pdev->id;
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
 	int xirq, xdma1, xdma2, err;
@@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
@@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
 	maxcard->gus = gus;
 	maxcard->cs4231 = cs4231;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -349,70 +351,33 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev)
 	return err;
 }
 
-static int __devexit snd_gusmax_remove(struct platform_device *devptr)
+static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-#define GUSMAX_DRIVER	"snd_gusmax"
+#define DEV_NAME "gusmax"
 
-static struct platform_driver snd_gusmax_driver = {
+static struct isa_driver snd_gusmax_driver = {
+	.match		= snd_gusmax_match,
 	.probe		= snd_gusmax_probe,
 	.remove		= __devexit_p(snd_gusmax_remove),
 	/* FIXME: suspend/resume */
 	.driver		= {
-		.name	= GUSMAX_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
-static void __init_or_module snd_gusmax_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_gusmax_driver);
-}
-
 static int __init alsa_card_gusmax_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_gusmax_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(GUSMAX_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "GUS MAX soundcard not found or device busy\n");
-#endif
-		snd_gusmax_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_gusmax_exit(void)
 {
-	snd_gusmax_unregister_all();
+	isa_unregister_driver(&snd_gusmax_driver);
 }
 
 module_init(alsa_card_gusmax_init)

+ 37 - 64
sound/isa/gus/interwave.c

@@ -25,7 +25,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
@@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver.");
 module_param_array(effect, int, NULL, 0444);
 MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-static int pnp_registered;
-
 struct snd_interwave {
 	int irq;
 	struct snd_card *card;
@@ -138,6 +135,7 @@ struct snd_interwave {
 
 
 #ifdef CONFIG_PNP
+static int pnp_registered;
 
 static struct pnp_card_device_id snd_interwave_pnpids[] = {
 #ifndef SNDRV_STB
@@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
 	return 0;
 }
 
-static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr)
 {
 	struct snd_card *card;
 	int err;
@@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device
 	if (! card)
 		return -ENOMEM;
 
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, devptr);
 	if ((err = snd_interwave_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(devptr, card);
 	return 0;
 }
 
-static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_interwave_isa_match(struct device *pdev,
+					     unsigned int dev)
+{
+	if (!enable[dev])
+		return 0;
+#ifdef CONFIG_PNP
+	if (isapnp[dev])
+		return 0;
+#endif
+	return 1;
+}
+
+static int __devinit snd_interwave_isa_probe(struct device *pdev,
+					     unsigned int dev)
 {
-	int dev = pdev->id;
 	int err;
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 	static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
@@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
 	}
 
 	if (port[dev] != SNDRV_AUTO_PORT)
-		return snd_interwave_nonpnp_probe1(dev, pdev);
+		return snd_interwave_isa_probe1(dev, pdev);
 	else {
 		static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
 		int i;
 		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
 			port[dev] = possible_ports[i];
-			err = snd_interwave_nonpnp_probe1(dev, pdev);
+			err = snd_interwave_isa_probe1(dev, pdev);
 			if (! err)
 				return 0;
 		}
@@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev)
 	}
 }
 
-static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-static struct platform_driver snd_interwave_driver = {
-	.probe		= snd_interwave_nonpnp_probe,
-	.remove		= __devexit_p(snd_interwave_nonpnp_remove),
+static struct isa_driver snd_interwave_driver = {
+	.match		= snd_interwave_isa_match,
+	.probe		= snd_interwave_isa_probe,
+	.remove		= __devexit_p(snd_interwave_isa_remove),
 	/* FIXME: suspend,resume */
 	.driver		= {
 		.name	= INTERWAVE_DRIVER
@@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = {
 };
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata interwave_pnp_devices;
-
 static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
 					      const struct pnp_card_device_id *pid)
 {
@@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
 	}
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	interwave_pnp_devices++;
 	return 0;
 }
 
@@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_interwave_unregister_all(void)
-{
-	int i;
-
-	if (pnp_registered)
-		pnp_unregister_card_driver(&interwave_pnpc_driver);
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_interwave_driver);
-}
-
 static int __init alsa_card_interwave_init(void)
 {
-	int i, err, cards = 0;
+	int err;
 
-	if ((err = platform_driver_register(&snd_interwave_driver)) < 0)
+	err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
 #ifdef CONFIG_PNP
-		if (isapnp[i])
-			continue;
-#endif
-		device = platform_device_register_simple(INTERWAVE_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		cards++;
-	}
-
 	/* ISA PnP cards */
 	err = pnp_register_card_driver(&interwave_pnpc_driver);
-	if (!err) {
+	if (!err)
 		pnp_registered = 1;
-		cards += interwave_pnp_devices;;
-	}
-
-	if (!cards) {
-#ifdef MODULE
-		printk(KERN_ERR "InterWave soundcard not found or device busy\n");
 #endif
-		snd_interwave_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_interwave_exit(void)
 {
-	snd_interwave_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&interwave_pnpc_driver);
+#endif
+	isa_unregister_driver(&snd_interwave_driver);
 }
 
 module_init(alsa_card_interwave_init)

+ 50 - 77
sound/isa/opl3sa2.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 static int pnpc_registered;
 #endif
-static unsigned int snd_opl3sa2_devices;
 
 /* control ports */
 #define OPL3SA2_PM_CTRL		0x01
@@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
 	}
 	pnp_set_drvdata(pdev, card);
 	dev++;
-	snd_opl3sa2_devices++;
 	return 0;
 }
 
@@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
 	}
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	snd_opl3sa2_devices++;
 	return 0;
 }
 
@@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
 };
 #endif /* CONFIG_PNP */
 
-static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_opl3sa2_isa_match(struct device *pdev,
+					   unsigned int dev)
 {
-	struct snd_card *card;
-	int err;
-	int dev = pdev->id;
-
+	if (!enable[dev])
+		return 0;
+#ifdef CONFIG_PNP
+	if (isapnp[dev])
+		return 0;
+#endif
 	if (port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify port\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (wss_port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify wss_port\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (fm_port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify fm_port\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (midi_port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify midi_port\n");
-		return -EINVAL;
+		return 0;
 	}
+	return 1;
+}
+
+static int __devinit snd_opl3sa2_isa_probe(struct device *pdev,
+					   unsigned int dev)
+{
+	struct snd_card *card;
+	int err;
 
 	card = snd_opl3sa2_card_new(dev);
 	if (! card)
 		return -ENOMEM;
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
-static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opl3sa2_isa_remove(struct device *devptr,
+					    unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
+				   pm_message_t state)
 {
-	return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
+	return snd_opl3sa2_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
+static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
 {
-	return snd_opl3sa2_resume(platform_get_drvdata(dev));
+	return snd_opl3sa2_resume(dev_get_drvdata(dev));
 }
 #endif
 
-#define OPL3SA2_DRIVER	"snd_opl3sa2"
+#define DEV_NAME "opl3sa2"
 
-static struct platform_driver snd_opl3sa2_nonpnp_driver = {
-	.probe		= snd_opl3sa2_nonpnp_probe,
-	.remove		= __devexit( snd_opl3sa2_nonpnp_remove),
+static struct isa_driver snd_opl3sa2_isa_driver = {
+	.match		= snd_opl3sa2_isa_match,
+	.probe		= snd_opl3sa2_isa_probe,
+	.remove		= __devexit( snd_opl3sa2_isa_remove),
 #ifdef CONFIG_PM
-	.suspend	= snd_opl3sa2_nonpnp_suspend,
-	.resume		= snd_opl3sa2_nonpnp_resume,
+	.suspend	= snd_opl3sa2_isa_suspend,
+	.resume		= snd_opl3sa2_isa_resume,
 #endif
 	.driver		= {
-		.name	= OPL3SA2_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
-static void __init_or_module snd_opl3sa2_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnpc_registered)
-		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-	if (pnp_registered)
-		pnp_unregister_driver(&opl3sa2_pnp_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
-}
-
 static int __init alsa_card_opl3sa2_init(void)
 {
-	int i, err;
+	int err;
 
-	if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
+	err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[i])
-			continue;
-#endif
-		device = platform_device_register_simple(OPL3SA2_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		snd_opl3sa2_devices++;
-	}
-
 #ifdef CONFIG_PNP
 	err = pnp_register_driver(&opl3sa2_pnp_driver);
 	if (!err)
@@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void)
 	if (!err)
 		pnpc_registered = 1;
 #endif
-
-	if (!snd_opl3sa2_devices) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
-#endif
-		snd_opl3sa2_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
 {
-	snd_opl3sa2_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+	if (pnp_registered)
+		pnp_unregister_driver(&opl3sa2_pnp_driver);
+#endif
+	isa_unregister_driver(&snd_opl3sa2_isa_driver);
 }
 
 module_init(alsa_card_opl3sa2_init)

+ 36 - 44
sound/isa/opti9xx/miro.c

@@ -25,7 +25,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
@@ -137,10 +137,6 @@ struct snd_miro {
 
 static void snd_miro_proc_init(struct snd_miro * miro);
 
-#define DRIVER_NAME "snd-miro"
-
-static struct platform_device *device;
-
 static char * snd_opti9xx_names[] = {
 	"unkown",
 	"82C928", "82C929",
@@ -558,7 +554,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
 	return change;
 }
 
-static struct snd_kcontrol_new snd_miro_controls[] = {
+static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = {
 MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER),
 MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC),
 MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE),
@@ -570,7 +566,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2),
 
 /* Equalizer with seven bands (only PCM20) 
    from -12dB up to +12dB on each band */
-static struct snd_kcontrol_new snd_miro_eq_controls[] = {
+static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = {
 MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1),
 MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2),
 MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3),
@@ -580,15 +576,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6),
 MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7),
 };
 
-static struct snd_kcontrol_new snd_miro_radio_control[] = {
+static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = {
 MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_line_control[] = {
+static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = {
 MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1),
 };
 
-static struct snd_kcontrol_new snd_miro_preamp_control[] = {
+static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Mic Boost",
@@ -598,7 +594,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = {
 	.put = snd_miro_put_preamp,
 }};
 
-static struct snd_kcontrol_new snd_miro_amp_control[] = {
+static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Line Boost",
@@ -608,7 +604,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = {
 	.put = snd_miro_put_amp,
 }};
 
-static struct snd_kcontrol_new snd_miro_capture_control[] = {
+static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Capture Switch",
@@ -618,7 +614,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = {
 	.put = snd_miro_put_capture,
 }};
 
-static unsigned char aci_init_values[][2] __initdata = {
+static unsigned char aci_init_values[][2] __devinitdata = {
 	{ ACI_SET_MUTE, 0x00 },
 	{ ACI_SET_POWERAMP, 0x00 },
 	{ ACI_SET_PREAMP, 0x00 },
@@ -641,7 +637,7 @@ static unsigned char aci_init_values[][2] __initdata = {
 	{ ACI_SET_MASTER + 1, 0x20 },
 };
 
-static int __init snd_set_aci_init_values(struct snd_miro *miro)
+static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
 {
 	int idx, error;
 
@@ -751,7 +747,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size)
 	return -1;
 }
 
-static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware)
+static int __devinit snd_miro_init(struct snd_miro *chip,
+				   unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -962,7 +959,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
 	snd_iprintf(buffer, "  preamp  : 0x%x\n", miro->aci_preamp);
 }
 
-static void __init snd_miro_proc_init(struct snd_miro * miro)
+static void __devinit snd_miro_proc_init(struct snd_miro * miro)
 {
 	struct snd_info_entry *entry;
 
@@ -974,7 +971,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro)
  *  Init
  */
 
-static int __init snd_miro_configure(struct snd_miro *chip)
+static int __devinit snd_miro_configure(struct snd_miro *chip)
 {
 	unsigned char wss_base_bits;
 	unsigned char irq_bits;
@@ -1131,7 +1128,8 @@ __skip_mpu:
 	return 0;
 }
 
-static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip)
+static int __devinit snd_card_miro_detect(struct snd_card *card,
+					  struct snd_miro *chip)
 {
 	int i, err;
 	unsigned char value;
@@ -1157,7 +1155,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c
 	return -ENODEV;
 }
 
-static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro)
+static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
+					      struct snd_miro * miro)
 {
 	unsigned char regval;
 	int i;
@@ -1213,7 +1212,12 @@ static void snd_card_miro_free(struct snd_card *card)
 	release_and_free_resource(miro->res_mc_base);
 }
 
-static int __init snd_miro_probe(struct platform_device *devptr)
+static int __devinit snd_miro_match(struct device *devptr, unsigned int n)
+{
+	return 1;
+}
+
+static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
 	static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
@@ -1399,56 +1403,44 @@ static int __init snd_miro_probe(struct platform_device *devptr)
                 return error;
 	}
 
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, devptr);
 
 	if ((error = snd_card_register(card))) {
 		snd_card_free(card);
 		return error;
 	}
 
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(devptr, card);
 	return 0;
 }
 
-static int __devexit snd_miro_remove(struct platform_device *devptr)
+static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-static struct platform_driver snd_miro_driver = {
+#define DEV_NAME "miro"
+
+static struct isa_driver snd_miro_driver = {
+	.match		= snd_miro_match,
 	.probe		= snd_miro_probe,
 	.remove		= __devexit_p(snd_miro_remove),
 	/* FIXME: suspend/resume */
 	.driver		= {
-		.name	= DRIVER_NAME
+		.name	= DEV_NAME
 	},
 };
 
 static int __init alsa_card_miro_init(void)
 {
-	int error;
-
-	if ((error = platform_driver_register(&snd_miro_driver)) < 0)
-		return error;
-	device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-	if (! IS_ERR(device)) {
-		if (platform_get_drvdata(device))
-			return 0;
-		platform_device_unregister(device);
-	}
-#ifdef MODULE
-	printk(KERN_ERR "no miro soundcard found\n");
-#endif
-	platform_driver_unregister(&snd_miro_driver);
-	return PTR_ERR(device);
+	return isa_register_driver(&snd_miro_driver, 1);
 }
 
 static void __exit alsa_card_miro_exit(void)
 {
-	platform_device_unregister(device);
-	platform_driver_unregister(&snd_miro_driver);
+	isa_unregister_driver(&snd_miro_driver);
 }
 
 module_init(alsa_card_miro_init)

+ 45 - 63
sound/isa/opti9xx/opti92x-ad1848.c

@@ -26,7 +26,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
@@ -259,7 +259,6 @@ struct snd_opti9xx {
 };
 
 static int snd_opti9xx_pnp_is_probed;
-static struct platform_device *snd_opti9xx_platform_device;
 
 #ifdef CONFIG_PNP
 
@@ -281,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
 #endif	/* CONFIG_PNP */
 
 #ifdef OPTi93X
-#define DRIVER_NAME	"snd-card-opti93x"
+#define DEV_NAME "opti93x"
 #else
-#define DRIVER_NAME	"snd-card-opti92x"
-#endif	/* OPTi93X */
+#define DEV_NAME "opti92x"
+#endif
 
 static char * snd_opti9xx_names[] = {
 	"unkown",
@@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = {
 };
 
 
-static long __init snd_legacy_find_free_ioport(long *port_table, long size)
+static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
 {
 	while (*port_table != -1) {
 		if (request_region(*port_table, size, "ALSA test")) {
@@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size)
 	return -1;
 }
 
-static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
+static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
+				      unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
 		(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
 
 
-static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
+static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
 {
 	unsigned char wss_base_bits;
 	unsigned char irq_bits;
@@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_STOP:
 	{
 		unsigned int what = 0;
-		struct list_head *pos;
 		struct snd_pcm_substream *s;
-		snd_pcm_group_for_each(pos, substream) {
-			s = snd_pcm_group_substream_entry(pos);
+		snd_pcm_group_for_each_entry(s, substream) {
 			if (s == chip->playback_substream) {
 				what |= OPTi93X_PLAYBACK_ENABLE;
 				snd_pcm_trigger_done(s, substream);
@@ -1291,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
 	}
 	codec->dma2 = chip->dma2;
 
-	if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) {
+	if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) {
 		snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
 		snd_opti93x_free(codec);
 		return -EBUSY;
@@ -1561,7 +1559,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	return change;
 }
 
-static struct snd_kcontrol_new snd_opti93x_controls[] = {
+static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = {
 OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
 OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), 
 OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
@@ -1622,7 +1620,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip)
 
 #endif /* OPTi93X */
 
-static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
+static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
+					     struct snd_opti9xx *chip)
 {
 	int i, err;
 
@@ -1676,8 +1675,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti
 }
 
 #ifdef CONFIG_PNP
-static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
-				       const struct pnp_card_device_id *pid)
+static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
+					  struct pnp_card_link *card,
+					  const struct pnp_card_device_id *pid)
 {
 	struct pnp_dev *pdev;
 	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
@@ -1778,7 +1778,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
 		release_and_free_resource(chip->res_mc_base);
 }
 
-static int __init snd_opti9xx_probe(struct snd_card *card)
+static int __devinit snd_opti9xx_probe(struct snd_card *card)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
 	int error;
@@ -1924,7 +1924,18 @@ static struct snd_card *snd_opti9xx_card_new(void)
 	return card;
 }
 
-static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
+static int __devinit snd_opti9xx_isa_match(struct device *devptr,
+					   unsigned int dev)
+{
+	if (snd_opti9xx_pnp_is_probed)
+		return 0;
+	if (isapnp)
+		return 0;
+	return 1;
+}
+
+static int __devinit snd_opti9xx_isa_probe(struct device *devptr,
+					   unsigned int dev)
 {
 	struct snd_card *card;
 	int error;
@@ -1940,9 +1951,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
 	static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
 #endif	/* CS4231 || OPTi93X */
 
-	if (snd_opti9xx_pnp_is_probed)
-		return -EBUSY;
-
 	if (mpu_port == SNDRV_AUTO_PORT) {
 		if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
 			snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
@@ -1984,34 +1992,36 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, devptr);
 	if ((error = snd_opti9xx_probe(card)) < 0) {
 		snd_card_free(card);
 		return error;
 	}
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(devptr, card);
 	return 0;
 }
 
-static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
+					    unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-static struct platform_driver snd_opti9xx_driver = {
-	.probe		= snd_opti9xx_nonpnp_probe,
-	.remove		= __devexit_p(snd_opti9xx_nonpnp_remove),
+static struct isa_driver snd_opti9xx_driver = {
+	.match		= snd_opti9xx_isa_match,
+	.probe		= snd_opti9xx_isa_probe,
+	.remove		= __devexit_p(snd_opti9xx_isa_remove),
 	/* FIXME: suspend/resume */
 	.driver		= {
-		.name	= DRIVER_NAME
+		.name	= DEV_NAME
 	},
 };
 
 #ifdef CONFIG_PNP
-static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
-					const struct pnp_card_device_id *pid)
+static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+					   const struct pnp_card_device_id *pid)
 {
 	struct snd_card *card;
 	int error, hw;
@@ -2074,11 +2084,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 };
 #endif
 
-#ifdef CONFIG_PNP
-#define is_isapnp_selected()	isapnp
-#else
-#define is_isapnp_selected()	0
-#endif
 #ifdef OPTi93X
 #define CHIP_NAME	"82C93x"
 #else
@@ -2087,42 +2092,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 
 static int __init alsa_card_opti9xx_init(void)
 {
-	int error;
-	struct platform_device *device;
-
 #ifdef CONFIG_PNP
 	pnp_register_card_driver(&opti9xx_pnpc_driver);
 	if (snd_opti9xx_pnp_is_probed)
 		return 0;
 #endif
-	if (! is_isapnp_selected()) {
-		error = platform_driver_register(&snd_opti9xx_driver);
-		if (error < 0)
-			return error;
-		device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
-		if (!IS_ERR(device)) {
-			if (platform_get_drvdata(device)) {
-				snd_opti9xx_platform_device = device;
-				return 0;
-			}
-			platform_device_unregister(device);
-		}
-		platform_driver_unregister(&snd_opti9xx_driver);
-	}
-#ifdef CONFIG_PNP
-	pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-#ifdef MODULE
-	printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
-#endif
-	return -ENODEV;
+	return isa_register_driver(&snd_opti9xx_driver, 1);
 }
 
 static void __exit alsa_card_opti9xx_exit(void)
 {
 	if (!snd_opti9xx_pnp_is_probed) {
-		platform_device_unregister(snd_opti9xx_platform_device);
-		platform_driver_unregister(&snd_opti9xx_driver);
+		isa_unregister_driver(&snd_opti9xx_driver);
+		return;
 	}
 #ifdef CONFIG_PNP
 	pnp_unregister_card_driver(&opti9xx_pnpc_driver);

+ 38 - 75
sound/isa/sb/sb16.c

@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/sb.h>
@@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444);
 MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
 #endif
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
 #ifdef CONFIG_PNP
 static int pnp_registered;
 #endif
@@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card)
 }
 #endif
 
-static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
+static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev)
 {
 	struct snd_card_sb16 *acard;
 	struct snd_card *card;
@@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev
 	awe_port[dev] = port[dev] + 0x400;
 #endif
 
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, pdev);
 	if ((err = snd_sb16_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
 
-static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev)
+{
+	return enable[dev] && !is_isapnp_selected(dev);
+}
+
+static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
 {
-	int dev = pdev->id;
 	int err;
 	static int possible_irqs[] = {5, 9, 10, 7, -1};
 	static int possible_dmas8[] = {1, 3, 0, -1};
@@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
 	}
 
 	if (port[dev] != SNDRV_AUTO_PORT)
-		return snd_sb16_nonpnp_probe1(dev, pdev);
+		return snd_sb16_isa_probe1(dev, pdev);
 	else {
 		static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
 		int i;
 		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
 			port[dev] = possible_ports[i];
-			err = snd_sb16_nonpnp_probe1(dev, pdev);
+			err = snd_sb16_isa_probe1(dev, pdev);
 			if (! err)
 				return 0;
 		}
@@ -591,47 +594,47 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev)
 	}
 }
 
-static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(pdev));
+	dev_set_drvdata(pdev, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
+				pm_message_t state)
 {
-	return snd_sb16_suspend(platform_get_drvdata(dev), state);
+	return snd_sb16_suspend(dev_get_drvdata(dev), state);
 }
 
-static int snd_sb16_nonpnp_resume(struct platform_device *dev)
+static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
 {
-	return snd_sb16_resume(platform_get_drvdata(dev));
+	return snd_sb16_resume(dev_get_drvdata(dev));
 }
 #endif
 
 #ifdef SNDRV_SBAWE
-#define SND_SB16_DRIVER	"snd_sbawe"
+#define DEV_NAME "sbawe"
 #else
-#define SND_SB16_DRIVER	"snd_sb16"
+#define DEV_NAME "sb16"
 #endif
 
-static struct platform_driver snd_sb16_nonpnp_driver = {
-	.probe		= snd_sb16_nonpnp_probe,
-	.remove		= __devexit_p(snd_sb16_nonpnp_remove),
+static struct isa_driver snd_sb16_isa_driver = {
+	.match		= snd_sb16_isa_match,
+	.probe		= snd_sb16_isa_probe,
+	.remove		= __devexit_p(snd_sb16_isa_remove),
 #ifdef CONFIG_PM
-	.suspend	= snd_sb16_nonpnp_suspend,
-	.resume		= snd_sb16_nonpnp_resume,
+	.suspend	= snd_sb16_isa_suspend,
+	.resume		= snd_sb16_isa_resume,
 #endif
 	.driver		= {
-		.name	= SND_SB16_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata sb16_pnp_devices;
-
 static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
 					 const struct pnp_card_device_id *pid)
 {
@@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
 		}
 		pnp_set_card_drvdata(pcard, card);
 		dev++;
-		sb16_pnp_devices++;
 		return 0;
 	}
 
@@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_sb16_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnp_registered)
-		pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_sb16_nonpnp_driver);
-}
-
 static int __init alsa_card_sb16_init(void)
 {
-	int i, err, cards = 0;
+	int err;
 
-	if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0)
+	err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i] || is_isapnp_selected(i))
-			continue;
-		device = platform_device_register_simple(SND_SB16_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		cards++;
-	}
 #ifdef CONFIG_PNP
 	/* PnP cards at last */
 	err = pnp_register_card_driver(&sb16_pnpc_driver);
-	if (!err) {
+	if (!err)
 		pnp_registered = 1;
-		cards += sb16_pnp_devices;
-	}
-#endif
-
-	if (!cards) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
-#ifdef SNDRV_SBAWE_EMU8000
-		snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n");
-#else
-		snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
 #endif
-#endif
-		snd_sb16_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_sb16_exit(void)
 {
-	snd_sb16_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sb16_pnpc_driver);
+#endif
+	isa_unregister_driver(&snd_sb16_isa_driver);
 }
 
 module_init(alsa_card_sb16_init)

+ 18 - 12
sound/isa/sb/sb16_csp.c

@@ -36,6 +36,13 @@
 MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>");
 MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor");
 MODULE_LICENSE("GPL");
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("sb16/mulaw_main.csp");
+MODULE_FIRMWARE("sb16/alaw_main.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_init.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp");
+MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp");
+#endif
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define CSP_HDR_VALUE(a,b,c,d)	((a) | ((b)<<8) | ((c)<<16) | ((d)<<24))
@@ -161,13 +168,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
  */
 static void snd_sb_csp_free(struct snd_hwdep *hwdep)
 {
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
 	int i;
+#endif
 	struct snd_sb_csp *p = hwdep->private_data;
 	if (p) {
 		if (p->running & SNDRV_SB_CSP_ST_RUNNING)
 			snd_sb_csp_stop(p);
+#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
 		for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i)
 			release_firmware(p->csp_programs[i]);
+#endif
 		kfree(p);
 	}
 }
@@ -690,9 +701,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use
 	return err;
 }
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
 #include "sb16_csp_codecs.h"
 
 static const struct firmware snd_sb_csp_static_programs[] = {
@@ -714,22 +723,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags)
 		"sb16/ima_adpcm_capture.csp",
 	};
 	const struct firmware *program;
-	int err;
 
 	BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT);
 	program = p->csp_programs[index];
 	if (!program) {
-		err = request_firmware(&program, names[index],
-				       p->chip->card->dev);
-		if (err >= 0)
-			p->csp_programs[index] = program;
-		else {
-#ifdef FIRMWARE_IN_THE_KERNEL
-			program = &snd_sb_csp_static_programs[index];
+#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL
+		program = &snd_sb_csp_static_programs[index];
 #else
+		int err = request_firmware(&program, names[index],
+				       p->chip->card->dev);
+		if (err < 0)
 			return err;
 #endif
-		}
+		p->csp_programs[index] = program;
 	}
 	return snd_sb_csp_load(p, program->data, program->size, flags);
 }

+ 33 - 57
sound/isa/sb/sb8.c

@@ -22,7 +22,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 struct snd_sb8 {
 	struct resource *fm_res;	/* used to block FM i/o region for legacy cards */
 	struct snd_sb *chip;
@@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card)
 	release_and_free_resource(acard->fm_res);
 }
 
-static int __devinit snd_sb8_probe(struct platform_device *pdev)
+static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
+{
+	if (!enable[dev])
+		return 0;
+	if (irq[dev] == SNDRV_AUTO_IRQ) {
+		snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id);
+		return 0;
+	}
+	if (dma8[dev] == SNDRV_AUTO_DMA) {
+		snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id);
+		return 0;
+	}
+	return 1;
+}
+
+static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
 {
-	int dev = pdev->id;
 	struct snd_sb *chip;
 	struct snd_card *card;
 	struct snd_sb8 *acard;
@@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
 		chip->port,
 		irq[dev], dma8[dev]);
 
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev)
 	return err;
 }
 
-static int __devexit snd_sb8_remove(struct platform_device *pdev)
+static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(pdev));
-	platform_set_drvdata(pdev, NULL);
+	snd_card_free(dev_get_drvdata(pdev));
+	dev_set_drvdata(pdev, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
+static int snd_sb8_suspend(struct device *dev, unsigned int n,
+			   pm_message_t state)
 {
-	struct snd_card *card = platform_get_drvdata(dev);
+	struct snd_card *card = dev_get_drvdata(dev);
 	struct snd_sb8 *acard = card->private_data;
 	struct snd_sb *chip = acard->chip;
 
@@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
 	return 0;
 }
 
-static int snd_sb8_resume(struct platform_device *dev)
+static int snd_sb8_resume(struct device *dev, unsigned int n)
 {
-	struct snd_card *card = platform_get_drvdata(dev);
+	struct snd_card *card = dev_get_drvdata(dev);
 	struct snd_sb8 *acard = card->private_data;
 	struct snd_sb *chip = acard->chip;
 
@@ -226,9 +239,10 @@ static int snd_sb8_resume(struct platform_device *dev)
 }
 #endif
 
-#define SND_SB8_DRIVER	"snd_sb8"
+#define DEV_NAME "sb8"
 
-static struct platform_driver snd_sb8_driver = {
+static struct isa_driver snd_sb8_driver = {
+	.match		= snd_sb8_match,
 	.probe		= snd_sb8_probe,
 	.remove		= __devexit_p(snd_sb8_remove),
 #ifdef CONFIG_PM
@@ -236,56 +250,18 @@ static struct platform_driver snd_sb8_driver = {
 	.resume		= snd_sb8_resume,
 #endif
 	.driver		= {
-		.name	= SND_SB8_DRIVER
+		.name	= DEV_NAME 
 	},
 };
 
-static void __init_or_module snd_sb8_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_sb8_driver);
-}
-
 static int __init alsa_card_sb8_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_sb8_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(SND_SB8_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n");
-#endif
-		snd_sb8_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_sb8_exit(void)
 {
-	snd_sb8_unregister_all();
+	isa_unregister_driver(&snd_sb8_driver);
 }
 
 module_init(alsa_card_sb8_init)

+ 38 - 69
sound/isa/sgalaxy.c

@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
@@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
 module_param_array(dma1, int, NULL, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
 
-static struct platform_device *devices[SNDRV_CARDS];
-
 #define SGALAXY_AUXC_LEFT 18
 #define SGALAXY_AUXC_RIGHT 19
 
@@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port)
 	return 0;
 }
 
-static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val)
+static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
+					       unsigned char val)
 {
 	int i;
        	
@@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
-static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
+static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
 {
 	static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 
 				       0x10, 0x18, 0x20, -1, -1, -1, -1};
@@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
 	return 0;
 }
 
-static int __init snd_sgalaxy_detect(int dev, int irq, int dma)
+static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
 {
 #if 0
 	snd_printdd(PFX "switching to WSS mode\n");
@@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7
 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
 };
 
-static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
+static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip)
 {
 	struct snd_card *card = chip->card;
 	struct snd_ctl_elem_id id1, id2;
@@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
 	return 0;
 }
 
-static int __init snd_sgalaxy_probe(struct platform_device *devptr)
+static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
 {
-	int dev = devptr->id;
-	static int possible_irqs[] = {7, 9, 10, 11, -1};
-	static int possible_dmas[] = {1, 3, 0, -1};
-	int err, xirq, xdma1;
-	struct snd_card *card;
-	struct snd_ad1848 *chip;
-
+	if (!enable[dev])
+		return 0;
 	if (sbport[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify SB port\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (wssport[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify WSS port\n");
-		return -EINVAL;
+		return 0;
 	}
+	return 1;
+}
+
+static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
+{
+	static int possible_irqs[] = {7, 9, 10, 11, -1};
+	static int possible_dmas[] = {1, 3, 0, -1};
+	int err, xirq, xdma1;
+	struct snd_card *card;
+	struct snd_ad1848 *chip;
+
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
@@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
 	sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
 		wssport[dev], xirq, xdma1);
 
-	snd_card_set_dev(card, &devptr->dev);
+	snd_card_set_dev(card, devptr);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	platform_set_drvdata(devptr, card);
+	dev_set_drvdata(devptr, card);
 	return 0;
 
  _err:
@@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr)
 	return err;
 }
 
-static int __devexit snd_sgalaxy_remove(struct platform_device *devptr)
+static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
 #ifdef CONFIG_PM
-static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
+static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
+			       pm_message_t state)
 {
-	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_card *card = dev_get_drvdata(pdev);
 	struct snd_ad1848 *chip = card->private_data;
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int snd_sgalaxy_resume(struct platform_device *pdev)
+static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
 {
-	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_card *card = dev_get_drvdata(pdev);
 	struct snd_ad1848 *chip = card->private_data;
 
 	chip->resume(chip);
@@ -328,9 +334,10 @@ static int snd_sgalaxy_resume(struct platform_device *pdev)
 }
 #endif
 
-#define SND_SGALAXY_DRIVER	"snd_sgalaxy"
+#define DEV_NAME "sgalaxy"
 
-static struct platform_driver snd_sgalaxy_driver = {
+static struct isa_driver snd_sgalaxy_driver = {
+	.match		= snd_sgalaxy_match,
 	.probe		= snd_sgalaxy_probe,
 	.remove		= __devexit_p(snd_sgalaxy_remove),
 #ifdef CONFIG_PM
@@ -338,56 +345,18 @@ static struct platform_driver snd_sgalaxy_driver = {
 	.resume		= snd_sgalaxy_resume,
 #endif
 	.driver		= {
-		.name	= SND_SGALAXY_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
-static void __init_or_module snd_sgalaxy_unregister_all(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(devices); ++i)
-		platform_device_unregister(devices[i]);
-	platform_driver_unregister(&snd_sgalaxy_driver);
-}
-
 static int __init alsa_card_sgalaxy_init(void)
 {
-	int i, cards, err;
-
-	err = platform_driver_register(&snd_sgalaxy_driver);
-	if (err < 0)
-		return err;
-
-	cards = 0;
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-		device = platform_device_register_simple(SND_SGALAXY_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		devices[i] = device;
-		cards++;
-	}
-	if (!cards) {
-#ifdef MODULE
-		snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n");
-#endif
-		snd_sgalaxy_unregister_all();
-		return -ENODEV;
-	}
-	return 0;
+	return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
 }
 
 static void __exit alsa_card_sgalaxy_exit(void)
 {
-	snd_sgalaxy_unregister_all();
+	isa_unregister_driver(&snd_sgalaxy_driver);
 }
 
 module_init(alsa_card_sgalaxy_init)

+ 40 - 80
sound/isa/sscape.c

@@ -24,7 +24,7 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/delay.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
@@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
 module_param_array(dma, int, NULL, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-  
 #ifdef CONFIG_PNP
 static int pnp_registered;
 static struct pnp_card_device_id sscape_pnpids[] = {
@@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp)
 }
 
 
-static int __devinit snd_sscape_probe(struct platform_device *pdev)
+static int __devinit snd_sscape_match(struct device *pdev, unsigned int i)
+{
+	/*
+	 * Make sure we were given ALL of the other parameters.
+	 */
+	if (port[i] == SNDRV_AUTO_PORT)
+		return 0;
+
+	if (irq[i] == SNDRV_AUTO_IRQ ||
+	    mpu_irq[i] == SNDRV_AUTO_IRQ ||
+	    dma[i] == SNDRV_AUTO_DMA) {
+		printk(KERN_INFO
+		       "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev)
 {
-	int dev = pdev->id;
 	struct snd_card *card;
 	int ret;
 
@@ -1264,30 +1280,31 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev)
 	ret = create_sscape(dev, &card);
 	if (ret < 0)
 		return ret;
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 	if ((ret = snd_card_register(card)) < 0) {
 		printk(KERN_ERR "sscape: Failed to register sound card\n");
 		return ret;
 	}
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
-static int __devexit snd_sscape_remove(struct platform_device *devptr)
+static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-#define SSCAPE_DRIVER	"snd_sscape"
+#define DEV_NAME "sscape"
 
-static struct platform_driver snd_sscape_driver = {
+static struct isa_driver snd_sscape_driver = {
+	.match		= snd_sscape_match,
 	.probe		= snd_sscape_probe,
 	.remove		= __devexit_p(snd_sscape_remove),
 	/* FIXME: suspend/resume */
 	.driver		= {
-		.name	= SSCAPE_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
@@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module sscape_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnp_registered)
-		pnp_unregister_card_driver(&sscape_pnpc_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_sscape_driver);
-}
-
-static int __init sscape_manual_probe(void)
-{
-	struct platform_device *device;
-	int i, ret;
-
-	ret = platform_driver_register(&snd_sscape_driver);
-	if (ret < 0)
-		return ret;
-
-	for (i = 0; i < SNDRV_CARDS; ++i) {
-		/*
-		 * We do NOT probe for ports.
-		 * If we're not given a port number for this
-		 * card then we completely ignore this line
-		 * of parameters.
-		 */
-		if (port[i] == SNDRV_AUTO_PORT)
-			continue;
-
-		/*
-		 * Make sure we were given ALL of the other parameters.
-		 */
-		if (irq[i] == SNDRV_AUTO_IRQ ||
-		    mpu_irq[i] == SNDRV_AUTO_IRQ ||
-		    dma[i] == SNDRV_AUTO_DMA) {
-			printk(KERN_INFO
-			       "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
-			sscape_unregister_all();
-			return -ENXIO;
-		}
-
-		/*
-		 * This cards looks OK ...
-		 */
-		device = platform_device_register_simple(SSCAPE_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-	}
-	return 0;
-}
-
-static void sscape_exit(void)
-{
-	sscape_unregister_all();
-}
-
-
 static int __init sscape_init(void)
 {
 	int ret;
@@ -1462,7 +1413,7 @@ static int __init sscape_init(void)
 	 * of allocating cards, because the operator is
 	 * S-P-E-L-L-I-N-G it out for us...
 	 */
-	ret = sscape_manual_probe();
+	ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
 	if (ret < 0)
 		return ret;
 #ifdef CONFIG_PNP
@@ -1472,5 +1423,14 @@ static int __init sscape_init(void)
 	return 0;
 }
 
+static void __exit sscape_exit(void)
+{
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sscape_pnpc_driver);
+#endif
+	isa_unregister_driver(&snd_sscape_driver);
+}
+
 module_init(sscape_init);
 module_exit(sscape_exit);

+ 42 - 71
sound/isa/wavefront/wavefront.c

@@ -24,7 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/err.h>
-#include <linux/platform_device.h>
+#include <linux/isa.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
@@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
 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;	    /* Enable this card */
+#ifdef CONFIG_PNP
 static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
+#endif
 static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
 static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */
 static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@@ -83,8 +85,6 @@ MODULE_PARM_DESC(fm_port, "FM port #.");
 module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
-static struct platform_device *platform_devices[SNDRV_CARDS];
-
 #ifdef CONFIG_PNP
 static int pnp_registered;
 
@@ -588,56 +588,67 @@ snd_wavefront_probe (struct snd_card *card, int dev)
 	return snd_card_register(card);
 }	
 
-static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev)
+static int __devinit snd_wavefront_isa_match(struct device *pdev,
+					     unsigned int dev)
 {
-	int dev = pdev->id;
-	struct snd_card *card;
-	int err;
-
+	if (!enable[dev])
+		return 0;
+#ifdef CONFIG_PNP
+	if (isapnp[dev])
+		return 0;
+#endif
 	if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk("specify CS4232 port\n");
-		return -EINVAL;
+		return 0;
 	}
 	if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk("specify ICS2115 port\n");
-		return -ENODEV;
+		return 0;
 	}
+	return 1;
+}
+
+static int __devinit snd_wavefront_isa_probe(struct device *pdev,
+					     unsigned int dev)
+{
+	struct snd_card *card;
+	int err;
 
 	card = snd_wavefront_card_new(dev);
 	if (! card)
 		return -ENOMEM;
-	snd_card_set_dev(card, &pdev->dev);
+	snd_card_set_dev(card, pdev);
 	if ((err = snd_wavefront_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 	
-	platform_set_drvdata(pdev, card);
+	dev_set_drvdata(pdev, card);
 	return 0;
 }
 
-static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr)
+static int __devexit snd_wavefront_isa_remove(struct device *devptr,
+					      unsigned int dev)
 {
-	snd_card_free(platform_get_drvdata(devptr));
-	platform_set_drvdata(devptr, NULL);
+	snd_card_free(dev_get_drvdata(devptr));
+	dev_set_drvdata(devptr, NULL);
 	return 0;
 }
 
-#define WAVEFRONT_DRIVER	"snd_wavefront"
+#define DEV_NAME "wavefront"
 
-static struct platform_driver snd_wavefront_driver = {
-	.probe		= snd_wavefront_nonpnp_probe,
-	.remove		= __devexit_p(snd_wavefront_nonpnp_remove),
+static struct isa_driver snd_wavefront_driver = {
+	.match		= snd_wavefront_isa_match,
+	.probe		= snd_wavefront_isa_probe,
+	.remove		= __devexit_p(snd_wavefront_isa_remove),
 	/* FIXME: suspend, resume */
 	.driver		= {
-		.name	= WAVEFRONT_DRIVER
+		.name	= DEV_NAME
 	},
 };
 
 
 #ifdef CONFIG_PNP
-static unsigned int __devinitdata wavefront_pnp_devices;
-
 static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
                                               const struct pnp_card_device_id *pid)
 {
@@ -670,7 +681,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
 
 	pnp_set_card_drvdata(pcard, card);
 	dev++;
-	wavefront_pnp_devices++;
 	return 0;
 }
 
@@ -691,67 +701,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = {
 
 #endif /* CONFIG_PNP */
 
-static void __init_or_module snd_wavefront_unregister_all(void)
-{
-	int i;
-
-#ifdef CONFIG_PNP
-	if (pnp_registered)
-		pnp_unregister_card_driver(&wavefront_pnpc_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
-		platform_device_unregister(platform_devices[i]);
-	platform_driver_unregister(&snd_wavefront_driver);
-}
-
 static int __init alsa_card_wavefront_init(void)
 {
-	int i, err, cards = 0;
+	int err;
 
-	if ((err = platform_driver_register(&snd_wavefront_driver)) < 0)
+	err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
+	if (err < 0)
 		return err;
-
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		struct platform_device *device;
-		if (! enable[i])
-			continue;
-#ifdef CONFIG_PNP
-		if (isapnp[i])
-			continue;
-#endif
-		device = platform_device_register_simple(WAVEFRONT_DRIVER,
-							 i, NULL, 0);
-		if (IS_ERR(device))
-			continue;
-		if (!platform_get_drvdata(device)) {
-			platform_device_unregister(device);
-			continue;
-		}
-		platform_devices[i] = device;
-		cards++;
-	}
-
 #ifdef CONFIG_PNP
 	err = pnp_register_card_driver(&wavefront_pnpc_driver);
-	if (!err) {
+	if (!err)
 		pnp_registered = 1;
-		cards += wavefront_pnp_devices;
-	}
-#endif
-
-	if (!cards) {
-#ifdef MODULE
-		printk (KERN_ERR "No WaveFront cards found or devices busy\n");
 #endif
-		snd_wavefront_unregister_all();
-		return -ENODEV;
-	}
 	return 0;
 }
 
 static void __exit alsa_card_wavefront_exit(void)
 {
-	snd_wavefront_unregister_all();
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&wavefront_pnpc_driver);
+#endif
+	isa_unregister_driver(&snd_wavefront_driver);
 }
 
 module_init(alsa_card_wavefront_init)

+ 12 - 11
sound/isa/wavefront/wavefront_fx.c

@@ -35,9 +35,7 @@
 
 #define WAIT_IDLE	0xff
 
-#define FIRMWARE_IN_THE_KERNEL
-
-#ifdef FIRMWARE_IN_THE_KERNEL
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
 #include "yss225.c"
 static const struct firmware yss225_registers_firmware = {
 	.data = (u8 *)yss225_registers,
@@ -258,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
 {
 	unsigned int i;
 	int err;
-	const struct firmware *firmware;
+	const struct firmware *firmware = NULL;
 
 	if (dev->fx_initialized)
 		return 0;
 
+#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+	firmware = &yss225_registers_firmware;
+#else
 	err = request_firmware(&firmware, "yamaha/yss225_registers.bin",
 			       dev->card->dev);
 	if (err < 0) {
-#ifdef FIRMWARE_IN_THE_KERNEL
-		firmware = &yss225_registers_firmware;
-#else
 		err = -1;
 		goto out;
-#endif
 	}
+#endif
 
 	for (i = 0; i + 1 < firmware->size; i += 2) {
 		if (firmware->data[i] >= 8 && firmware->data[i] < 16) {
@@ -295,9 +293,12 @@ snd_wavefront_fx_start (snd_wavefront_t *dev)
 	err = 0;
 
 out:
-#ifdef FIRMWARE_IN_THE_KERNEL
-	if (firmware != &yss225_registers_firmware)
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+	release_firmware(firmware);
 #endif
-		release_firmware(firmware);
 	return err;
 }
+
+#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL
+MODULE_FIRMWARE("yamaha/yss225_registers.bin");
+#endif

+ 30 - 3
sound/pci/Kconfig

@@ -576,7 +576,7 @@ config SND_INTEL8X0M
 config SND_KORG1212
 	tristate "Korg 1212 IO"
 	depends on SND
-	select FW_LOADER
+	select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL
 	select SND_PCM
 	help
 	  Say Y here to include support for Korg 1212IO soundcards.
@@ -584,10 +584,19 @@ config SND_KORG1212
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-korg1212.
 
+config SND_KORG1212_FIRMWARE_IN_KERNEL
+	bool "In-kernel firmware for Korg1212 driver"
+	depends on SND_KORG1212
+	default y
+	help
+	  Say Y here to include the static firmware built in the kernel
+	  for the Korg1212 driver.  If you choose N here, you need to
+	  install the firmware files from the alsa-firmware package.
+
 config SND_MAESTRO3
 	tristate "ESS Allegro/Maestro3"
 	depends on SND
-	select FW_LOADER
+	select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL
 	select SND_AC97_CODEC
 	help
 	  Say Y here to include support for soundcards based on ESS Maestro 3
@@ -596,6 +605,15 @@ config SND_MAESTRO3
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-maestro3.
 
+config SND_MAESTRO3_FIRMWARE_IN_KERNEL
+	bool "In-kernel firmware for Maestro3 driver"
+	depends on SND_MAESTRO3
+	default y
+	help
+	  Say Y here to include the static firmware built in the kernel
+	  for the Maestro3 driver.  If you choose N here, you need to
+	  install the firmware files from the alsa-firmware package.
+
 config SND_MIXART
 	tristate "Digigram miXart"
 	depends on SND
@@ -737,7 +755,7 @@ config SND_VX222
 config SND_YMFPCI
 	tristate "Yamaha YMF724/740/744/754"
 	depends on SND
-	select FW_LOADER
+	select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_AC97_CODEC
@@ -748,6 +766,15 @@ config SND_YMFPCI
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-ymfpci.
 
+config SND_YMFPCI_FIRMWARE_IN_KERNEL
+	bool "In-kernel firmware for YMFPCI driver"
+	depends on SND_YMFPCI
+	default y
+	help
+	  Say Y here to include the static firmware built in the kernel
+	  for the YMFPCI driver.  If you choose N here, you need to
+	  install the firmware files from the alsa-firmware package.
+
 config SND_AC97_POWER_SAVE
 	bool "AC97 Power-Saving Mode"
 	depends on SND_AC97_CODEC && EXPERIMENTAL

+ 1 - 1
sound/pci/ac97/Makefile

@@ -3,7 +3,7 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o
+snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o
 
 ifneq ($(CONFIG_PROC_FS),)
 snd-ac97-codec-objs += ac97_proc.o

+ 27 - 16
sound/pci/ac97/ac97_codec.c

@@ -35,9 +35,9 @@
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
 #include <sound/initval.h>
-#include "ac97_local.h"
 #include "ac97_id.h"
-#include "ac97_patch.h"
+
+#include "ac97_patch.c"
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("Universal interface for Audio Codec '97");
@@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns
  * Controls
  */
 
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
 	
@@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
 	return 0;
 }
 
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
 	return 0;
 }
 
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
@@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
 }
 
 /* volume and switch controls */
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0x0f;
@@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
 	return 0;
 }
 
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
@@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
 	return 0;
 }
 
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
@@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]),
 AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
 };
 
-const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
 AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
 AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
 };
@@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
 	return change;
 }
 
-const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha
 	}
 }
 
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
 {
 	unsigned short mask, val, orig, res;
 
@@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x)
 	return x;
 }
 
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97)
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+					  struct snd_ac97 * ac97)
 {
 	struct snd_kcontrol_new template;
 	memcpy(&template, _template, sizeof(template));
@@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix)
 }	
 
 /* remove the control with the given name and optional suffix */
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix)
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+			       const char *suffix)
 {
 	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
@@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co
 }
 
 /* rename the control with the given name and optional suffix */
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix)
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+			       const char *dst, const char *suffix)
 {
 	struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
 	if (kctl) {
@@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst,
 }
 
 /* rename both Volume and Switch controls - don't check the return value */
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst)
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+				    const char *dst)
 {
 	snd_ac97_rename_ctl(ac97, src, dst, "Switch");
 	snd_ac97_rename_ctl(ac97, src, dst, "Volume");
 }
 
 /* swap controls */
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix)
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+			     const char *s2, const char *suffix)
 {
 	struct snd_kcontrol *kctl1, *kctl2;
 	kctl1 = ctl_find(ac97, s1, suffix);

+ 2 - 53
sound/pci/ac97/ac97_local.h

@@ -22,59 +22,8 @@
  *
  */
 
-#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
-#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
-#define AC97_SINGLE(xname, reg, shift, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
-#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
-#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
-  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
-  .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
-
-/* enum control */
-struct ac97_enum {
-	unsigned char reg;
-	unsigned char shift_l;
-	unsigned char shift_r;
-	unsigned short mask;
-	const char **texts;
-};
-
-#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
-{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
-  .mask = xmask, .texts = xtexts }
-#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
-	AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
-#define AC97_ENUM(xname, xenum) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
-  .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
-  .private_value = (unsigned long)&xenum }
-
-/* ac97_codec.c */
-extern const struct snd_kcontrol_new snd_ac97_controls_3d[];
-extern const struct snd_kcontrol_new snd_ac97_controls_spdif[];
-struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97);
-void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem);
-int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
-int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix);
-int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix);
-int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix);
-void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst);
-void snd_ac97_restore_status(struct snd_ac97 *ac97);
-void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
-int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
-int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
-
+void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name,
+		       int modem);
 int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
 				unsigned short mask, unsigned short value);
 

+ 139 - 55
sound/pci/ac97/ac97_patch.c

@@ -23,20 +23,8 @@
  *
  */
 
-#include <sound/driver.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-#include <sound/ac97_codec.h>
-#include "ac97_patch.h"
-#include "ac97_id.h"
 #include "ac97_local.h"
+#include "ac97_patch.h"
 
 /*
  *  Chip specific initialization
@@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
 	.build_post_spdif = patch_yamaha_ymf753_post_spdif
 };
 
-int patch_yamaha_ymf753(struct snd_ac97 * ac97)
+static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
 {
 	/* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
 	   This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
@@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
 	.build_specific = patch_wolfson_wm9703_specific,
 };
 
-int patch_wolfson03(struct snd_ac97 * ac97)
+static int patch_wolfson03(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_wolfson_wm9703_ops;
 	return 0;
@@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
 	.build_specific = patch_wolfson_wm9704_specific,
 };
 
-int patch_wolfson04(struct snd_ac97 * ac97)
+static int patch_wolfson04(struct snd_ac97 * ac97)
 {
 	/* WM9704M/9704Q */
 	ac97->build_ops = &patch_wolfson_wm9704_ops;
@@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = {
 	.build_specific = patch_wolfson_wm9705_specific,
 };
 
-int patch_wolfson05(struct snd_ac97 * ac97)
+static int patch_wolfson05(struct snd_ac97 * ac97)
 {
 	/* WM9705, WM9710 */
 	ac97->build_ops = &patch_wolfson_wm9705_ops;
@@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
 	.build_specific = patch_wolfson_wm9711_specific,
 };
 
-int patch_wolfson11(struct snd_ac97 * ac97)
+static int patch_wolfson11(struct snd_ac97 * ac97)
 {
 	/* WM9711, WM9712 */
 	ac97->build_ops = &patch_wolfson_wm9711_ops;
@@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
 #endif
 };
 
-int patch_wolfson13(struct snd_ac97 * ac97)
+static int patch_wolfson13(struct snd_ac97 * ac97)
 {
 	/* WM9713, WM9714 */
 	ac97->build_ops = &patch_wolfson_wm9713_ops;
@@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97)
 /*
  * Tritech codec
  */
-int patch_tritech_tr28028(struct snd_ac97 * ac97)
+static int patch_tritech_tr28028(struct snd_ac97 * ac97)
 {
 	snd_ac97_write_cache(ac97, 0x26, 0x0300);
 	snd_ac97_write_cache(ac97, 0x26, 0x0000);
@@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
 	.build_specific	= patch_sigmatel_stac97xx_specific
 };
 
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
 	return 0;
@@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
 	.build_specific	= patch_sigmatel_stac9708_specific
 };
 
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
 {
 	unsigned int codec72, codec6c;
 
@@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
 	return 0;
 }
 
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
 	if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
@@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
 	return 0;
 }
 
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
 {
 	// patch for SigmaTel
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
 	return 0;
 }
 
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
 {
 	// patch for SigmaTel
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
 	.build_specific	= patch_sigmatel_stac9758_specific
 };
 
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
+static int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
 {
 	static unsigned short regs[4] = {
 		AC97_SIGMATEL_OUTSEL,
@@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = {
 	.build_spdif = patch_cirrus_build_spdif
 };
 
-int patch_cirrus_spdif(struct snd_ac97 * ac97)
+static int patch_cirrus_spdif(struct snd_ac97 * ac97)
 {
 	/* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
 	   WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC?  *sigh*
@@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97)
 	return 0;
 }
 
-int patch_cirrus_cs4299(struct snd_ac97 * ac97)
+static int patch_cirrus_cs4299(struct snd_ac97 * ac97)
 {
 	/* force the detection of PC Beep */
 	ac97->flags |= AC97_HAS_PC_BEEP;
@@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = {
 	.build_spdif = patch_conexant_build_spdif
 };
 
-int patch_conexant(struct snd_ac97 * ac97)
+static int patch_conexant(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_conexant_ops;
 	ac97->flags |= AC97_CX_SPDIF;
@@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97)
 	return 0;
 }
 
-int patch_cx20551(struct snd_ac97 *ac97)
+static int patch_cx20551(struct snd_ac97 *ac97)
 {
 	snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01);
 	return 0;
@@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = {
 	{ } /* terminator */
 };
 
-int patch_ad1819(struct snd_ac97 * ac97)
+static int patch_ad1819(struct snd_ac97 * ac97)
 {
 	unsigned short scfg;
 
@@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = {
 #endif
 };
 
-int patch_ad1881(struct snd_ac97 * ac97)
+static int patch_ad1881(struct snd_ac97 * ac97)
 {
 	static const char cfg_idxs[3][2] = {
 		{2, 1},
@@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = {
 #endif
 };
 
-int patch_ad1885(struct snd_ac97 * ac97)
+static int patch_ad1885(struct snd_ac97 * ac97)
 {
 	patch_ad1881(ac97);
 	/* This is required to deal with the Intel D815EEAL2 */
@@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = {
 #endif
 };
 
-int patch_ad1886(struct snd_ac97 * ac97)
+static int patch_ad1886(struct snd_ac97 * ac97)
 {
 	patch_ad1881(ac97);
 	/* Presario700 workaround */
@@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
 		snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
 }
 
-int patch_ad1981a(struct snd_ac97 *ac97)
+static int patch_ad1981a(struct snd_ac97 *ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1981a_build_ops;
@@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = {
 #endif
 };
 
-int patch_ad1981b(struct snd_ac97 *ac97)
+static int patch_ad1981b(struct snd_ac97 *ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1981b_build_ops;
@@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = {
 	.update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1888(struct snd_ac97 * ac97)
+static int patch_ad1888(struct snd_ac97 * ac97)
 {
 	unsigned short misc;
 	
@@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = {
 	.update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1980(struct snd_ac97 * ac97)
+static int patch_ad1980(struct snd_ac97 * ac97)
 {
 	patch_ad1888(ac97);
 	ac97->build_ops = &patch_ad1980_build_ops;
@@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = {
 	.update_jacks = ad1985_update_jacks,
 };
 
-int patch_ad1985(struct snd_ac97 * ac97)
+static int patch_ad1985(struct snd_ac97 * ac97)
 {
 	unsigned short misc;
 	
@@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = {
 	.update_jacks = ad1986_update_jacks,
 };
 
-int patch_ad1986(struct snd_ac97 * ac97)
+static int patch_ad1986(struct snd_ac97 * ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1986_build_ops;
@@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
 	.update_jacks = alc650_update_jacks
 };
 
-int patch_alc650(struct snd_ac97 * ac97)
+static int patch_alc650(struct snd_ac97 * ac97)
 {
 	unsigned short val;
 
@@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = {
 	.update_jacks = alc655_update_jacks
 };
 
-int patch_alc655(struct snd_ac97 * ac97)
+static int patch_alc655(struct snd_ac97 * ac97)
 {
 	unsigned int val;
 
@@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97)
 		    (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
 		     ac97->subsystem_device == 0x0161 || /* LG K1 Express */
 		     ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
+		     ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */
 		     ac97->subsystem_device == 0x0061))  /* MSI S250 laptop */
 			val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
 		else
@@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = {
 	.update_jacks = alc850_update_jacks
 };
 
-int patch_alc850(struct snd_ac97 *ac97)
+static int patch_alc850(struct snd_ac97 *ac97)
 {
 	ac97->build_ops = &patch_alc850_ops;
 
@@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = {
 	.update_jacks = cm9738_update_jacks
 };
 
-int patch_cm9738(struct snd_ac97 * ac97)
+static int patch_cm9738(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_cm9738_ops;
 	/* FIXME: can anyone confirm below? */
@@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = {
 	.update_jacks = cm9739_update_jacks
 };
 
-int patch_cm9739(struct snd_ac97 * ac97)
+static int patch_cm9739(struct snd_ac97 * ac97)
 {
 	unsigned short val;
 
@@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = {
 	.update_jacks = cm9761_update_jacks
 };
 
-int patch_cm9761(struct snd_ac97 *ac97)
+static int patch_cm9761(struct snd_ac97 *ac97)
 {
 	unsigned short val;
 
@@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = {
 	.build_post_spdif = patch_cm9761_post_spdif	/* identical with CM9761 */
 };
 
-int patch_cm9780(struct snd_ac97 *ac97)
+static int patch_cm9780(struct snd_ac97 *ac97)
 {
 	unsigned short val;
 
@@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = {
 	.build_specific	= patch_vt1616_specific
 };
 
-int patch_vt1616(struct snd_ac97 * ac97)
+static int patch_vt1616(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_vt1616_ops;
 	return 0;
@@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97)
 /*
  * VT1617A codec
  */
+
+/*
+ * unfortunately, the vt1617a stashes the twiddlers required for
+ * nooding the i/o jacks on 2 different regs. * thameans that we cant
+ * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
+ * are own funcs.
+ *
+ * NB: this is absolutely and utterly different from the vt1618. dunno
+ * about the 1616.
+ */
+
+/* copied from ac97_surround_jack_mode_info() */
+static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
+{
+	/* ordering in this list reflects vt1617a docs for Reg 20 and
+	 * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51
+	 * is SM51EN *AND* it's Bit14, not Bit15 so the table is very
+	 * counter-intuitive */ 
+
+	static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3",
+				       "Surr LFE/C Mic3", "LineIn LFE/C Mic3",
+				       "LineIn Mic2", "LineIn Mic2 Mic1",
+				       "Surr LFE Mic1", "Surr LFE Mic1 Mic2"};
+	return ac97_enum_text_info(kcontrol, uinfo, texts, 8);
+}
+
+static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	ushort usSM51, usMS;  
+
+	struct snd_ac97 *pac97;
+	
+	pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+	/* grab our desirec bits, then mash them together in a manner
+	 * consistent with Table 6 on page 17 in the 1617a docs */
+ 
+	usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
+	usMS   = snd_ac97_read(pac97, 0x20) >> 8;
+  
+	ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS;
+
+	return 0;
+}
+
+static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	ushort usSM51, usMS, usReg;  
+
+	struct snd_ac97 *pac97;
+
+	pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
+
+	usSM51 = ucontrol->value.enumerated.item[0] >> 1;
+	usMS   = ucontrol->value.enumerated.item[0] &  1;
+
+	/* push our values into the register - consider that things will be left
+	 * in a funky state if the write fails */
+
+	usReg = snd_ac97_read(pac97, 0x7a);
+	snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14));
+	usReg = snd_ac97_read(pac97, 0x20);
+	snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS   <<  8));
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = {
+
+	AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0),
+	/*
+	 * These are used to enable/disable surround sound on motherboards
+	 * that have 3 bidirectional analog jacks
+	 */
+	{
+		.iface         = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name          = "Smart 5.1 Select",
+		.info          = snd_ac97_vt1617a_smart51_info,
+		.get           = snd_ac97_vt1617a_smart51_get,
+		.put           = snd_ac97_vt1617a_smart51_put,
+	},
+};
+
 int patch_vt1617a(struct snd_ac97 * ac97)
 {
-	/* bring analog power consumption to normal, like WinXP driver
-	 * for EPIA SP
+	int err = 0;
+
+	/* we choose to not fail out at this point, but we tell the
+	   caller when we return */
+
+	err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0],
+				   ARRAY_SIZE(snd_ac97_controls_vt1617a));
+
+	/* bring analog power consumption to normal by turning off the
+	 * headphone amplifier, like WinXP driver for EPIA SP
 	 */
 	snd_ac97_write_cache(ac97, 0x5c, 0x20);
 	ac97->ext_id |= AC97_EI_SPDIF;	/* force the detection of spdif */
 	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
 	ac97->build_ops = &patch_vt1616_ops;
-	return 0;
+
+	return err;
 }
 
 /*
@@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = {
 	.update_jacks = it2646_update_jacks
 };
 
-int patch_it2646(struct snd_ac97 * ac97)
+static int patch_it2646(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_it2646_ops;
 	/* full DAC volume */
@@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = {
 	.build_specific	= patch_si3036_specific,
 };
 
-int mpatch_si3036(struct snd_ac97 * ac97)
+static int mpatch_si3036(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_si3036_ops;
 	snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
@@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = {
 	{ } /* terminator */
 };
 
-int patch_lm4550(struct snd_ac97 *ac97)
+static int patch_lm4550(struct snd_ac97 *ac97)
 {
 	ac97->res_table = lm4550_restbl;
 	return 0;
@@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = {
 	.build_specific	= patch_ucb1400_specific,
 };
 
-int patch_ucb1400(struct snd_ac97 * ac97)
+static int patch_ucb1400(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_ucb1400_ops;
 	/* enable headphone driver and smart low power mode by default */

+ 69 - 41
sound/pci/ac97/ac97_patch.h

@@ -22,44 +22,72 @@
  *
  */
 
-int patch_yamaha_ymf753(struct snd_ac97 * ac97);
-int patch_wolfson00(struct snd_ac97 * ac97);
-int patch_wolfson03(struct snd_ac97 * ac97);
-int patch_wolfson04(struct snd_ac97 * ac97);
-int patch_wolfson05(struct snd_ac97 * ac97);
-int patch_wolfson11(struct snd_ac97 * ac97);
-int patch_wolfson13(struct snd_ac97 * ac97);
-int patch_tritech_tr28028(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9700(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9708(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9721(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9744(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9756(struct snd_ac97 * ac97);
-int patch_sigmatel_stac9758(struct snd_ac97 * ac97);
-int patch_cirrus_cs4299(struct snd_ac97 * ac97);
-int patch_cirrus_spdif(struct snd_ac97 * ac97);
-int patch_conexant(struct snd_ac97 * ac97);
-int patch_cx20551(struct snd_ac97 * ac97);
-int patch_ad1819(struct snd_ac97 * ac97);
-int patch_ad1881(struct snd_ac97 * ac97);
-int patch_ad1885(struct snd_ac97 * ac97);
-int patch_ad1886(struct snd_ac97 * ac97);
-int patch_ad1888(struct snd_ac97 * ac97);
-int patch_ad1980(struct snd_ac97 * ac97);
-int patch_ad1981a(struct snd_ac97 * ac97);
-int patch_ad1981b(struct snd_ac97 * ac97);
-int patch_ad1985(struct snd_ac97 * ac97);
-int patch_ad1986(struct snd_ac97 * ac97);
-int patch_alc650(struct snd_ac97 * ac97);
-int patch_alc655(struct snd_ac97 * ac97);
-int patch_alc850(struct snd_ac97 * ac97);
-int patch_cm9738(struct snd_ac97 * ac97);
-int patch_cm9739(struct snd_ac97 * ac97);
-int patch_cm9761(struct snd_ac97 * ac97);
-int patch_cm9780(struct snd_ac97 * ac97);
-int patch_vt1616(struct snd_ac97 * ac97);
-int patch_vt1617a(struct snd_ac97 * ac97);
-int patch_it2646(struct snd_ac97 * ac97);
-int patch_ucb1400(struct snd_ac97 * ac97);
-int mpatch_si3036(struct snd_ac97 * ac97);
-int patch_lm4550(struct snd_ac97 * ac97);
+#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \
+	((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \
+	 ((invert) << 24))
+#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \
+	(AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
+#define AC97_SINGLE(xname, reg, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_volsw,		\
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value =  AC97_SINGLE_VALUE(reg, shift, mask, invert) }
+#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page)		\
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_volsw,		\
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value =  AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
+#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+  .info = snd_ac97_info_volsw,		\
+  .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
+  .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
+
+/* enum control */
+struct ac97_enum {
+	unsigned char reg;
+	unsigned char shift_l;
+	unsigned char shift_r;
+	unsigned short mask;
+	const char **texts;
+};
+
+#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
+{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
+  .mask = xmask, .texts = xtexts }
+#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \
+	AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts)
+#define AC97_ENUM(xname, xenum) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_ac97_info_enum_double,		    \
+  .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
+  .private_value = (unsigned long)&xenum }
+
+/* ac97_codec.c */
+static const struct snd_kcontrol_new snd_ac97_controls_3d[];
+static const struct snd_kcontrol_new snd_ac97_controls_spdif[];
+static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template,
+					  struct snd_ac97 * ac97);
+static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
+static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+			       const char *suffix);
+static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+			       const char *dst, const char *suffix);
+static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+			     const char *s2, const char *suffix);
+static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src,
+				    const char *dst);
+static void snd_ac97_restore_status(struct snd_ac97 *ac97);
+static void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
+static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo);
+static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol);
+static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol);

+ 0 - 1
sound/pci/ac97/ac97_pcm.c

@@ -34,7 +34,6 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 #include <sound/asoundef.h>
-#include "ac97_patch.h"
 #include "ac97_id.h"
 #include "ac97_local.h"
 

+ 421 - 448
sound/pci/ali5451/ali5451.c

@@ -69,10 +69,10 @@ module_param(enable, bool, 0444);
  *  Debug part definitions
  */
 
-//#define ALI_DEBUG
+/* #define ALI_DEBUG */
 
 #ifdef ALI_DEBUG
-#define snd_ali_printk(format, args...) printk(format, ##args);
+#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args);
 #else
 #define snd_ali_printk(format, args...)
 #endif
@@ -105,10 +105,10 @@ module_param(enable, bool, 0444);
  *  Direct Registers
  */
 
-#define ALI_LEGACY_DMAR0        0x00  // ADR0
-#define ALI_LEGACY_DMAR4        0x04  // CNT0
-#define ALI_LEGACY_DMAR11       0x0b  // MOD 
-#define ALI_LEGACY_DMAR15       0x0f  // MMR 
+#define ALI_LEGACY_DMAR0        0x00  /* ADR0 */
+#define ALI_LEGACY_DMAR4        0x04  /* CNT0 */
+#define ALI_LEGACY_DMAR11       0x0b  /* MOD  */
+#define ALI_LEGACY_DMAR15       0x0f  /* MMR  */
 #define ALI_MPUR0		0x20
 #define ALI_MPUR1		0x21
 #define ALI_MPUR2		0x22
@@ -175,7 +175,7 @@ struct snd_ali;
 struct snd_ali_voice;
 
 struct snd_ali_channel_control {
-	// register data
+	/* register data */
 	struct REGDATA {
 		unsigned int start;
 		unsigned int stop;
@@ -183,7 +183,7 @@ struct snd_ali_channel_control {
 		unsigned int ainten;
 	} data;
 		
-	// register addresses
+	/* register addresses */
 	struct REGS {
 		unsigned int start;
 		unsigned int stop;
@@ -197,19 +197,18 @@ struct snd_ali_channel_control {
 
 struct snd_ali_voice {
 	unsigned int number;
-	unsigned int use: 1,
-	    pcm: 1,
-	    midi: 1,
-	    mode: 1,
-	    synth: 1;
+	unsigned int use :1,
+		pcm :1,
+		midi :1,
+		mode :1,
+		synth :1,
+		running :1;
 
 	/* PCM data */
 	struct snd_ali *codec;
 	struct snd_pcm_substream *substream;
 	struct snd_ali_voice *extra;
 	
-	unsigned int running: 1;
-
 	int eso;                /* final ESO value for channel */
 	int count;              /* runtime->period_size */
 
@@ -231,14 +230,12 @@ struct snd_alidev {
 };
 
 
-#ifdef CONFIG_PM
 #define ALI_GLOBAL_REGS		56
 #define ALI_CHANNEL_REGS	8
 struct snd_ali_image {
-	unsigned long regs[ALI_GLOBAL_REGS];
-	unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
+	u32 regs[ALI_GLOBAL_REGS];
+	u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
 };
-#endif
 
 
 struct snd_ali {
@@ -246,8 +243,8 @@ struct snd_ali {
 	unsigned long	port;
 	unsigned char	revision;
 
-	unsigned int hw_initialized: 1;
-	unsigned int spdif_support: 1;
+	unsigned int hw_initialized :1;
+	unsigned int spdif_support :1;
 
 	struct pci_dev	*pci;
 	struct pci_dev	*pci_m1533;
@@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids);
 
 static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int);
 static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short);
-static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short);
-
-/*
- *  Debug Part
- */
-
-#ifdef ALI_DEBUG
-
-static void ali_read_regs(struct snd_ali *codec, int channel)
-{
-	int i,j;
-	unsigned int dwVal;
-
-	printk("channel %d registers map:\n", channel);
-	outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR));
-
-	printk("    ");
-	for(j=0;j<8;j++)
-		printk("%2.2x       ", j*4);
-	printk("\n");
-
-	for (i=0; i<=0xf8/4;i++) {
-		if(i%8 == 0)
-			printk("%2.2x  ", (i*4/0x10)*0x10);
-		dwVal = inl(ALI_REG(codec,i*4));
-		printk("%8.8x ", dwVal);
-		if ((i+1)%8 == 0)
-			printk("\n");
-	}
-	printk("\n");
-}
-static void ali_read_cfg(unsigned int vendor, unsigned deviceid)
-{
-	unsigned int dwVal;
-	struct pci_dev *pci_dev;
-	int i,j;
-
-	pci_dev = pci_get_device(vendor, deviceid, NULL);
-	if (pci_dev == NULL)
-		return ;
-
-	printk("\nM%x PCI CFG\n", deviceid);
-	printk("    ");
-	for(j=0;j<8;j++)
-		printk("%d        ",j);
-	printk("\n");
-
-	for(i=0;i<8;i++) {
-		printk("%d   ",i);
-		for(j=0;j<8;j++)
-		{
-			pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal);
-			printk("%8.8x ", dwVal);
-		}
-		printk("\n");
-	}
-	pci_dev_put(pci_dev);
- }
-static void ali_read_ac97regs(struct snd_ali *codec, int secondary)
-{
-	unsigned short i,j;
-	unsigned short wVal;
-
-	printk("\ncodec %d registers map:\n", secondary);
-
-	printk("    ");
-	for(j=0;j<8;j++)
-		printk("%2.2x   ",j*2);
-	printk("\n");
-
-	for (i=0; i<64;i++) {
-		if(i%8 == 0)
-			printk("%2.2x  ", (i/8)*0x10);
-		wVal = snd_ali_codec_peek(codec, secondary, i*2);
-		printk("%4.4x ", wVal);
-		if ((i+1)%8 == 0)
-			printk("\n");
-	}
-	printk("\n");
-}
-
-#endif
+static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short,
+			       unsigned short);
 
 /*
  *  AC97 ACCESS
  */
 
 static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec,
-						unsigned int port )
+					     unsigned int port)
 {
 	return (unsigned int)inl(ALI_REG(codec, port)); 
 }
 
-static inline void snd_ali_5451_poke(	struct snd_ali *codec,
-					unsigned int port,
-					unsigned int val )
+static inline void snd_ali_5451_poke(struct snd_ali *codec,
+				     unsigned int port,
+				     unsigned int val)
 {
 	outl((unsigned int)val, ALI_REG(codec, port));
 }
 
-static int snd_ali_codec_ready(	struct snd_ali *codec,
-				unsigned int port )
+static int snd_ali_codec_ready(struct snd_ali *codec,
+			       unsigned int port)
 {
 	unsigned long end_time;
 	unsigned int res;
@@ -396,7 +313,7 @@ static int snd_ali_codec_ready(	struct snd_ali *codec,
 	end_time = jiffies + msecs_to_jiffies(250);
 	do {
 		res = snd_ali_5451_peek(codec,port);
-		if (! (res & 0x8000))
+		if (!(res & 0x8000))
 			return 0;
 		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
@@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec)
 }
 
 static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
-				     unsigned short reg,
-				     unsigned short val)
+			       unsigned short reg,
+			       unsigned short val)
 {
-	unsigned int dwVal = 0;
-	unsigned int port = 0;
+	unsigned int dwVal;
+	unsigned int port;
 
 	if (reg >= 0x80) {
 		snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
@@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
 
 	dwVal  = (unsigned int) (reg & 0xff);
 	dwVal |= 0x8000 | (val << 16);
-	if (secondary) dwVal |= 0x0080;
-	if (codec->revision == ALI_5451_V02) dwVal |= 0x0100;
+	if (secondary)
+		dwVal |= 0x0080;
+	if (codec->revision == ALI_5451_V02)
+		dwVal |= 0x0100;
 
-	snd_ali_5451_poke(codec,port,dwVal);
+	snd_ali_5451_poke(codec, port, dwVal);
 
 	return ;
 }
 
-static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
-					  int secondary,
-					  unsigned short reg)
+static unsigned short snd_ali_codec_peek(struct snd_ali *codec,
+					 int secondary,
+					 unsigned short reg)
 {
-	unsigned int dwVal = 0;
-	unsigned int port = 0;
+	unsigned int dwVal;
+	unsigned int port;
 
 	if (reg >= 0x80) {
 		snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
@@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
 
 	dwVal  = (unsigned int) (reg & 0xff);
 	dwVal |= 0x8000;				/* bit 15*/
-	if (secondary) dwVal |= 0x0080;
+	if (secondary)
+		dwVal |= 0x0080;
 
 	snd_ali_5451_poke(codec, port, dwVal);
 
@@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
 	if (snd_ali_codec_ready(codec, port) < 0)
 		return ~0;
 	
-	return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
+	return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16;
 }
 
 static void snd_ali_codec_write(struct snd_ac97 *ac97,
@@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
 	struct snd_ali *codec = ac97->private_data;
 
 	snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
-	if(reg == AC97_GPIO_STATUS) {
-		outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE,
-			ALI_REG(codec, ALI_AC97_GPIO));
+	if (reg == AC97_GPIO_STATUS) {
+		outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE,
+		     ALI_REG(codec, ALI_AC97_GPIO));
 		return;
 	}
 	snd_ali_codec_poke(codec, ac97->num, reg, val);
@@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97,
 }
 
 
-static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
+static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97,
+					 unsigned short reg)
 {
 	struct snd_ali *codec = ac97->private_data;
 
 	snd_ali_printk("codec_read reg=%xh.\n", reg);
-	return (snd_ali_codec_peek(codec, ac97->num, reg));
+	return snd_ali_codec_peek(codec, ac97->num, reg);
 }
 
 /*
@@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r
 
 static int snd_ali_reset_5451(struct snd_ali *codec)
 {
-	struct pci_dev *pci_dev = NULL;
+	struct pci_dev *pci_dev;
 	unsigned short wCount, wReg;
 	unsigned int   dwVal;
 	
-	if ((pci_dev = codec->pci_m1533) != NULL) {
+	pci_dev = codec->pci_m1533;
+	if (pci_dev) {
 		pci_read_config_dword(pci_dev, 0x7c, &dwVal);
 		pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
 		udelay(5000);
@@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
 	wCount = 200;
 	while(wCount--) {
 		wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN);
-		if((wReg & 0x000f) == 0x000f)
+		if ((wReg & 0x000f) == 0x000f)
 			return 0;
 		udelay(5000);
 	}
@@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
 
 static int snd_ali_reset_codec(struct snd_ali *codec)
 {
-	struct pci_dev *pci_dev = NULL;
-	unsigned char bVal = 0;
+	struct pci_dev *pci_dev;
+	unsigned char bVal;
 	unsigned int   dwVal;
 	unsigned short wCount, wReg;
 
@@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
 	udelay(15000);
 
 	wCount = 200;
-	while(wCount--) {
+	while (wCount--) {
 		wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
-		if((wReg & 0x000f) == 0x000f)
+		if ((wReg & 0x000f) == 0x000f)
 			return 0;
 		udelay(5000);
 	}
@@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec)
  *  ALI 5451 Controller
  */
 
-static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_enable_special_channel(struct snd_ali *codec,
+					   unsigned int channel)
 {
-	unsigned long dwVal = 0;
+	unsigned long dwVal;
 
-	dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+	dwVal  = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
 	dwVal |= 1 << (channel & 0x0000001f);
-	outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+	outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_special_channel(struct snd_ali *codec,
+					    unsigned int channel)
 {
-	unsigned long dwVal = 0;
+	unsigned long dwVal;
 
-	dwVal  = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL));
+	dwVal  = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL));
 	dwVal &= ~(1 << (channel & 0x0000001f));
-	outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
+	outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_enable_address_interrupt(struct snd_ali *codec)
 {
 	unsigned int gc;
 
@@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
 	outl( gc, ALI_REG(codec, ALI_GC_CIR));
 }
 
-static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
+static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
 {
 	unsigned int gc;
 
@@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
 	outl(gc, ALI_REG(codec, ALI_GC_CIR));
 }
 
-#if 0 // not used
-static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_enable_voice_irq(struct snd_ali *codec,
+				     unsigned int channel)
 {
 	unsigned int mask;
 	struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel
 	snd_ali_printk("enable_voice_irq channel=%d\n",channel);
 	
 	mask = 1 << (channel & 0x1f);
-	pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
+	pchregs->data.ainten  = inl(ALI_REG(codec, pchregs->regs.ainten));
 	pchregs->data.ainten |= mask;
-	outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+	outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
 }
 #endif
 
-static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel)
+static void snd_ali_disable_voice_irq(struct snd_ali *codec,
+				      unsigned int channel)
 {
 	unsigned int mask;
 	struct snd_ali_channel_control *pchregs = &(codec->chregs);
@@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe
 	snd_ali_printk("disable_voice_irq channel=%d\n",channel);
 
 	mask = 1 << (channel & 0x1f);
-	pchregs->data.ainten  = inl(ALI_REG(codec,pchregs->regs.ainten));
+	pchregs->data.ainten  = inl(ALI_REG(codec, pchregs->regs.ainten));
 	pchregs->data.ainten &= ~mask;
-	outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
+	outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
 }
 
 static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
@@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
 	unsigned int idx =  channel & 0x1f;
 
 	if (codec->synth.chcnt >= ALI_CHANNELS){
-		snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
+		snd_printk(KERN_ERR
+			   "ali_alloc_pcm_channel: no free channels.\n");
 		return -1;
 	}
 
@@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec)
 
 	snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm");
 
-	// recording
+	/* recording */
 	if (rec) {
 		if (codec->spdif_support &&
-		    (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT))
+		    (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+		     ALI_SPDIF_IN_SUPPORT))
 			idx = ALI_SPDIF_IN_CHANNEL;
 		else
 			idx = ALI_PCM_IN_CHANNEL;
 
-		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+		result = snd_ali_alloc_pcm_channel(codec, idx);
+		if (result >= 0)
 			return result;
-		} else {
-			snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
+		else {
+			snd_printk(KERN_ERR "ali_find_free_channel: "
+				   "record channel is busy now.\n");
 			return -1;
 		}
 	}
 
-	//playback...
+	/* playback... */
 	if (codec->spdif_support &&
-	    (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) {
+	    (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+	     ALI_SPDIF_OUT_CH_ENABLE)) {
 		idx = ALI_SPDIF_OUT_CHANNEL;
-		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
+		result = snd_ali_alloc_pcm_channel(codec, idx);
+		if (result >= 0)
 			return result;
-		} else {
-			snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
-		}
+		else
+			snd_printk(KERN_ERR "ali_find_free_channel: "
+				   "S/PDIF out channel is in busy now.\n");
 	}
 
 	for (idx = 0; idx < ALI_CHANNELS; idx++) {
-		if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
+		result = snd_ali_alloc_pcm_channel(codec, idx);
+		if (result >= 0)
 			return result;
 	}
 	snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
@@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
 		return;
 
 	if (!(codec->synth.chmap & (1 << idx))) {
-		snd_printk(KERN_ERR "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);
@@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
 	}
 }
 
-#if 0 // not used
-static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
+#if 0 /* not used */
+static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned int mask = 1 << (channel & 0x1f);
 	
@@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
 }
 #endif
 
-static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel)
+static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned int mask = 1 << (channel & 0x1f);
 
@@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval)
 	currenttimer = inl(ALI_REG(codec, ALI_STIMER));
 
 	while (currenttimer < begintimer + interval) {
-		if(snd_ali_stimer_ready(codec) < 0)
+		if (snd_ali_stimer_ready(codec) < 0)
 			break;
 		currenttimer = inl(ALI_REG(codec,  ALI_STIMER));
+		cpu_relax();
 	}
 }
 
 static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
 {
-	u16 wval  = 0;
+	u16 wval;
 	u16 count = 0;
-	u8  bval = 0, R1 = 0, R2 = 0;
+	u8  bval, R1 = 0, R2;
 
-	bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+	bval  = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
 	bval |= 0x1F;
-	outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+	outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1));
 
-	while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) {
+	while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) {
 		count ++;
 		snd_ali_delay(codec, 6);
-		bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
+		bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1));
 		R1 = bval & 0x1F;
 	}
 
@@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
 		snd_ali_delay(codec, 6);
 		bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1));
 		R2 = bval & 0x1F;
-		if (R2 != R1) R1 = R2; else break;
+		if (R2 != R1)
+			R1 = R2;
+		else
+			break;
 	}
 
 	if (count > 50000) {
@@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
 	}
 
 	if (R2 >= 0x0b && R2 <= 0x0e) {
-		wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
-		wval &= 0xE0F0;
-		wval |= (u16)0x09 << 8 | (u16)0x05;
-		outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+		wval  = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+		wval &= 0xe0f0;
+		wval |= (0x09 << 8) | 0x05;
+		outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
 
-		bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
-		outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3));
+		bval  = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0;
+		outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3));
 	} else if (R2 == 0x12) {
-		wval  = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2));
-		wval &= 0xE0F0;
-		wval |= (u16)0x0E << 8 | (u16)0x08;
-		outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2));
+		wval  = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2));
+		wval &= 0xe0f0;
+		wval |= (0x0e << 8) | 0x08;
+		outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2));
 
-		bval  = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0;
-		outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3));
+		bval  = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0;
+		outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3));
 	}
 }
 
 static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec)
 {
-	u32	dwRate = 0;
-	u8	bval = 0;
+	u32	dwRate;
+	u8	bval;
 
-	bval  = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
-	bval &= 0x7F;
+	bval  = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
+	bval &= 0x7f;
 	bval |= 0x40;
-	outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL));
+	outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL));
 
 	snd_ali_detect_spdif_rate(codec);
 
-	bval  = inb(ALI_REG(codec,ALI_SPDIF_CS + 3));
-	bval &= 0x0F;
+	bval  = inb(ALI_REG(codec, ALI_SPDIF_CS + 3));
+	bval &= 0x0f;
 
-	if (bval == 0) dwRate = 44100;
-	if (bval == 1) dwRate = 48000;
-	if (bval == 2) dwRate = 32000;
+	switch (bval) {
+	case 0: dwRate = 44100; break;
+	case 1: dwRate = 48000; break;
+	case 2: dwRate = 32000; break;
+	default: dwRate = 0; break;
+	}
 
 	return dwRate;
 }
@@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec)
 static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate)
 {
 	unsigned char  bVal;
-	unsigned int  dwRate = 0;
+	unsigned int  dwRate;
 	
-	if (rate == 32000) dwRate = 0x300;
-	if (rate == 44100) dwRate = 0;
-	if (rate == 48000) dwRate = 0x200;
+	switch (rate) {
+	case 32000: dwRate = 0x300; break;
+	case 48000: dwRate = 0x200; break;
+	default: dwRate = 0; break;
+	}
 	
 	bVal  = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
 	bVal &= (unsigned char)(~(1<<6));
 	
-	bVal |= 0x80;		//select right
+	bVal |= 0x80;		/* select right */
 	outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
 	outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2));
 	
-	bVal &= (~0x80);	//select left
+	bVal &= ~0x80;	/* select left */
 	outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL));
 	outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
 }
@@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
 {
 	unsigned short wVal;
 	unsigned char bVal;
-
-        struct pci_dev *pci_dev = NULL;
+        struct pci_dev *pci_dev;
 
         pci_dev = codec->pci_m1533;
         if (pci_dev == NULL)
@@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec)
 	bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL));
 	outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL));
    
-	{
-   		wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
-   		wVal |= ALI_SPDIF_OUT_SEL_PCM;
-   		outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
-		snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
-   	}
+	wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
+	wVal |= ALI_SPDIF_OUT_SEL_PCM;
+	outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
+	snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
 }
 
 static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
 {
-	unsigned short wVal = 0;
+	unsigned short wVal;
 
 	wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
    	wVal &= ~ALI_SPDIF_OUT_SEL_PCM;
@@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
 		wVal &= (~0x0002);
    	outw(wVal, ALI_REG(codec, ALI_SPDIF_CS));
 */
-	snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
+	snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
 }
 
 static void snd_ali_disable_spdif_chnout(struct snd_ali *codec)
 {
-	unsigned short wVal = 0;
+	unsigned short wVal;
+
   	wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
    	wVal |= ALI_SPDIF_OUT_SEL_PCM;
    	outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL));
@@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec)
 	snd_ali_disable_spdif_chnout(codec);
 }
 
-static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
+static void snd_ali_update_ptr(struct snd_ali *codec, int channel)
 {
-	struct snd_ali_voice *pvoice = NULL;
+	struct snd_ali_voice *pvoice;
 	struct snd_pcm_runtime *runtime;
-	struct snd_ali_channel_control *pchregs = NULL;
+	struct snd_ali_channel_control *pchregs;
 	unsigned int old, mask;
 #ifdef ALI_DEBUG
 	unsigned int temp, cspf;
@@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
 
 	pchregs = &(codec->chregs);
 
-	// check if interrupt occurred for channel
+	/* check if interrupt occurred for channel */
 	old  = pchregs->data.aint;
-	mask = ((unsigned int) 1L) << (channel & 0x1f);
+	mask = 1U << (channel & 0x1f);
 
 	if (!(old & mask))
 		return;
@@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
 		cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask;
 #endif
 		if (pvoice->running) {
-			snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf);
+			snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",
+				       (u16)temp, cspf);
 			spin_unlock(&codec->reg_lock);
 			snd_pcm_period_elapsed(pvoice->substream);
 			spin_lock(&codec->reg_lock);
@@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
 	pchregs->data.aint = old & (~mask);
 }
 
-static void snd_ali_interrupt(struct snd_ali * codec)
+static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
 {
+	struct snd_ali 	*codec = dev_id;
 	int channel;
 	unsigned int audio_int;
-	struct snd_ali_channel_control *pchregs = NULL;
-	pchregs = &(codec->chregs);
+	struct snd_ali_channel_control *pchregs;
+
+	if (codec == NULL || !codec->hw_initialized)
+		return IRQ_NONE;
 
 	audio_int = inl(ALI_REG(codec, ALI_MISCINT));
+	if (!audio_int)
+		return IRQ_NONE;
+
+	pchregs = &(codec->chregs);
 	if (audio_int & ADDRESS_IRQ) {
-		// get interrupt status for all channels
-		pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint));
-		for (channel = 0; channel < ALI_CHANNELS; channel++) {
+		/* get interrupt status for all channels */
+		pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint));
+		for (channel = 0; channel < ALI_CHANNELS; channel++)
 			snd_ali_update_ptr(codec, channel);
-		}
 	}
 	outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
-		ALI_REG(codec,ALI_MISCINT));
-}
-
-
-static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id)
-{
-	struct snd_ali 	*codec = dev_id;
+		ALI_REG(codec, ALI_MISCINT));
 
-	if (codec == NULL)
-		return IRQ_NONE;
-	snd_ali_interrupt(codec);
 	return IRQ_HANDLED;
 }
 
 
-static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel)
+static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec,
+						 int type, int rec, int channel)
 {
-	struct snd_ali_voice *pvoice = NULL;
+	struct snd_ali_voice *pvoice;
 	int idx;
 
-	snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
+	snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec);
 
 	spin_lock_irq(&codec->voice_alloc);
 	if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
 		idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
 			snd_ali_find_free_channel(codec,rec);
-		if(idx < 0) {
+		if (idx < 0) {
 			snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
 			spin_unlock_irq(&codec->voice_alloc);
 			return NULL;
@@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ
 }
 
 
-static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice)
+static void snd_ali_free_voice(struct snd_ali * codec,
+			       struct snd_ali_voice *pvoice)
 {
 	void (*private_free)(void *);
 	void *private_data;
@@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
 	private_data = pvoice->private_data;
 	pvoice->private_free = NULL;
 	pvoice->private_data = NULL;
-	if (pvoice->pcm) {
+	if (pvoice->pcm)
 		snd_ali_free_channel_pcm(codec, pvoice->number);
-	}
 	pvoice->use = pvoice->pcm = pvoice->synth = 0;
 	pvoice->substream = NULL;
 	spin_unlock_irq(&codec->voice_alloc);
@@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo
 }
 
 
-static void snd_ali_clear_voices(struct snd_ali * codec,
-			  unsigned int v_min,
-			  unsigned int v_max)
+static void snd_ali_clear_voices(struct snd_ali *codec,
+				 unsigned int v_min,
+				 unsigned int v_max)
 {
 	unsigned int i;
 
@@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec,
 	}
 }
 
-static void snd_ali_write_voice_regs(struct snd_ali * codec,
+static void snd_ali_write_voice_regs(struct snd_ali *codec,
 			 unsigned int Channel,
 			 unsigned int LBA,
 			 unsigned int CSO,
@@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
 {
 	unsigned int ctlcmds[4];
 	
-	outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR));
+	outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR));
 
 	ctlcmds[0] =  (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
 	ctlcmds[1] =  LBA;
@@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec,
 
 	outb(Channel, ALI_REG(codec, ALI_GC_CIR));
 
-	outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS));
-	outl(ctlcmds[1], ALI_REG(codec,ALI_LBA));
-	outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA));
-	outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC));
+	outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS));
+	outl(ctlcmds[1], ALI_REG(codec, ALI_LBA));
+	outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA));
+	outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC));
 
 	outl(0x30000000, ALI_REG(codec, ALI_EBUF1));	/* Still Mode */
 	outl(0x30000000, ALI_REG(codec, ALI_EBUF2));	/* Still Mode */
@@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec)
 {
 	unsigned int delta;
 
-	if (rate < 4000)  rate = 4000;
-	if (rate > 48000) rate = 48000;
+	if (rate < 4000)
+		rate = 4000;
+	if (rate > 48000)
+		rate = 48000;
 
 	if (rec) {
 		if (rate == 44100)
@@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
 	 */
 	CTRL = 0x00000001;
 	if (snd_pcm_format_width(runtime->format) == 16)
-		CTRL |= 0x00000008;	// 16-bit data
+		CTRL |= 0x00000008;	/* 16-bit data */
 	if (!snd_pcm_format_unsigned(runtime->format))
-		CTRL |= 0x00000002;	// signed data
+		CTRL |= 0x00000002;	/* signed data */
 	if (runtime->channels > 1)
-		CTRL |= 0x00000004;	// stereo data
+		CTRL |= 0x00000004;	/* stereo data */
 	return CTRL;
 }
 
@@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
  *  PCM part
  */
 
-static int snd_ali_ioctl(struct snd_pcm_substream *substream,
-				  unsigned int cmd, void *arg)
-{
-	return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
 static int snd_ali_trigger(struct snd_pcm_substream *substream,
 			       int cmd)
 				    
 {
 	struct snd_ali *codec = snd_pcm_substream_chip(substream);
-	struct list_head *pos;
 	struct snd_pcm_substream *s;
 	unsigned int what, whati, capture_flag;
-	struct snd_ali_voice *pvoice = NULL, *evoice = NULL;
+	struct snd_ali_voice *pvoice, *evoice;
 	unsigned int val;
 	int do_start;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
-		do_start = 1; break;
+		do_start = 1;
+		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
-		do_start = 0; break;
+		do_start = 0;
+		break;
 	default:
 		return -EINVAL;
 	}
 
 	what = whati = capture_flag = 0;
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) {
 			pvoice = s->runtime->private_data;
 			evoice = pvoice->extra;
 			what |= 1 << (pvoice->number & 0x1f);
-			if (evoice == NULL) {
+			if (evoice == NULL)
 				whati |= 1 << (pvoice->number & 0x1f);
-			} else {
+			else {
 				whati |= 1 << (evoice->number & 0x1f);
 				what |= 1 << (evoice->number & 0x1f);
 			}
@@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream,
 		}
 	}
 	spin_lock(&codec->reg_lock);
-	if (! do_start) {
+	if (!do_start)
 		outl(what, ALI_REG(codec, ALI_STOP));
-	}
 	val = inl(ALI_REG(codec, ALI_AINTEN));
-	if (do_start) {
+	if (do_start)
 		val |= whati;
-	} else {
+	else
 		val &= ~whati;
-	}
 	outl(val, ALI_REG(codec, ALI_AINTEN));
-	if (do_start) {
+	if (do_start)
 		outl(what, ALI_REG(codec, ALI_START));
-	}
-	snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati);
+	snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati);
 	spin_unlock(&codec->reg_lock);
 
 	return 0;
 }
 
 static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
-				 struct snd_pcm_hw_params *hw_params)
+				      struct snd_pcm_hw_params *hw_params)
 {
 	struct snd_ali *codec = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_ali_voice *pvoice = runtime->private_data;
 	struct snd_ali_voice *evoice = pvoice->extra;
 	int err;
-	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-	if (err < 0) return err;
+
+	err = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (err < 0)
+		return err;
 	
 	/* voice management */
 
-	if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
-		if (evoice == NULL) {
-			evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1);
-			if (evoice == NULL)
+	if (params_buffer_size(hw_params) / 2 !=
+	    params_period_size(hw_params)) {
+		if (!evoice) {
+			evoice = snd_ali_alloc_voice(codec,
+						     SNDRV_ALI_VOICE_TYPE_PCM,
+						     0, -1);
+			if (!evoice)
 				return -ENOMEM;
 			pvoice->extra = evoice;
 			evoice->substream = substream;
 		}
 	} else {
-		if (evoice != NULL) {
+		if (!evoice) {
 			snd_ali_free_voice(codec, evoice);
 			pvoice->extra = evoice = NULL;
 		}
@@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
 	struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
 
 	snd_pcm_lib_free_pages(substream);
-	if (evoice != NULL) {
+	if (!evoice) {
 		snd_ali_free_voice(codec, evoice);
 		pvoice->extra = NULL;
 	}
@@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
 }
 
 static int snd_ali_hw_params(struct snd_pcm_substream *substream,
-				 struct snd_pcm_hw_params *hw_params)
+			     struct snd_pcm_hw_params *hw_params)
 {
-	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+	return snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
 }
 
 static int snd_ali_hw_free(struct snd_pcm_substream *substream)
@@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
 	/* set Delta (rate) value */
 	Delta = snd_ali_convert_rate(runtime->rate, 0);
 
-	if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || 
-	    (pvoice->number == ALI_PCM_IN_CHANNEL))
+	if (pvoice->number == ALI_SPDIF_IN_CHANNEL || 
+	    pvoice->number == ALI_PCM_IN_CHANNEL)
 		snd_ali_disable_special_channel(codec, pvoice->number);
 	else if (codec->spdif_support &&
-		 (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
-		 && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) {
+		 (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) &
+		  ALI_SPDIF_OUT_CH_ENABLE)
+		 && pvoice->number == ALI_SPDIF_OUT_CHANNEL) {
 		snd_ali_set_spdif_out_rate(codec, runtime->rate);
 		Delta = 0x1000;
 	}
@@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
 	/* set target ESO for channel */
 	pvoice->eso = runtime->buffer_size; 
 
-	snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count);
+	snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",
+		       pvoice->eso, pvoice->count);
 
 	/* set ESO to capture first MIDLP interrupt */
 	ESO = pvoice->eso -1;
@@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
 	PAN = 0;
 	VOL = 0;
 	EC = 0;
-	snd_ali_printk("playback_prepare:\n    ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
-	snd_ali_write_voice_regs(    codec,
-				     pvoice->number,
-				     LBA,
-				     0,	/* cso */
-				     ESO,
-				     Delta,
-				     0,	/* alpha */
-				     GVSEL,
-				     PAN,
-				     VOL,
-				     CTRL,
-				     EC);
-	if (evoice != NULL) {
+	snd_ali_printk("playback_prepare:\n");
+	snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",
+		       pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL);
+	snd_ali_write_voice_regs(codec,
+				 pvoice->number,
+				 LBA,
+				 0,	/* cso */
+				 ESO,
+				 Delta,
+				 0,	/* alpha */
+				 GVSEL,
+				 PAN,
+				 VOL,
+				 CTRL,
+				 EC);
+	if (!evoice) {
 		evoice->count = pvoice->count;
 		evoice->eso = pvoice->count << 1;
 		ESO = evoice->eso - 1;
 		snd_ali_write_voice_regs(codec,
-				     evoice->number,
-				     LBA,
-				     0,	/* cso */
-				     ESO,
-				     Delta,
-				     0,	/* alpha */
-				     GVSEL,
-				     (unsigned int)0x7f,
-				     (unsigned int)0x3ff,
-				     CTRL,
-				     EC);
+					 evoice->number,
+					 LBA,
+					 0,	/* cso */
+					 ESO,
+					 Delta,
+					 0,	/* alpha */
+					 GVSEL,
+					 0x7f,
+					 0x3ff,
+					 CTRL,
+					 EC);
 	}
 	spin_unlock_irq(&codec->reg_lock);
 	return 0;
@@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
 		 pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 
 		0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
 
-	// Prepare capture intr channel
+	/* Prepare capture intr channel */
 	if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
 
 		unsigned int rate;
@@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
 
 		rate = snd_ali_get_spdif_in_rate(codec);
 		if (rate == 0) {
-			snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
+			snd_printk(KERN_WARNING "ali_capture_preapre: "
+				   "spdif rate detect err!\n");
 			rate = 48000;
 		}
 		spin_lock_irq(&codec->reg_lock);
@@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
 		}
 
 		if (rate != 48000)
-			Delta = ((rate << 12)/runtime->rate)&0x00ffff;
+			Delta = ((rate << 12) / runtime->rate) & 0x00ffff;
 	}
 
-	// set target ESO for channel 
+	/* set target ESO for channel  */
 	pvoice->eso = runtime->buffer_size; 
 
-	// set interrupt count size 
+	/* set interrupt count size  */
 	pvoice->count = runtime->period_size;
 
-	// set Loop Back Address 
+	/* set Loop Back Address  */
 	LBA = runtime->dma_addr;
 
-	// set ESO to capture first MIDLP interrupt 
+	/* set ESO to capture first MIDLP interrupt  */
 	ESO = pvoice->eso - 1;
 	CTRL = snd_ali_control_mode(substream);
 	GVSEL = 0;
@@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream)
 				     CTRL,
 				     EC);
 
-
 	spin_unlock_irq(&codec->reg_lock);
 
 	return 0;
 }
 
 
-static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream)
+static snd_pcm_uframes_t
+snd_ali_playback_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_ali *codec = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
 
 static struct snd_pcm_hardware snd_ali_playback =
 {
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_RESUME |
-				 SNDRV_PCM_INFO_SYNC_START),
-	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
-				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+	.info =		(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+			 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+			 SNDRV_PCM_INFO_MMAP_VALID |
+			 SNDRV_PCM_INFO_RESUME |
+			 SNDRV_PCM_INFO_SYNC_START),
+	.formats =	(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+			 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+	.rates =	SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		4000,
 	.rate_max =		48000,
 	.channels_min =		1,
@@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback =
 
 static struct snd_pcm_hardware snd_ali_capture =
 {
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_RESUME |
-				 SNDRV_PCM_INFO_SYNC_START),
-	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
-				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+	.info =		(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+			 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+			 SNDRV_PCM_INFO_MMAP_VALID |
+			 SNDRV_PCM_INFO_RESUME |
+			 SNDRV_PCM_INFO_SYNC_START),
+	.formats =	(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+			 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
+	.rates =	SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		4000,
 	.rate_max =		48000,
 	.channels_min =		1,
@@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
 	}
 }
 
-static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel,
-		struct snd_pcm_hardware *phw)
+static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
+			int channel, struct snd_pcm_hardware *phw)
 {
 	struct snd_ali *codec = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_ali_voice *pvoice;
 
-	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
-	if (pvoice == NULL)
+	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec,
+				     channel);
+	if (!pvoice)
 		return -EAGAIN;
 
 	pvoice->substream = substream;
@@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe
 
 	runtime->hw = *phw;
 	snd_pcm_set_sync(substream);
-	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
+	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+				     0, 64*1024);
 	return 0;
 }
 
@@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream)
 static struct snd_pcm_ops snd_ali_playback_ops = {
 	.open =		snd_ali_playback_open,
 	.close =	snd_ali_playback_close,
-	.ioctl =	snd_ali_ioctl,
+	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_ali_playback_hw_params,
 	.hw_free =	snd_ali_playback_hw_free,
 	.prepare =	snd_ali_playback_prepare,
@@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = {
 static struct snd_pcm_ops snd_ali_capture_ops = {
 	.open =		snd_ali_capture_open,
 	.close =	snd_ali_close,
-	.ioctl =	snd_ali_ioctl,
+	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_ali_hw_params,
 	.hw_free =	snd_ali_hw_free,
 	.prepare =	snd_ali_prepare,
@@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_ali *chip = snd_pcm_substream_chip(substream);
 	unsigned int modem_num = chip->num_of_codecs - 1;
-	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
+	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE,
+		       params_rate(hw_params));
 	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
 	return snd_ali_hw_params(substream, hw_params);
 }
 
 static struct snd_pcm_hardware snd_ali_modem =
 {
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_RESUME |
-				 SNDRV_PCM_INFO_SYNC_START),
-	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000,
+	.info =		(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+			 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+			 SNDRV_PCM_INFO_MMAP_VALID |
+			 SNDRV_PCM_INFO_RESUME |
+			 SNDRV_PCM_INFO_SYNC_START),
+	.formats =	SNDRV_PCM_FMTBIT_S16_LE,
+	.rates =	(SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 |
+			 SNDRV_PCM_RATE_16000),
 	.rate_min =		8000,
 	.rate_max =		16000,
 	.channels_min =		1,
@@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem =
 	.fifo_size =		0,
 };
 
-static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel)
+static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec,
+			      int channel)
 {
-	static unsigned int rates [] = {8000,9600,12000,16000};
+	static unsigned int rates[] = {8000, 9600, 12000, 16000};
 	static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
 		.count = ARRAY_SIZE(rates),
 		.list = rates,
 		.mask = 0,
 	};
 	int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
+
 	if (err)
 		return err;
 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm)
 }
 
 
-static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc)
+static int __devinit snd_ali_pcm(struct snd_ali * codec, int device,
+				 struct ali_pcm_description *desc)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
 	pcm->private_data = codec;
 	pcm->private_free = snd_ali_pcm_free;
 	if (desc->playback_ops)
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				desc->playback_ops);
 	if (desc->capture_ops)
-		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops);
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+				desc->capture_ops);
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
+					      snd_dma_pci_data(codec->pci),
+					      64*1024, 128*1024);
 
 	pcm->info_flags = 0;
 	pcm->dev_class = desc->class;
@@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_
 }
 
 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, SNDRV_PCM_CLASS_MODEM }
+	{ .name = "ALI 5451",
+	  .playback_num = ALI_CHANNELS,
+	  .capture_num = 1,
+	  .playback_ops = &snd_ali_playback_ops,
+	  .capture_ops = &snd_ali_capture_ops
+	},
+	{ .name = "ALI 5451 modem",
+	  .playback_num = 1,
+	  .capture_num = 1,
+	  .playback_ops = &snd_ali_modem_playback_ops,
+	  .capture_ops = &snd_ali_modem_capture_ops,
+	  .class = SNDRV_PCM_CLASS_MODEM
+	}
 };
 
 static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
 {
 	int i, err;
-	for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
-		if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0)
+	for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) {
+		err = snd_ali_pcm(codec, i, &ali_pcms[i]);
+		if (err < 0)
 			return err;
+	}
 	return 0;
 }
 
@@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
 .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
 .put = snd_ali5451_spdif_put, .private_value = value}
 
-static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
         return 0;
 }
 
-static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ali *codec = kcontrol->private_data;
 	unsigned int enable;
@@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	enable = ucontrol->value.integer.value[0] ? 1 : 0;
 
 	spin_lock_irq(&codec->reg_lock);
-	switch(kcontrol->private_value) {
+	switch (kcontrol->private_value) {
 	case 0:
 		enable = (codec->spdif_mask & 0x02) ? 1 : 0;
 		break;
 	case 1:
-		enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0;
+		enable = ((codec->spdif_mask & 0x02) &&
+			  (codec->spdif_mask & 0x04)) ? 1 : 0;
 		break;
 	case 2:
 		enable = (codec->spdif_mask & 0x01) ? 1 : 0;
@@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	return 0;
 }
 
-static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ali *codec = kcontrol->private_data;
 	unsigned int change = 0, enable = 0;
@@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
 	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
 };
 
-static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
-{
-	struct snd_ali *codec = bus->private_data;
-	codec->ac97_bus = NULL;
-}
-
-static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97)
-{
-	struct snd_ali *codec = ac97->private_data;
-	codec->ac97[ac97->num] = NULL;
-}
-
 static int __devinit snd_ali_mixer(struct snd_ali * codec)
 {
 	struct snd_ac97_template ac97;
@@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
 		.read = snd_ali_codec_read,
 	};
 
-	if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0)
+	err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus);
+	if (err < 0)
 		return err;
-	codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = codec;
-	ac97.private_free = snd_ali_mixer_free_ac97;
 
-	for ( i = 0 ; i < codec->num_of_codecs ; i++) {
+	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(KERN_ERR "ali mixer %d creating error.\n", i);
-			if(i == 0)
+		err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]);
+		if (err < 0) {
+			snd_printk(KERN_ERR
+				   "ali mixer %d creating error.\n", i);
+			if (i == 0)
 				return err;
 			codec->num_of_codecs = 1;
 			break;
@@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
 	}
 
 	if (codec->spdif_support) {
-		for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
-			err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
-			if (err < 0) return err;
+		for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
+			err = snd_ctl_add(codec->card,
+					  snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
+			if (err < 0)
+				return err;
 		}
 	}
 	return 0;
@@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
 	int i, j;
 
 	im = chip->image;
-	if (! im)
+	if (!im)
 		return 0;
 
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	for(i = 0 ; i < chip->num_of_codecs ; i++) {
+	for (i = 0; i < chip->num_of_codecs; i++) {
 		snd_pcm_suspend_all(chip->pcm[i]);
 		snd_ac97_suspend(chip->ac97[i]);
 	}
@@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
 	spin_lock_irq(&chip->reg_lock);
 	
 	im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT));
-	// im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START));
+	/* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */
 	im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP));
 	
-	// disable all IRQ bits
+	/* disable all IRQ bits */
 	outl(0, ALI_REG(chip, ALI_MISCINT));
 	
 	for (i = 0; i < ALI_GLOBAL_REGS; i++) {	
@@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
 			im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0));
 	}
 
-	// stop all HW channel
+	/* stop all HW channel */
 	outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
 	spin_unlock_irq(&chip->reg_lock);
@@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci)
 	int i, j;
 
 	im = chip->image;
-	if (! im)
+	if (!im)
 		return 0;
 
 	pci_set_power_state(pci, PCI_D0);
@@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci)
 	}
 	
 	for (i = 0; i < ALI_GLOBAL_REGS; i++) {	
-		if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START))
+		if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) ||
+		    (i*4 == ALI_START))
 			continue;
 		outl(im->regs[i], ALI_REG(chip, i*4));
 	}
 	
-	// start HW channel
+	/* start HW channel */
 	outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START));
-	// restore IRQ enable bits
+	/* restore IRQ enable bits */
 	outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT));
 	
 	spin_unlock_irq(&chip->reg_lock);
 
-	for(i = 0 ; i < chip->num_of_codecs ; i++)
+	for (i = 0 ; i < chip->num_of_codecs; i++)
 		snd_ac97_resume(chip->ac97[i]);
 	
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 {
 	unsigned int legacy;
 	unsigned char temp;
-	struct pci_dev *pci_dev = NULL;
+	struct pci_dev *pci_dev;
 
 	snd_ali_printk("chip initializing ... \n");
 
@@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 	outb(0x10, 	 ALI_REG(codec, ALI_MPUR2));
 
 	codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID);
-	codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS);
+	codec->ac97_ext_status = snd_ali_codec_peek(codec, 0,
+						    AC97_EXTENDED_STATUS);
 	if (codec->spdif_support) {
 		snd_ali_enable_spdif_out(codec);
 		codec->spdif_mask = 0x00000002;
@@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 	if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
 		codec->num_of_codecs++;
 		outl(inl(ALI_REG(codec, ALI_SCTRL)) |
-			(ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN),
-			ALI_REG(codec, ALI_SCTRL));
+		     (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 |
+		      ALI_SCTRL_LINE_OUT_EN),
+		     ALI_REG(codec, ALI_SCTRL));
 	}
 
 	snd_ali_printk("chip initialize succeed.\n");
@@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec)
 }
 
 /* proc for register dump */
-static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
+static void snd_ali_proc_read(struct snd_info_entry *entry,
+			      struct snd_info_buffer *buf)
 {
 	struct snd_ali *codec = entry->private_data;
 	int i;
-	for(i = 0 ; i < 256 ; i+= 4)
+	for (i = 0; i < 256 ; i+= 4)
 		snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
 }
 
 static void __devinit snd_ali_proc_init(struct snd_ali *codec)
 {
 	struct snd_info_entry *entry;
-	if(!snd_card_proc_new(codec->card, "ali5451", &entry))
+	if (!snd_card_proc_new(codec->card, "ali5451", &entry))
 		snd_info_set_text_ops(entry, codec, snd_ali_proc_read);
 }
 
@@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
 	int err;
 
 	snd_ali_printk("resouces allocation ...\n");
-	if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0)
+	err = pci_request_regions(codec->pci, "ALI 5451");
+	if (err < 0)
 		return err;
 	codec->port = pci_resource_start(codec->pci, 0);
 
@@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
 	snd_ali_printk("resouces allocated.\n");
 	return 0;
 }
-static int snd_ali_dev_free(struct snd_device *device) 
+static int snd_ali_dev_free(struct snd_device *device)
 {
-	struct snd_ali *codec=device->device_data;
+	struct snd_ali *codec = device->device_data;
 	snd_ali_free(codec);
 	return 0;
 }
@@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card,
 	snd_ali_printk("creating ...\n");
 
 	/* enable PCI device */
-	if ((err = pci_enable_device(pci)) < 0)
+	err = pci_enable_device(pci);
+	if (err < 0)
 		return err;
 	/* check, if we can restrict PCI DMA transfers to 31 bits */
 	if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 ||
 	    pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) {
-		snd_printk(KERN_ERR "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;
 	}
 
-	if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) {
+	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
+	if (!codec) {
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
@@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card,
 
 	/* M1533: southbridge */
 	codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
-	if (! codec->pci_m1533) {
+	if (!codec->pci_m1533) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
 		snd_ali_free(codec);
 		return -ENODEV;
 	}
 	/* M7101: power management */
 	codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
-	if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
+	if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
 		snd_ali_free(codec);
 		return -ENODEV;
 	}
 
 	snd_ali_printk("snd_device_new is called.\n");
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) {
+	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops);
+	if (err < 0) {
 		snd_ali_free(codec);
 		return err;
 	}
@@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card,
 	snd_card_set_dev(card, &pci->dev);
 
 	/* initialise synth voices*/
-	for (i = 0; i < ALI_CHANNELS; i++ ) {
+	for (i = 0; i < ALI_CHANNELS; i++)
 		codec->synth.voices[i].number = i;
-	}
 
-	if ((err = snd_ali_chip_init(codec)) < 0) {
+	err = snd_ali_chip_init(codec);
+	if (err < 0) {
 		snd_printk(KERN_ERR "ali create: chip init error.\n");
 		return err;
 	}
 
 #ifdef CONFIG_PM
 	codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
-	if (! codec->image)
+	if (!codec->image)
 		snd_printk(KERN_WARNING "can't allocate apm buffer\n");
 #endif
 
@@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
 	snd_ali_printk("probe ...\n");
 
 	card = snd_card_new(index, id, THIS_MODULE, 0);
-	if (card == NULL)
+	if (!card)
 		return -ENOMEM;
 
-	if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_ali_create(card, pci, pcm_channels, spdif, &codec);
+	if (err < 0)
+		goto error;
 	card->private_data = codec;
 
 	snd_ali_printk("mixer building ...\n");
-	if ((err = snd_ali_mixer(codec)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_ali_mixer(codec);
+	if (err < 0)
+		goto error;
 	
 	snd_ali_printk("pcm building ...\n");
-	if ((err = snd_ali_build_pcms(codec)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_ali_build_pcms(codec);
+	if (err < 0)
+		goto error;
 
 	snd_ali_proc_init(codec);
 
@@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
 		card->shortname, codec->port, codec->irq);
 
 	snd_ali_printk("register card.\n");
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_card_register(card);
+	if (err < 0)
+		goto error;
+
 	pci_set_drvdata(pci, card);
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static void __devexit snd_ali_remove(struct pci_dev *pci)

+ 0 - 40
sound/pci/au88x0/au88x0_sb.h

@@ -1,40 +0,0 @@
-/***************************************************************************
- *            au88x0_sb.h
- *
- *  Wed Oct 29 22:10:42 2003
- *  
- ****************************************************************************/
-
-#ifdef CHIP_AU8820
-/* AU8820 starting @ 64KiB offset */
-#define SBEMU_BASE 0x10000
-#else
-/* AU8810? and AU8830 starting @ 164KiB offset */
-#define SBEMU_BASE 0x29000
-#endif
-
-#define FM_A_STATUS			(SBEMU_BASE + 0x00)	/* read */
-#define FM_A_ADDRESS		(SBEMU_BASE + 0x00)	/* write */
-#define FM_A_DATA			(SBEMU_BASE + 0x04)
-#define FM_B_STATUS			(SBEMU_BASE + 0x08)
-#define FM_B_ADDRESS		(SBEMU_BASE + 0x08)
-#define FM_B_DATA			(SBEMU_BASE + 0x0C)
-#define SB_MIXER_ADDR		(SBEMU_BASE + 0x10)
-#define SB_MIXER_DATA		(SBEMU_BASE + 0x14)
-#define SB_RESET			(SBEMU_BASE + 0x18)
-#define SB_RESET_ALIAS		(SBEMU_BASE + 0x1C)
-#define FM_STATUS2			(SBEMU_BASE + 0x20)
-#define FM_ADDR2			(SBEMU_BASE + 0x20)
-#define FM_DATA2			(SBEMU_BASE + 0x24)
-#define SB_DSP_READ			(SBEMU_BASE + 0x28)
-#define SB_DSP_WRITE		(SBEMU_BASE + 0x30)
-#define SB_DSP_WRITE_STATUS	(SBEMU_BASE + 0x30)	/* bit 7 */
-#define SB_DSP_READ_STATUS	(SBEMU_BASE + 0x38)	/* bit 7 */
-#define SB_LACR				(SBEMU_BASE + 0x40)	/* ? */
-#define SB_LADCR			(SBEMU_BASE + 0x44)	/* ? */
-#define SB_LAMR				(SBEMU_BASE + 0x48)	/* ? */
-#define SB_LARR				(SBEMU_BASE + 0x4C)	/* ? */
-#define SB_VERSION			(SBEMU_BASE + 0x50)
-#define SB_CTRLSTAT			(SBEMU_BASE + 0x54)
-#define SB_TIMERSTAT		(SBEMU_BASE + 0x58)
-#define FM_RAM				(SBEMU_BASE + 0x100)	/* 0x40 ULONG */

+ 23 - 11
sound/pci/azt3328.c

@@ -1,6 +1,6 @@
 /*
  *  azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
- *  Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de>
+ *  Copyright (C) 2002, 2005, 2006, 2007 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),
@@ -52,6 +52,9 @@
  *  - full duplex 16bit playback/record at independent sampling rate
  *  - MPU401 (+ legacy address support) FIXME: how to enable legacy addr??
  *  - game port (legacy address support)
+ *  - builtin 3D enhancement (said to be YAMAHA Ymersion)
+ *  - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven
+ *    features supported)
  *  - built-in General DirectX timer having a 20 bits counter
  *    with 1us resolution (see below!)
  *  - I2S serial port for external DAC
@@ -94,6 +97,10 @@
  * 
  * BUGS
  *  - full-duplex might *still* be problematic, not fully tested recently
+ *  - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated
+ *    if you set PCM output switch to "pre 3D" instead of "post 3D".
+ *    If this can't be set, then get a mixer application that Isn't Stupid (tm)
+ *    (e.g. kmix, gamix) - unfortunately several are!!
  * 
  * TODO
  *  - test MPU401 MIDI playback etc.
@@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
 	return (nreg != oreg);
 }
 
-static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
+static struct snd_kcontrol_new 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),
@@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
 	AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
 	AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
 	AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
-	AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
+	AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
 	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 - Switch", IDX_MIXER_ADVCTL2, 13, 0),
@@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata
 #endif
 };
 
-static const u16 __devinitdata snd_azf3328_init_values[][2] = {
+static 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 },
@@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream)
 	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 
 	snd_azf3328_dbgcallenter();
-
 	chip->playback_substream = NULL;
 	snd_azf3328_dbgcallleave();
 	return 0;
@@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit)
 }
 #endif
 
+#if DEBUG_MISC
 static void
 snd_azf3328_debug_show_ports(const struct snd_azf3328 *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);
@@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
 	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
+	for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2)
+		snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp));
+
+	for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
+		snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp));
 }
+#else
+static inline void
+snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {}
+#endif
 
 static int __devinit
 snd_azf3328_create(struct snd_card *card,
@@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 
 #ifdef MODULE
 	printk(
-"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n"
-"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n"
+"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
+"azt3328: Hardware was completely undocumented, unfortunately.\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);

+ 2 - 2
sound/pci/azt3328.h

@@ -106,8 +106,8 @@
   #define IRQ_RECORDING			0x0002
   #define IRQ_MPU401			0x0010
   #define IRQ_TIMER			0x0020 /* DirectX timer */
-  #define IRQ_UNKNOWN1			0x0040 /* probably unused */
-  #define IRQ_UNKNOWN2			0x0080 /* probably unused */
+  #define IRQ_UNKNOWN1			0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */
+  #define IRQ_UNKNOWN2			0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */
 #define IDX_IO_66H		0x66    /* writing 0xffff returns 0x0000 */
 #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 (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */

+ 3 - 1
sound/pci/bt87x.c

@@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000),
 	/* Viewcast Osprey 200 */
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100),
+	/* ATI TV-Wonder */
+	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000),
 	/* Leadtek Winfast tv 2000xp delux */
 	BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000),
 	/* Voodoo TV 200 */
@@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
 	           pci->device, pci->subsystem_vendor, pci->subsystem_device);
 	snd_printk(KERN_DEBUG "please mail id, board name, and, "
 		   "if it works, the correct digital_rate option to "
-		   "<alsa-devel@lists.sf.net>\n");
+		   "<alsa-devel@alsa-project.org>\n");
 	return 32000; /* default rate */
 }
 

+ 1 - 3
sound/pci/ca0106/ca0106_main.c

@@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
 	struct snd_ca0106_pcm *epcm;
 	int channel;
 	int result = 0;
-	struct list_head *pos;
         struct snd_pcm_substream *s;
 	u32 basic = 0;
 	u32 extended = 0;
@@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
 		running=0;
 		break;
 	}
-        snd_pcm_group_for_each(pos, substream) {
-                s = snd_pcm_group_substream_entry(pos);
+        snd_pcm_group_for_each_entry(s, substream) {
 		runtime = s->runtime;
 		epcm = runtime->private_data;
 		channel = epcm->channel_id;

+ 1 - 1
sound/pci/cs46xx/cs46xx_lib.c

@@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
 	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");
+	snd_printk(KERN_ERR "       this message please report to alsa-devel@alsa-project.org\n");
 
 	return -EIO;
 #endif

+ 0 - 1607
sound/pci/cs46xx/imgs/cwcemb80.h

@@ -1,1607 +0,0 @@
-/* generated from cwcemb80.osp DO NOT MODIFY */
-
-#ifndef __HEADER_cwcemb80_H__
-#define __HEADER_cwcemb80_H__
-
-static struct dsp_symbol_entry cwcemb80_symbols[] = {
-  { 0x0000, "BEGINADDRESS",0x00 },
-  { 0x8000, "EXECCHILD",0x03 },
-  { 0x8001, "EXECCHILD_98",0x03 },
-  { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
-  { 0x8008, "EXECSIBLING",0x03 },
-  { 0x800a, "EXECSIBLING_298",0x03 },
-  { 0x800b, "EXECSIBLING_2IND1",0x03 },
-  { 0x8010, "TIMINGMASTER",0x03 },
-  { 0x804f, "S16_CODECINPUTTASK",0x03 },
-  { 0x805e, "PCMSERIALINPUTTASK",0x03 },
-  { 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
-  { 0x809a, "S16_MIX",0x03 },
-  { 0x80bb, "S16_UPSRC",0x03 },
-  { 0x813b, "MIX3_EXP",0x03 },
-  { 0x8164, "DECIMATEBYPOW2",0x03 },
-  { 0x8197, "VARIDECIMATE",0x03 },
-  { 0x81f2, "_3DINPUTTASK",0x03 },
-  { 0x820a, "_3DPRLGCINPTASK",0x03 },
-  { 0x8227, "_3DSTEREOINPUTTASK",0x03 },
-  { 0x8242, "_3DOUTPUTTASK",0x03 },
-  { 0x82c4, "HRTF_MORPH_TASK",0x03 },
-  { 0x82c6, "WAIT4DATA",0x03 },
-  { 0x82fa, "PROLOGIC",0x03 },
-  { 0x8496, "DECORRELATOR",0x03 },
-  { 0x84a4, "STEREO2MONO",0x03 },
-  { 0x0070, "SPOSCB",0x02 },
-  { 0x0105, "TASKTREETHREAD",0x03 },
-  { 0x0136, "TASKTREEHEADERCODE",0x03 },
-  { 0x013f, "FGTASKTREEHEADERCODE",0x03 },
-  { 0x0163, "NULLALGORITHM",0x03 },
-  { 0x0167, "HFGEXECCHILD",0x03 },
-  { 0x0168, "HFGEXECCHILD_98",0x03 },
-  { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 },
-  { 0x016d, "HFGEXECSIBLING",0x03 },
-  { 0x016f, "HFGEXECSIBLING_298",0x03 },
-  { 0x0170, "HFGEXECSIBLING_2IND1",0x03 },
-  { 0x0173, "S16_CODECOUTPUTTASK",0x03 },
-  { 0x018e, "#CODE_END",0x00 },
-}; /* cwcemb80 symbols */
-
-static u32 cwcemb80_code[] = {
-/* BEGINADDRESS */
-/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
-/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
-/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
-/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
-/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
-/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
-/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
-/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
-/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
-/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
-/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
-/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
-/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
-/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
-/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
-/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
-/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
-/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
-/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
-/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002,
-/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
-/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
-/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
-/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
-/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
-/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
-/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
-/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
-/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
-/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
-/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
-/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
-/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
-/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
-/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
-/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
-/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004,
-/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
-/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640,
-/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0,
-/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0,
-/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b,
-/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44,
-/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917,
-/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880,
-/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000,
-/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000,
-/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40,
-/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
-/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
-/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0,
-/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
-/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
-/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
-/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
-/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
-/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
-/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
-/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
-/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
-/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
-/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
-/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
-/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
-/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
-/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1,
-/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000,
-/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
-/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700,
-/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
-/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
-/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500,
-/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
-/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800,
-/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500,
-/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
-/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00,
-/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500,
-/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
-/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80,
-/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500,
-/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1,
-/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380,
-/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000,
-/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
-/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
-/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
-/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
-/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
-/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080,
-/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540,
-/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
-/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40,
-/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
-/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
-/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240,
-/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
-/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
-/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c,
-/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
-/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
-/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
-/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
-/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
-/* 0104 */ 0x0000ba01,0x00000000,
-/* TASKTREETHREAD */
-/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
-/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
-/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
-/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa,
-/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
-/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000,
-/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
-/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008,
-/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
-/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0,
-/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
-/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009,
-/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
-/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000,
-/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000,
-/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008,
-/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
-/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000,
-/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000,
-/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
-/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000,
-/* 0135 */ 0x00000000,0x00000000,
-/* TASKTREEHEADERCODE */
-/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
-/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b,
-/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
-/* 013E */ 0x00042731,0x00001003,
-/* FGTASKTREEHEADERCODE */
-/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a,
-/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
-/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b,
-/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140,
-/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
-/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
-/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
-/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
-/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
-/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
-/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
-/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
-/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
-/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
-/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7,
-/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004,
-/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
-/* NULLALGORITHM */
-/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
-/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
-/* HFGEXECCHILD */
-/* 0167 */ 0x00000000,0x000eba44,
-/* HFGEXECCHILD_98 */
-/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
-/* HFGEXECCHILD_PUSH1IND */
-/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 016C */ 0x00006a88,0x000c75c4,
-/* HFGEXECSIBLING */
-/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
-/* HFGEXECSIBLING_298 */
-/* 016F */ 0x00087401,0x000e4782,
-/* HFGEXECSIBLING_2IND1 */
-/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
-/* 0172 */ 0x00006a88,0x000c75c4,
-/* S16_CODECOUTPUTTASK */
-/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
-/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
-/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
-/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
-/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c,
-/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
-/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
-/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
-/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
-/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
-/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
-/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
-/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
-/* 018D */ 0x00048f05,0x00000000
-};
-/* #CODE_END */
-
-static u32 cwcemb80_parameter[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000,
-/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000,
-/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000,
-/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2,
-/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000,
-/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3,
-/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d,
-/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000,
-/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a,
-/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3,
-/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000,
-/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2,
-/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff,
-/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0,
-/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000,
-/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9,
-/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff,
-/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780,
-/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000,
-/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9,
-/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1,
-/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000,
-/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000,
-/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004,
-/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610,
-/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d,
-/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
-/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
-/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d,
-/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d,
-/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136,
-/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000,
-/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d,
-/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
-/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
-/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000
-}; /* #PARAMETER_END */
-
-static u32 cwcemb80_sample[] = {
-/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000,
-/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004
-}; /* #SAMPLE_END */
-
-
-static struct dsp_segment_desc cwcemb80_segments[] = {
-  { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code },
-  { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter },
-  { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample },
-};
-
-static struct dsp_module_desc cwcemb80_module = {
-  "cwcemb80",
-  {
-    38,
-    cwcemb80_symbols
-  },
-  3,
-  cwcemb80_segments,
-};
-
-#endif /* __HEADER_cwcemb80_H__ */

+ 2 - 0
sound/pci/echoaudio/darla20.c

@@ -56,6 +56,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/darla20_dsp.fw");
+
 #define FW_DARLA20_DSP	0
 
 static const struct firmware card_fw[] = {

+ 2 - 0
sound/pci/echoaudio/darla24.c

@@ -60,6 +60,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/darla24_dsp.fw");
+
 #define FW_DARLA24_DSP	0
 
 static const struct firmware card_fw[] = {

+ 4 - 0
sound/pci/echoaudio/echo3g.c

@@ -68,6 +68,10 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/echo3g_dsp.fw");
+MODULE_FIRMWARE("ea/3g_asic.fw");
+
 #define FW_361_LOADER	0
 #define FW_ECHO3G_DSP	1
 #define FW_3G_ASIC	2

+ 1 - 3
sound/pci/echoaudio/echoaudio.c

@@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct audiopipe *pipe = runtime->private_data;
 	int i, err;
 	u32 channelmask = 0;
-	struct list_head *pos;
 	struct snd_pcm_substream *s;
 
-	snd_pcm_group_for_each(pos, substream) {
-		s = snd_pcm_group_substream_entry(pos);
+	snd_pcm_group_for_each_entry(s, substream) {
 		for (i = 0; i < DSP_MAXPIPES; i++) {
 			if (s == chip->substream[i]) {
 				channelmask |= 1 << i;

+ 2 - 2
sound/pci/echoaudio/echoaudio_3g.c

@@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip)
 
 	chip->asic_code = &card_fw[FW_3G_ASIC];
 
-	/* Now give the new ASIC a little time to set up */
-	mdelay(2);
+	/* Now give the new ASIC some time to set up */
+	msleep(1000);
 	/* See if it worked */
 	box_type = check_asic_status(chip);
 

+ 2 - 0
sound/pci/echoaudio/gina20.c

@@ -60,6 +60,8 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/gina20_dsp.fw");
+
 #define FW_GINA20_DSP	0
 
 static const struct firmware card_fw[] = {

+ 6 - 0
sound/pci/echoaudio/gina24.c

@@ -66,6 +66,12 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_361_dsp.fw");
+MODULE_FIRMWARE("ea/gina24_301_asic.fw");
+MODULE_FIRMWARE("ea/gina24_361_asic.fw");
+
 #define FW_361_LOADER		0
 #define FW_GINA24_301_DSP	1
 #define FW_GINA24_361_DSP	2

+ 3 - 0
sound/pci/echoaudio/indigo.c

@@ -58,6 +58,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dsp.fw");
+
 #define FW_361_LOADER	0
 #define FW_INDIGO_DSP	1
 

+ 3 - 0
sound/pci/echoaudio/indigodj.c

@@ -58,6 +58,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_dj_dsp.fw");
+
 #define FW_361_LOADER		0
 #define FW_INDIGO_DJ_DSP	1
 

+ 3 - 0
sound/pci/echoaudio/indigoio.c

@@ -59,6 +59,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/indigo_io_dsp.fw");
+
 #define FW_361_LOADER		0
 #define FW_INDIGO_IO_DSP	1
 

+ 3 - 0
sound/pci/echoaudio/layla20.c

@@ -66,6 +66,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/layla20_dsp.fw");
+MODULE_FIRMWARE("ea/layla20_asic.fw");
+
 #define FW_LAYLA20_DSP	0
 #define FW_LAYLA20_ASIC	1
 

+ 6 - 0
sound/pci/echoaudio/layla24.c

@@ -68,6 +68,12 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_dsp.fw");
+MODULE_FIRMWARE("ea/layla24_1_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2A_asic.fw");
+MODULE_FIRMWARE("ea/layla24_2S_asic.fw");
+
 #define FW_361_LOADER		0
 #define FW_LAYLA24_DSP		1
 #define FW_LAYLA24_1_ASIC	2

+ 3 - 0
sound/pci/echoaudio/mia.c

@@ -66,6 +66,9 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mia_dsp.fw");
+
 #define FW_361_LOADER	0
 #define FW_MIA_DSP	1
 

+ 9 - 0
sound/pci/echoaudio/mona.c

@@ -64,6 +64,15 @@
 #include <asm/atomic.h>
 #include "echoaudio.h"
 
+MODULE_FIRMWARE("ea/loader_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_dsp.fw");
+MODULE_FIRMWARE("ea/mona_361_dsp.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw");
+MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw");
+MODULE_FIRMWARE("ea/mona_2_asic.fw");
+
 #define FW_361_LOADER		0
 #define FW_MONA_301_DSP		1
 #define FW_MONA_361_DSP		2

+ 19 - 5
sound/pci/emu10k1/emu10k1_main.c

@@ -49,6 +49,13 @@
 #include "p17v.h"
 
 
+#define HANA_FILENAME "emu/hana.fw"
+#define DOCK_FILENAME "emu/audio_dock.fw"
+
+MODULE_FIRMWARE(HANA_FILENAME);
+MODULE_FIRMWARE(DOCK_FILENAME);
+
+
 /*************************************************************************
  * EMU10K1 init / done
  *************************************************************************/
@@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
 	int tmp,tmp2;
 	int reg;
 	int err;
-	const char *hana_filename = "emu/hana.fw";
-	const char *dock_filename = "emu/audio_dock.fw";
 
 	snd_printk(KERN_INFO "emu1010: Special config.\n");
 	/* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
@@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
 		return -ENODEV;
 	}
 	snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
-	if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
-		snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
+	if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) {
+		snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME);
 		return err;
 	}
 
@@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
 		/* Return to Audio Dock programming mode */
 		snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
 		snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
-		if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
+		if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) {
 			return err;
 		}
 		snd_emu1010_fpga_write(emu,  EMU_HANA_FPGA_CONFIG, 0 );
@@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = {
 	 .spi_dac = 1,
 	 .i2c_adc = 1,
 	 .spk71 = 1} ,
+	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
+	 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", 
+	 .id = "EMU1010",
+	 .emu10k2_chip = 1,
+	 .ca0108_chip = 1,
+	 .ca_cardbus_chip = 1,
+	 .spi_dac = 1,
+	 .i2c_adc = 1,
+	 .spk71 = 1} ,
 	{.vendor = 0x1102, .device = 0x0008, 
 	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
 	 .id = "Audigy2",

+ 1 - 3
sound/pci/emu10k1/p16v.c

@@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
 	struct snd_emu10k1_pcm *epcm;
 	int channel;
 	int result = 0;
-	struct list_head *pos;
         struct snd_pcm_substream *s;
 	u32 basic = 0;
 	u32 inte = 0;
@@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
 		running = 0;
 		break;
 	}
-        snd_pcm_group_for_each(pos, substream) {
-                s = snd_pcm_group_substream_entry(pos);
+        snd_pcm_group_for_each_entry(s, substream) {
 		runtime = s->runtime;
 		epcm = runtime->private_data;
 		channel = substream->pcm->device-emu->p16v_device_offset;

+ 2 - 6
sound/pci/ens1370.c

@@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 	{
 		unsigned int what = 0;
-		struct list_head *pos;
 		struct snd_pcm_substream *s;
-		snd_pcm_group_for_each(pos, substream) {
-			s = snd_pcm_group_substream_entry(pos);
+		snd_pcm_group_for_each_entry(s, substream) {
 			if (s == ensoniq->playback1_substream) {
 				what |= ES_P1_PAUSE;
 				snd_pcm_trigger_done(s, substream);
@@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_STOP:
 	{
 		unsigned int what = 0;
-		struct list_head *pos;
 		struct snd_pcm_substream *s;
-		snd_pcm_group_for_each(pos, substream) {
-			s = snd_pcm_group_substream_entry(pos);
+		snd_pcm_group_for_each_entry(s, substream) {
 			if (s == ensoniq->playback1_substream) {
 				what |= ES_DAC1_EN;
 				snd_pcm_trigger_done(s, substream);

+ 3 - 8
sound/pci/es1968.c

@@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
 	runtime->hw = snd_es1968_playback;
 	runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
 		calc_available_memory_size(chip);
-#if 0
-	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-				   1024);
-#endif
+
 	spin_lock_irq(&chip->substream_lock);
 	list_add(&es->list, &chip->substream_list);
 	spin_unlock_irq(&chip->substream_lock);
@@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
 	runtime->hw = snd_es1968_capture;
 	runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max =
 		calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */
-#if 0
-	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
-				   1024);
-#endif
+	snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
+
 	spin_lock_irq(&chip->substream_lock);
 	list_add(&es->list, &chip->substream_list);
 	spin_unlock_irq(&chip->substream_lock);

+ 6 - 3
sound/pci/hda/Makefile

@@ -1,5 +1,8 @@
 snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o \
+# since snd-hda-intel is the only driver using hda-codec,
+# merge it into a single module although it was originally
+# designed to be individual modules
+snd-hda-intel-objs += hda_codec.o \
 	hda_generic.o \
 	patch_realtek.o \
 	patch_cmedia.o \
@@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \
 	patch_conexant.o \
 	patch_via.o
 ifdef CONFIG_PROC_FS
-snd-hda-codec-objs += hda_proc.o
+snd-hda-intel-objs += hda_proc.o
 endif
 
-obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
+obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o

+ 420 - 309
sound/pci/hda/hda_codec.c

@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
-#include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <sound/core.h>
 #include "hda_codec.h"
@@ -34,11 +33,6 @@
 #include "hda_local.h"
 
 
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec");
-MODULE_LICENSE("GPL");
-
-
 /*
  * vendor / preset table
  */
@@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = {
  *
  * Returns the obtained response value, or -1 for an error.
  */
-unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct,
+unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
+				int direct,
 				unsigned int verb, unsigned int parm)
 {
 	unsigned int res;
 	mutex_lock(&codec->bus->cmd_mutex);
-	if (! codec->bus->ops.command(codec, nid, direct, verb, parm))
+	if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
 		res = codec->bus->ops.get_response(codec);
 	else
 		res = (unsigned int)-1;
@@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire
 	return res;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_read);
-
 /**
  * snd_hda_codec_write - send a single command without waiting for response
  * @codec: the HDA codec
@@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
 	return err;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_write);
-
 /**
  * snd_hda_sequence_write - sequence writes
  * @codec: the HDA codec
@@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
 		snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
 }
 
-EXPORT_SYMBOL(snd_hda_sequence_write);
-
 /**
  * snd_hda_get_sub_nodes - get the range of sub nodes
  * @codec: the HDA codec
@@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write);
  * Parse the NID and store the start NID of its sub-nodes.
  * Returns the number of sub-nodes.
  */
-int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id)
+int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
+			  hda_nid_t *start_id)
 {
 	unsigned int parm;
 
@@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta
 	return (int)(parm & 0x7fff);
 }
 
-EXPORT_SYMBOL(snd_hda_get_sub_nodes);
-
 /**
  * snd_hda_get_connections - get connection list
  * @codec: the HDA codec
@@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
 	conn_len = parm & AC_CLIST_LENGTH;
 	mask = (1 << (shift-1)) - 1;
 
-	if (! conn_len)
+	if (!conn_len)
 		return 0; /* no connection */
 
 	if (conn_len == 1) {
 		/* single connection */
-		parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0);
+		parm = snd_hda_codec_read(codec, nid, 0,
+					  AC_VERB_GET_CONNECT_LIST, 0);
 		conn_list[0] = parm & mask;
 		return 1;
 	}
@@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
 		if (i % num_elems == 0)
 			parm = snd_hda_codec_read(codec, nid, 0,
 						  AC_VERB_GET_CONNECT_LIST, i);
-		range_val = !! (parm & (1 << (shift-1))); /* ranges */
+		range_val = !!(parm & (1 << (shift-1))); /* ranges */
 		val = parm & mask;
 		parm >>= shift;
 		if (range_val) {
 			/* ranges between the previous and this one */
-			if (! prev_nid || prev_nid >= val) {
-				snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val);
+			if (!prev_nid || prev_nid >= val) {
+				snd_printk(KERN_WARNING "hda_codec: "
+					   "invalid dep_range_val %x:%x\n",
+					   prev_nid, val);
 				continue;
 			}
 			for (n = prev_nid + 1; n <= val; n++) {
 				if (conns >= max_conns) {
-					snd_printk(KERN_ERR "Too many connections\n");
+					snd_printk(KERN_ERR
+						   "Too many connections\n");
 					return -EINVAL;
 				}
 				conn_list[conns++] = n;
@@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
 	struct hda_bus_unsolicited *unsol;
 	unsigned int wp;
 
-	if ((unsol = bus->unsol) == NULL)
+	unsol = bus->unsol;
+	if (!unsol)
 		return 0;
 
 	wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
@@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_queue_unsol_event);
-
 /*
  * process queueud unsolicited events
  */
@@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work)
 		rp <<= 1;
 		res = unsol->queue[rp];
 		caddr = unsol->queue[rp + 1];
-		if (! (caddr & (1 << 4))) /* no unsolicited event? */
+		if (!(caddr & (1 << 4))) /* no unsolicited event? */
 			continue;
 		codec = bus->caddr_tbl[caddr & 0x0f];
 		if (codec && codec->patch_ops.unsol_event)
@@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work)
 /*
  * initialize unsolicited queue
  */
-static int init_unsol_queue(struct hda_bus *bus)
+static int __devinit init_unsol_queue(struct hda_bus *bus)
 {
 	struct hda_bus_unsolicited *unsol;
 
@@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus)
 		return 0;
 
 	unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
-	if (! unsol) {
-		snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
+	if (!unsol) {
+		snd_printk(KERN_ERR "hda_codec: "
+			   "can't allocate unsolicited queue\n");
 		return -ENOMEM;
 	}
 	INIT_WORK(&unsol->work, process_unsol_events);
@@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec);
 
 static int snd_hda_bus_free(struct hda_bus *bus)
 {
-	struct list_head *p, *n;
+	struct hda_codec *codec, *n;
 
-	if (! bus)
+	if (!bus)
 		return 0;
 	if (bus->unsol) {
 		flush_scheduled_work();
 		kfree(bus->unsol);
 	}
-	list_for_each_safe(p, n, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
 		snd_hda_codec_free(codec);
 	}
 	if (bus->ops.private_free)
@@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
-		    struct hda_bus **busp)
+int __devinit snd_hda_bus_new(struct snd_card *card,
+			      const struct hda_bus_template *temp,
+			      struct hda_bus **busp)
 {
 	struct hda_bus *bus;
 	int err;
@@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 	mutex_init(&bus->cmd_mutex);
 	INIT_LIST_HEAD(&bus->codec_list);
 
-	if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
+	err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
+	if (err < 0) {
 		snd_hda_bus_free(bus);
 		return err;
 	}
@@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_bus_new);
-
 /*
  * find a matching codec preset
  */
-static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec)
+static const struct hda_codec_preset __devinit *
+find_codec_preset(struct hda_codec *codec)
 {
 	const struct hda_codec_preset **tbl, *preset;
 
+	if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic"))
+		return NULL; /* use the generic parser */
+
 	for (tbl = hda_preset_tables; *tbl; tbl++) {
 		for (preset = *tbl; preset->id; preset++) {
 			u32 mask = preset->mask;
-			if (! mask)
+			if (!mask)
 				mask = ~0;
 			if (preset->id == (codec->vendor_id & mask) &&
-			    (! preset->rev ||
+			    (!preset->rev ||
 			     preset->rev == codec->revision_id))
 				return preset;
 		}
@@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
 			break;
 		}
 	}
-	if (! vendor) {
+	if (!vendor) {
 		sprintf(tmp, "Generic %04x", vendor_id);
 		vendor = tmp;
 	}
 	if (codec->preset && codec->preset->name)
 		snprintf(name, namelen, "%s %s", vendor, codec->preset->name);
 	else
-		snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff);
+		snprintf(name, namelen, "%s ID %x", vendor,
+			 codec->vendor_id & 0xffff);
 }
 
 /*
  * look for an AFG and MFG nodes
  */
-static void setup_fg_nodes(struct hda_codec *codec)
+static void __devinit setup_fg_nodes(struct hda_codec *codec)
 {
 	int i, total_nodes;
 	hda_nid_t nid;
 
 	total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
 	for (i = 0; i < total_nodes; i++, nid++) {
-		switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) {
+		unsigned int func;
+		func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE);
+		switch (func & 0xff) {
 		case AC_GRP_AUDIO_FUNCTION:
 			codec->afg = nid;
 			break;
@@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
 	codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
 						 &codec->start_nid);
 	codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
-	if (! codec->wcaps)
+	if (!codec->wcaps)
 		return -ENOMEM;
 	nid = codec->start_nid;
 	for (i = 0; i < codec->num_nodes; i++, nid++)
@@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
  */
 static void snd_hda_codec_free(struct hda_codec *codec)
 {
-	if (! codec)
+	if (!codec)
 		return;
 	list_del(&codec->list);
 	codec->bus->caddr_tbl[codec->addr] = NULL;
@@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec);
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
-		      struct hda_codec **codecp)
+int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
+				struct hda_codec **codecp)
 {
 	struct hda_codec *codec;
 	char component[13];
@@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 	snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL);
 
 	if (bus->caddr_tbl[codec_addr]) {
-		snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr);
+		snd_printk(KERN_ERR "hda_codec: "
+			   "address 0x%x is already occupied\n", codec_addr);
 		return -EBUSY;
 	}
 
@@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 	list_add_tail(&codec->list, &bus->codec_list);
 	bus->caddr_tbl[codec_addr] = codec;
 
-	codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID);
+	codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+					      AC_PAR_VENDOR_ID);
 	if (codec->vendor_id == -1)
 		/* read again, hopefully the access method was corrected
 		 * in the last read...
 		 */
 		codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
 						      AC_PAR_VENDOR_ID);
-	codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID);
-	codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID);
+	codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+						 AC_PAR_SUBSYSTEM_ID);
+	codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT,
+						AC_PAR_REV_ID);
 
 	setup_fg_nodes(codec);
-	if (! codec->afg && ! codec->mfg) {
+	if (!codec->afg && !codec->mfg) {
 		snd_printdd("hda_codec: no AFG or MFG node found\n");
 		snd_hda_codec_free(codec);
 		return -ENODEV;
@@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 		return -ENOMEM;
 	}
 
-	if (! codec->subsystem_id) {
+	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->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)
+	/* audio codec should override the mixer name */
+	if (codec->afg || !*bus->card->mixername)
 		snd_hda_get_codec_name(codec, bus->card->mixername,
 				       sizeof(bus->card->mixername));
 
@@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_codec_new);
-
 /**
  * snd_hda_codec_setup_stream - set up the codec for streaming
  * @codec: the CODEC to set up
@@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new);
  * @channel_id: channel id to pass, zero based.
  * @format: stream format.
  */
-void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
+void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
+				u32 stream_tag,
 				int channel_id, int format)
 {
-	if (! nid)
+	if (!nid)
 		return;
 
-	snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
+	snd_printdd("hda_codec_setup_stream: "
+		    "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
 		    nid, stream_tag, channel_id, format);
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
 			    (stream_tag << 4) | channel_id);
@@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
 }
 
-EXPORT_SYMBOL(snd_hda_codec_setup_stream);
-
 /*
  * amp access functions
  */
@@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream);
 #define INFO_AMP_VOL(ch)	(1 << (1 + (ch)))
 
 /* initialize the hash table */
-static void init_amp_hash(struct hda_codec *codec)
+static void __devinit init_amp_hash(struct hda_codec *codec)
 {
 	memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
 	codec->num_amp_entries = 0;
@@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
 	if (codec->num_amp_entries >= codec->amp_info_size) {
 		/* reallocate the array */
 		int new_size = codec->amp_info_size + 64;
-		struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
-							GFP_KERNEL);
-		if (! new_info) {
-			snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");
+		struct hda_amp_info *new_info;
+		new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
+				   GFP_KERNEL);
+		if (!new_info) {
+			snd_printk(KERN_ERR "hda_codec: "
+				   "can't malloc amp_info\n");
 			return NULL;
 		}
 		if (codec->amp_info) {
 			memcpy(new_info, codec->amp_info,
-			       codec->amp_info_size * sizeof(struct hda_amp_info));
+			       codec->amp_info_size *
+			       sizeof(struct hda_amp_info));
 			kfree(codec->amp_info);
 		}
 		codec->amp_info_size = new_size;
@@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key)
  */
 static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
 {
-	struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+	struct hda_amp_info *info;
 
-	if (! info)
+	info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
+	if (!info)
 		return 0;
-	if (! (info->status & INFO_AMP_CAPS)) {
-		if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
+	if (!(info->status & INFO_AMP_CAPS)) {
+		if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
 			nid = codec->afg;
-		info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
-						    AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
+		info->amp_caps = snd_hda_param_read(codec, nid,
+						    direction == HDA_OUTPUT ?
+						    AC_PAR_AMP_OUT_CAP :
+						    AC_PAR_AMP_IN_CAP);
 		info->status |= INFO_AMP_CAPS;
 	}
 	return info->amp_caps;
@@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
  * read the current volume to info
  * if the cache exists, read the cache value.
  */
-static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
-			 hda_nid_t nid, int ch, int direction, int index)
+static unsigned int get_vol_mute(struct hda_codec *codec,
+				 struct hda_amp_info *info, hda_nid_t nid,
+				 int ch, int direction, int index)
 {
 	u32 val, parm;
 
@@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
 	parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
 	parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
 	parm |= index;
-	val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);
+	val = snd_hda_codec_read(codec, nid, 0,
+				 AC_VERB_GET_AMP_GAIN_MUTE, parm);
 	info->vol[ch] = val & 0xff;
 	info->status |= INFO_AMP_VOL(ch);
 	return info->vol[ch];
@@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i
  * write the current volume in info to the h/w and update the cache
  */
 static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
-			 hda_nid_t nid, int ch, int direction, int index, int val)
+			 hda_nid_t nid, int ch, int direction, int index,
+			 int val)
 {
 	u32 parm;
 
@@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
 int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
 			   int direction, int index)
 {
-	struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
-	if (! info)
+	struct hda_amp_info *info;
+	info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
+	if (!info)
 		return 0;
 	return get_vol_mute(codec, info, nid, ch, direction, index);
 }
@@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
 int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
 			     int direction, int idx, int mask, int val)
 {
-	struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+	struct hda_amp_info *info;
 
-	if (! info)
+	info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+	if (!info)
 		return 0;
 	val &= mask;
 	val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
-	if (info->vol[ch] == val && ! codec->in_resume)
+	if (info->vol[ch] == val && !codec->in_resume)
 		return 0;
 	put_vol_mute(codec, info, nid, ch, direction, idx, val);
 	return 1;
@@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
 #define get_amp_index(kc)	(((kc)->private_value >> 19) & 0xf)
 
 /* volume */
-int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	u16 nid = get_amp_nid(kcontrol);
@@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	u32 caps;
 
 	caps = query_amp_caps(codec, nid, dir);
-	caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */
-	if (! caps) {
-		printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid);
+	/* num steps */
+	caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
+	if (!caps) {
+		printk(KERN_WARNING "hda_codec: "
+		       "num_steps = 0 for NID=0x%x\n", nid);
 		return -EINVAL;
 	}
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	return 0;
 }
 
-int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	return 0;
 }
 
-int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 	if (size < 4 * sizeof(unsigned int))
 		return -ENOMEM;
 	caps = query_amp_caps(codec, nid, dir);
-	val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25;
+	val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
+	val2 = (val2 + 1) * 25;
 	val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
 	val1 = ((int)val1) * ((int)val2);
 	if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
@@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 }
 
 /* switch */
-int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int chs = get_amp_channels(kcontrol);
 
@@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	return 0;
 }
 
-int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 	long *valp = ucontrol->value.integer.value;
 
 	if (chs & 1)
-		*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1;
+		*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
+			   0x80) ? 0 : 1;
 	if (chs & 2)
-		*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1;
+		*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
+			 0x80) ? 0 : 1;
 	return 0;
 }
 
-int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
 #define AMP_VAL_IDX_SHIFT	19
 #define AMP_VAL_IDX_MASK	(0x0f<<19)
 
-int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	unsigned long pval;
@@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	return err;
 }
 
-int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	unsigned long pval;
@@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
 	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);
+		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;
@@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
  * SPDIF out controls
  */
 
-static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
 					   IEC958_AES0_NONAUDIO |
@@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
 	return 0;
 }
 
-static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
 					   IEC958_AES0_NONAUDIO |
@@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl
 	return 0;
 }
 
-static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits)
 	unsigned short val = 0;
 
 	if (sbits & IEC958_AES0_PROFESSIONAL)
-		val |= 1 << 6;
+		val |= AC_DIG1_PROFESSIONAL;
 	if (sbits & IEC958_AES0_NONAUDIO)
-		val |= 1 << 5;
+		val |= AC_DIG1_NONAUDIO;
 	if (sbits & IEC958_AES0_PROFESSIONAL) {
-		if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
-			val |= 1 << 3;
+		if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
+		    IEC958_AES0_PRO_EMPHASIS_5015)
+			val |= AC_DIG1_EMPHASIS;
 	} else {
-		if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015)
-			val |= 1 << 3;
-		if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
-			val |= 1 << 4;
+		if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
+		    IEC958_AES0_CON_EMPHASIS_5015)
+			val |= AC_DIG1_EMPHASIS;
+		if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
+			val |= AC_DIG1_COPYRIGHT;
 		if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
-			val |= 1 << 7;
+			val |= AC_DIG1_LEVEL;
 		val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
 	}
 	return val;
@@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val)
 {
 	unsigned int sbits = 0;
 
-	if (val & (1 << 5))
+	if (val & AC_DIG1_NONAUDIO)
 		sbits |= IEC958_AES0_NONAUDIO;
-	if (val & (1 << 6))
+	if (val & AC_DIG1_PROFESSIONAL)
 		sbits |= IEC958_AES0_PROFESSIONAL;
 	if (sbits & IEC958_AES0_PROFESSIONAL) {
-		if (sbits & (1 << 3))
+		if (sbits & AC_DIG1_EMPHASIS)
 			sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
 	} else {
-		if (val & (1 << 3))
+		if (val & AC_DIG1_EMPHASIS)
 			sbits |= IEC958_AES0_CON_EMPHASIS_5015;
-		if (! (val & (1 << 4)))
+		if (!(val & AC_DIG1_COPYRIGHT))
 			sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
-		if (val & (1 << 7))
+		if (val & AC_DIG1_LEVEL)
 			sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
 		sbits |= val & (0x7f << 8);
 	}
 	return sbits;
 }
 
-static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c
 	codec->spdif_ctls = val;
 
 	if (change || codec->in_resume) {
-		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
-		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8);
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+				    val & 0xff);
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2,
+				    val >> 8);
 	}
 
 	mutex_unlock(&codec->spdif_mutex);
 	return change;
 }
 
-static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s
 	return 0;
 }
 
-static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
-	ucontrol->value.integer.value[0] = codec->spdif_ctls & 1;
+	ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE;
 	return 0;
 }
 
-static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn
 	int change;
 
 	mutex_lock(&codec->spdif_mutex);
-	val = codec->spdif_ctls & ~1;
+	val = codec->spdif_ctls & ~AC_DIG1_ENABLE;
 	if (ucontrol->value.integer.value[0])
-		val |= 1;
+		val |= AC_DIG1_ENABLE;
 	change = codec->spdif_ctls != val;
 	if (change || codec->in_resume) {
 		codec->spdif_ctls = val;
-		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff);
-		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-				    AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
-				    AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80));
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+				    val & 0xff);
+		/* unmute amp switch (if any) */
+		if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
+		    (val & AC_DIG1_ENABLE))
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_AMP_GAIN_MUTE,
+					    AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT |
+					    AC_AMP_SET_OUTPUT);
 	}
 	mutex_unlock(&codec->spdif_mutex);
 	return change;
@@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
+					    hda_nid_t nid)
 {
 	int err;
 	struct snd_kcontrol *kctl;
@@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
 	for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
 		kctl = snd_ctl_new1(dig_mix, codec);
 		kctl->private_value = nid;
-		if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+		err = snd_ctl_add(codec->bus->card, kctl);
+		if (err < 0)
 			return err;
 	}
-	codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
+	codec->spdif_ctls =
+		snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0);
 	codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
 	return 0;
 }
@@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
 
 #define snd_hda_spdif_in_switch_info	snd_hda_spdif_out_switch_info
 
-static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd
 	return 0;
 }
 
-static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd
 	change = codec->spdif_in_enable != val;
 	if (change || codec->in_resume) {
 		codec->spdif_in_enable = val;
-		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val);
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+				    val);
 	}
 	mutex_unlock(&codec->spdif_mutex);
 	return change;
 }
 
-static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
+int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec,
+					   hda_nid_t nid)
 {
 	int err;
 	struct snd_kcontrol *kctl;
@@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
 	for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
 		kctl = snd_ctl_new1(dig_mix, codec);
 		kctl->private_value = nid;
-		if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+		err = snd_ctl_add(codec->bus->card, kctl);
+		if (err < 0)
 			return err;
 	}
-	codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1;
+	codec->spdif_in_enable =
+		snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) &
+		AC_DIG1_ENABLE;
 	return 0;
 }
 
@@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
  *
  * Returns 0 if successful, otherwise a negative error code.
  */
-int snd_hda_build_controls(struct hda_bus *bus)
+int __devinit snd_hda_build_controls(struct hda_bus *bus)
 {
-	struct list_head *p;
+	struct hda_codec *codec;
 
 	/* build controls */
-	list_for_each(p, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry(codec, &bus->codec_list, list) {
 		int err;
-		if (! codec->patch_ops.build_controls)
+		if (!codec->patch_ops.build_controls)
 			continue;
 		err = codec->patch_ops.build_controls(codec);
 		if (err < 0)
@@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus)
 	}
 
 	/* initialize */
-	list_for_each(p, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry(codec, &bus->codec_list, list) {
 		int err;
 		hda_set_power_state(codec,
 				    codec->afg ? codec->afg : codec->mfg,
 				    AC_PWRST_D0);
-		if (! codec->patch_ops.init)
+		if (!codec->patch_ops.init)
 			continue;
 		err = codec->patch_ops.init(codec);
 		if (err < 0)
@@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus)
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_build_controls);
-
 /*
  * stream formats
  */
@@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = {
 	{ 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
 	{ 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
 	{ 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
+#define AC_PAR_PCM_RATE_BITS	11
+	/* up to bits 10, 384kHZ isn't supported properly */
+
+	/* not autodetected value */
+	{ 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
 
 	{ 0 } /* terminator */
 };
@@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
 			val = rate_bits[i].hda_fmt;
 			break;
 		}
-	if (! rate_bits[i].hz) {
+	if (!rate_bits[i].hz) {
 		snd_printdd("invalid rate %d\n", rate);
 		return 0;
 	}
@@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
 			val |= 0x20;
 		break;
 	default:
-		snd_printdd("invalid format width %d\n", snd_pcm_format_width(format));
+		snd_printdd("invalid format width %d\n",
+			    snd_pcm_format_width(format));
 		return 0;
 	}
 
 	return val;
 }
 
-EXPORT_SYMBOL(snd_hda_calc_stream_format);
-
 /**
  * snd_hda_query_supported_pcm - query the supported PCM rates and formats
  * @codec: the HDA codec
@@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 		if (val == -1)
 			return -EIO;
 	}
-	if (! val)
+	if (!val)
 		val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
 
 	if (ratesp) {
 		u32 rates = 0;
-		for (i = 0; rate_bits[i].hz; i++) {
+		for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
 			if (val & (1 << i))
 				rates |= rate_bits[i].alsa_bits;
 		}
@@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 		streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
 		if (streams == -1)
 			return -EIO;
-		if (! streams) {
-			streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
+		if (!streams) {
+			streams = snd_hda_param_read(codec, codec->afg,
+						     AC_PAR_STREAM);
 			if (streams == -1)
 				return -EIO;
 		}
@@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 					bps = 24;
 				else if (val & AC_SUPPCM_BITS_20)
 					bps = 20;
-			} else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) {
+			} else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
+					  AC_SUPPCM_BITS_32)) {
 				formats |= SNDRV_PCM_FMTBIT_S32_LE;
 				if (val & AC_SUPPCM_BITS_32)
 					bps = 32;
@@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 					bps = 20;
 			}
 		}
-		else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */
+		else if (streams == AC_SUPFMT_FLOAT32) {
+			/* should be exclusive */
 			formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
 			bps = 32;
-		} else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */
+		} else if (streams == AC_SUPFMT_AC3) {
+			/* should be exclusive */
 			/* temporary hack: we have still no proper support
 			 * for the direct AC3 stream...
 			 */
@@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
 }
 
 /**
- * snd_hda_is_supported_format - check whether the given node supports the format val
+ * snd_hda_is_supported_format - check whether the given node supports
+ * the format val
  *
  * Returns 1 if supported, 0 if not.
  */
@@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
 		if (val == -1)
 			return 0;
 	}
-	if (! val) {
+	if (!val) {
 		val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
 		if (val == -1)
 			return 0;
 	}
 
 	rate = format & 0xff00;
-	for (i = 0; rate_bits[i].hz; i++)
+	for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
 		if (rate_bits[i].hda_fmt == rate) {
 			if (val & (1 << i))
 				break;
 			return 0;
 		}
-	if (! rate_bits[i].hz)
+	if (i >= AC_PAR_PCM_RATE_BITS)
 		return 0;
 
 	stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
 	if (stream == -1)
 		return 0;
-	if (! stream && nid != codec->afg)
+	if (!stream && nid != codec->afg)
 		stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
-	if (! stream || stream == -1)
+	if (!stream || stream == -1)
 		return 0;
 
 	if (stream & AC_SUPFMT_PCM) {
 		switch (format & 0xf0) {
 		case 0x00:
-			if (! (val & AC_SUPPCM_BITS_8))
+			if (!(val & AC_SUPPCM_BITS_8))
 				return 0;
 			break;
 		case 0x10:
-			if (! (val & AC_SUPPCM_BITS_16))
+			if (!(val & AC_SUPPCM_BITS_16))
 				return 0;
 			break;
 		case 0x20:
-			if (! (val & AC_SUPPCM_BITS_20))
+			if (!(val & AC_SUPPCM_BITS_20))
 				return 0;
 			break;
 		case 0x30:
-			if (! (val & AC_SUPPCM_BITS_24))
+			if (!(val & AC_SUPPCM_BITS_24))
 				return 0;
 			break;
 		case 0x40:
-			if (! (val & AC_SUPPCM_BITS_32))
+			if (!(val & AC_SUPPCM_BITS_32))
 				return 0;
 			break;
 		default:
@@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
 	return 0;
 }
 
-static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info)
+static int __devinit set_pcm_default_values(struct hda_codec *codec,
+					    struct hda_pcm_stream *info)
 {
-	if (info->nid) {
-		/* query support PCM information from the given NID */
-		if (! info->rates || ! info->formats)
-			snd_hda_query_supported_pcm(codec, info->nid,
-						    info->rates ? NULL : &info->rates,
-						    info->formats ? NULL : &info->formats,
-						    info->maxbps ? NULL : &info->maxbps);
+	/* query support PCM information from the given NID */
+	if (info->nid && (!info->rates || !info->formats)) {
+		snd_hda_query_supported_pcm(codec, info->nid,
+				info->rates ? NULL : &info->rates,
+				info->formats ? NULL : &info->formats,
+				info->maxbps ? NULL : &info->maxbps);
 	}
 	if (info->ops.open == NULL)
 		info->ops.open = hda_pcm_default_open_close;
@@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream
  *
  * This function returns 0 if successfull, or a negative error code.
  */
-int snd_hda_build_pcms(struct hda_bus *bus)
+int __devinit snd_hda_build_pcms(struct hda_bus *bus)
 {
-	struct list_head *p;
+	struct hda_codec *codec;
 
-	list_for_each(p, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry(codec, &bus->codec_list, list) {
 		unsigned int pcm, s;
 		int err;
-		if (! codec->patch_ops.build_pcms)
+		if (!codec->patch_ops.build_pcms)
 			continue;
 		err = codec->patch_ops.build_pcms(codec);
 		if (err < 0)
@@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus)
 			for (s = 0; s < 2; s++) {
 				struct hda_pcm_stream *info;
 				info = &codec->pcm_info[pcm].stream[s];
-				if (! info->substreams)
+				if (!info->substreams)
 					continue;
 				err = set_pcm_default_values(codec, info);
 				if (err < 0)
@@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus)
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_build_pcms);
-
 /**
  * snd_hda_check_board_config - compare the current codec with the config table
  * @codec: the HDA codec
@@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
  *
  * If no entries are matching, the function returns a negative value.
  */
-int snd_hda_check_board_config(struct hda_codec *codec,
-			       int num_configs, const char **models,
-			       const struct snd_pci_quirk *tbl)
+int __devinit snd_hda_check_board_config(struct hda_codec *codec,
+					 int num_configs, const char **models,
+					 const struct snd_pci_quirk *tbl)
 {
 	if (codec->bus->modelname && models) {
 		int i;
@@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec,
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
+int __devinit snd_hda_add_new_ctls(struct hda_codec *codec,
+				   struct snd_kcontrol_new *knew)
 {
 	int err;
 
 	for (; knew->name; knew++) {
 		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(knew, codec);
-		if (! kctl)
+		if (!kctl)
 			return -ENOMEM;
 		err = snd_ctl_add(codec->bus->card, kctl);
 		if (err < 0) {
-			if (! codec->addr)
+			if (!codec->addr)
 				return err;
 			kctl = snd_ctl_new1(knew, codec);
-			if (! kctl)
+			if (!kctl)
 				return -ENOMEM;
 			kctl->id.device = codec->addr;
-			if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+			err = snd_ctl_add(codec->bus->card, kctl);
+			if (err < 0)
 				return err;
 		}
 	}
@@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 /*
  * Channel mode helper
  */
-int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
-			 const struct hda_channel_mode *chmode, int num_chmodes)
+int snd_hda_ch_mode_info(struct hda_codec *codec,
+			 struct snd_ctl_elem_info *uinfo,
+			 const struct hda_channel_mode *chmode,
+			 int num_chmodes)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf
 	return 0;
 }
 
-int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
-			const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_get(struct hda_codec *codec,
+			struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode,
+			int num_chmodes,
 			int max_channels)
 {
 	int i;
@@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
 	return 0;
 }
 
-int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
-			const struct hda_channel_mode *chmode, int num_chmodes,
+int snd_hda_ch_mode_put(struct hda_codec *codec,
+			struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode,
+			int num_chmodes,
 			int *max_channelsp)
 {
 	unsigned int mode;
 
 	mode = ucontrol->value.enumerated.item[0];
 	snd_assert(mode < num_chmodes, return -EINVAL);
-	if (*max_channelsp == chmode[mode].channels && ! codec->in_resume)
+	if (*max_channelsp == chmode[mode].channels && !codec->in_resume)
 		return 0;
 	/* change the current channel setting */
 	*max_channelsp = chmode[mode].channels;
@@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon
 /*
  * input MUX helper
  */
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo)
+int snd_hda_input_mux_info(const struct hda_input_mux *imux,
+			   struct snd_ctl_elem_info *uinfo)
 {
 	unsigned int index;
 
@@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem
 	return 0;
 }
 
-int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
-			  struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
+int snd_hda_input_mux_put(struct hda_codec *codec,
+			  const struct hda_input_mux *imux,
+			  struct snd_ctl_elem_value *ucontrol,
+			  hda_nid_t nid,
 			  unsigned int *cur_val)
 {
 	unsigned int idx;
@@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
 	idx = ucontrol->value.enumerated.item[0];
 	if (idx >= imux->num_items)
 		idx = imux->num_items - 1;
-	if (*cur_val == idx && ! codec->in_resume)
+	if (*cur_val == idx && !codec->in_resume)
 		return 0;
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
 			    imux->items[idx].index);
@@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i
  * Multi-channel / digital-out PCM helper functions
  */
 
+/* setup SPDIF output stream */
+static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
+				 unsigned int stream_tag, unsigned int format)
+{
+	/* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
+	if (codec->spdif_ctls & AC_DIG1_ENABLE)
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+				    codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
+	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
+	/* turn on again (if needed) */
+	if (codec->spdif_ctls & AC_DIG1_ENABLE)
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
+				    codec->spdif_ctls & 0xff);
+}
+
 /*
  * open the digital out in the exclusive mode
  */
-int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_open(struct hda_codec *codec,
+			       struct hda_multi_out *mout)
 {
 	mutex_lock(&codec->spdif_mutex);
-	if (mout->dig_out_used) {
-		mutex_unlock(&codec->spdif_mutex);
-		return -EBUSY; /* already being used */
-	}
+	if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
+		/* already opened as analog dup; reset it once */
+		snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
 	mout->dig_out_used = HDA_DIG_EXCLUSIVE;
 	mutex_unlock(&codec->spdif_mutex);
 	return 0;
 }
 
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+				  struct hda_multi_out *mout,
+				  unsigned int stream_tag,
+				  unsigned int format,
+				  struct snd_pcm_substream *substream)
+{
+	mutex_lock(&codec->spdif_mutex);
+	setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
+	mutex_unlock(&codec->spdif_mutex);
+	return 0;
+}
+
 /*
  * release the digital out
  */
-int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_dig_close(struct hda_codec *codec,
+				struct hda_multi_out *mout)
 {
 	mutex_lock(&codec->spdif_mutex);
 	mout->dig_out_used = 0;
@@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m
 /*
  * set up more restrictions for analog out
  */
-int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_open(struct hda_codec *codec,
+				  struct hda_multi_out *mout,
 				  struct snd_pcm_substream *substream)
 {
 	substream->runtime->hw.channels_max = mout->max_channels;
@@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out
  * set up the i/o for analog out
  * when the digital out is available, copy the front out to digital out, too.
  */
-int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
+int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
+				     struct hda_multi_out *mout,
 				     unsigned int stream_tag,
 				     unsigned int format,
 				     struct snd_pcm_substream *substream)
@@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
 	mutex_lock(&codec->spdif_mutex);
 	if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
 		if (chs == 2 &&
-		    snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
-		    ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
+		    snd_hda_is_supported_format(codec, mout->dig_out_nid,
+						format) &&
+		    !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
 			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
-			/* setup digital receiver */
-			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
-						   stream_tag, 0, format);
+			setup_dig_out_stream(codec, mout->dig_out_nid,
+					     stream_tag, format);
 		} else {
 			mout->dig_out_used = 0;
-			snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
+			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+						   0, 0, 0);
 		}
 	}
 	mutex_unlock(&codec->spdif_mutex);
 
 	/* front */
-	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
+	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
+				   0, format);
 	if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
 		/* headphone out will just decode front left/right (stereo) */
-		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
+		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
+					   0, format);
 	/* extra outputs copied from front */
 	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
 		if (mout->extra_out_nid[i])
@@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
 	/* surrounds */
 	for (i = 1; i < mout->num_dacs; i++) {
 		if (chs >= (i + 1) * 2) /* independent out */
-			snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
-						   format);
+			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+						   i * 2, format);
 		else /* copy front */
-			snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
-						   format);
+			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
+						   0, format);
 	}
 	return 0;
 }
@@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o
 /*
  * clean up the setting for analog out
  */
-int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout)
+int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
+				     struct hda_multi_out *mout)
 {
 	hda_nid_t *nids = mout->dac_nids;
 	int i;
@@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o
  * Helper for automatic ping configuration
  */
 
-static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
+static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
 {
 	for (; *list; list++)
 		if (*list == nid)
@@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
 	return 0;
 }
 
+
+/*
+ * Sort an associated group of pins according to their sequence numbers.
+ */
+static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
+				  int num_pins)
+{
+	int i, j;
+	short seq;
+	hda_nid_t nid;
+	
+	for (i = 0; i < num_pins; i++) {
+		for (j = i + 1; j < num_pins; j++) {
+			if (sequences[i] > sequences[j]) {
+				seq = sequences[i];
+				sequences[i] = sequences[j];
+				sequences[j] = seq;
+				nid = pins[i];
+				pins[i] = pins[j];
+				pins[j] = nid;
+			}
+		}
+	}
+}
+
+
 /*
  * Parse all pin widgets and store the useful pin nids to cfg
  *
@@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
  * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
  * respectively.
  */
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
-				 hda_nid_t *ignore_nids)
+int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec,
+					   struct auto_pin_cfg *cfg,
+					   hda_nid_t *ignore_nids)
 {
 	hda_nid_t nid, nid_start;
-	int i, j, nodes;
-	short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
+	int nodes;
+	short seq, assoc_line_out, assoc_speaker;
+	short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
+	short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
 
 	memset(cfg, 0, sizeof(*cfg));
 
-	memset(sequences, 0, sizeof(sequences));
-	assoc_line_out = 0;
+	memset(sequences_line_out, 0, sizeof(sequences_line_out));
+	memset(sequences_speaker, 0, sizeof(sequences_speaker));
+	assoc_line_out = assoc_speaker = 0;
 
 	nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
 	for (nid = nid_start; nid < nodes + nid_start; nid++) {
 		unsigned int wid_caps = get_wcaps(codec, nid);
-		unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		unsigned int wid_type =
+			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 		unsigned int def_conf;
 		short assoc, loc;
 
@@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
 		if (ignore_nids && is_in_nid_list(nid, ignore_nids))
 			continue;
 
-		def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+		def_conf = snd_hda_codec_read(codec, nid, 0,
+					      AC_VERB_GET_CONFIG_DEFAULT, 0);
 		if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
 			continue;
 		loc = get_defcfg_location(def_conf);
@@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
 		case AC_JACK_LINE_OUT:
 			seq = get_defcfg_sequence(def_conf);
 			assoc = get_defcfg_association(def_conf);
-			if (! assoc)
+			if (!assoc)
 				continue;
-			if (! assoc_line_out)
+			if (!assoc_line_out)
 				assoc_line_out = assoc;
 			else if (assoc_line_out != assoc)
 				continue;
 			if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
 				continue;
 			cfg->line_out_pins[cfg->line_outs] = nid;
-			sequences[cfg->line_outs] = seq;
+			sequences_line_out[cfg->line_outs] = seq;
 			cfg->line_outs++;
 			break;
 		case AC_JACK_SPEAKER:
+			seq = get_defcfg_sequence(def_conf);
+			assoc = get_defcfg_association(def_conf);
+			if (! assoc)
+				continue;
+			if (! assoc_speaker)
+				assoc_speaker = assoc;
+			else if (assoc_speaker != assoc)
+				continue;
 			if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
 				continue;
 			cfg->speaker_pins[cfg->speaker_outs] = nid;
+			sequences_speaker[cfg->speaker_outs] = seq;
 			cfg->speaker_outs++;
 			break;
 		case AC_JACK_HP_OUT:
@@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
 	}
 
 	/* sort by sequence */
-	for (i = 0; i < cfg->line_outs; i++)
-		for (j = i + 1; j < cfg->line_outs; j++)
-			if (sequences[i] > sequences[j]) {
-				seq = sequences[i];
-				sequences[i] = sequences[j];
-				sequences[j] = seq;
-				nid = cfg->line_out_pins[i];
-				cfg->line_out_pins[i] = cfg->line_out_pins[j];
-				cfg->line_out_pins[j] = nid;
-			}
+	sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
+			      cfg->line_outs);
+	sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
+			      cfg->speaker_outs);
+	
+	/*
+	 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
+	 * as a primary output
+	 */
+	if (!cfg->line_outs) {
+		if (cfg->speaker_outs) {
+			cfg->line_outs = cfg->speaker_outs;
+			memcpy(cfg->line_out_pins, cfg->speaker_pins,
+			       sizeof(cfg->speaker_pins));
+			cfg->speaker_outs = 0;
+			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
+			cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
+		} else if (cfg->hp_outs) {
+			cfg->line_outs = cfg->hp_outs;
+			memcpy(cfg->line_out_pins, cfg->hp_pins,
+			       sizeof(cfg->hp_pins));
+			cfg->hp_outs = 0;
+			memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+			cfg->line_out_type = AUTO_PIN_HP_OUT;
+		}
+	}
 
 	/* Reorder the surround channels
 	 * ALSA sequence is front/surr/clfe/side
 	 * HDA sequence is:
 	 *    4-ch: front/surr  =>  OK as it is
 	 *    6-ch: front/clfe/surr
-	 *    8-ch: front/clfe/side/surr
+	 *    8-ch: front/clfe/rear/side|fc
 	 */
 	switch (cfg->line_outs) {
 	case 3:
-		nid = cfg->line_out_pins[1];
-		cfg->line_out_pins[1] = cfg->line_out_pins[2];
-		cfg->line_out_pins[2] = nid;
-		break;
 	case 4:
 		nid = cfg->line_out_pins[1];
-		cfg->line_out_pins[1] = cfg->line_out_pins[3];
-		cfg->line_out_pins[3] = cfg->line_out_pins[2];
+		cfg->line_out_pins[1] = cfg->line_out_pins[2];
 		cfg->line_out_pins[2] = nid;
 		break;
 	}
@@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
 		   cfg->input_pins[AUTO_PIN_CD],
 		   cfg->input_pins[AUTO_PIN_AUX]);
 
-	/*
-	 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
-	 * as a primary output
-	 */
-	if (! cfg->line_outs) {
-		if (cfg->speaker_outs) {
-			cfg->line_outs = cfg->speaker_outs;
-			memcpy(cfg->line_out_pins, cfg->speaker_pins,
-			       sizeof(cfg->speaker_pins));
-			cfg->speaker_outs = 0;
-			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
-		} else if (cfg->hp_outs) {
-			cfg->line_outs = cfg->hp_outs;
-			memcpy(cfg->line_out_pins, cfg->hp_pins,
-			       sizeof(cfg->hp_pins));
-			cfg->hp_outs = 0;
-			memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
-		}
-	}
-
 	return 0;
 }
 
@@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
  */
 int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
 {
-	struct list_head *p;
+	struct hda_codec *codec;
 
 	/* FIXME: should handle power widget capabilities */
-	list_for_each(p, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry(codec, &bus->codec_list, list) {
 		if (codec->patch_ops.suspend)
 			codec->patch_ops.suspend(codec, state);
 		hda_set_power_state(codec,
@@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_suspend);
-
 /**
  * snd_hda_resume - resume the codecs
  * @bus: the HDA bus
@@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend);
  */
 int snd_hda_resume(struct hda_bus *bus)
 {
-	struct list_head *p;
+	struct hda_codec *codec;
 
-	list_for_each(p, &bus->codec_list) {
-		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+	list_for_each_entry(codec, &bus->codec_list, list) {
 		hda_set_power_state(codec,
 				    codec->afg ? codec->afg : codec->mfg,
 				    AC_PWRST_D0);
@@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus)
 	return 0;
 }
 
-EXPORT_SYMBOL(snd_hda_resume);
-
 /**
  * snd_hda_resume_ctls - resume controls in the new control list
  * @codec: the HDA codec
@@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 	struct snd_ctl_elem_value *val;
 
 	val = kmalloc(sizeof(*val), GFP_KERNEL);
-	if (! val)
+	if (!val)
 		return -ENOMEM;
 	codec->in_resume = 1;
 	for (; knew->name; knew++) {
@@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec)
 	return snd_hda_resume_ctls(codec, dig_in_ctls);
 }
 #endif
-
-/*
- *  INIT part
- */
-
-static int __init alsa_hda_init(void)
-{
-	return 0;
-}
-
-static void __exit alsa_hda_exit(void)
-{
-}
-
-module_init(alsa_hda_init)
-module_exit(alsa_hda_exit)

+ 1 - 1
sound/pci/hda/hda_codec.h

@@ -233,7 +233,7 @@ enum {
  */
 
 /* Amp gain/mute */
-#define AC_AMP_MUTE			(1<<8)
+#define AC_AMP_MUTE			(1<<7)
 #define AC_AMP_GAIN			(0x7f)
 #define AC_AMP_GET_INDEX		(0xf<<0)
 

+ 1 - 1
sound/pci/hda/hda_generic.c

@@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
 			return -ENOMEM;
 		}
 	}
-	memcpy(node->conn_list, conn_list, nconns);
+	memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
 	node->nconns = nconns;
 	node->wid_caps = get_wcaps(codec, nid);
 	node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;

+ 25 - 6
sound/pci/hda/hda_intel.c

@@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
 			 "{ATI, SB600},"
 			 "{ATI, RS600},"
 			 "{ATI, RS690},"
+			 "{ATI, RS780},"
+			 "{ATI, R600},"
 			 "{VIA, VT8251},"
 			 "{VIA, VT8237A},"
 			 "{SiS, SIS966},"
@@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define RIRB_INT_MASK		0x05
 
 /* STATESTS int mask: SD2,SD1,SD0 */
+#define AZX_MAX_CODECS		3
 #define STATESTS_INT_MASK	0x07
 
 /* SD_CTL bits */
@@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = {
 static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
 	struct hda_bus_template bus_temp;
-	int c, codecs, err;
+	int c, codecs, audio_codecs, err;
 
 	memset(&bus_temp, 0, sizeof(bus_temp));
 	bus_temp.private_data = chip;
@@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
 	if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0)
 		return err;
 
-	codecs = 0;
-	for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) {
+	codecs = audio_codecs = 0;
+	for (c = 0; c < AZX_MAX_CODECS; c++) {
 		if ((chip->codec_mask & (1 << c)) & probe_mask) {
-			err = snd_hda_codec_new(chip->bus, c, NULL);
+			struct hda_codec *codec;
+			err = snd_hda_codec_new(chip->bus, c, &codec);
 			if (err < 0)
 				continue;
 			codecs++;
+			if (codec->afg)
+				audio_codecs++;
 		}
 	}
-	if (! codecs) {
+	if (!audio_codecs) {
+		/* probe additional slots if no codec is found */
+		for (; c < azx_max_codecs[chip->driver_type]; c++) {
+			if ((chip->codec_mask & (1 << c)) & probe_mask) {
+				err = snd_hda_codec_new(chip->bus, c, NULL);
+				if (err < 0)
+					continue;
+				codecs++;
+			}
+		}
+	}
+	if (!codecs) {
 		snd_printk(KERN_ERR SFX "no codecs initialized\n");
 		return -ENXIO;
 	}
@@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device)
 /*
  * white/black-listing for position_fix
  */
-static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
+static struct snd_pci_quirk position_fix_list[] __devinitdata = {
 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
 	{}
 };
@@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = {
 	{ 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */
 	{ 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */
 	{ 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */
+	{ 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */
+	{ 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */
 	{ 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 */

+ 12 - 0
sound/pci/hda/hda_local.h

@@ -148,6 +148,11 @@ struct hda_multi_out {
 
 int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
 int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
+int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
+				  struct hda_multi_out *mout,
+				  unsigned int stream_tag,
+				  unsigned int format,
+				  struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
 				  struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
@@ -217,6 +222,12 @@ enum {
 	AUTO_PIN_LAST
 };
 
+enum {
+	AUTO_PIN_LINE_OUT,
+	AUTO_PIN_SPEAKER_OUT,
+	AUTO_PIN_HP_OUT
+};
+
 extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
 
 struct auto_pin_cfg {
@@ -225,6 +236,7 @@ struct auto_pin_cfg {
 	int speaker_outs;
 	hda_nid_t speaker_pins[5];
 	int hp_outs;
+	int line_out_type;	/* AUTO_PIN_XXX_OUT */
 	hda_nid_t hp_pins[5];
 	hda_nid_t input_pins[AUTO_PIN_LAST];
 	hda_nid_t dig_out_pin;

+ 48 - 37
sound/pci/hda/patch_analog.c

@@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					   struct hda_codec *codec,
+					   unsigned int stream_tag,
+					   unsigned int format,
+					   struct snd_pcm_substream *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+					     format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = {
 	.nid = 0, /* fill later */
 	.ops = {
 		.open = ad198x_dig_playback_pcm_open,
-		.close = ad198x_dig_playback_pcm_close
+		.close = ad198x_dig_playback_pcm_close,
+		.prepare = ad198x_dig_playback_pcm_prepare
 	},
 };
 
@@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = {
 	{ } /* end */
 };
 
-/* additional verbs for 3-stack model */
-static struct hda_verb ad1986a_3st_init_verbs[] = {
- 	/* Mic and line-in selectors */
-	{0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
-	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
- 	{ } /* end */
-};
-
 static struct hda_verb ad1986a_ch2_init[] = {
 	/* Surround out -> Line In */
-	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-	{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+ 	/* Line-in selectors */
+	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
 	/* CLFE -> Mic in */
-	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-	{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	/* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
+	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
 	{ } /* end */
 };
 
 static struct hda_verb ad1986a_ch4_init[] = {
 	/* Surround out -> Surround */
-	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
 	/* CLFE -> Mic in */
-	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-	{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
 	{ } /* end */
 };
 
 static struct hda_verb ad1986a_ch6_init[] = {
 	/* Surround out -> Surround out */
-	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	{ 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{ 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
 	/* CLFE -> CLFE */
-	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	{ 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{ 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
 	{ } /* end */
 };
 
@@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
+	SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
 	SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
@@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec)
 	case AD1986A_3STACK:
 		spec->num_mixers = 2;
 		spec->mixers[1] = ad1986a_3st_mixers;
-		spec->num_init_verbs = 3;
-		spec->init_verbs[1] = ad1986a_3st_init_verbs;
-		spec->init_verbs[2] = ad1986a_ch2_init;
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = ad1986a_ch2_init;
 		spec->channel_mode = ad1986a_modes;
 		spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
 		spec->need_dac_fix = 1;
@@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
 
 	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
 	if (sel > 0) {
-		sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
-		if (sel <= 3)
+		sel = snd_hda_codec_read(codec, 0x0b, 0,
+					 AC_VERB_GET_CONNECT_SEL, 0);
+		if (sel < 3)
 			sel++;
 		else
 			sel = 0;
@@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
 					    struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	unsigned int sel;
+	unsigned int val, sel;
 	int change;
 
+	val = ucontrol->value.enumerated.item[0];
 	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
-	if (! ucontrol->value.enumerated.item[0]) {
+	if (!val) {
 		change = sel != 0;
-		if (change)
-			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
+		if (change || codec->in_resume)
+			snd_hda_codec_write(codec, 0x02, 0,
+					    AC_VERB_SET_CONNECT_SEL, 0);
 	} else {
 		change = sel == 0;
-		if (change)
-			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
-		sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
-		change |= sel == ucontrol->value.enumerated.item[0];
-		if (change)
-			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
-					    ucontrol->value.enumerated.item[0] - 1);
+		if (change || codec->in_resume)
+			snd_hda_codec_write(codec, 0x02, 0,
+					    AC_VERB_SET_CONNECT_SEL, 1);
+		sel = snd_hda_codec_read(codec, 0x0b, 0,
+					 AC_VERB_GET_CONNECT_SEL, 0) + 1;
+		change |= sel != val;
+		if (change || codec->in_resume)
+			snd_hda_codec_write(codec, 0x0b, 0,
+					    AC_VERB_SET_CONNECT_SEL, val - 1);
 	}
 	return change;
 }

+ 15 - 2
sound/pci/hda/patch_atihdmi.c

@@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					    struct hda_codec *codec,
+					    unsigned int stream_tag,
+					    unsigned int format,
+					    struct snd_pcm_substream *substream)
+{
+	struct atihdmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+					     format, substream);
+}
+
 static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
 	.substreams = 1,
 	.channels_min = 2,
@@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = {
 	.nid = 0x2, /* NID to query formats and rates and setup streams */
 	.ops = {
 		.open = atihdmi_dig_playback_pcm_open,
-		.close = atihdmi_dig_playback_pcm_close
+		.close = atihdmi_dig_playback_pcm_close,
+		.prepare = atihdmi_dig_playback_pcm_prepare
 	},
 };
 
@@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec)
  */
 struct hda_codec_preset snd_hda_preset_atihdmi[] = {
 	{ .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi },
-	{ .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi },
+	{ .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi },
+	{ .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi },
 	{} /* terminator */
 };

+ 13 - 1
sound/pci/hda/patch_cmedia.c

@@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					    struct hda_codec *codec,
+					    unsigned int stream_tag,
+					    unsigned int format,
+					    struct snd_pcm_substream *substream)
+{
+	struct cmi_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
+					     format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = {
 	/* NID is set in cmi9880_build_pcms */
 	.ops = {
 		.open = cmi9880_dig_playback_pcm_open,
-		.close = cmi9880_dig_playback_pcm_close
+		.close = cmi9880_dig_playback_pcm_close,
+		.prepare = cmi9880_dig_playback_pcm_prepare
 	},
 };
 

+ 118 - 192
sound/pci/hda/patch_conexant.c

@@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 unsigned int stream_tag,
+					 unsigned int format,
+					 struct snd_pcm_substream *substream)
+{
+	struct conexant_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+					     stream_tag,
+					     format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = {
 	.nid = 0, /* fill later */
 	.ops = {
 		.open = conexant_dig_playback_pcm_open,
-		.close = conexant_dig_playback_pcm_close
+		.close = conexant_dig_playback_pcm_close,
+		.prepare = conexant_dig_playback_pcm_prepare
 	},
 };
 
@@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
 	  .put = conexant_ch_mode_put, \
 	  .private_value = nid | (dir<<16) }
 
-static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_info *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}                                
-
-static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int val = snd_hda_codec_read(codec, nid, 0,
-					      AC_VERB_GET_GPIO_DATA, 0x00);
-
-	*valp = (val & mask) != 0;
-	return 0;
-}
-
-static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
-						    AC_VERB_GET_GPIO_DATA,
-						    0x00);
-	unsigned int old_data = gpio_data;
-
-	/* Set/unset the masked GPIO bit(s) as needed */
-	if (val == 0)
-		gpio_data &= ~mask;
-	else
-		gpio_data |= mask;
-	if (gpio_data == old_data && !codec->in_resume)
-		return 0;
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
-	return 1;
-}
-
-#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .info = cxt_gpio_data_info, \
-	  .get = cxt_gpio_data_get, \
-	  .put = cxt_gpio_data_put, \
-	  .private_value = nid | (mask<<16) }
-#if 0
-static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_info *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}                                
-
-static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int val = snd_hda_codec_read(codec, nid, 0,
-					      AC_VERB_GET_DIGI_CONVERT, 0x00);
-
-	*valp = (val & mask) != 0;
-	return 0;
-}
-
-static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-						    AC_VERB_GET_DIGI_CONVERT,
-						    0x00);
-	unsigned int old_data = ctrl_data;
-
-	/* Set/unset the masked control bit(s) as needed */
-	if (val == 0)
-		ctrl_data &= ~mask;
-	else
-		ctrl_data |= mask;
-	if (ctrl_data == old_data && !codec->in_resume)
-		return 0;
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-			    ctrl_data);
-	return 1;
-}
-
-#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .info = cxt_spdif_ctrl_info, \
-	  .get = cxt_spdif_ctrl_get, \
-	  .put = cxt_spdif_ctrl_put, \
-	  .private_value = nid | (mask<<16) }
-#endif
 #endif /* CONFIG_SND_DEBUG */
 
 /* Conexant 5045 specific */
@@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
 	snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
+
 	bits = spec->cur_eapd ? 0 : 0x80;
 	snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
@@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
 	return change;
 }
 
+/* toggle input of built-in and mic jack appropriately */
+static void cxt5045_hp_automic(struct hda_codec *codec)
+{
+	static struct hda_verb mic_jack_on[] = {
+		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	static struct hda_verb mic_jack_off[] = {
+		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+		{}
+	};
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x12, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	if (present)
+		snd_hda_sequence_write(codec, mic_jack_on);
+	else
+		snd_hda_sequence_write(codec, mic_jack_off);
+}
+
 
 /* mute internal speaker if HP is plugged */
 static void cxt5045_hp_automute(struct hda_codec *codec)
@@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
 	spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 
-	bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
+	bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; 
 	snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
 }
@@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
 	case CONEXANT_HP_EVENT:
 		cxt5045_hp_automute(codec);
 		break;
+	case CONEXANT_MIC_EVENT:
+		cxt5045_hp_automic(codec);
+		break;
+
 	}
 }
 
@@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
 		.get = conexant_mux_enum_get,
 		.put = conexant_mux_enum_put
 	},
-	HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT),
+	HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Volume",
@@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
 static struct hda_verb cxt5045_init_verbs[] = {
 	/* Line in, Mic */
 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 	/* HP, Amp  */
 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	{0x17, AC_VERB_SET_CONNECT_SEL,0x01},
@@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = {
 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE,
 	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04},
 	/* Record selector: Int mic */
-	{0x1a, AC_VERB_SET_CONNECT_SEL,0x0},
+	{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
 	/* SPDIF route: PCM */
 	{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
-	/* pin sensing on HP and Mic jacks */
-	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
 	/* EAPD */
 	{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
 	{ } /* end */
 };
 
+
+static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
+	/* pin sensing on HP jack */
+	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
+	{ } /* end */
+};
+
+static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
+	/* pin sensing on HP jack */
+	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
+	{ } /* end */
+};
+
 #ifdef CONFIG_SND_DEBUG
 /* Test configuration for debugging, modelled after the ALC260 test
  * configuration.
@@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
 	/* Output controls */
 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
 	
 	/* Modes for retasking pin widgets */
 	CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
@@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
 	CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
 
 	/* Loopback mixer controls */
-	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT),
-	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT),
-
-	HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
+	HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
+	HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Input Source",
@@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = {
 		.get = conexant_mux_enum_get,
 		.put = conexant_mux_enum_put,
 	},
-
 	{ } /* end */
 };
 
 static struct hda_verb cxt5045_test_init_verbs[] = {
+	/* Set connections */
+	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
+	{ 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
+	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
 	/* Enable retasking pins as output, initially without power amp */
 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 
 	/* Disable digital (SPDIF) pins initially, but users can enable
 	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
@@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = {
 	 * pin)
 	 */
 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
 
 	/* Mute all inputs to mixer widget (even unconnected ones) */
 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
@@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec)
 
 
 enum {
-	CXT5045_LAPTOP,	/* Laptops w/ EAPD support */
+	CXT5045_LAPTOP,	 /* Laptops w/ EAPD support */
+	CXT5045_FUJITSU, /* Laptops w/ EAPD support */ 
 #ifdef CONFIG_SND_DEBUG
 	CXT5045_TEST,
 #endif
@@ -836,6 +778,7 @@ enum {
 
 static const char *cxt5045_models[CXT5045_MODELS] = {
 	[CXT5045_LAPTOP]	= "laptop",
+	[CXT5045_FUJITSU]	= "fujitsu",
 #ifdef CONFIG_SND_DEBUG
 	[CXT5045_TEST]		= "test",
 #endif
@@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = {
 static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP),
 	SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP),
-	SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP),
+	SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP),
+	SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP),
+	SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP),
+	SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU),
+	SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP),
 	{}
 };
 
@@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec)
 
 
 	codec->patch_ops = conexant_patch_ops;
-	codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
 
 	board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
 						  cxt5045_models,
 						  cxt5045_cfg_tbl);
 	switch (board_config) {
 	case CXT5045_LAPTOP:
+		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
+		spec->input_mux = &cxt5045_capture_source;
+		spec->num_init_verbs = 2;
+		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
+		spec->mixers[0] = cxt5045_mixers;
+		codec->patch_ops.init = cxt5045_init;
+		break;
+	case CXT5045_FUJITSU:
 		spec->input_mux = &cxt5045_capture_source;
 		spec->num_init_verbs = 2;
-		spec->init_verbs[1] = cxt5045_init_verbs;
+		spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
 		spec->mixers[0] = cxt5045_mixers;
 		codec->patch_ops.init = cxt5045_init;
 		break;
@@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = {
 };
 
 static struct hda_input_mux cxt5047_capture_source = {
-	.num_items = 2,
+	.num_items = 1,
 	.items = {
-		{ "ExtMic", 0x0 },
-		{ "IntMic", 0x1 },
+		{ "Mic", 0x2 },
 	}
 };
 
@@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec)
 	};
 	unsigned int present;
 
-	present = snd_hda_codec_read(codec, 0x08, 0,
+	present = snd_hda_codec_read(codec, 0x15, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 	if (present)
 		snd_hda_sequence_write(codec, mic_jack_on);
@@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
 }
 
 static struct snd_kcontrol_new cxt5047_mixers[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
-		.info = conexant_mux_enum_info,
-		.get = conexant_mux_enum_get,
-		.put = conexant_mux_enum_put
-	},
 	HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
 	HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
 	HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
 	HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
 	HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
-		.info = snd_hda_mixer_amp_volume_info,
-		.get = snd_hda_mixer_amp_volume_get,
-		.put = cxt5047_hp_master_vol_put,
-		.private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT),
-	},
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = cxt_eapd_info,
-		.get = cxt_eapd_get,
-		.put = cxt5047_hp_master_sw_put,
-		.private_value = 0x13,
-	},
+	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT),
 
 	{}
 };
@@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = {
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
-	/* HP, Amp, Speaker  */
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{0x1A, AC_VERB_SET_CONNECT_SEL,0x00},
-	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
-	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
-	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
+	/* HP, Speaker  */
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+	{0x13, AC_VERB_SET_CONNECT_SEL,0x1},
 	{0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
-	/* Record selector: Front mic */
+	/* Record selector: Mic */
 	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
+	{0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
+	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
+	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
 	/* SPDIF route: PCM */
 	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
 	/* Enable unsolicited events */
@@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = {
 	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
 	/* Speaker routing */
 	{0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
-	/* Change default to ExtMic for recording */
-	{0x1a, AC_VERB_SET_CONNECT_SEL,0x2},
 	{}
 };
 
@@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = {
 	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
 	/* Record selector: Ext Mic */
 	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
-	{0x1a, AC_VERB_SET_CONNECT_SEL,0x02},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
 	/* Speaker routing */
@@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = {
 		.get = conexant_mux_enum_get,
 		.put = conexant_mux_enum_put,
 	},
-       /* Controls for GPIO pins, assuming they exist and are configured
-	* as outputs
-	*/
-	CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
-	CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
-	CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
-	CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
 	{ } /* end */
 };
 

+ 1909 - 362
sound/pci/hda/patch_realtek.c

@@ -74,6 +74,8 @@ enum {
 	ALC260_HP_3013,
 	ALC260_FUJITSU_S702X,
 	ALC260_ACER,
+	ALC260_WILL,
+	ALC260_REPLACER_672V,
 #ifdef CONFIG_SND_DEBUG
 	ALC260_TEST,
 #endif
@@ -115,15 +117,28 @@ enum {
 	ALC861VD_3ST,
 	ALC861VD_3ST_DIG,
 	ALC861VD_6ST_DIG,
+	ALC861VD_LENOVO,
 	ALC861VD_AUTO,
 	ALC861VD_MODEL_LAST,
 };
 
+/* ALC662 models */
+enum {
+	ALC662_3ST_2ch_DIG,
+	ALC662_3ST_6ch_DIG,
+	ALC662_3ST_6ch,
+	ALC662_5ST_DIG,
+	ALC662_LENOVO_101E,
+	ALC662_AUTO,
+	ALC662_MODEL_LAST,
+};
+
 /* ALC882 models */
 enum {
 	ALC882_3ST_DIG,
 	ALC882_6ST_DIG,
 	ALC882_ARIMA,
+	ALC882_W2JC,
 	ALC882_AUTO,
 	ALC885_MACPRO,
 	ALC882_MODEL_LAST,
@@ -141,6 +156,7 @@ enum {
 	ALC883_ACER,
 	ALC883_MEDION,
 	ALC883_LAPTOP_EAPD,
+	ALC883_LENOVO_101E_2ch,
 	ALC883_AUTO,
 	ALC883_MODEL_LAST,
 };
@@ -163,7 +179,7 @@ struct alc_spec {
 	struct hda_pcm_stream *stream_analog_playback;
 	struct hda_pcm_stream *stream_analog_capture;
 
-	char *stream_name_digital;	/* digital PCM stream */ 
+	char *stream_name_digital;	/* digital PCM stream */
 	struct hda_pcm_stream *stream_digital_playback;
 	struct hda_pcm_stream *stream_digital_capture;
 
@@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
 						 AC_VERB_GET_PIN_WIDGET_CONTROL,
 						 0x00);
 
-	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 
+	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
 		val = alc_pin_mode_min(dir);
 
 	change = pinctl != alc_pin_mode_values[val];
@@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = 1;
 	return 0;
-}                                
+}
+
 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
 			     struct snd_ctl_elem_value *ucontrol)
 {
@@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = 1;
 	return 0;
-}                                
+}
+
 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
 			      struct snd_ctl_elem_value *ucontrol)
 {
@@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec,
 	spec->multiout.hp_nid = preset->hp_nid;
 	
 	spec->num_mux_defs = preset->num_mux_defs;
-	if (! spec->num_mux_defs)
+	if (!spec->num_mux_defs)
 		spec->num_mux_defs = 1;
 	spec->input_mux = preset->input_mux;
 
@@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec,
 	spec->init_hook = preset->init_hook;
 }
 
+/* Enable GPIO mask and set output */
+static struct hda_verb alc_gpio1_init_verbs[] = {
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+	{ }
+};
+
+static struct hda_verb alc_gpio2_init_verbs[] = {
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
+	{ }
+};
+
+static struct hda_verb alc_gpio3_init_verbs[] = {
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+	{ }
+};
+
+/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
+ *	31 ~ 16 :	Manufacture ID
+ *	15 ~ 8	:	SKU ID
+ *	7  ~ 0	:	Assembly ID
+ *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
+ */
+static void alc_subsystem_id(struct hda_codec *codec,
+			     unsigned int porta, unsigned int porte,
+			     unsigned int portd)
+{
+	unsigned int ass, tmp;
+
+	ass = codec->subsystem_id;
+	if (!(ass & 1))
+		return;
+
+	/* Override */
+	tmp = (ass & 0x38) >> 3;	/* external Amp control */
+	switch (tmp) {
+	case 1:
+		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
+		break;
+	case 3:
+		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
+		break;
+	case 7:
+		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
+		break;
+	case 5:
+		switch (codec->vendor_id) {
+		case 0x10ec0862:
+		case 0x10ec0660:
+		case 0x10ec0662:	
+		case 0x10ec0267:
+		case 0x10ec0268:
+			snd_hda_codec_write(codec, 0x14, 0,
+					    AC_VERB_SET_EAPD_BTLENABLE, 2);
+			snd_hda_codec_write(codec, 0x15, 0,
+					    AC_VERB_SET_EAPD_BTLENABLE, 2);
+			return;
+		}
+	case 6:
+		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
+			hda_nid_t port = 0;
+			tmp = (ass & 0x1800) >> 11;
+			switch (tmp) {
+			case 0: port = porta; break;
+			case 1: port = porte; break;
+			case 2: port = portd; break;
+			}
+			if (port)
+				snd_hda_codec_write(codec, port, 0,
+						    AC_VERB_SET_EAPD_BTLENABLE,
+						    2);
+		}
+		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
+				    (tmp == 5 ? 0x3040 : 0x3050));
+		break;
+	}
+}
+
 /*
  * ALC880 3-stack model
  *
@@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {
 static hda_nid_t alc880_6st_dac_nids[4] = {
 	/* front, rear, clfe, rear_surr */
 	0x02, 0x03, 0x04, 0x05
-};	
+};
 
 static struct hda_input_mux alc880_6stack_capture_source = {
 	.num_items = 4,
@@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = {
 };
 
 /* toggle speaker-output according to the hp-jack state */
-static void alc880_uniwill_automute(struct hda_codec *codec)
+static void alc880_uniwill_hp_automute(struct hda_codec *codec)
 {
  	unsigned int present;
+	unsigned char bits;
 
  	present = snd_hda_codec_read(codec, 0x14, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
 	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
+}
+
+/* auto-toggle front mic */
+static void alc880_uniwill_mic_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+	unsigned char bits;
 
 	present = snd_hda_codec_read(codec, 0x18, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-	snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
-			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+				 0x80, bits);
+}
+
+static void alc880_uniwill_automute(struct hda_codec *codec)
+{
+	alc880_uniwill_hp_automute(codec);
+	alc880_uniwill_mic_automute(codec);
 }
 
 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
 	/* Looks like the unsol event is incompatible with the standard
 	 * definition.  4bit tag is placed at 28 bit!
 	 */
-	if ((res >> 28) == ALC880_HP_EVENT ||
-	    (res >> 28) == ALC880_MIC_EVENT)
-		alc880_uniwill_automute(codec);
+	switch (res >> 28) {
+	case ALC880_HP_EVENT:
+		alc880_uniwill_hp_automute(codec);
+		break;
+	case ALC880_MIC_EVENT:
+		alc880_uniwill_mic_automute(codec);
+		break;
+	}
 }
 
 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
 {
  	unsigned int present;
+	unsigned char bits;
 
  	present = snd_hda_codec_read(codec, 0x14, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-
+	bits = present ? 0x80 : 0;
 	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 }
 
 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
 	 */
 	if ((res >> 28) == ALC880_HP_EVENT)
 		alc880_uniwill_p53_hp_automute(codec);
-	if ((res >> 28) == ALC880_DCVOL_EVENT) 
+	if ((res >> 28) == ALC880_DCVOL_EVENT)
 		alc880_uniwill_p53_dcvol_automute(codec);
 }
 
@@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {
 };
 
 /* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio1_init_verbs[] = {
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-
-	{ }
-};
-
-/* Enable GPIO mask and set output */
-static struct hda_verb alc880_gpio2_init_verbs[] = {
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
-
-	{ }
-};
+#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
+#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
 
 /* Clevo m520g init */
 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
@@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = {
 static void alc880_lg_automute(struct hda_codec *codec)
 {
 	unsigned int present;
+	unsigned char bits;
 
 	present = snd_hda_codec_read(codec, 0x1b, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
 	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 }
 
 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
 static void alc880_lg_lw_automute(struct hda_codec *codec)
 {
 	unsigned int present;
+	unsigned char bits;
 
 	present = snd_hda_codec_read(codec, 0x1b, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
 	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 }
 
 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 }
 
+static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					   struct hda_codec *codec,
+					   unsigned int stream_tag,
+					   unsigned int format,
+					   struct snd_pcm_substream *substream)
+{
+	struct alc_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+					     stream_tag, format, substream);
+}
+
 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 					 struct hda_codec *codec,
 					 struct snd_pcm_substream *substream)
@@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {
 	/* NID is set in alc_build_pcms */
 	.ops = {
 		.open = alc880_dig_playback_pcm_open,
-		.close = alc880_dig_playback_pcm_close
+		.close = alc880_dig_playback_pcm_close,
+		.prepare = alc880_dig_playback_pcm_prepare
 	},
 };
 
@@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	unsigned int i;
 
-	if (! spec)
+	if (!spec)
 		return;
 
 	if (spec->kctl_alloc) {
@@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
 static struct alc_config_preset alc880_presets[] = {
 	[ALC880_3ST] = {
 		.mixers = { alc880_three_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_3stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
 		.dac_nids = alc880_dac_nids,
 		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
@@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_3ST_DIG] = {
 		.mixers = { alc880_three_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_3stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
 		.dac_nids = alc880_dac_nids,
 		.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = {
 		.input_mux = &alc880_capture_source,
 	},
 	[ALC880_5ST] = {
-		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+		.mixers = { alc880_three_stack_mixer,
+			    alc880_five_stack_mixer},
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_5stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
 		.dac_nids = alc880_dac_nids,
 		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
@@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = {
 		.input_mux = &alc880_capture_source,
 	},
 	[ALC880_5ST_DIG] = {
-		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+		.mixers = { alc880_three_stack_mixer,
+			    alc880_five_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_5stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
 		.dac_nids = alc880_dac_nids,
 		.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_6ST] = {
 		.mixers = { alc880_six_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_6stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
 		.dac_nids = alc880_6st_dac_nids,
 		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
@@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_6ST_DIG] = {
 		.mixers = { alc880_six_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_6stack_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
 		.dac_nids = alc880_6st_dac_nids,
 		.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_W810] = {
 		.mixers = { alc880_w810_base_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_w810_init_verbs,
 				alc880_gpio2_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
 		.dac_nids = alc880_w810_dac_nids,
@@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_Z71V] = {
 		.mixers = { alc880_z71v_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_z71v_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
 		.dac_nids = alc880_z71v_dac_nids,
 		.dig_out_nid = ALC880_DIGOUT_NID,
@@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_F1734] = {
 		.mixers = { alc880_f1734_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_f1734_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
 		.dac_nids = alc880_f1734_dac_nids,
 		.hp_nid = 0x02,
@@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_ASUS] = {
 		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_asus_init_verbs,
 				alc880_gpio1_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 		.dac_nids = alc880_asus_dac_nids,
@@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_ASUS_DIG] = {
 		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_asus_init_verbs,
 				alc880_gpio1_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 		.dac_nids = alc880_asus_dac_nids,
@@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_ASUS_DIG2] = {
 		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_asus_init_verbs,
 				alc880_gpio2_init_verbs }, /* use GPIO2 */
 		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 		.dac_nids = alc880_asus_dac_nids,
@@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = {
 	},
 	[ALC880_ASUS_W1V] = {
 		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
-		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_asus_init_verbs,
 				alc880_gpio1_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 		.dac_nids = alc880_asus_dac_nids,
@@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = {
 		.init_hook = alc880_uniwill_p53_hp_automute,
 	},
 	[ALC880_FUJITSU] = {
-		.mixers = { alc880_fujitsu_mixer, 
+		.mixers = { alc880_fujitsu_mixer,
 			    alc880_pcbeep_mixer, },
 		.init_verbs = { alc880_volume_init_verbs,
 				alc880_uniwill_p53_init_verbs,
@@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = {
 		.mixers = { alc880_lg_lw_mixer },
 		.init_verbs = { alc880_volume_init_verbs,
 				alc880_lg_lw_init_verbs },
-		.num_dacs = 1, 
+		.num_dacs = 1,
 		.dac_nids = alc880_dac_nids,
 		.dig_out_nid = ALC880_DIGOUT_NID,
 		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
@@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = {
 };
 
 /* add dynamic controls */
-static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
+static int add_control(struct alc_spec *spec, int type, const char *name,
+		       unsigned long val)
 {
 	struct snd_kcontrol_new *knew;
 
 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
 
-		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
-		if (! knew)
+		/* array + terminator */
+		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
+		if (!knew)
 			return -ENOMEM;
 		if (spec->kctl_alloc) {
-			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+			memcpy(knew, spec->kctl_alloc,
+			       sizeof(*knew) * spec->num_kctl_alloc);
 			kfree(spec->kctl_alloc);
 		}
 		spec->kctl_alloc = knew;
@@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
 	knew = &spec->kctl_alloc[spec->num_kctl_used];
 	*knew = alc880_control_templates[type];
 	knew->name = kstrdup(name, GFP_KERNEL);
-	if (! knew->name)
+	if (!knew->name)
 		return -ENOMEM;
 	knew->private_value = val;
 	spec->num_kctl_used++;
@@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign
 #define ALC880_PIN_CD_NID		0x1c
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
+				     const struct auto_pin_cfg *cfg)
 {
 	hda_nid_t nid;
 	int assigned[4];
@@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi
 			continue;
 		/* search for an empty channel */
 		for (j = 0; j < cfg->line_outs; j++) {
-			if (! assigned[j]) {
-				spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
+			if (!assigned[j]) {
+				spec->multiout.dac_nids[i] =
+					alc880_idx_to_dac(j);
 				assigned[j] = 1;
 				break;
 			}
@@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
 					     const struct auto_pin_cfg *cfg)
 {
 	char name[32];
-	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	static const char *chname[4] = {
+		"Front", "Surround", NULL /*CLFE*/, "Side"
+	};
 	hda_nid_t nid;
 	int i, err;
 
 	for (i = 0; i < cfg->line_outs; i++) {
-		if (! spec->multiout.dac_nids[i])
+		if (!spec->multiout.dac_nids[i])
 			continue;
 		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
 		if (i == 2) {
 			/* Center/LFE */
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
-					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "Center Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
-					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "LFE Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "Center Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "LFE Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
 		} else {
 			sprintf(name, "%s Playback Volume", chname[i]);
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 			sprintf(name, "%s Playback Switch", chname[i]);
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-					       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
 		}
 	}
@@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
 	int err;
 	char name[32];
 
-	if (! pin)
+	if (!pin)
 		return 0;
 
 	if (alc880_is_fixed_pin(pin)) {
 		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
 		/* specify the DAC as the extra output */
-		if (! spec->multiout.hp_nid)
+		if (!spec->multiout.hp_nid)
 			spec->multiout.hp_nid = nid;
 		else
 			spec->multiout.extra_out_nid[0] = nid;
 		/* control HP volume/switch on the output mixer amp */
 		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
 		sprintf(name, "%s Playback Volume", pfx);
-		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 		sprintf(name, "%s Playback Switch", pfx);
-		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+		if (err < 0)
 			return err;
 	} else if (alc880_is_multi_pin(pin)) {
 		/* set manual connection */
 		/* we have only a switch on HP-out PIN */
 		sprintf(name, "%s Playback Switch", pfx);
-		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 	}
 	return 0;
 }
 
 /* create input playback/capture controls for the given pin */
-static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
+static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
+			    const char *ctlname,
 			    int idx, hda_nid_t mix_nid)
 {
 	char name[32];
 	int err;
 
 	sprintf(name, "%s Playback Volume", ctlname);
-	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+	if (err < 0)
 		return err;
 	sprintf(name, "%s Playback Switch", ctlname);
-	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
+	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
+	if (err < 0)
 		return err;
 	return 0;
 }
@@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
 					       idx, 0x0b);
 			if (err < 0)
 				return err;
-			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
-			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
+			imux->items[imux->num_items].label =
+				auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].index =
+				alc880_input_pin_idx(cfg->input_pins[i]);
 			imux->num_items++;
 		}
 	}
@@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
 					      int dac_idx)
 {
 	/* set as output */
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    AMP_OUT_UNMUTE);
 	/* need the manual connection? */
 	if (alc880_is_multi_pin(nid)) {
 		struct alc_spec *spec = codec->spec;
@@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
 	}
 }
 
+static int get_pin_type(int line_out_type)
+{
+	if (line_out_type == AUTO_PIN_HP_OUT)
+		return PIN_HP;
+	else
+		return PIN_OUT;
+}
+
 static void alc880_auto_init_multi_out(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	int i;
-
+	
+	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 	for (i = 0; i < spec->autocfg.line_outs; i++) {
 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
-		alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
+		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
 	}
 }
 
@@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = spec->autocfg.input_pins[i];
 		if (alc880_is_input_pin(nid)) {
-			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ?
+					    PIN_VREF80 : PIN_IN);
 			if (nid != ALC880_PIN_CD_NID)
-				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				snd_hda_codec_write(codec, nid, 0,
+						    AC_VERB_SET_AMP_GAIN_MUTE,
 						    AMP_OUT_MUTE);
 		}
 	}
 }
 
 /* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
 static int alc880_parse_auto_config(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	int err;
 	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-						alc880_ignore)) < 0)
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc880_ignore);
+	if (err < 0)
 		return err;
-	if (! spec->autocfg.line_outs)
+	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-	    (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-	    (err = alc880_auto_create_extra_out(spec,
-						spec->autocfg.speaker_pins[0],
-						"Speaker")) < 0 ||
-	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
-						"Headphone")) < 0 ||
-	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc880_auto_create_extra_out(spec,
+					   spec->autocfg.speaker_pins[0],
+					   "Speaker");
+	if (err < 0)
+		return err;
+	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+					   "Headphone");
+	if (err < 0)
+		return err;
+	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using 3-stack mode...\n");
@@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec)
 	spec->stream_digital_playback = &alc880_pcm_digital_playback;
 	spec->stream_digital_capture = &alc880_pcm_digital_capture;
 
-	if (! spec->adc_nids && spec->input_mux) {
+	if (!spec->adc_nids && spec->input_mux) {
 		/* check whether NID 0x07 is valid */
 		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
-		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		/* get type */
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 		if (wcap != AC_WID_AUD_IN) {
 			spec->adc_nids = alc880_adc_nids_alt;
 			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
-			spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
+			spec->mixers[spec->num_mixers] =
+				alc880_capture_alt_mixer;
 			spec->num_mixers++;
 		} else {
 			spec->adc_nids = alc880_adc_nids;
@@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 	{ } /* end */
-};	
+};
 
 static struct snd_kcontrol_new alc260_input_mixer[] = {
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
@@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {
 	{ } /* end */
 };
 
+/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
+ * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
+ */
+static struct snd_kcontrol_new alc260_will_mixer[] = {
+	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
+	{ } /* end */
+};
+
+/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
+ * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
+ */
+static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
+	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
+	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
+	{ } /* end */
+};
+
 /* capture mixer elements */
 static struct snd_kcontrol_new alc260_capture_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
@@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = {
 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	/* unmute LINE-2 out pin */
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+	 * Line In 2 = 0x03
+	 */
 	/* mute CD */
 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 	/* mute Line In */
@@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = {
 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 	/* mute pin widget amp left and right (no gain on this amp) */
 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+	 * Line In 2 = 0x03
+	 */
 	/* unmute CD */
 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
 	/* unmute Line In */
@@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {
 	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 	/* mute pin widget amp left and right (no gain on this amp) */
 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
+	 * Line In 2 = 0x03
+	 */
 	/* unmute CD */
 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
 	/* unmute Line In */
@@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = {
 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 
-	/* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
+	/* Unmute Line-out pin widget amp left and right
+	 * (no equiv mixer ctrl)
+	 */
 	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = {
 	{ }
 };
 
+static struct hda_verb alc260_will_verbs[] = {
+	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
+	{}
+};
+
+static struct hda_verb alc260_replacer_672v_verbs[] = {
+	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
+	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
+	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
+
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
+
+	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+	{}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc260_replacer_672v_automute(struct hda_codec *codec)
+{
+        unsigned int present;
+
+	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
+        present = snd_hda_codec_read(codec, 0x0f, 0,
+                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	if (present) {
+		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
+		snd_hda_codec_write(codec, 0x0f, 0,
+				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
+	} else {
+		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
+		snd_hda_codec_write(codec, 0x0f, 0,
+				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+	}
+}
+
+static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
+                                       unsigned int res)
+{
+        if ((res >> 26) == ALC880_HP_EVENT)
+                alc260_replacer_672v_automute(codec);
+}
+
 /* Test configuration for debugging, modelled after the ALC880 test
  * configuration.
  */
@@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
 		return 0; /* N/A */
 	
 	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
-	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
+	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
+	if (err < 0)
 		return err;
 	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
-	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
+	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
+	if (err < 0)
 		return err;
 	return 1;
 }
@@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 		if (err < 0)
 			return err;
 	}
-	return 0;	
+	return 0;
 }
 
 /* create playback/capture controls for input pins */
@@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
 		if (cfg->input_pins[i] >= 0x12) {
 			idx = cfg->input_pins[i] - 0x12;
 			err = new_analog_input(spec, cfg->input_pins[i],
-					       auto_pin_cfg_labels[i], idx, 0x07);
+					       auto_pin_cfg_labels[i], idx,
+					       0x07);
 			if (err < 0)
 				return err;
-			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].label =
+				auto_pin_cfg_labels[i];
 			imux->items[imux->num_items].index = idx;
 			imux->num_items++;
 		}
-		if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
+		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
 			idx = cfg->input_pins[i] - 0x09;
 			err = new_analog_input(spec, cfg->input_pins[i],
-					       auto_pin_cfg_labels[i], idx, 0x07);
+					       auto_pin_cfg_labels[i], idx,
+					       0x07);
 			if (err < 0)
 				return err;
-			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].label =
+				auto_pin_cfg_labels[i];
 			imux->items[imux->num_items].index = idx;
 			imux->num_items++;
 		}
@@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
 					      int sel_idx)
 {
 	/* set as output */
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    AMP_OUT_UNMUTE);
 	/* need the manual connection? */
 	if (nid >= 0x12) {
 		int idx = nid - 0x12;
 		snd_hda_codec_write(codec, idx + 0x0b, 0,
 				    AC_VERB_SET_CONNECT_SEL, sel_idx);
-				    
 	}
 }
 
@@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	hda_nid_t nid;
 
-	nid = spec->autocfg.line_out_pins[0];	
-	if (nid)
-		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
+	nid = spec->autocfg.line_out_pins[0];
+	if (nid) {
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
+		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
+	}
 	
 	nid = spec->autocfg.speaker_pins[0];
 	if (nid)
@@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
 
 	nid = spec->autocfg.hp_pins[0];
 	if (nid)
-		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
-}	
+		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
+}
 
 #define ALC260_PIN_CD_NID		0x16
 static void alc260_auto_init_analog_input(struct hda_codec *codec)
@@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = spec->autocfg.input_pins[i];
 		if (nid >= 0x12) {
-			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ?
+					    PIN_VREF80 : PIN_IN);
 			if (nid != ALC260_PIN_CD_NID)
-				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				snd_hda_codec_write(codec, nid, 0,
+						    AC_VERB_SET_AMP_GAIN_MUTE,
 						    AMP_OUT_MUTE);
 		}
 	}
@@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = {
 	
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
 	int err;
 	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-						alc260_ignore)) < 0)
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc260_ignore);
+	if (err < 0)
 		return err;
-	if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
+	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
-	if (! spec->kctl_alloc)
+	if (!spec->kctl_alloc)
 		return 0; /* can't find valid BIOS pin config */
-	if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
 
 	spec->multiout.max_channels = 2;
@@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = {
 	[ALC260_HP_3013]	= "hp-3013",
 	[ALC260_FUJITSU_S702X]	= "fujitsu",
 	[ALC260_ACER]		= "acer",
+	[ALC260_WILL]		= "will",
+	[ALC260_REPLACER_672V]	= "replacer",
 #ifdef CONFIG_SND_DEBUG
 	[ALC260_TEST]		= "test",
 #endif
@@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
 	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
 	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
+	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
+	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
 	{}
 };
 
@@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = {
 		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
 		.input_mux = alc260_acer_capture_sources,
 	},
+	[ALC260_WILL] = {
+		.mixers = { alc260_will_mixer,
+			    alc260_capture_mixer },
+		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+		.adc_nids = alc260_adc_nids,
+		.dig_out_nid = ALC260_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_capture_source,
+	},
+	[ALC260_REPLACER_672V] = {
+		.mixers = { alc260_replacer_672v_mixer,
+			    alc260_capture_mixer },
+		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+		.adc_nids = alc260_adc_nids,
+		.dig_out_nid = ALC260_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_capture_source,
+		.unsol_event = alc260_replacer_672v_unsol_event,
+		.init_hook = alc260_replacer_672v_automute,
+	},
 #ifdef CONFIG_SND_DEBUG
 	[ALC260_TEST] = {
 		.mixers = { alc260_test_mixer,
@@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = {
 #define alc882_mux_enum_info alc_mux_enum_info
 #define alc882_mux_enum_get alc_mux_enum_get
 
-static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
@@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
 	idx = ucontrol->value.enumerated.item[0];
 	if (idx >= imux->num_items)
 		idx = imux->num_items - 1;
-	if (*cur_val == idx && ! codec->in_resume)
+	if (*cur_val == idx && !codec->in_resume)
 		return 0;
 	for (i = 0; i < imux->num_items; i++) {
 		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 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),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+	{ } /* end */
+};
+
 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = {
 	/* change to EAPD mode */
 	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
-	{ } 
+	{ }
 };
 
 /* Mac Pro test */
@@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
 
 	{ }
 };
+
 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
 {
 	unsigned int gpiostate, gpiomask, gpiodir;
@@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = {
 
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
 	[ALC882_3ST_DIG]	= "3stack-dig",
 	[ALC882_6ST_DIG]	= "6stack-dig",
 	[ALC882_ARIMA]		= "arima",
+	[ALC882_W2JC]		= "w2jc",
 	[ALC885_MACPRO]		= "macpro",
 	[ALC882_AUTO]		= "auto",
 };
@@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
 	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
 	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
+	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
 	{}
 };
 
@@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = {
 		.channel_mode = alc882_sixstack_modes,
 		.input_mux = &alc882_capture_source,
 	},
+	[ALC882_W2JC] = {
+		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
+		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
+				alc880_gpio1_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+		.channel_mode = alc880_threestack_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc882_capture_source,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+	},
 	[ALC885_MACPRO] = {
 		.mixers = { alc882_macpro_mixer },
 		.init_verbs = { alc882_macpro_init_verbs },
@@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
 {
 	/* set as output */
 	struct alc_spec *spec = codec->spec;
-	int idx; 
-	
+	int idx;
+
 	if (spec->multiout.dac_nids[dac_idx] == 0x25)
 		idx = 4;
 	else
 		idx = spec->multiout.dac_nids[dac_idx] - 2;
 
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    AMP_OUT_UNMUTE);
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
 
 }
@@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	int i;
 
+	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 	for (i = 0; i <= HDA_SIDE; i++) {
-		hda_nid_t nid = spec->autocfg.line_out_pins[i];	
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
 		if (nid)
-			alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
+							  i);
 	}
 }
 
@@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)
 
 	pin = spec->autocfg.hp_pins[0];
 	if (pin) /* connect to front */
-		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
+		/* use dac 0 */
+		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 }
 
 #define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
@@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec)
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = spec->autocfg.input_pins[i];
 		if (alc882_is_input_pin(nid)) {
-			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ?
+					    PIN_VREF80 : PIN_IN);
 			if (nid != ALC882_PIN_CD_NID)
-				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				snd_hda_codec_write(codec, nid, 0,
+						    AC_VERB_SET_AMP_GAIN_MUTE,
 						    AMP_OUT_MUTE);
 		}
 	}
@@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec)
 	spec->stream_digital_playback = &alc882_pcm_digital_playback;
 	spec->stream_digital_capture = &alc882_pcm_digital_capture;
 
-	if (! spec->adc_nids && spec->input_mux) {
+	if (!spec->adc_nids && spec->input_mux) {
 		/* check whether NID 0x07 is valid */
 		unsigned int wcap = get_wcaps(codec, 0x07);
-		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		/* get type */
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 		if (wcap != AC_WID_AUD_IN) {
 			spec->adc_nids = alc882_adc_nids_alt;
 			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
-			spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
+			spec->mixers[spec->num_mixers] =
+				alc882_capture_alt_mixer;
 			spec->num_mixers++;
 		} else {
 			spec->adc_nids = alc882_adc_nids;
@@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = {
 	/* ADC1-2 */
 	0x08, 0x09,
 };
+
 /* input MUX */
 /* FIXME: should be a matrix-type input source selection */
 
@@ -5045,7 +5432,16 @@ static struct hda_input_mux alc883_capture_source = {
 		{ "CD", 0x4 },
 	},
 };
-#define alc883_mux_enum_info alc_mux_enum_info
+
+static struct hda_input_mux alc883_lenovo_101e_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "Mic", 0x1 },
+		{ "Line", 0x2 },
+	},
+};
+
+#define alc883_mux_enum_info alc_mux_enum_info
 #define alc883_mux_enum_get alc_mux_enum_get
 
 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
@@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
 	idx = ucontrol->value.enumerated.item[0];
 	if (idx >= imux->num_items)
 		idx = imux->num_items - 1;
-	if (*cur_val == idx && ! codec->in_resume)
+	if (*cur_val == idx && !codec->in_resume)
 		return 0;
 	for (i = 0; i < imux->num_items; i++) {
 		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
 	*cur_val = idx;
 	return 1;
 }
+
 /*
  * 2ch mode
  */
@@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
 		.put = alc883_mux_enum_put,
 	},
 	{ } /* end */
-};	
+};
 
 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
 		.put = alc883_mux_enum_put,
 	},
 	{ } /* end */
-};	
+};
+
+static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc883_mux_enum_info,
+		.get = alc883_mux_enum_get,
+		.put = alc883_mux_enum_put,
+	},
+	{ } /* end */
+};
 
 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
 	{
@@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 
 	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+
+	{ } /* end */
+};
 
+static struct hda_verb alc883_lenovo_101e_verbs[] = {
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
+        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
 	{ } /* end */
 };
 
@@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = {
 static void alc883_tagra_automute(struct hda_codec *codec)
 {
  	unsigned int present;
+	unsigned char bits;
 
  	present = snd_hda_codec_read(codec, 0x14, 0,
 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
 	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
+				 0x80, bits);
 	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
-				 0x80, present ? 0x80 : 0);
-	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+				 0x80, bits);
+	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
+			    present ? 1 : 3);
 }
 
 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
 		alc883_tagra_automute(codec);
 }
 
+static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+	unsigned char bits;
+
+ 	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+}
+
+static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+	unsigned char bits;
+
+ 	present = snd_hda_codec_read(codec, 0x1b, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+}
+
+static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
+					   unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc883_lenovo_101e_all_automute(codec);
+	if ((res >> 26) == ALC880_FRONT_EVENT)
+		alc883_lenovo_101e_ispeaker_automute(codec);
+}
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = {
 
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = {
 	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	//{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
 	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 	/* Input mixer2 */
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	//{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
 	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 
 	{ }
@@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
 	[ALC883_ACER]		= "acer",
 	[ALC883_MEDION]		= "medion",
 	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
+	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
 	[ALC883_AUTO]		= "auto",
 };
 
@@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
 	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
+	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
@@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
+	SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
 	{}
 };
 
@@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = {
 		.channel_mode = alc883_3ST_6ch_modes,
 		.need_dac_fix = 1,
 		.input_mux = &alc883_capture_source,
-	},	
+	},
 	[ALC883_3ST_6ch] = {
 		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 		.init_verbs = { alc883_init_verbs },
@@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = {
 		.channel_mode = alc883_3ST_6ch_modes,
 		.need_dac_fix = 1,
 		.input_mux = &alc883_capture_source,
-	},	
+	},
 	[ALC883_6ST_DIG] = {
 		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
 		.init_verbs = { alc883_init_verbs },
@@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = {
 		.channel_mode = alc883_3ST_2ch_modes,
 		.input_mux = &alc883_capture_source,
 	},
+	[ALC883_LENOVO_101E_2ch] = {
+		.mixers = { alc883_lenovo_101e_2ch_mixer},
+		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
+		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
+		.dac_nids = alc883_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+		.adc_nids = alc883_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+		.channel_mode = alc883_3ST_2ch_modes,
+		.input_mux = &alc883_lenovo_101e_capture_source,
+		.unsol_event = alc883_lenovo_101e_unsol_event,
+		.init_hook = alc883_lenovo_101e_all_automute,
+	},
 };
 
 
@@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
 {
 	/* set as output */
 	struct alc_spec *spec = codec->spec;
-	int idx; 
-	
+	int idx;
+
 	if (spec->multiout.dac_nids[dac_idx] == 0x25)
 		idx = 4;
 	else
@@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	int i;
 
+	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 	for (i = 0; i <= HDA_SIDE; i++) {
-		hda_nid_t nid = spec->autocfg.line_out_pins[i];	
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
 		if (nid)
-			alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
+							  i);
 	}
 }
 
@@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
 	else if (err > 0)
 		/* hack - override the init verbs */
 		spec->init_verbs[0] = alc883_auto_init_verbs;
-                spec->mixers[spec->num_mixers] = alc883_capture_mixer;
-		spec->num_mixers++;
+	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
+	spec->num_mixers++;
 	return err;
 }
 
@@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec)
 	spec->stream_digital_playback = &alc883_pcm_digital_playback;
 	spec->stream_digital_capture = &alc883_pcm_digital_capture;
 
-	if (! spec->adc_nids && spec->input_mux) {
+	if (!spec->adc_nids && spec->input_mux) {
 		spec->adc_nids = alc883_adc_nids;
 		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
 	}
@@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = {
 
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = {
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},	
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 
 	{ }
 };
@@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force)
 	struct alc_spec *spec = codec->spec;
 	unsigned int mute;
 
-	if (force || ! spec->sense_updated) {
+	if (force || !spec->sense_updated) {
 		unsigned int present;
 		/* need to execute and sync at first */
 		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force)
 	struct alc_spec *spec = codec->spec;
 	unsigned int mute;
 
-	if (force || ! spec->sense_updated) {
+	if (force || !spec->sense_updated) {
 		unsigned int present;
 		/* need to execute and sync at first */
 		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
 	struct alc_spec *spec = codec->spec;
 	unsigned int mute;
 
-	if (force || ! spec->sense_updated) {
+	if (force || !spec->sense_updated) {
 		unsigned int present;
 		/* need to execute and sync at first */
 		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
@@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = {
 };
 
 /* add playback controls from the parsed DAC table */
-static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
+					     const struct auto_pin_cfg *cfg)
 {
 	hda_nid_t nid;
 	int err;
@@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
 
 	nid = cfg->line_out_pins[0];
 	if (nid) {
-		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
-				       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_VOL,
+				  "Front Playback Volume",
+				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
-		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
-				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+				  "Front Playback Switch",
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 	}
 
 	nid = cfg->speaker_pins[0];
 	if (nid) {
 		if (nid == 0x16) {
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
-					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "Speaker Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+					  "Speaker Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		} else {
-			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+					  "Speaker Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		}
 	}
@@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
 	if (nid) {
 		/* spec->multiout.hp_nid = 2; */
 		if (nid == 0x16) {
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
-					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "Headphone Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+					  "Headphone Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		} else {
-			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+					  "Headphone Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		}
 	}
-	return 0;	
+	return 0;
 }
 
 /* identical with ALC880 */
-#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
+#define alc262_auto_create_analog_input_ctls \
+	alc880_auto_create_analog_input_ctls
 
 /*
  * generic initialization of ADC, input mixers and output mixers
@@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = {
 
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
 
 	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
-	 * mic (mic 2)
+	 * Note: PASD motherboards uses the Line In 2 as the input for
+	 * front panel mic (mic 2)
 	 */
 	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
 	int err;
 	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-						alc262_ignore)) < 0)
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc262_ignore);
+	if (err < 0)
 		return err;
-	if (! spec->autocfg.line_outs)
+	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
-	if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-	    (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = {
 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_HP_capture_source,
-	},	
+	},
 	[ALC262_HP_BPC_D7000_WF] = {
 		.mixers = { alc262_HP_BPC_WildWest_mixer },
 		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
@@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = {
 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_HP_capture_source,
-	},	
+	},
 	[ALC262_HP_BPC_D7000_WL] = {
 		.mixers = { alc262_HP_BPC_WildWest_mixer,
 			    alc262_HP_BPC_WildWest_option_mixer },
@@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = {
 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_HP_capture_source,
-	},	
+	},
 	[ALC262_BENQ_ED8] = {
 		.mixers = { alc262_base_mixer },
 		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = {
 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_capture_source,
-	},		
+	},
 };
 
 static int patch_alc262(struct hda_codec *codec)
@@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec)
 
 	codec->spec = spec;
 #if 0
-	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
+	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
+	 * under-run
+	 */
 	{
 	int tmp;
 	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
@@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec)
 	spec->stream_digital_playback = &alc262_pcm_digital_playback;
 	spec->stream_digital_capture = &alc262_pcm_digital_capture;
 
-	if (! spec->adc_nids && spec->input_mux) {
+	if (!spec->adc_nids && spec->input_mux) {
 		/* check whether NID 0x07 is valid */
 		unsigned int wcap = get_wcaps(codec, 0x07);
 
-		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		/* get type */
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 		if (wcap != AC_WID_AUD_IN) {
 			spec->adc_nids = alc262_adc_nids_alt;
 			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
-			spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
+			spec->mixers[spec->num_mixers] =
+				alc262_capture_alt_mixer;
 			spec->num_mixers++;
 		} else {
 			spec->adc_nids = alc262_adc_nids;
@@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec)
 static struct hda_verb alc861_threestack_ch2_init[] = {
 	/* set pin widget 1Ah (line in) for input */
 	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+	/* set pin widget 18h (mic1/2) for input, for mic also enable
+	 * the vref
+	 */
 	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 
 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
 static struct hda_verb alc861_asus_ch2_init[] = {
 	/* set pin widget 1Ah (line in) for input */
 	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+	/* set pin widget 18h (mic1/2) for input, for mic also enable
+	 * the vref
+	 */
 	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 
 	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
@@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
- 
+
         /* Capture mixer control */
 	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
- 
+
 	/* Capture mixer control */
 	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
 	},
 
 	{ } /* end */
-};	
+};
 
 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
         /* output mixer control */
@@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
- 
+
 	/* Capture mixer control */
 	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
 	},
 	{ } /* end */
-};			
+};
 
 static struct snd_kcontrol_new alc861_asus_mixer[] = {
         /* output mixer control */
@@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
- 
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
+
 	/* Capture mixer control */
 	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
@@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = {
 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+	/* hp used DAC 3 (Front) */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 
 	{ }
@@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+	/* hp used DAC 3 (Front) */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 	{ }
 };
@@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
 	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-E for HP out (front panel) */
-	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
+	/* this has to be set to VREF80 */
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 	/* route front PCM to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-F for mic-in (front panel) with vref */
@@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+	/* hp used DAC 3 (Front) */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 	{ }
 };
@@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = {
 	/*
 	 * Unmute ADC0 and set the default input to mic-in
 	 */
-	/* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
+	/* port-A for surround (rear panel)
+	 * according to codec#0 this is the HP jack
+	 */
 	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
 	/* route front PCM to HP */
 	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
 	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-E for HP out (front panel) */
-	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
+	/* this has to be set to VREF80 */
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 	/* route front PCM to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-F for mic-in (front panel) with vref */
@@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, /* Output 0~12 step */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
 
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = {
 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
+	/* hp used DAC 3 (Front) */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 	{ }
 };
@@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {
 	/*
 	 * Unmute ADC0 and set the default input to mic-in
 	 */
-//	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
 	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	
 	/* Unmute DAC0~3 & spdif out*/
@@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = {
 
 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},	
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},		
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},	
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},	
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
 
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	// set Mic 1
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
 
 	{ }
 };
 
 static struct hda_verb alc861_toshiba_init_verbs[] = {
 	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
-        
+
 	{ }
 };
 
@@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec)
 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
 				       unsigned int res)
 {
-	/* Looks like the unsol event is incompatible with the standard
-	 * definition.  6bit tag is placed at 26 bit!
-	 */
 	if ((res >> 26) == ALC880_HP_EVENT)
 		alc861_toshiba_automute(codec);
 }
@@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = {
 };
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
+				     const struct auto_pin_cfg *cfg)
 {
 	int i;
 	hda_nid_t nid;
@@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
 					     const struct auto_pin_cfg *cfg)
 {
 	char name[32];
-	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	static const char *chname[4] = {
+		"Front", "Surround", NULL /*CLFE*/, "Side"
+	};
 	hda_nid_t nid;
 	int i, idx, err;
 
 	for (i = 0; i < cfg->line_outs; i++) {
 		nid = spec->multiout.dac_nids[i];
-		if (! nid)
+		if (!nid)
 			continue;
 		if (nid == 0x05) {
 			/* Center/LFE */
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "Center Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
-					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "LFE Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		} else {
-			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
+			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
+			     idx++)
 				if (nid == alc861_dac_nids[idx])
 					break;
 			sprintf(name, "%s Playback Switch", chname[idx]);
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 		}
 	}
@@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
 	int err;
 	hda_nid_t nid;
 
-	if (! pin)
+	if (!pin)
 		return 0;
 
 	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
 		nid = 0x03;
-		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
-				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
+				  "Headphone Playback Switch",
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 		spec->multiout.hp_nid = nid;
 	}
@@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
 }
 
 /* create playback/capture controls for input pins */
-static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
+						const struct auto_pin_cfg *cfg)
 {
 	struct hda_input_mux *imux = &spec->private_imux;
 	int i, err, idx, idx1;
 
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
-		switch(cfg->input_pins[i]) {
+		switch (cfg->input_pins[i]) {
 		case 0x0c:
 			idx1 = 1;
-			idx = 2;	// Line In
+			idx = 2;	/* Line In */
 			break;
 		case 0x0f:
 			idx1 = 2;
-			idx = 2;	// Line In
+			idx = 2;	/* Line In */
 			break;
 		case 0x0d:
 			idx1 = 0;
-			idx = 1;	// Mic In 
+			idx = 1;	/* Mic In */
 			break;
-		case 0x10:	
+		case 0x10:
 			idx1 = 3;
-			idx = 1;	// Mic In 
+			idx = 1;	/* Mic In */
 			break;
 		case 0x11:
 			idx1 = 4;
-			idx = 0;	// CD
+			idx = 0;	/* CD */
 			break;
 		default:
 			continue;
@@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str
 
 		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
 		imux->items[imux->num_items].index = idx1;
-		imux->num_items++;	
+		imux->num_items++;
 	}
 	return 0;
 }
@@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = {
 	{ } /* end */
 };
 
-static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
+static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid,
 					      int pin_type, int dac_idx)
 {
 	/* set as output */
 
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    pin_type);
+	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    AMP_OUT_UNMUTE);
 
 }
 
@@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	int i;
 
+	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
 	for (i = 0; i < spec->autocfg.line_outs; i++) {
 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
 		if (nid)
-			alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
+			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
+							  spec->multiout.dac_nids[i]);
 	}
 }
 
@@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
 
 	pin = spec->autocfg.hp_pins[0];
 	if (pin) /* connect to front */
-		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
+		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
+						  spec->multiout.dac_nids[0]);
 }
 
 static void alc861_auto_init_analog_input(struct hda_codec *codec)
@@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec)
 
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = spec->autocfg.input_pins[i];
-		if ((nid>=0x0c) && (nid <=0x11)) {
-			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
-					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+		if (nid >= 0x0c && nid <= 0x11) {
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ?
+					    PIN_VREF80 : PIN_IN);
 		}
 	}
 }
 
 /* parse the BIOS configuration and set up the alc_spec */
-/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+/* return 1 if successful, 0 if the proper config is not found,
+ * or a negative error code
+ */
 static int alc861_parse_auto_config(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	int err;
 	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-						alc861_ignore)) < 0)
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc861_ignore);
+	if (err < 0)
 		return err;
-	if (! spec->autocfg.line_outs)
+	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-	    (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-	    (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
-	    (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
+	if (err < 0)
+		return err;
+	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
 	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
 	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
+	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
 	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
 	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
 	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
 	SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
 	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
 	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
+	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
 	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
 	{}
 };
@@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = {
 	},
 	[ALC861_TOSHIBA] = {
 		.mixers = { alc861_toshiba_mixer },
-		.init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
+		.init_verbs = { alc861_base_init_verbs,
+				alc861_toshiba_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
 		.dac_nids = alc861_dac_nids,
 		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
@@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec)
 	if (spec == NULL)
 		return -ENOMEM;
 
-	codec->spec = spec;	
+	codec->spec = spec;
 
         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
 						  alc861_models,
@@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
 	idx = ucontrol->value.enumerated.item[0];
 	if (idx >= imux->num_items)
 		idx = imux->num_items - 1;
-	if (*cur_val == idx && ! codec->in_resume)
+	if (*cur_val == idx && !codec->in_resume)
 		return 0;
 	for (i = 0; i < imux->num_items; i++) {
 		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
@@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
+	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+
+	{ } /* end */
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {
 	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 
 	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)},
 
 	/*
 	 * Set up output mixers (0x02 - 0x05)
@@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {
 	{ }
 };
 
+static struct hda_verb alc861vd_eapd_verbs[] = {
+	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
+	{ }
+};
+
+static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},	
+	{}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+	unsigned char bits;
+
+	present = snd_hda_codec_read(codec, 0x1b, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+}
+
+static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+	unsigned char bits;
+
+	present = snd_hda_codec_read(codec, 0x18, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
+				 0x80, bits);
+}
+
+static void alc861vd_lenovo_automute(struct hda_codec *codec)
+{
+	alc861vd_lenovo_hp_automute(codec);
+	alc861vd_lenovo_mic_automute(codec);
+}
+
+static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
+					unsigned int res)
+{
+	switch (res >> 26) {
+	case ALC880_HP_EVENT:
+		alc861vd_lenovo_hp_automute(codec);
+		break;
+	case ALC880_MIC_EVENT:
+		alc861vd_lenovo_mic_automute(codec);
+		break;
+	}
+}
+
 /* pcm configuration: identiacal with ALC880 */
 #define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
 #define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
@@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
 	[ALC861VD_3ST]		= "3stack",
 	[ALC861VD_3ST_DIG]	= "3stack-digout",
 	[ALC861VD_6ST_DIG]	= "6stack-digout",
+	[ALC861VD_LENOVO]	= "lenovo",
 	[ALC861VD_AUTO]		= "auto",
 };
 
 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
+	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
-	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST),
+	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
+	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
 	{}
 };
 
@@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = {
 		.channel_mode = alc861vd_6stack_modes,
 		.input_mux = &alc861vd_capture_source,
 	},
+	[ALC861VD_LENOVO] = {
+		.mixers = { alc861vd_lenovo_mixer },
+		.init_verbs = { alc861vd_volume_init_verbs,
+				alc861vd_3stack_init_verbs,
+				alc861vd_eapd_verbs,
+				alc861vd_lenovo_unsol_verbs },
+		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
+		.dac_nids = alc660vd_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+		.adc_nids = alc861vd_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+		.channel_mode = alc861vd_3stack_2ch_modes,
+		.input_mux = &alc861vd_capture_source,
+		.unsol_event = alc861vd_lenovo_unsol_event,
+		.init_hook = alc861vd_lenovo_automute,
+	},
 };
 
 /*
@@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
 	struct alc_spec *spec = codec->spec;
 	int i;
 
+	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 	for (i = 0; i <= HDA_SIDE; i++) {
 		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
 		if (nid)
 			alc861vd_auto_set_output_and_unmute(codec, nid,
-								PIN_OUT, i);
+							    pin_type, i);
 	}
 }
 
@@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 	int i, err;
 
 	for (i = 0; i < cfg->line_outs; i++) {
-		if (! spec->multiout.dac_nids[i])
+		if (!spec->multiout.dac_nids[i])
 			continue;
 		nid_v = alc861vd_idx_to_mixer_vol(
 				alc880_dac_to_idx(
@@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
 
 		if (i == 2) {
 			/* Center/LFE */
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
-						"Center Playback Volume",
-						HDA_COMPOSE_AMP_VAL(nid_v, 1,
-							0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "Center Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
-						"LFE Playback Volume",
-						HDA_COMPOSE_AMP_VAL(nid_v, 2,
-							0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "LFE Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
-						"Center Playback Switch",
-						HDA_COMPOSE_AMP_VAL(nid_s, 1,
-						2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "Center Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
-						"LFE Playback Switch",
-						HDA_COMPOSE_AMP_VAL(nid_s, 2,
-						2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "LFE Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
 		} else {
 			sprintf(name, "%s Playback Volume", chname[i]);
-			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-						HDA_COMPOSE_AMP_VAL(nid_v, 3,
-							0, HDA_OUTPUT))) < 0)
+			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
 				return err;
 			sprintf(name, "%s Playback Switch", chname[i]);
-			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-						HDA_COMPOSE_AMP_VAL(nid_v, 3,
-							2, HDA_INPUT))) < 0)
+			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
+							      HDA_INPUT));
+			if (err < 0)
 				return err;
 		}
 	}
@@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
 	int err;
 	char name[32];
 
-	if (! pin)
+	if (!pin)
 		return 0;
 
 	if (alc880_is_fixed_pin(pin)) {
 		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
 		/* specify the DAC as the extra output */
-		if (! spec->multiout.hp_nid)
+		if (!spec->multiout.hp_nid)
 			spec->multiout.hp_nid = nid_v;
 		else
 			spec->multiout.extra_out_nid[0] = nid_v;
@@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
 				alc880_fixed_pin_idx(pin));
 
 		sprintf(name, "%s Playback Volume", pfx);
-		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-				HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
-							HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 		sprintf(name, "%s Playback Switch", pfx);
-		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
-				HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
-							HDA_INPUT))) < 0)
+		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
+		if (err < 0)
 			return err;
 	} else if (alc880_is_multi_pin(pin)) {
 		/* set manual connection */
 		/* we have only a switch on HP-out PIN */
 		sprintf(name, "%s Playback Switch", pfx);
-		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-				HDA_COMPOSE_AMP_VAL(pin, 3, 0,
-							HDA_OUTPUT))) < 0)
+		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+		if (err < 0)
 			return err;
 	}
 	return 0;
@@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
 	int err;
 	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
-						alc861vd_ignore)) < 0)
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc861vd_ignore);
+	if (err < 0)
 		return err;
-	if (! spec->autocfg.line_outs)
+	if (!spec->autocfg.line_outs)
 		return 0; /* can't find valid BIOS pin config */
 
-	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
-		(err = alc861vd_auto_create_multi_out_ctls(spec,
-			&spec->autocfg)) < 0 ||
-		(err = alc861vd_auto_create_extra_out(spec,
-			spec->autocfg.speaker_pins[0], "Speaker")) < 0 ||
-		(err = alc861vd_auto_create_extra_out(spec,
-			spec->autocfg.hp_pins[0], "Headphone")) < 0 ||
-		(err = alc880_auto_create_analog_input_ctls(spec,
-			&spec->autocfg)) < 0)
+	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc861vd_auto_create_extra_out(spec,
+					     spec->autocfg.speaker_pins[0],
+					     "Speaker");
+	if (err < 0)
+		return err;
+	err = alc861vd_auto_create_extra_out(spec,
+					     spec->autocfg.hp_pins[0],
+					     "Headphone");
+	if (err < 0)
+		return err;
+	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
 		return err;
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
@@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec)
 		if (err < 0) {
 			alc_free(codec);
 			return err;
-		} else if (! err) {
+		} else if (!err) {
 			printk(KERN_INFO
 			       "hda_codec: Cannot set up configuration "
 			       "from BIOS.  Using base mode...\n");
@@ -8674,6 +9362,861 @@ static int patch_alc861vd(struct hda_codec *codec)
 	return 0;
 }
 
+/*
+ * ALC662 support
+ *
+ * ALC662 is almost identical with ALC880 but has cleaner and more flexible
+ * configuration.  Each pin widget can choose any input DACs and a mixer.
+ * Each ADC is connected from a mixer of all inputs.  This makes possible
+ * 6-channel independent captures.
+ *
+ * In addition, an independent DAC for the multi-playback (not used in this
+ * driver yet).
+ */
+#define ALC662_DIGOUT_NID	0x06
+#define ALC662_DIGIN_NID	0x0a
+
+static hda_nid_t alc662_dac_nids[4] = {
+	/* front, rear, clfe, rear_surr */
+	0x02, 0x03, 0x04
+};
+
+static hda_nid_t alc662_adc_nids[1] = {
+	/* ADC1-2 */
+	0x09,
+};
+/* input MUX */
+/* FIXME: should be a matrix-type input source selection */
+
+static struct hda_input_mux alc662_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Front Mic", 0x1 },
+		{ "Line", 0x2 },
+		{ "CD", 0x4 },
+	},
+};
+
+static struct hda_input_mux alc662_lenovo_101e_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "Mic", 0x1 },
+		{ "Line", 0x2 },
+	},
+};
+#define alc662_mux_enum_info alc_mux_enum_info
+#define alc662_mux_enum_get alc_mux_enum_get
+
+static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct alc_spec *spec = codec->spec;
+	const struct hda_input_mux *imux = spec->input_mux;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
+	hda_nid_t nid = capture_mixers[adc_idx];
+	unsigned int *cur_val = &spec->cur_mux[adc_idx];
+	unsigned int i, idx;
+
+	idx = ucontrol->value.enumerated.item[0];
+	if (idx >= imux->num_items)
+		idx = imux->num_items - 1;
+	if (*cur_val == idx && !codec->in_resume)
+		return 0;
+	for (i = 0; i < imux->num_items; i++) {
+		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				    v | (imux->items[i].index << 8));
+	}
+	*cur_val = idx;
+	return 1;
+}
+/*
+ * 2ch mode
+ */
+static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
+	{ 2, NULL }
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_3ST_ch2_init[] = {
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_3ST_ch6_init[] = {
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+	{ } /* end */
+};
+
+static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
+	{ 2, alc662_3ST_ch2_init },
+	{ 6, alc662_3ST_ch6_init },
+};
+
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc662_sixstack_ch6_init[] = {
+	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc662_sixstack_ch8_init[] = {
+	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ } /* end */
+};
+
+static struct hda_channel_mode alc662_5stack_modes[2] = {
+	{ 2, alc662_sixstack_ch6_init },
+	{ 6, alc662_sixstack_ch8_init },
+};
+
+/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
+ *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
+ */
+
+static struct snd_kcontrol_new alc662_base_mixer[] = {
+	/* output mixer control */
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+
+	/*Input mixer control */
+	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
+
+	/* Capture mixer control */
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x02, 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),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc662_mux_enum_info,
+		.get = alc662_mux_enum_get,
+		.put = alc662_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 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),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc662_mux_enum_info,
+		.get = alc662_mux_enum_get,
+		.put = alc662_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc662_mux_enum_info,
+		.get = alc662_mux_enum_get,
+		.put = alc662_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc662_chmode_mixer[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
+	},
+	{ } /* end */
+};
+
+static struct hda_verb alc662_init_verbs[] = {
+	/* ADC: mute amp left and right */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* Front mixer: unmute input/output amp left and right (volume = 0) */
+
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	/* Front Pin: output 0 (0x0c) */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	/* Rear Pin: output 1 (0x0d) */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	/* CLFE Pin: output 2 (0x0e) */
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	/* Mic (rear) pin: input vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Front Mic pin: input vref at 80% */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line In pin: input */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line-2 In: Headphone output (output 0 - 0x0c) */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* CD pin widget for input */
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+	{ }
+};
+
+static struct hda_verb alc662_sue_init_verbs[] = {
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
+	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
+        {}
+};
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc662_auto_init_verbs[] = {
+	/*
+	 * Unmute ADC and set the default input to mic-in
+	 */
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
+	 * Note: PASD motherboards uses the Line In 2 as the input for front
+	 * panel mic (mic 2)
+	 */
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x0c - 0x0f)
+	 */
+	/* set vol=0 to output mixers */
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	/*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	{ }
+};
+
+/* capture mixer elements */
+static struct snd_kcontrol_new alc662_capture_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc882_mux_enum_info,
+		.get = alc882_mux_enum_get,
+		.put = alc882_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+	unsigned char bits;
+
+	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+}
+
+static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+	unsigned char bits;
+
+ 	present = snd_hda_codec_read(codec, 0x1b, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? 0x80 : 0;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, bits);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, bits);
+}
+
+static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
+					   unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc662_lenovo_101e_all_automute(codec);
+	if ((res >> 26) == ALC880_FRONT_EVENT)
+		alc662_lenovo_101e_ispeaker_automute(codec);
+}
+
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
+#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
+#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
+#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
+
+/*
+ * configuration and preset
+ */
+static const char *alc662_models[ALC662_MODEL_LAST] = {
+	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
+	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
+	[ALC662_3ST_6ch]	= "3stack-6ch",
+	[ALC662_5ST_DIG]	= "6stack-dig",
+	[ALC662_LENOVO_101E]	= "lenovo-101e",
+	[ALC662_AUTO]		= "auto",
+};
+
+static struct snd_pci_quirk alc662_cfg_tbl[] = {
+	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
+	{}
+};
+
+static struct alc_config_preset alc662_presets[] = {
+	[ALC662_3ST_2ch_DIG] = {
+		.mixers = { alc662_3ST_2ch_mixer },
+		.init_verbs = { alc662_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
+		.dac_nids = alc662_dac_nids,
+		.dig_out_nid = ALC662_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+		.adc_nids = alc662_adc_nids,
+		.dig_in_nid = ALC662_DIGIN_NID,
+		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+		.channel_mode = alc662_3ST_2ch_modes,
+		.input_mux = &alc662_capture_source,
+	},
+	[ALC662_3ST_6ch_DIG] = {
+		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+		.init_verbs = { alc662_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
+		.dac_nids = alc662_dac_nids,
+		.dig_out_nid = ALC662_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+		.adc_nids = alc662_adc_nids,
+		.dig_in_nid = ALC662_DIGIN_NID,
+		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+		.channel_mode = alc662_3ST_6ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc662_capture_source,
+	},
+	[ALC662_3ST_6ch] = {
+		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
+		.init_verbs = { alc662_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
+		.dac_nids = alc662_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+		.adc_nids = alc662_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
+		.channel_mode = alc662_3ST_6ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc662_capture_source,
+	},
+	[ALC662_5ST_DIG] = {
+		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
+		.init_verbs = { alc662_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
+		.dac_nids = alc662_dac_nids,
+		.dig_out_nid = ALC662_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+		.adc_nids = alc662_adc_nids,
+		.dig_in_nid = ALC662_DIGIN_NID,
+		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
+		.channel_mode = alc662_5stack_modes,
+		.input_mux = &alc662_capture_source,
+	},
+	[ALC662_LENOVO_101E] = {
+		.mixers = { alc662_lenovo_101e_mixer },
+		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
+		.dac_nids = alc662_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
+		.adc_nids = alc662_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+		.channel_mode = alc662_3ST_2ch_modes,
+		.input_mux = &alc662_lenovo_101e_capture_source,
+		.unsol_event = alc662_lenovo_101e_unsol_event,
+		.init_hook = alc662_lenovo_101e_all_automute,
+	},
+
+};
+
+
+/*
+ * BIOS auto configuration
+ */
+
+/* add playback controls from the parsed DAC table */
+static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
+					     const struct auto_pin_cfg *cfg)
+{
+	char name[32];
+	static const char *chname[4] = {
+		"Front", "Surround", NULL /*CLFE*/, "Side"
+	};
+	hda_nid_t nid;
+	int i, err;
+
+	for (i = 0; i < cfg->line_outs; i++) {
+		if (!spec->multiout.dac_nids[i])
+			continue;
+		nid = alc880_idx_to_dac(i);
+		if (i == 2) {
+			/* Center/LFE */
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "Center Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, ALC_CTL_WIDGET_VOL,
+					  "LFE Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "Center Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
+							      HDA_INPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, ALC_CTL_BIND_MUTE,
+					  "LFE Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
+							      HDA_INPUT));
+			if (err < 0)
+				return err;
+		} else {
+			sprintf(name, "%s Playback Volume", chname[i]);
+			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
+							      HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			sprintf(name, "%s Playback Switch", chname[i]);
+			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
+							      HDA_INPUT));
+			if (err < 0)
+				return err;
+		}
+	}
+	return 0;
+}
+
+/* add playback controls for speaker and HP outputs */
+static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+					const char *pfx)
+{
+	hda_nid_t nid;
+	int err;
+	char name[32];
+
+	if (!pin)
+		return 0;
+
+	if (alc880_is_fixed_pin(pin)) {
+		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+                /* printk("DAC nid=%x\n",nid); */
+		/* specify the DAC as the extra output */
+		if (!spec->multiout.hp_nid)
+			spec->multiout.hp_nid = nid;
+		else
+			spec->multiout.extra_out_nid[0] = nid;
+		/* control HP volume/switch on the output mixer amp */
+		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+		sprintf(name, "%s Playback Volume", pfx);
+		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
+		if (err < 0)
+			return err;
+		sprintf(name, "%s Playback Switch", pfx);
+		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+		if (err < 0)
+			return err;
+	} else if (alc880_is_multi_pin(pin)) {
+		/* set manual connection */
+		/* we have only a switch on HP-out PIN */
+		sprintf(name, "%s Playback Switch", pfx);
+		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
+		if (err < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
+						const struct auto_pin_cfg *cfg)
+{
+	struct hda_input_mux *imux = &spec->private_imux;
+	int i, err, idx;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		if (alc880_is_input_pin(cfg->input_pins[i])) {
+			idx = alc880_input_pin_idx(cfg->input_pins[i]);
+			err = new_analog_input(spec, cfg->input_pins[i],
+					       auto_pin_cfg_labels[i],
+					       idx, 0x0b);
+			if (err < 0)
+				return err;
+			imux->items[imux->num_items].label =
+				auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].index =
+				alc880_input_pin_idx(cfg->input_pins[i]);
+			imux->num_items++;
+		}
+	}
+	return 0;
+}
+
+static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid, int pin_type,
+					      int dac_idx)
+{
+	/* set as output */
+	snd_hda_codec_write(codec, nid, 0,
+			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, nid, 0,
+			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	/* need the manual connection? */
+	if (alc880_is_multi_pin(nid)) {
+		struct alc_spec *spec = codec->spec;
+		int idx = alc880_multi_pin_idx(nid);
+		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
+				    AC_VERB_SET_CONNECT_SEL,
+				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+	}
+}
+
+static void alc662_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i <= HDA_SIDE; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		int pin_type = get_pin_type(spec->autocfg.line_out_type);
+		if (nid)
+			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
+							  i);
+	}
+}
+
+static void alc662_auto_init_hp_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t pin;
+
+	pin = spec->autocfg.hp_pins[0];
+	if (pin) /* connect to front */
+		/* use dac 0 */
+		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+}
+
+#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
+#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
+
+static void alc662_auto_init_analog_input(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if (alc662_is_input_pin(nid)) {
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    (i <= AUTO_PIN_FRONT_MIC ?
+					     PIN_VREF80 : PIN_IN));
+			if (nid != ALC662_PIN_CD_NID)
+				snd_hda_codec_write(codec, nid, 0,
+						    AC_VERB_SET_AMP_GAIN_MUTE,
+						    AMP_OUT_MUTE);
+		}
+	}
+}
+
+static int alc662_parse_auto_config(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int err;
+	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
+
+	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+					   alc662_ignore);
+	if (err < 0)
+		return err;
+	if (!spec->autocfg.line_outs)
+		return 0; /* can't find valid BIOS pin config */
+
+	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+	err = alc662_auto_create_extra_out(spec,
+					   spec->autocfg.speaker_pins[0],
+					   "Speaker");
+	if (err < 0)
+		return err;
+	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
+					   "Headphone");
+	if (err < 0)
+		return err;
+	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
+	if (err < 0)
+		return err;
+
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->num_mux_defs = 1;
+	spec->input_mux = &spec->private_imux;
+	
+	if (err < 0)
+		return err;
+	else if (err > 0)
+		/* hack - override the init verbs */
+		spec->init_verbs[0] = alc662_auto_init_verbs;
+	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
+	spec->num_mixers++;
+	return err;
+}
+
+/* additional initialization for auto-configuration model */
+static void alc662_auto_init(struct hda_codec *codec)
+{
+	alc662_auto_init_multi_out(codec);
+	alc662_auto_init_hp_out(codec);
+	alc662_auto_init_analog_input(codec);
+}
+
+static int patch_alc662(struct hda_codec *codec)
+{
+	struct alc_spec *spec;
+	int err, board_config;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
+						  alc662_models,
+			  	                  alc662_cfg_tbl);
+	if (board_config < 0) {
+		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
+		       "trying auto-probe from BIOS...\n");
+		board_config = ALC662_AUTO;
+	}
+
+	if (board_config == ALC662_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc662_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (err) {
+			printk(KERN_INFO
+			       "hda_codec: Cannot set up configuration "
+			       "from BIOS.  Using base mode...\n");
+			board_config = ALC662_3ST_2ch_DIG;
+		}
+	}
+
+	if (board_config != ALC662_AUTO)
+		setup_preset(spec, &alc662_presets[board_config]);
+
+	spec->stream_name_analog = "ALC662 Analog";
+	spec->stream_analog_playback = &alc662_pcm_analog_playback;
+	spec->stream_analog_capture = &alc662_pcm_analog_capture;
+
+	spec->stream_name_digital = "ALC662 Digital";
+	spec->stream_digital_playback = &alc662_pcm_digital_playback;
+	spec->stream_digital_capture = &alc662_pcm_digital_capture;
+
+	if (!spec->adc_nids && spec->input_mux) {
+		spec->adc_nids = alc662_adc_nids;
+		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
+	}
+
+	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC662_AUTO)
+		spec->init_hook = alc662_auto_init;
+
+	return 0;
+}
+
 /*
  * patch entries
  */
@@ -8681,10 +10224,14 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
 	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
 	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
 	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
-		.patch = patch_alc861 },
+	  .patch = patch_alc861 },
 	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
 	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
 	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
+	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
+	  .patch = patch_alc883 },
+	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
+	  .patch = patch_alc662 },
 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
 	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
 	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },

+ 127 - 51
sound/pci/hda/patch_sigmatel.c

@@ -62,6 +62,7 @@ enum {
 	STAC_MACBOOK,
 	STAC_MACBOOK_PRO_V1,
 	STAC_MACBOOK_PRO_V2,
+	STAC_IMAC_INTEL,
 	STAC_922X_MODELS
 };
 
@@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = {
         0x19, 0x1a
 };
 
-static hda_nid_t stac9205_dmic_nids[3] = {
-        0x17, 0x18, 0
+static hda_nid_t stac9205_dmic_nids[2] = {
+        0x17, 0x18,
 };
 
 static hda_nid_t stac9200_pin_nids[8] = {
@@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = {
 	0x02a19320, 0x40000100,
 };
 
-static unsigned int macbook_pin_configs[10] = {
-	0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110,
-	0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e,
-	0x400000fc, 0x400000fb,
-};
-
 static unsigned int macbook_pro_v1_pin_configs[10] = {
 	0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010,
 	0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e,
@@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = {
 	0x400000fc, 0x400000fb,
 };
 
+static unsigned int imac_intel_pin_configs[10] = {
+	0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe,
+	0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa,
+	0x400000fc, 0x400000fb,
+};
+
 static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
 	[STAC_D945_REF] = ref922x_pin_configs,
 	[STAC_D945GTP3] = d945gtp3_pin_configs,
 	[STAC_D945GTP5] = d945gtp5_pin_configs,
-	[STAC_MACMINI] = d945gtp5_pin_configs,
-	[STAC_MACBOOK] = macbook_pin_configs,
+	[STAC_MACMINI] = macbook_pro_v1_pin_configs,
+	[STAC_MACBOOK] = macbook_pro_v1_pin_configs,
 	[STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs,
 	[STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs,
+	[STAC_IMAC_INTEL] = imac_intel_pin_configs,
 };
 
 static const char *stac922x_models[STAC_922X_MODELS] = {
@@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
 	[STAC_MACBOOK]	= "macbook",
 	[STAC_MACBOOK_PRO_V1]	= "macbook-pro-v1",
 	[STAC_MACBOOK_PRO_V2]	= "macbook-pro",
+	[STAC_IMAC_INTEL] = "imac-intel",
 };
 
 static struct snd_pci_quirk stac922x_cfg_tbl[] = {
@@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 unsigned int stream_tag,
+					 unsigned int format,
+					 struct snd_pcm_substream *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+					     stream_tag, format, substream);
+}
+
 
 /*
  * Analog capture callbacks
@@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
 	/* NID is set in stac92xx_build_pcms */
 	.ops = {
 		.open = stac92xx_dig_playback_pcm_open,
-		.close = stac92xx_dig_playback_pcm_close
+		.close = stac92xx_dig_playback_pcm_close,
+		.prepare = stac92xx_dig_playback_pcm_prepare
 	},
 };
 
@@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
 static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
 {
 	struct sigmatel_spec *spec = codec->spec;
+	unsigned int wcaps, wtype;
+	int i, num_dacs = 0;
+	
+	/* use the wcaps cache to count all DACs available for line-outs */
+	for (i = 0; i < codec->num_nodes; i++) {
+		wcaps = codec->wcaps[i];
+		wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
+			num_dacs++;
+	}
 
+	snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
+	
 	switch (cfg->line_outs) {
 	case 3:
 		/* add line-in as side */
-		if (cfg->input_pins[AUTO_PIN_LINE]) {
+		if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
 			cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
 			spec->line_switch = 1;
 			cfg->line_outs++;
@@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
 		break;
 	case 2:
 		/* add line-in as clfe and mic as side */
-		if (cfg->input_pins[AUTO_PIN_LINE]) {
+		if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
 			cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
 			spec->line_switch = 1;
 			cfg->line_outs++;
 		}
-		if (cfg->input_pins[AUTO_PIN_MIC]) {
+		if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
 			cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
 			spec->mic_switch = 1;
 			cfg->line_outs++;
@@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
 		break;
 	case 1:
 		/* add line-in as surr and mic as clfe */
-		if (cfg->input_pins[AUTO_PIN_LINE]) {
+		if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
 			cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
 			spec->line_switch = 1;
 			cfg->line_outs++;
 		}
-		if (cfg->input_pins[AUTO_PIN_MIC]) {
+		if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
 			cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
 			spec->mic_switch = 1;
 			cfg->line_outs++;
@@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
 	return 0;
 }
 
+
+static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
+{
+	int i;
+	
+	for (i = 0; i < spec->multiout.num_dacs; i++) {
+		if (spec->multiout.dac_nids[i] == nid)
+			return 1;
+	}
+
+	return 0;
+}
+
 /*
- * XXX The line_out pin widget connection list may not be set to the
- * desired DAC nid. This is the case on 927x where ports A and B can
- * be routed to several DACs.
- *
- * This requires an analysis of the line-out/hp pin configuration
- * to provide a best fit for pin/DAC configurations that are routable.
- * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
- * A and B is not supported.
+ * Fill in the dac_nids table from the parsed pin configuration
+ * This function only works when every pin in line_out_pins[]
+ * contains atleast one DAC in its connection list. Some 92xx
+ * codecs are not connected directly to a DAC, such as the 9200
+ * and 9202/925x. For those, dac_nids[] must be hard-coded.
  */
-/* fill in the dac_nids table from the parsed pin configuration */
 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
 				       const struct auto_pin_cfg *cfg)
 {
 	struct sigmatel_spec *spec = codec->spec;
-	hda_nid_t nid;
-	int i;
-
-	/* check the pins hardwired to audio widget */
+	int i, j, conn_len = 0; 
+	hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
+	unsigned int wcaps, wtype;
+	
 	for (i = 0; i < cfg->line_outs; i++) {
 		nid = cfg->line_out_pins[i];
-		spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
-					AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
-	}
+		conn_len = snd_hda_get_connections(codec, nid, conn,
+						   HDA_MAX_CONNECTIONS);
+		for (j = 0; j < conn_len; j++) {
+			wcaps = snd_hda_param_read(codec, conn[j],
+						   AC_PAR_AUDIO_WIDGET_CAP);
+			wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+
+			if (wtype != AC_WID_AUD_OUT ||
+			    (wcaps & AC_WCAP_DIGITAL))
+				continue;
+			/* conn[j] is a DAC routed to this line-out */
+			if (!is_in_dac_nids(spec, conn[j]))
+				break;
+		}
+
+		if (j == conn_len) {
+			/* error out, no available DAC found */
+			snd_printk(KERN_ERR
+				   "%s: No available DAC for pin 0x%x\n",
+				   __func__, nid);
+			return -ENODEV;
+		}
 
-	spec->multiout.num_dacs = cfg->line_outs;
+		spec->multiout.dac_nids[i] = conn[j];
+		spec->multiout.num_dacs++;
+		if (conn_len > 1) {
+			/* select this DAC in the pin's input mux */
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_CONNECT_SEL, j);
+
+		}
+	}
 
+	snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
+		   spec->multiout.num_dacs,
+		   spec->multiout.dac_nids[0],
+		   spec->multiout.dac_nids[1],
+		   spec->multiout.dac_nids[2],
+		   spec->multiout.dac_nids[3],
+		   spec->multiout.dac_nids[4]);
 	return 0;
 }
 
@@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
 
 static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
 {
-	int i;
-
-	for (i = 0; i < spec->multiout.num_dacs; i++) {
-		if (spec->multiout.dac_nids[i] == nid)
-			return 1;
-	}
+	if (is_in_dac_nids(spec, nid))
+		return 1;
 	if (spec->multiout.hp_nid == nid)
 		return 1;
 	return 0;
@@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
 		add_spec_dacs(spec, nid);
 	}
 	for (i = 0; i < cfg->speaker_outs; i++) {
-		nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0,
+		nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
 					 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
 		if (check_in_dac_nids(spec, nid))
 			nid = 0;
-		if (check_in_dac_nids(spec, nid))
-			nid = 0;
 		if (! nid)
 			continue;
 		add_spec_dacs(spec, nid);
@@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
 		imux->num_items++;
 	}
 
-	if (imux->num_items == 1) {
+	if (imux->num_items) {
 		/*
 		 * Set the current input for the muxes.
 		 * The STAC9221 has two input muxes with identical source
@@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
 {
 	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
 			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
-	if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN))
-		return;
+
+	/* if setting pin direction bits, clear the current
+	   direction bits first */
+	if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
+		pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
+	
 	snd_hda_codec_write(codec, nid, 0,
 			AC_VERB_SET_PIN_WIDGET_CONTROL,
 			pin_ctl | flag);
@@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec)
 
 	stac92xx_init(codec);
 	stac92xx_set_config_regs(codec);
+	snd_hda_resume_ctls(codec, spec->mixer);
 	for (i = 0; i < spec->num_mixers; i++)
 		snd_hda_resume_ctls(codec, spec->mixers[i]);
 	if (spec->multiout.dig_out_nid)
@@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec)
 		 */
 		printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id);
 		switch (codec->subsystem_id) {
+		case 0x106b0a00: /* MacBook First generatoin */
+			spec->board_config = STAC_MACBOOK;
+			break;
 		case 0x106b0200: /* MacBook Pro first generation */
 			spec->board_config = STAC_MACBOOK_PRO_V1;
 			break;
 		case 0x106b1e00: /* MacBook Pro second generation */
 			spec->board_config = STAC_MACBOOK_PRO_V2;
 			break;
+		case 0x106b0700: /* Intel-based iMac */
+			spec->board_config = STAC_IMAC_INTEL;
+			break;
 		}
 	}
 
@@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec)
 
 	spec->adc_nids = stac922x_adc_nids;
 	spec->mux_nids = stac922x_mux_nids;
-	spec->num_muxes = 2;
+	spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids);
 	spec->num_dmics = 0;
 
 	spec->init = stac922x_core_init;
@@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec)
 	case STAC_D965_3ST:
 		spec->adc_nids = stac927x_adc_nids;
 		spec->mux_nids = stac927x_mux_nids;
-		spec->num_muxes = 3;
+		spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
 		spec->num_dmics = 0;
 		spec->init = d965_core_init;
 		spec->mixer = stac9227_mixer;
@@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec)
 	case STAC_D965_5ST:
 		spec->adc_nids = stac927x_adc_nids;
 		spec->mux_nids = stac927x_mux_nids;
-		spec->num_muxes = 3;
+		spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
 		spec->num_dmics = 0;
 		spec->init = d965_core_init;
 		spec->mixer = stac9227_mixer;
@@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec)
 	default:
 		spec->adc_nids = stac927x_adc_nids;
 		spec->mux_nids = stac927x_mux_nids;
-		spec->num_muxes = 3;
+		spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids);
 		spec->num_dmics = 0;
 		spec->init = stac927x_core_init;
 		spec->mixer = stac927x_mixer;
@@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec)
 
 	spec->adc_nids = stac9205_adc_nids;
 	spec->mux_nids = stac9205_mux_nids;
-	spec->num_muxes = 2;
+	spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
 	spec->dmic_nids = stac9205_dmic_nids;
-	spec->num_dmics = 2;
+	spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
 	spec->dmux_nid = 0x1d;
 
 	spec->init = stac9205_core_init;
@@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
 	SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
 	SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
+	SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO),
 	{}
 };
 

+ 13 - 1
sound/pci/hda/patch_via.c

@@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 }
 
+static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					unsigned int stream_tag,
+					unsigned int format,
+					struct snd_pcm_substream *substream)
+{
+	struct via_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
+					     stream_tag, format, substream);
+}
+
 /*
  * Analog capture
  */
@@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = {
 	/* NID is set in via_build_pcms */
 	.ops = {
 		.open = via_dig_playback_pcm_open,
-		.close = via_dig_playback_pcm_close
+		.close = via_dig_playback_pcm_close,
+		.prepare = via_dig_playback_pcm_prepare
 	},
 };
 

+ 1 - 1
sound/pci/ice1712/amp.c

@@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
 	{
 		.subvendor = VT1724_SUBDEVICE_AV710,
 		.name = "Chaintech AV-710",

+ 1 - 1
sound/pci/ice1712/amp.h

@@ -42,7 +42,7 @@
 #define WM_DAC_CTRL	0x02
 #define WM_INT_CTRL	0x03
 
-extern const struct snd_ice1712_card_info  snd_vt1724_amp_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_amp_cards[];
 
 
 #endif /* __SOUND_AMP_H */

+ 9 - 9
sound/pci/ice1712/aureon.c

@@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
  * mixers
  */
 
-static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
 	}
 };
 
-static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Switch",
@@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
 	}
 };
 
-static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
  	}
 };
 
-static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
 
 };
 
-static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
+static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
  * hence the driver needs to sets up it properly.
  */
 
-static const unsigned char aureon51_eeprom[] __devinitdata = {
+static unsigned char aureon51_eeprom[] __devinitdata = {
 	[ICE_EEP2_SYSCONF]     = 0x0a,	/* clock 512, spdif-in/ADC, 3DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = {
 	[ICE_EEP2_GPIO_STATE2] = 0x00,
 };
 
-static const unsigned char aureon71_eeprom[] __devinitdata = {
+static unsigned char aureon71_eeprom[] __devinitdata = {
 	[ICE_EEP2_SYSCONF]     = 0x0b,	/* clock 512, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = {
 };
 #define prodigy71_eeprom aureon71_eeprom
 
-static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
+static unsigned char prodigy71lt_eeprom[] __devinitdata = {
 	[ICE_EEP2_SYSCONF]     = 0x4b,	/* clock 384, spdif-in/ADC, 4DACs */
 	[ICE_EEP2_ACLINK]      = 0x80,	/* I2S */
 	[ICE_EEP2_I2S]         = 0xfc,	/* vol, 96k, 24bit, 192k */
@@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
 #define prodigy71xt_eeprom prodigy71lt_eeprom
 
 /* entry point */
-const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
 	{
 		.subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
 		.name = "Terratec Aureon 5.1-Sky",

+ 1 - 1
sound/pci/ice1712/aureon.h

@@ -38,7 +38,7 @@
 #define VT1724_SUBDEVICE_PRODIGY71LT	0x32315441	/* PRODIGY 7.1 LT */
 #define VT1724_SUBDEVICE_PRODIGY71XT	0x36315441	/* PRODIGY 7.1 XT*/
 
-extern const struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];
+extern struct snd_ice1712_card_info  snd_vt1724_aureon_cards[];
 
 /* GPIO bits */
 #define AUREON_CS8415_CS	(1 << 22)

+ 17 - 17
sound/pci/ice1712/delta.c

@@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
 	return 0;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
 {
 	.access =	(SNDRV_CTL_ELEM_ACCESS_READ),
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __
  * initialize the chips on M-Audio cards
  */
 
-static const struct snd_akm4xxx akm_audiophile __devinitdata = {
+static struct snd_akm4xxx akm_audiophile __devinitdata = {
 	.type = SND_AK4528,
 	.num_adcs = 2,
 	.num_dacs = 2,
@@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta410 __devinitdata = {
+static struct snd_akm4xxx akm_delta410 __devinitdata = {
 	.type = SND_AK4529,
 	.num_adcs = 2,
 	.num_dacs = 8,
@@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
 	.caddr = 0,
 	.cif = 0,
 	.data_mask = ICE1712_DELTA_AP_DOUT,
@@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
+static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 8,
 	.num_dacs = 8,
@@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 0, /* the default level of the CIF pin from AK4524 */
 	.data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_delta44 __devinitdata = {
+static struct snd_akm4xxx akm_delta44 __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 0, /* the default level of the CIF pin from AK4524 */
 	.data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_vx442 __devinitdata = {
+static struct snd_akm4xxx akm_vx442 __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 0,
 	.data_mask = ICE1712_VX442_DOUT,
@@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
  * additional controls for M-Audio cards
  */
 
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
 
 
@@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_DELTA1010,
 		.name = "M Audio Delta 1010",

+ 1 - 1
sound/pci/ice1712/delta.h

@@ -46,7 +46,7 @@
 #define ICE1712_SUBDEVICE_MEDIASTATION	0x694c0100
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
 
 
 /*

+ 12 - 12
sound/pci/ice1712/ews.c

@@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
 
 /*
  */
-static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
+static struct snd_akm4xxx akm_ews88mt __devinitdata = {
 	.num_adcs = 8,
 	.num_dacs = 8,
 	.type = SND_AK4524,
@@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
+static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
 	.num_adcs = 2,
 	.num_dacs = 2,
 	.type = SND_AK4524,
@@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
 	.mask_flags = 0,
 };
 
-static const struct snd_akm4xxx akm_6fire __devinitdata = {
+static struct snd_akm4xxx akm_6fire __devinitdata = {
 	.num_adcs = 6,
 	.num_dacs = 6,
 	.type = SND_AK4524,
@@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = {
 	}
 };
 
-static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
+static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
 	.caddr = 2,
 	.cif = 1, /* CIF high */
 	.data_mask = ICE1712_6FIRE_SERIAL_DATA,
@@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn
 	return val != nval;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Input Sensitivity Switch",
@@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
 	return ndata != data;
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Input Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda
 	.count = 8,
 };
 
-static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Output Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
   .private_value = xshift | (xinvert << 8),\
 }
 
-static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
   .private_value = xshift | (xinvert << 8),\
 }
 
-static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Analog Input Select",
@@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_EWX2496,
 		.name = "TerraTec EWX24/96",

+ 1 - 1
sound/pci/ice1712/ews.h

@@ -40,7 +40,7 @@
 #define ICE1712_SUBDEVICE_PHASE88	0x3b155111
 
 /* entry point */
-extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[];
+extern struct snd_ice1712_card_info snd_ice1712_ews_cards[];
 
 
 /* TerraTec EWX 24/96 configuration definitions */

+ 3 - 3
sound/pci/ice1712/hoontech.c

@@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
 {
 	/* Hoontech STDSP24 with modified hardware */
-	static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
+	static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
 		.num_adcs = 2,
 		.num_dacs = 2,
 		.type = SND_AK4524,
@@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
 		}
 	};
 
-	static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
+	static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
 		.caddr = 2,
 		.cif = 1, /* CIF high */
 		.data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
 
 
 /* entry point */
-const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
+struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
 	{
 		.subvendor = ICE1712_SUBDEVICE_STDSP24,
 		.name = "Hoontech SoundTrack Audio DSP24",

Неке датотеке нису приказане због велике количине промена