[ALSA] ice1712, ice1724 - Code clean up

Clean up ice1712/ice1724 codes.  The board-specific data is allocated
locally in each code instead of having an ungly union in struct ice1712.
Also, fix coding issues in prodigy_hifi.c.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 3374891..868ae29 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -61,6 +61,15 @@
 #include "aureon.h"
 #include <sound/tlv.h>
 
+/* AC97 register cache for Aureon */
+struct aureon_spec {
+	unsigned short stac9744[64];
+	unsigned int cs8415_mux;
+	unsigned short master[2];
+	unsigned short vol[8];
+	unsigned char pca9554_out;
+};
+
 /* WM8770 registers */
 #define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
 #define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
@@ -204,7 +213,8 @@
 				     struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.enumerated.item[0] = ice->spec.aureon.pca9554_out;
+	struct aureon_spec *spec = ice->spec;
+	ucontrol->value.enumerated.item[0] = spec->pca9554_out;
 	return 0;
 }
 
@@ -212,6 +222,7 @@
 				     struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	unsigned char oval, nval;
 	int change;
 
@@ -219,10 +230,10 @@
 	if (nval >= 3)
 		return -EINVAL;
 	snd_ice1712_save_gpio_status(ice);
-	oval = ice->spec.aureon.pca9554_out;
+	oval = spec->pca9554_out;
 	if ((change = (oval != nval))) {
 		aureon_pca9554_write(ice, PCA9554_OUT, nval);
-		ice->spec.aureon.pca9554_out = nval;
+		spec->pca9554_out = nval;
 	}
 	snd_ice1712_restore_gpio_status(ice);
 	
@@ -233,6 +244,7 @@
 static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
 			      unsigned short val)
 {
+	struct aureon_spec *spec = ice->spec;
 	unsigned int tmp;
 
 	/* Send address to XILINX chip */
@@ -280,12 +292,13 @@
 	udelay(10);
 	
 	/* Store the data in out private buffer */
-	ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
+	spec->stac9744[(reg & 0x7F) >> 1] = val;
 }
 
 static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
 {
-       return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
+	struct aureon_spec *spec = ice->spec;
+	return spec->stac9744[(reg & 0x7F) >> 1];
 }
 
 /*
@@ -293,6 +306,7 @@
  */
 static int aureon_ac97_init (struct snd_ice1712 *ice)
 {
+	struct aureon_spec *spec = ice->spec;
 	int i;
 	static const unsigned short ac97_defaults[] = {
 		0x00, 0x9640,
@@ -330,9 +344,9 @@
 	snd_ice1712_gpio_write(ice, tmp);
 	udelay(3);
 	
-	memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744));
+	memset(&spec->stac9744, 0, sizeof(spec->stac9744));
 	for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
-		ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
+		spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
 		
 	aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
 
@@ -744,15 +758,18 @@
 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int i;
 	for (i=0; i<2; i++)
-		ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
+		ucontrol->value.integer.value[i] =
+			spec->master[i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int ch, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -760,14 +777,14 @@
 		unsigned int vol = ucontrol->value.integer.value[ch];
 		if (vol > WM_VOL_MAX)
 			continue;
-		vol |= ice->spec.aureon.master[ch] & WM_VOL_MUTE;
-		if (vol != ice->spec.aureon.master[ch]) {
+		vol |= spec->master[ch] & WM_VOL_MUTE;
+		if (vol != spec->master[ch]) {
 			int dac;
-			ice->spec.aureon.master[ch] = vol;
+			spec->master[ch] = vol;
 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
-					   ice->spec.aureon.vol[dac + ch],
-					   ice->spec.aureon.master[ch]);
+					   spec->vol[dac + ch],
+					   spec->master[ch]);
 			change = 1;
 		}
 	}
@@ -791,18 +808,21 @@
 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xff;
 	for (i = 0; i < voices; i++)
-		ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE;
+		ucontrol->value.integer.value[i] =
+			spec->vol[ofs+i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int i, idx, ofs, voices;
 	int change = 0;
 
@@ -813,12 +833,12 @@
 		unsigned int vol = ucontrol->value.integer.value[i];
 		if (vol > 0x7f)
 			continue;
-		vol |= ice->spec.aureon.vol[ofs+i];
-		if (vol != ice->spec.aureon.vol[ofs+i]) {
-			ice->spec.aureon.vol[ofs+i] = vol;
+		vol |= spec->vol[ofs+i];
+		if (vol != spec->vol[ofs+i]) {
+			spec->vol[ofs+i] = vol;
 			idx  = WM_DAC_ATTEN + ofs + i;
-			wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i],
-				   ice->spec.aureon.master[i]);
+			wm_set_vol(ice, idx, spec->vol[ofs + i],
+				   spec->master[i]);
 			change = 1;
 		}
 	}
@@ -840,19 +860,22 @@
 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int voices, ofs, i;
 	
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xFF;
 
 	for (i = 0; i < voices; i++)
-		ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
+		ucontrol->value.integer.value[i] =
+			(spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int change = 0, voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
@@ -860,13 +883,13 @@
 
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < voices; i++) {
-		int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
+		int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
 		if (ucontrol->value.integer.value[i] != val) {
-			ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE;
-			ice->spec.aureon.vol[ofs + i] |=
+			spec->vol[ofs + i] &= ~WM_VOL_MUTE;
+			spec->vol[ofs + i] |=
 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
-			wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i],
-				   ice->spec.aureon.master[i]);
+			wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
+				   spec->master[i]);
 			change = 1;
 		}
 	}
@@ -883,29 +906,33 @@
 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	
-	ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
-	ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[0] =
+		(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[1] =
+		(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	int change = 0, i;
 
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < 2; i++) {
-		int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1;
+		int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
 		if (ucontrol->value.integer.value[i] != val) {
 			int dac;
-			ice->spec.aureon.master[i] &= ~WM_VOL_MUTE;
-			ice->spec.aureon.master[i] |=
+			spec->master[i] &= ~WM_VOL_MUTE;
+			spec->master[i] |=
 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
-					   ice->spec.aureon.vol[dac + i],
-					   ice->spec.aureon.master[i]);
+					   spec->vol[dac + i],
+					   spec->master[i]);
 			change = 1;
 		}
 	}
@@ -1151,10 +1178,11 @@
 static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 
 	//snd_ice1712_save_gpio_status(ice);
 	//val = aureon_cs8415_get(ice, CS8415_CTRL2);
-	ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux;
+	ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
 	//snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
@@ -1162,6 +1190,7 @@
 static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct aureon_spec *spec = ice->spec;
 	unsigned short oval, nval;
 	int change;
 
@@ -1173,7 +1202,7 @@
 	if (change)
 		aureon_cs8415_put(ice, CS8415_CTRL2, nval);
 	snd_ice1712_restore_gpio_status(ice);
-	ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0];
+	spec->cs8415_mux = ucontrol->value.enumerated.item[0];
 	return change;
 }
 
@@ -2009,10 +2038,16 @@
 		0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
 		(unsigned short)-1
 	};
+	struct aureon_spec *spec;
 	unsigned int tmp;
 	const unsigned short *p;
 	int err, i;
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
 		ice->num_total_dacs = 6;
 		ice->num_total_adcs = 2;
@@ -2063,7 +2098,7 @@
 	    ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
 		for (p = cs_inits; *p != (unsigned short)-1; p++)
 			aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
-		ice->spec.aureon.cs8415_mux = 1;
+		spec->cs8415_mux = 1;
 
 		aureon_set_headphone_amp(ice, 1);
 	}
@@ -2074,11 +2109,11 @@
 	aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
 	aureon_pca9554_write(ice, PCA9554_OUT, 0x00);   /* internal AUX */
 	
-	ice->spec.aureon.master[0] = WM_VOL_MUTE;
-	ice->spec.aureon.master[1] = WM_VOL_MUTE;
+	spec->master[0] = WM_VOL_MUTE;
+	spec->master[1] = WM_VOL_MUTE;
 	for (i = 0; i < ice->num_total_dacs; i++) {
-		ice->spec.aureon.vol[i] = WM_VOL_MUTE;
-		wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]);
+		spec->vol[i] = WM_VOL_MUTE;
+		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
 	}
 
 	return 0;
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 6f65da4..064760d 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -44,6 +44,11 @@
 };
 	
 
+/* additional i2c devices for EWS boards */
+struct ews_spec {
+	struct snd_i2c_device *i2cdevs[3];
+};
+
 /*
  * access via i2c mode (for EWX 24/96, EWS 88MT&D)
  */
@@ -141,15 +146,17 @@
 /* AK4524 chip select; address 0x48 bit 0-3 */
 static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
 {
+	struct ews_spec *spec = ice->spec;
 	unsigned char data, ndata;
 
 	snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
 		goto __error;
 	ndata = (data & 0xf0) | chip_mask;
 	if (ndata != data)
-		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1)
+		if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1)
+		    != 1)
 			goto __error;
 	snd_i2c_unlock(ice->i2c);
 	return 0;
@@ -223,6 +230,7 @@
 
 static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
 {
+	struct ews_spec *spec = ice->spec;
 	unsigned char bytes[2];
 
 	snd_i2c_lock(ice->i2c);
@@ -230,15 +238,18 @@
 	case ICE1712_SUBDEVICE_EWS88MT:
 	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_PHASE88:
-		if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1)
+		if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1)
+		    != 1)
 			goto _error;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
+		if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2)
+		    != 2)
 			goto _error;
 		if (bits != bytes[1]) {
 			bytes[1] = bits;
-			if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2)
+			if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D],
+					      bytes, 2) != 2)
 				goto _error;
 		}
 		break;
@@ -411,6 +422,7 @@
 {
 	int err;
 	struct snd_akm4xxx *ak;
+	struct ews_spec *spec;
 
 	/* set the analog DACs */
 	switch (ice->eeprom.subvendor) {
@@ -435,6 +447,11 @@
 		break;
 	}
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	/* create i2c */
 	if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
 		snd_printk(KERN_ERR "unable to create I2C bus\n");
@@ -446,7 +463,10 @@
 	/* create i2c devices */
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DMX6FIRE:
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) {
+		err = snd_i2c_device_create(ice->i2c, "PCF9554",
+					    ICE1712_6FIRE_PCF9554_ADDR,
+					    &spec->i2cdevs[EWS_I2C_6FIRE]);
+		if (err < 0) {
 			snd_printk(KERN_ERR "PCF9554 initialization failed\n");
 			return err;
 		}
@@ -455,18 +475,30 @@
 	case ICE1712_SUBDEVICE_EWS88MT:
 	case ICE1712_SUBDEVICE_EWS88MT_NEW:
 	case ICE1712_SUBDEVICE_PHASE88:
-		if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0)
+		err = snd_i2c_device_create(ice->i2c, "CS8404",
+					    ICE1712_EWS88MT_CS8404_ADDR,
+					    &spec->i2cdevs[EWS_I2C_CS8404]);
+		if (err < 0)
 			return err;
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0)
+		err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)",
+					    ICE1712_EWS88MT_INPUT_ADDR,
+					    &spec->i2cdevs[EWS_I2C_PCF1]);
+		if (err < 0)
 			return err;
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0)
+		err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)",
+					    ICE1712_EWS88MT_OUTPUT_ADDR,
+					    &spec->i2cdevs[EWS_I2C_PCF2]);
+		if (err < 0)
 			return err;
 		/* Check if the front module is connected */
 		if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
 			return err;
 		break;
 	case ICE1712_SUBDEVICE_EWS88D:
-		if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0)
+		err = snd_i2c_device_create(ice->i2c, "PCF8575",
+					    ICE1712_EWS88D_PCF_ADDR,
+					    &spec->i2cdevs[EWS_I2C_88D]);
+		if (err < 0)
 			return err;
 		break;
 	}
@@ -506,7 +538,7 @@
 	}
 
 	/* analog section */
-	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
+	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -604,10 +636,11 @@
 static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	unsigned char data;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -620,15 +653,17 @@
 static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	unsigned char data, ndata;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
 	ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
-	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) {
+	if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2],
+					       &ndata, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -640,12 +675,13 @@
 static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned char data;
 
 	snd_assert(channel >= 0 && channel <= 7, return 0);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -659,17 +695,19 @@
 static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned char data, ndata;
 
 	snd_assert(channel >= 0 && channel <= 7, return 0);
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
 	ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
-	if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) {
+	if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1],
+					       &ndata, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -704,12 +742,13 @@
 static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	unsigned char data[2];
 	
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -724,13 +763,14 @@
 static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct ews_spec *spec = ice->spec;
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	unsigned char data[2], ndata[2];
 	int change;
 
 	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -743,7 +783,8 @@
 			ndata[shift >> 3] |= (1 << (shift & 7));
 	}
 	change = (data[shift >> 3] != ndata[shift >> 3]);
-	if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) {
+	if (change &&
+	    snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
@@ -777,11 +818,13 @@
 static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
 {
 	unsigned char byte;
+	struct ews_spec *spec = ice->spec;
+
 	snd_i2c_lock(ice->i2c);
 	byte = reg;
-	snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1);
+	snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1);
 	byte = 0;
-	if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
+	if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
 		snd_i2c_unlock(ice->i2c);
 		printk(KERN_ERR "cannot read pca\n");
 		return -EIO;
@@ -793,10 +836,12 @@
 static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
 {
 	unsigned char bytes[2];
+	struct ews_spec *spec = ice->spec;
+
 	snd_i2c_lock(ice->i2c);
 	bytes[0] = reg;
 	bytes[1] = data;
-	if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
+	if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
 		snd_i2c_unlock(ice->i2c);
 		return -EIO;
 	}
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index b042e5c..cf5c7c08 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -33,6 +33,12 @@
 #include "ice1712.h"
 #include "hoontech.h"
 
+/* Hoontech-specific setting */
+struct hoontech_spec {
+	unsigned char boxbits[4];
+	unsigned int config;
+	unsigned short boxconfig[4];
+};
 
 static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
 {
@@ -49,169 +55,182 @@
 
 static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
 {
+	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
-	ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
+	ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
 {
+	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+	ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
 {
+	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+	ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
 {
+	struct hoontech_spec *spec = ice->spec;
+
 	mutex_lock(&ice->gpio_mutex);
 
 	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
+	ICE1712_STDSP24_0_BOX(spec->boxbits, box);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
 
 	/* prepare for write */
 	if (chn == 3)
-		ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
-	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+		ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
+	ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 
-	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
+	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 	udelay(100);
 	if (chn == 3) {
-		ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0);
-		snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+		ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
+		snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 	} else {
 		switch (chn) {
-		case 0:	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break;
-		case 1:	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break;
-		case 2:	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break;
+		case 0:	ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
+		case 1:	ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
+		case 2:	ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
 		}
-		snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
+		snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
 	}
 	udelay(100);
-	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
+	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 	udelay(100);
 
-	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
 {
+	struct hoontech_spec *spec = ice->spec;
+
 	mutex_lock(&ice->gpio_mutex);
 
 	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]);
+	ICE1712_STDSP24_0_BOX(spec->boxbits, box);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
 
-	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
+	ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 
 	udelay(100);
 	
-	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 	
 	mdelay(10);
 	
-	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]);
+	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
 
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
 {
+	struct hoontech_spec *spec = ice->spec;
 	mutex_lock(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]);
+	ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
+	snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
 	mutex_unlock(&ice->gpio_mutex);
 }
 
 static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
 {
+	struct hoontech_spec *spec;
 	int box, chn;
 
 	ice->num_total_dacs = 8;
 	ice->num_total_adcs = 8;
 
-	ice->spec.hoontech.boxbits[0] = 
-	ice->spec.hoontech.boxbits[1] = 
-	ice->spec.hoontech.boxbits[2] = 
-	ice->spec.hoontech.boxbits[3] = 0;	/* should be already */
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
 
-	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0);
-	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1);
-	ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0);
-	ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
+	ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
+	ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
+	ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
 
-	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1);
-	ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1);
+	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
+	ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
+	ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
+	ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
 	
-	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2);
-	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1);
-	ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
+	ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
+	ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
+	ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
+	ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
 
-	ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3);
-	ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1);
-	ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0);
-	ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1);
-	ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0);
+	ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
+	ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
+	ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
+	ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
+	ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
 
 	/* let's go - activate only functions in first box */
-	ice->spec.hoontech.config = 0;
+	spec->config = 0;
 			    /* ICE1712_STDSP24_MUTE |
 			       ICE1712_STDSP24_INSEL |
 			       ICE1712_STDSP24_DAREAR; */
-	ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
+	spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
 				     ICE1712_STDSP24_BOX_CHN2 |
 				     ICE1712_STDSP24_BOX_CHN3 |
 				     ICE1712_STDSP24_BOX_CHN4 |
 				     ICE1712_STDSP24_BOX_MIDI1 |
 				     ICE1712_STDSP24_BOX_MIDI2;
-	ice->spec.hoontech.boxconfig[1] = 
-	ice->spec.hoontech.boxconfig[2] = 
-	ice->spec.hoontech.boxconfig[3] = 0;
-	snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
-	snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0);
-	snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0);
+	spec->boxconfig[1] = 
+	spec->boxconfig[2] = 
+	spec->boxconfig[3] = 0;
+	snd_ice1712_stdsp24_darear(ice,
+		(spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
+	snd_ice1712_stdsp24_mute(ice,
+		(spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
+	snd_ice1712_stdsp24_insel(ice,
+		(spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
 	for (box = 0; box < 1; box++) {
-		if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
+		if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
                         snd_ice1712_stdsp24_midi2(ice, 1);
 		for (chn = 0; chn < 4; chn++)
-			snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0);
+			snd_ice1712_stdsp24_box_channel(ice, box, chn,
+				(spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
 		snd_ice1712_stdsp24_box_midi(ice, box,
-				(ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
+				(spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
 	}
 
 	return 0;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 47d7737..df292af 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2490,6 +2490,7 @@
 		pci_release_regions(ice->pci);
 	snd_ice1712_akm4xxx_free(ice);
 	pci_disable_device(ice->pci);
+	kfree(ice->spec);
 	kfree(ice);
 	return 0;
 }
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 86e418e..303cffe 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -366,56 +366,7 @@
 	struct mutex gpio_mutex;
 
 	/* other board-specific data */
-	union {
-		/* additional i2c devices for EWS boards */
-		struct snd_i2c_device *i2cdevs[3];
-		/* AC97 register cache for Aureon */
-		struct aureon_spec {
-			unsigned short stac9744[64];
-			unsigned int cs8415_mux;
-			unsigned short master[2];
-			unsigned short vol[8];
-			unsigned char pca9554_out;
-		} aureon;
-		/* AC97 register cache for Phase28 */
-		struct phase28_spec {
-			unsigned short master[2];
-			unsigned short vol[8];
-		} phase28;
-		/* a non-standard I2C device for revo51 */
-		struct revo51_spec {
-			struct snd_i2c_device *dev;
-			struct snd_pt2258 *pt2258;
-		} revo51;
-		/* Hoontech-specific setting */
-		struct hoontech_spec {
-			unsigned char boxbits[4];
-			unsigned int config;
-			unsigned short boxconfig[4];
-		} hoontech;
-		struct {
-			struct ak4114 *ak4114;
-			unsigned int analog: 1;
-		} juli;
-		struct {
-			struct ak4114 *ak4114;
-			/* rate change needs atomic mute/unmute of all dacs*/
-			struct mutex mute_mutex;
-		} prodigy192;
-		struct {
-			struct {
-				unsigned char ch1, ch2;
-			} vol[8];
-		} se;
-		struct prodigy_hifi_spec {
-			unsigned short master[2];
-			unsigned short vol[8];
-		} prodigy_hifi;
-		struct prodigy_hd2_spec {
-			unsigned short vol[2];
-		} prodigy_hd2;
-	} spec;
-
+	void *spec;
 };
 
 
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index c89a4fe..f533850 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2176,6 +2176,7 @@
 	pci_release_regions(ice->pci);
 	snd_ice1712_akm4xxx_free(ice);
 	pci_disable_device(ice->pci);
+	kfree(ice->spec);
 	kfree(ice);
 	return 0;
 }
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 1a435df..e8038c0 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -32,6 +32,11 @@
 #include "envy24ht.h"
 #include "juli.h"
 
+struct juli_spec {
+	struct ak4114 *ak4114;
+	unsigned int analog: 1;
+};
+
 /*
  * chip addresses on I2C bus
  */
@@ -137,12 +142,13 @@
 
 static int __devinit juli_add_controls(struct snd_ice1712 *ice)
 {
+	struct juli_spec *spec = ice->spec;
 	int err;
 	err = snd_ice1712_akm4xxx_build_controls(ice);
 	if (err < 0)
 		return err;
 	/* only capture SPDIF over AK4114 */
-	err = snd_ak4114_build(ice->spec.juli.ak4114, NULL,
+	err = snd_ak4114_build(spec->ak4114, NULL,
 			       ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
 	if (err < 0)
 		return err;
@@ -166,13 +172,19 @@
 		0x41, 0x02, 0x2c, 0x00, 0x00
 	};
 	int err;
+	struct juli_spec *spec;
 	struct snd_akm4xxx *ak;
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	err = snd_ak4114_create(ice->card,
 				juli_ak4114_read,
 				juli_ak4114_write,
 				ak4114_init_vals, ak4114_init_txcsb,
-				ice, &ice->spec.juli.ak4114);
+				ice, &spec->ak4114);
 	if (err < 0)
 		return err;
 
@@ -180,12 +192,12 @@
         /* it seems that the analog doughter board detection does not work
            reliably, so force the analog flag; it should be very rare
            to use Juli@ without the analog doughter board */
-	ice->spec.juli.analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
+	spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
 #else
-        ice->spec.juli.analog = 1;
+        spec->analog = 1;
 #endif
 
-	if (ice->spec.juli.analog) {
+	if (spec->analog) {
 		printk(KERN_INFO "juli@: analog I/O detected\n");
 		ice->num_total_dacs = 2;
 		ice->num_total_adcs = 2;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 718e935..9ab4a9f 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -47,6 +47,12 @@
 #include "phase.h"
 #include <sound/tlv.h>
 
+/* AC97 register cache for Phase28 */
+struct phase28_spec {
+	unsigned short master[2];
+	unsigned short vol[8];
+} phase28;
+
 /* WM8770 registers */
 #define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
 #define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
@@ -312,15 +318,17 @@
 static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int i;
 	for (i=0; i<2; i++)
-		ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE;
+		ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
 static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int ch, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -328,14 +336,14 @@
 		unsigned int vol = ucontrol->value.integer.value[ch];
 		if (vol > WM_VOL_MAX)
 			continue;
-		vol |= ice->spec.phase28.master[ch] & WM_VOL_MUTE;
-		if (vol != ice->spec.phase28.master[ch]) {
+		vol |= spec->master[ch] & WM_VOL_MUTE;
+		if (vol != spec->master[ch]) {
 			int dac;
-			ice->spec.phase28.master[ch] = vol;
+			spec->master[ch] = vol;
 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
-					   ice->spec.phase28.vol[dac + ch],
-					   ice->spec.phase28.master[ch]);
+					   spec->vol[dac + ch],
+					   spec->master[ch]);
 			change = 1;
 		}
 	}
@@ -384,12 +392,18 @@
 
 	unsigned int tmp;
 	struct snd_akm4xxx *ak;
+	struct phase28_spec *spec;
 	const unsigned short *p;
 	int i;
 
 	ice->num_total_dacs = 8;
 	ice->num_total_adcs = 2;
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	// Initialize analog chips
 	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (!ak)
@@ -419,11 +433,11 @@
 
 	snd_ice1712_restore_gpio_status(ice);
 
-	ice->spec.phase28.master[0] = WM_VOL_MUTE;
-	ice->spec.phase28.master[1] = WM_VOL_MUTE;
+	spec->master[0] = WM_VOL_MUTE;
+	spec->master[1] = WM_VOL_MUTE;
 	for (i = 0; i < ice->num_total_dacs; i++) {
-		ice->spec.phase28.vol[i] = WM_VOL_MUTE;
-		wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]);
+		spec->vol[i] = WM_VOL_MUTE;
+		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
 	}
 
 	return 0;
@@ -445,18 +459,21 @@
 static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xff;
 	for (i = 0; i < voices; i++)
-		ucontrol->value.integer.value[i] = ice->spec.phase28.vol[ofs+i] & ~WM_VOL_MUTE;
+		ucontrol->value.integer.value[i] =
+			spec->vol[ofs+i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
 static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int i, idx, ofs, voices;
 	int change = 0;
 
@@ -468,12 +485,12 @@
 		vol = ucontrol->value.integer.value[i];
 		if (vol > 0x7f)
 			continue;
-		vol |= ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE;
-		if (vol != ice->spec.phase28.vol[ofs+i]) {
-			ice->spec.phase28.vol[ofs+i] = vol;
+		vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
+		if (vol != spec->vol[ofs+i]) {
+			spec->vol[ofs+i] = vol;
 			idx  = WM_DAC_ATTEN + ofs + i;
-			wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i],
-				   ice->spec.phase28.master[i]);
+			wm_set_vol(ice, idx, spec->vol[ofs+i],
+				   spec->master[i]);
 			change = 1;
 		}
 	}
@@ -495,19 +512,22 @@
 static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xFF;
 
 	for (i = 0; i < voices; i++)
-		ucontrol->value.integer.value[i] = (ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
+		ucontrol->value.integer.value[i] =
+			(spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
 static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int change = 0, voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
@@ -515,13 +535,13 @@
 
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < voices; i++) {
-		int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
+		int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
 		if (ucontrol->value.integer.value[i] != val) {
-			ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE;
-			ice->spec.phase28.vol[ofs + i] |=
+			spec->vol[ofs + i] &= ~WM_VOL_MUTE;
+			spec->vol[ofs + i] |=
 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
-			wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i],
-				   ice->spec.phase28.master[i]);
+			wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
+				   spec->master[i]);
 			change = 1;
 		}
 	}
@@ -538,29 +558,33 @@
 static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 
-	ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1;
-	ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[0] =
+		(spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[1] =
+		(spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
 static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct phase28_spec *spec = ice->spec;
 	int change = 0, i;
 
 	snd_ice1712_save_gpio_status(ice);
 	for (i = 0; i < 2; i++) {
-		int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1;
+		int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
 		if (ucontrol->value.integer.value[i] != val) {
 			int dac;
-			ice->spec.phase28.master[i] &= ~WM_VOL_MUTE;
-			ice->spec.phase28.master[i] |=
+			spec->master[i] &= ~WM_VOL_MUTE;
+			spec->master[i] |=
 				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
 			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
 				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
-					   ice->spec.phase28.vol[dac + i],
-					   ice->spec.phase28.master[i]);
+					   spec->vol[dac + i],
+					   spec->master[i]);
 			change = 1;
 		}
 	}
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 7339378..48cf40a 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -67,6 +67,12 @@
 #include "stac946x.h"
 #include <sound/tlv.h>
 
+struct prodigy192_spec {
+	struct ak4114 *ak4114;
+	/* rate change needs atomic mute/unmute of all dacs*/
+	struct mutex mute_mutex;
+};
+
 static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
 {
 	snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
@@ -118,6 +124,7 @@
 static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy192_spec *spec = ice->spec;
 	int idx, change;
 
 	if (kcontrol->private_value)
@@ -125,11 +132,11 @@
 	else
 		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
 	/* due to possible conflicts with stac9460_set_rate_val, mutexing */
-	mutex_lock(&ice->spec.prodigy192.mute_mutex);
+	mutex_lock(&spec->mute_mutex);
 	/*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
 		ucontrol->value.integer.value[0]);*/
 	change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
-	mutex_unlock(&ice->spec.prodigy192.mute_mutex);
+	mutex_unlock(&spec->mute_mutex);
 	return change;
 }
 
@@ -318,6 +325,7 @@
 	int idx;
 	unsigned char changed[7];
 	struct snd_ice1712 *ice = ak->private_data[0];
+	struct prodigy192_spec *spec = ice->spec;
 
 	if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
 		return;
@@ -332,7 +340,7 @@
 		return;
 	/* change detected, setting master clock, muting first */
 	/* due to possible conflicts with mute controls - mutexing */
-	mutex_lock(&ice->spec.prodigy192.mute_mutex);
+	mutex_lock(&spec->mute_mutex);
 	/* we have to remember current mute status for each DAC */
 	for (idx = 0; idx < 7 ; ++idx)
 		changed[idx] = stac9460_dac_mute(ice,
@@ -346,7 +354,7 @@
 		if (changed[idx])
 			stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
 	}
-	mutex_unlock(&ice->spec.prodigy192.mute_mutex);
+	mutex_unlock(&spec->mute_mutex);
 }
 
 /* using akm infrastructure for setting rate of the codec */
@@ -633,12 +641,13 @@
 	static const unsigned char ak4114_init_txcsb[] = {
 		0x41, 0x02, 0x2c, 0x00, 0x00
 	};
+	struct prodigy192_spec *spec = ice->spec;
 
 	return snd_ak4114_create(ice->card,
 				 prodigy192_ak4114_read,
 				 prodigy192_ak4114_write,
 				 ak4114_init_vals, ak4114_init_txcsb,
-				 ice, &ice->spec.prodigy192.ak4114);
+				 ice, &spec->ak4114);
 }
 
 static void stac9460_proc_regs_read(struct snd_info_entry *entry,
@@ -664,6 +673,7 @@
 
 static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
 {
+	struct prodigy192_spec *spec = ice->spec;
 	unsigned int i;
 	int err;
 
@@ -673,7 +683,7 @@
 		if (err < 0)
 			return err;
 	}
-	if (ice->spec.prodigy192.ak4114) {
+	if (spec->ak4114) {
 		/* ak4114 is connected */
 		for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
 			err = snd_ctl_add(ice->card,
@@ -682,7 +692,7 @@
 			if (err < 0)
 				return err;
 		}
-		err = snd_ak4114_build(ice->spec.prodigy192.ak4114,
+		err = snd_ak4114_build(spec->ak4114,
 				NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
 				ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
 		if (err < 0)
@@ -734,12 +744,19 @@
 	const unsigned short *p;
 	int err = 0;
 	struct snd_akm4xxx *ak;
+	struct prodigy192_spec *spec;
 
 	/* prodigy 192 */
 	ice->num_total_dacs = 6;
 	ice->num_total_adcs = 2;
 	ice->vt1720 = 0;  /* ice1724, e.g. 23 GPIOs */
 	
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+	mutex_init(&spec->mute_mutex);
+
 	/* initialize codec */
 	p = stac_inits_prodigy;
 	for (; *p != (unsigned short)-1; p += 2)
@@ -758,7 +775,7 @@
 	if (prodigy192_miodio_exists(ice)) {
 		err = prodigy192_ak4114_init(ice);
 		/* from this moment if err = 0 then
-		 * ice->spec.prodigy192.ak4114 should not be null
+		 * spec->ak4114 should not be null
 		 */
 		snd_printdd("AK4114 initialized with status %d\n", err);
 	} else
@@ -766,8 +783,6 @@
 	if (err < 0)
 		return err;
 
-	mutex_init(&ice->spec.prodigy192.mute_mutex);
-
 	return 0;
 }
 
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 6ec1aa4..043a938 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -40,6 +40,11 @@
 #include "envy24ht.h"
 #include "prodigy_hifi.h"
 
+struct prodigy_hifi_spec {
+	unsigned short master[2];
+	unsigned short vol[8];
+};
+
 /* I2C addresses */
 #define WM_DEV		0x34
 
@@ -177,7 +182,8 @@
 	}
 }
 
-static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg, unsigned int data)
+static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
+			     unsigned int data)
 {
 	unsigned int block;
 
@@ -216,7 +222,8 @@
 	}
 }
 
-static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg, unsigned int data)
+static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
+			 unsigned int data)
 {
 	unsigned int block;
 
@@ -246,7 +253,8 @@
  * DAC volume attenuation mixer control (-64dB to 0dB)
  */
 
-static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -255,31 +263,32 @@
 	return 0;
 }
 
-static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i;
 	
-	for (i = 0; i < 2; i++) {
-		ucontrol->value.integer.value[i] =ice->spec.prodigy_hd2.vol[i];
-	}
+	for (i = 0; i < 2; i++)
+		ucontrol->value.integer.value[i] = spec->vol[i];
+
 	return 0;
 }
 
 static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i;
 	int change = 0;
 	
 	mutex_lock(&ice->gpio_mutex);
 	for (i = 0; i < 2; i++) {
-		if (ucontrol->value.integer.value[i] !=
-				  ice->spec.prodigy_hd2.vol[i]) {
-			ice->spec.prodigy_hd2.vol[i] =
-					ucontrol->value.integer.value[i];
-			ak4396_write(ice, AK4396_LCH_ATT+i,
-				     (ice->spec.prodigy_hd2.vol[i] & 0xff));
+		if (ucontrol->value.integer.value[i] != spec->vol[i]) {
+			spec->vol[i] = ucontrol->value.integer.value[i];
+			ak4396_write(ice, AK4396_LCH_ATT + i,
+				     spec->vol[i] & 0xff);
 			change = 1;
 		}
 	}
@@ -333,7 +342,8 @@
 #define DAC_MIN	(DAC_0dB - DAC_RES)
 
 
-static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
+static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
+		       unsigned short vol, unsigned short master)
 {
 	unsigned char nvol;
 	
@@ -349,7 +359,8 @@
 	wm_put_nocache(ice, index, 0x100 | nvol);
 }
 
-static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
+static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
+			   unsigned short vol, unsigned short master)
 {
 	unsigned char nvol;
 	
@@ -360,7 +371,6 @@
 				& WM_VOL_MAX;
 		nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
 	}
-	
 
 	wm8766_spi_write(ice, index, (0x0100 | nvol));
 }
@@ -370,7 +380,8 @@
  * DAC volume attenuation mixer control (-64dB to 0dB)
  */
 
-static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -379,33 +390,32 @@
 	return 0;
 }
 
-static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i;
 
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < 2; i++)
 		ucontrol->value.integer.value[i] =
-				ice->spec.prodigy_hifi.vol[2+i] & ~WM_VOL_MUTE;
-	}
+			spec->vol[2 + i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
 static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i, idx, change = 0;
 
 	mutex_lock(&ice->gpio_mutex);
 	for (i = 0; i < 2; i++) {
-		if (ucontrol->value.integer.value[i] !=
-				  ice->spec.prodigy_hifi.vol[2+i]) {
+		if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
 			idx = WM_DAC_ATTEN_L + i;
-			ice->spec.prodigy_hifi.vol[2+i] &= WM_VOL_MUTE;
-			ice->spec.prodigy_hifi.vol[2+i] |=
-					ucontrol->value.integer.value[i];
-			wm_set_vol(ice, idx, ice->spec.prodigy_hifi.vol[2+i],
-				   ice->spec.prodigy_hifi.master[i]);
+			spec->vol[2 + i] &= WM_VOL_MUTE;
+			spec->vol[2 + i] |= ucontrol->value.integer.value[i];
+			wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
 			change = 1;
 		}
 	}
@@ -417,7 +427,8 @@
 /*
  * WM8766 DAC volume attenuation mixer control
  */
-static int wm8766_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_info *uinfo)
 {
 	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -427,22 +438,24 @@
 	return 0;
 }
 
-static int wm8766_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
 	ofs = kcontrol->private_value & 0xff;
 	for (i = 0; i < voices; i++)
-		ucontrol->value.integer.value[i] =
-				ice->spec.prodigy_hifi.vol[ofs+i];
+		ucontrol->value.integer.value[i] = spec->vol[ofs + i];
 	return 0;
 }
 
 static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i, idx, ofs, voices;
 	int change = 0;
 
@@ -450,15 +463,12 @@
 	ofs = kcontrol->private_value & 0xff;
 	mutex_lock(&ice->gpio_mutex);
 	for (i = 0; i < voices; i++) {
-		if (ucontrol->value.integer.value[i] !=
-				  ice->spec.prodigy_hifi.vol[ofs+i]) {
+		if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
 			idx = WM8766_LDA1 + ofs + i;
-			ice->spec.prodigy_hifi.vol[ofs+i] &= WM_VOL_MUTE;
-			ice->spec.prodigy_hifi.vol[ofs+i] |=
-					ucontrol->value.integer.value[i];
+			spec->vol[ofs + i] &= WM_VOL_MUTE;
+			spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
 			wm8766_set_vol(ice, idx,
-					ice->spec.prodigy_hifi.vol[ofs+i],
-					ice->spec.prodigy_hifi.master[i]);
+				       spec->vol[ofs + i], spec->master[i]);
 			change = 1;
 		}
 	}
@@ -469,7 +479,8 @@
 /*
  * Master volume attenuation mixer control / applied to WM8776+WM8766
  */
-static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -478,45 +489,41 @@
 	return 0;
 }
 
-static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int i;
-	for (i=0; i<2; i++)
-		ucontrol->value.integer.value[i] =
-				ice->spec.prodigy_hifi.master[i];
+	for (i = 0; i < 2; i++)
+		ucontrol->value.integer.value[i] = spec->master[i];
 	return 0;
 }
 
-static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	struct prodigy_hifi_spec *spec = ice->spec;
 	int ch, change = 0;
 
 	mutex_lock(&ice->gpio_mutex);
 	for (ch = 0; ch < 2; ch++) {
-		if (ucontrol->value.integer.value[ch] !=
-				  ice->spec.prodigy_hifi.master[ch]) {
-			ice->spec.prodigy_hifi.master[ch] &= 0x00;
-			ice->spec.prodigy_hifi.master[ch] |=
-					ucontrol->value.integer.value[ch];
+		if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
+			spec->master[ch] = ucontrol->value.integer.value[ch];
 
 			/* Apply to front DAC */
 			wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
-				   ice->spec.prodigy_hifi.vol[2 + ch],
-				   ice->spec.prodigy_hifi.master[ch]);
+				   spec->vol[2 + ch], spec->master[ch]);
 
 			wm8766_set_vol(ice, WM8766_LDA1 + ch,
-				   ice->spec.prodigy_hifi.vol[0 + ch],
-				   ice->spec.prodigy_hifi.master[ch]);
+				       spec->vol[0 + ch], spec->master[ch]);
 
 			wm8766_set_vol(ice, WM8766_LDA2 + ch,
-				   ice->spec.prodigy_hifi.vol[4 + ch],
-				   ice->spec.prodigy_hifi.master[ch]);
+				       spec->vol[4 + ch], spec->master[ch]);
 
 			wm8766_set_vol(ice, WM8766_LDA3 + ch,
-				   ice->spec.prodigy_hifi.vol[6 + ch],
-				   ice->spec.prodigy_hifi.master[ch]);
+				       spec->vol[6 + ch], spec->master[ch]);
 			change = 1;
 		}
 	}
@@ -525,64 +532,71 @@
 }
 
 
-
 /* KONSTI */
 
-static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
-	static char* texts[32] = {"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
-				  WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
-				  WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
-				  WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
-				  WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
-				  WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
-				  WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
-				  WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
-				  WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
-				  WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5};
+	static char* texts[32] = {
+		"NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
+		WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
+		WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
+		WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
+		WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
+		WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
+		WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
+		WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
+		WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
+		WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
+	};
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
 	uinfo->value.enumerated.items = 32;
 	if (uinfo->value.enumerated.item > 31)
 		uinfo->value.enumerated.item = 31;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
 	return 0;
 }
 
-static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	mutex_lock(&ice->gpio_mutex);
-	ucontrol->value.integer.value[0]=wm_get(ice, WM_ADC_MUX) & 0x1f;
+	ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
 	mutex_unlock(&ice->gpio_mutex);
 	return 0;
 }
 
-static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short oval, nval;
+	int change = 0;
 
 	mutex_lock(&ice->gpio_mutex);
 	oval = wm_get(ice, WM_ADC_MUX);
-	nval = ( oval & 0xe0 ) | ucontrol->value.integer.value[0] ;
-	if ( nval != oval ) {
+	nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
+	if (nval != oval) {
 		wm_put(ice, WM_ADC_MUX, nval);
+		change = 1;
 	}
 	mutex_unlock(&ice->gpio_mutex);
-	return 0;
+	return change;
 }
 
 /* KONSTI */
@@ -595,7 +609,8 @@
 #define ADC_RES	128
 #define ADC_MIN	(ADC_0dB - ADC_RES)
 
-static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -604,7 +619,8 @@
 	return 0;
 }
 
-static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
@@ -620,7 +636,8 @@
 	return 0;
 }
 
-static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
@@ -644,27 +661,23 @@
 /*
  * ADC input mux mixer control
  */
-static int wm_adc_mux_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;
-}
+#define wm_adc_mux_info		snd_ctl_boolean_mono_info
 
-static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int bit = kcontrol->private_value;
 
 	mutex_lock(&ice->gpio_mutex);
-	ucontrol->value.integer.value[0] = (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
+	ucontrol->value.integer.value[0] =
+		(wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
 	mutex_unlock(&ice->gpio_mutex);
 	return 0;
 }
 
-static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int bit = kcontrol->private_value;
@@ -688,26 +701,22 @@
 /*
  * Analog bypass (In -> Out)
  */
-static int wm_bypass_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;
-}
+#define wm_bypass_info		snd_ctl_boolean_mono_info
 
-static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_bypass_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	mutex_lock(&ice->gpio_mutex);
-	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
+	ucontrol->value.integer.value[0] =
+		(wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
 	mutex_unlock(&ice->gpio_mutex);
 	return 0;
 }
 
-static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_bypass_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val, oval;
@@ -730,16 +739,10 @@
 /*
  * Left/Right swap
  */
-static int wm_chswap_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;
-}
+#define wm_chswap_info		snd_ctl_boolean_mono_info
 
-static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_chswap_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
@@ -750,7 +753,8 @@
 	return 0;
 }
 
-static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+static int wm_chswap_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val, oval;
@@ -894,9 +898,10 @@
 /*
  * WM codec registers
  */
-static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+static void wm_proc_regs_write(struct snd_info_entry *entry,
+			       struct snd_info_buffer *buffer)
 {
-	struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
+	struct snd_ice1712 *ice = entry->private_data;
 	char line[64];
 	unsigned int reg, val;
 	mutex_lock(&ice->gpio_mutex);
@@ -909,9 +914,10 @@
 	mutex_unlock(&ice->gpio_mutex);
 }
 
-static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+static void wm_proc_regs_read(struct snd_info_entry *entry,
+			      struct snd_info_buffer *buffer)
 {
-	struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
+	struct snd_ice1712 *ice = entry->private_data;
 	int reg, val;
 
 	mutex_lock(&ice->gpio_mutex);
@@ -925,7 +931,7 @@
 static void wm_proc_init(struct snd_ice1712 *ice)
 {
 	struct snd_info_entry *entry;
-	if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
+	if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
 		snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
 		entry->mode |= S_IWUSR;
 		entry->c.text.write = wm_proc_regs_write;
@@ -938,7 +944,8 @@
 	int err;
 
 	for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&prodigy_hifi_controls[i], ice));
+		err = snd_ctl_add(ice->card,
+				  snd_ctl_new1(&prodigy_hifi_controls[i], ice));
 		if (err < 0)
 			return err;
 	}
@@ -950,18 +957,19 @@
 
 static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
 {
-    unsigned int i;
-    int err;
+	unsigned int i;
+	int err;
 
-    for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
-	err = snd_ctl_add(ice->card, snd_ctl_new1(&prodigy_hd2_controls[i], ice));
-	if (err < 0)
-	    return err;
-    }
+	for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
+		err = snd_ctl_add(ice->card,
+				  snd_ctl_new1(&prodigy_hd2_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
 
-    wm_proc_init(ice);
+	wm_proc_init(ice);
 
-    return 0;
+	return 0;
 }
 
 
@@ -1025,7 +1033,7 @@
 		WM8766_MUTE2,	   0x0000,
 	};
 
-
+	struct prodigy_hifi_spec *spec;
 	unsigned int i;
 
 	ice->vt1720 = 0;
@@ -1033,7 +1041,6 @@
 
 	ice->num_total_dacs = 8;
 	ice->num_total_adcs = 1;
-	ice->akm_codecs = 2;
 
 	/* HACK - use this as the SPDIF source.
 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
@@ -1044,7 +1051,12 @@
 	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
-		ice->akm_codecs = 1;
+	ice->akm_codecs = 1;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
 
 	/* initialize WM8776 codec */
 	for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
@@ -1054,7 +1066,6 @@
 		wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
 
 	/* initialize WM8766 codec */
-
 	for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
 		wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
 
@@ -1076,7 +1087,7 @@
 		AK4396_RCH_ATT,	 0x00,
 	};
 
-
+	struct prodigy_hifi_spec *spec;
 	unsigned int i;
 
 	ice->vt1720 = 0;
@@ -1084,7 +1095,6 @@
 
 	ice->num_total_dacs = 1;
 	ice->num_total_adcs = 1;
-	ice->akm_codecs = 1;
 
 	/* HACK - use this as the SPDIF source.
 	* don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
@@ -1097,6 +1107,11 @@
 		return -ENOMEM;
 	ice->akm_codecs = 1;
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	/* initialize ak4396 codec */
 	/* reset codec */
 	ak4396_write(ice, AK4396_CTRL1, 0x86);
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 05a751c..ddd5fc8 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -32,6 +32,12 @@
 #include "envy24ht.h"
 #include "revo.h"
 
+/* a non-standard I2C device for revo51 */
+struct revo51_spec {
+	struct snd_i2c_device *dev;
+	struct snd_pt2258 *pt2258;
+} revo51;
+
 static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
 {
 	/* assert PRST# to converters; MT05 bit 7 */
@@ -152,8 +158,14 @@
 static int revo51_i2c_init(struct snd_ice1712 *ice,
 			   struct snd_pt2258 *pt)
 {
+	struct revo51_spec *spec;
 	int err;
 
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	/* create the I2C bus */
 	err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
 	if (err < 0)
@@ -163,15 +175,14 @@
 	ice->i2c->hw_ops.bit = &revo51_bit_ops;
 
 	/* create the I2C device */
-	err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40,
-				    &ice->spec.revo51.dev);
+	err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
 	if (err < 0)
 		return err;
 
 	pt->card = ice->card;
 	pt->i2c_bus = ice->i2c;
-	pt->i2c_dev = ice->spec.revo51.dev;
-	ice->spec.revo51.pt2258 = pt;
+	pt->i2c_dev = spec->dev;
+	spec->pt2258 = pt;
 
 	snd_pt2258_reset(pt);
 
@@ -555,6 +566,7 @@
 
 static int __devinit revo_add_controls(struct snd_ice1712 *ice)
 {
+	struct revo51_spec *spec;
 	int err;
 
 	switch (ice->eeprom.subvendor) {
@@ -567,7 +579,8 @@
 		err = snd_ice1712_akm4xxx_build_controls(ice);
 		if (err < 0)
 			return err;
-		err = snd_pt2258_build_controls(ice->spec.revo51.pt2258);
+		spec = ice->spec;
+		err = snd_pt2258_build_controls(spec->pt2258);
 		if (err < 0)
 			return err;
 		break;
diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c
index 6661f65..69673b9 100644
--- a/sound/pci/ice1712/se.c
+++ b/sound/pci/ice1712/se.c
@@ -34,6 +34,11 @@
 #include "envy24ht.h"
 #include "se.h"
 
+struct se_spec {
+	struct {
+		unsigned char ch1, ch2;
+	} vol[8];
+};
 
 /****************************************************************************/
 /*  ONKYO WAVIO SE-200PCI                                                   */
@@ -462,9 +467,10 @@
 				    struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
-	uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
-	uc->value.integer.value[1] = ice->spec.se.vol[n].ch2;
+	uc->value.integer.value[0] = spec->vol[n].ch1;
+	uc->value.integer.value[1] = spec->vol[n].ch2;
 	return 0;
 }
 
@@ -472,8 +478,9 @@
 				     struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
-	uc->value.integer.value[0] = ice->spec.se.vol[n].ch1;
+	uc->value.integer.value[0] = spec->vol[n].ch1;
 	return 0;
 }
 
@@ -481,44 +488,46 @@
 				  struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
-	uc->value.enumerated.item[0] = ice->spec.se.vol[n].ch1;
+	uc->value.enumerated.item[0] = spec->vol[n].ch1;
 	return 0;
 }
 
 static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
 {
+	struct se_spec *spec = ice->spec;
 	switch (se200pci_cont[n].target) {
 	case WM8766:
 		se200pci_WM8766_set_volume(ice,
 					   se200pci_cont[n].ch,
-					   ice->spec.se.vol[n].ch1,
-					   ice->spec.se.vol[n].ch2);
+					   spec->vol[n].ch1,
+					   spec->vol[n].ch2);
 		break;
 
 	case WM8776in:
 		se200pci_WM8776_set_input_volume(ice,
-						 ice->spec.se.vol[n].ch1,
-						 ice->spec.se.vol[n].ch2);
+						 spec->vol[n].ch1,
+						 spec->vol[n].ch2);
 		break;
 
 	case WM8776out:
 		se200pci_WM8776_set_output_volume(ice,
-						  ice->spec.se.vol[n].ch1,
-						  ice->spec.se.vol[n].ch2);
+						  spec->vol[n].ch1,
+						  spec->vol[n].ch2);
 		break;
 
 	case WM8776sel:
 		se200pci_WM8776_set_input_selector(ice,
-						   ice->spec.se.vol[n].ch1);
+						   spec->vol[n].ch1);
 		break;
 
 	case WM8776agc:
-		se200pci_WM8776_set_agc(ice, ice->spec.se.vol[n].ch1);
+		se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
 		break;
 
 	case WM8776afl:
-		se200pci_WM8776_set_afl(ice, ice->spec.se.vol[n].ch1);
+		se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
 		break;
 
 	default:
@@ -530,6 +539,7 @@
 				    struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
 	unsigned int vol1, vol2;
 	int changed;
@@ -537,12 +547,12 @@
 	changed = 0;
 	vol1 = uc->value.integer.value[0] & 0xff;
 	vol2 = uc->value.integer.value[1] & 0xff;
-	if (ice->spec.se.vol[n].ch1 != vol1) {
-		ice->spec.se.vol[n].ch1 = vol1;
+	if (spec->vol[n].ch1 != vol1) {
+		spec->vol[n].ch1 = vol1;
 		changed = 1;
 	}
-	if (ice->spec.se.vol[n].ch2 != vol2) {
-		ice->spec.se.vol[n].ch2 = vol2;
+	if (spec->vol[n].ch2 != vol2) {
+		spec->vol[n].ch2 = vol2;
 		changed = 1;
 	}
 	if (changed)
@@ -555,12 +565,13 @@
 				     struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
 	unsigned int vol1;
 
 	vol1 = !!uc->value.integer.value[0];
-	if (ice->spec.se.vol[n].ch1 != vol1) {
-		ice->spec.se.vol[n].ch1 = vol1;
+	if (spec->vol[n].ch1 != vol1) {
+		spec->vol[n].ch1 = vol1;
 		se200pci_cont_update(ice, n);
 		return 1;
 	}
@@ -571,14 +582,15 @@
 				  struct snd_ctl_elem_value *uc)
 {
 	struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
+	struct se_spec *spec = ice->spec;
 	int n = kc->private_value;
 	unsigned int vol1;
 
 	vol1 = uc->value.enumerated.item[0];
 	if (vol1 >= se200pci_get_enum_count(n))
 		return -EINVAL;
-	if (ice->spec.se.vol[n].ch1 != vol1) {
-		ice->spec.se.vol[n].ch1 = vol1;
+	if (spec->vol[n].ch1 != vol1) {
+		spec->vol[n].ch1 = vol1;
 		se200pci_cont_update(ice, n);
 		return 1;
 	}
@@ -668,6 +680,13 @@
 
 static int __devinit se_init(struct snd_ice1712 *ice)
 {
+	struct se_spec *spec;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (!spec)
+		return -ENOMEM;
+	ice->spec = spec;
+
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
 		ice->num_total_dacs = 2;
 		ice->num_total_adcs = 0;