You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


ChangeSet@1.655, 2002-10-01 16:59:17+02:00, perex@suse.cz
  ALSA update 2002/10/01 :
    - deleted sound/pci/ice1712.c
    - fixed Makefile to point to sound/pci/ice1712 directory
    - added Ensoniq SoundScape header file and HWDEP IFACE
    - CS4231
      - added CS4231_HW_AD1845 and register definitions for AD1845
    - USB
      - added snd-rawmidi.o to the snd-usb-audio's dependency if sequencer is
    - PCI DMA allocation
      - fixed the wrapper again
    - AC'97 codec
      - added HSD11246 identification (Conexant), a bit improved proc contents
    - CMIPCI
      - changed the DMA configuration for period size
      - fixed compile with SOFT_AC3 option
      - added PCM_INFO_PAUSE to hw settings.  now pause should work properly
      - corrected the modem on/off bit (FLINK)
    - ICE1712
      - compilation fixes
    - intel8x0
      - use mmio for codec on nforce (pci resource 2)
      - clean up and fix ali5455 codes
    - RME32
      - enable 88.2/96kHz on capture with CS8414
    - VIA82xx
      - fixed the size of allocated bd array to be released
      - fixed the allocation size of idx_table
    - PPC Awacs
      - replaced one more mdelay() with schedule
      - try to touch mic boost on screamer at init
    - USB Audio
      - reset each interface at initialization
      - reset the old interface if a new interface is chosen
      - don't claim the interface which already claimed


 b/include/sound/asound.h             |    3 
 b/include/sound/cs4231.h             |    7 
 b/include/sound/opl3.h               |    2 
 b/include/sound/sscape_ioctl.h       |   19 
 b/include/sound/version.h            |    2 
 b/sound/core/Makefile                |    3 
 b/sound/core/control.c               |    7 
 b/sound/core/hwdep.c                 |    8 
 b/sound/core/seq/oss/seq_oss_synth.c |    2 
 b/sound/core/sound.c                 |    3 
 b/sound/core/wrappers.c              |   23 
 b/sound/isa/ad1848/ad1848_lib.c      |    1 
 b/sound/isa/cs423x/cs4231_lib.c      |    8 
 b/sound/pci/Makefile                 |    4 
 b/sound/pci/ac97/ac97_codec.c        |    8 
 b/sound/pci/cmipci.c                 |   26 
 b/sound/pci/ice1712/ews.c            |    3 
 b/sound/pci/intel8x0.c               |   77 
 b/sound/pci/rme32.c                  |    4 
 b/sound/pci/via82xx.c                |    4 
 b/sound/ppc/awacs.c                  |   33 
 b/sound/usb/usbaudio.c               |   28 
 sound/pci/ice1712.c                  | 4441 -----------------------------------
 23 files changed, 183 insertions(+), 4533 deletions(-)


diff -Nru a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h	Tue Oct  1 17:11:59 2002
+++ b/include/sound/asound.h	Tue Oct  1 17:11:59 2002
@@ -103,9 +103,10 @@
 	SNDRV_HWDEP_IFACE_EMU10K1,	/* FX8010 processor in EMU10K1 chip */
 	SNDRV_HWDEP_IFACE_YSS225,	/* Yamaha FX processor */
 	SNDRV_HWDEP_IFACE_ICS2115,	/* Wavetable synth */
+	SNDRV_HWDEP_IFACE_SSCAPE,	/* Ensoniq SoundScape ISA card (MC68EC000) */
 
 	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_ICS2115,
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SSCAPE,
 };
 
 struct sndrv_hwdep_info {
diff -Nru a/include/sound/cs4231.h b/include/sound/cs4231.h
--- a/include/sound/cs4231.h	Tue Oct  1 17:11:59 2002
+++ b/include/sound/cs4231.h	Tue Oct  1 17:11:59 2002
@@ -54,22 +54,28 @@
 #define CS4231_PLY_UPR_CNT	0x0e	/* playback upper base count */
 #define CS4231_PLY_LWR_CNT	0x0f	/* playback lower base count */
 #define CS4231_ALT_FEATURE_1	0x10	/* alternate #1 feature enable */
+#define AD1845_AF1_MIC_LEFT	0x10	/* alternate #1 feature + MIC left */
 #define CS4231_ALT_FEATURE_2	0x11	/* alternate #2 feature enable */
+#define AD1845_AF2_MIC_RIGHT	0x11	/* alternate #2 feature + MIC right */
 #define CS4231_LEFT_LINE_IN	0x12	/* left line input control */
 #define CS4231_RIGHT_LINE_IN	0x13	/* right line input control */
 #define CS4231_TIMER_LOW	0x14	/* timer low byte */
 #define CS4231_TIMER_HIGH	0x15	/* timer high byte */
 #define CS4231_LEFT_MIC_INPUT	0x16	/* left MIC input control register (InterWave only) */
+#define AD1845_UPR_FREQ_SEL	0x16	/* upper byte of frequency select */
 #define CS4231_RIGHT_MIC_INPUT	0x17	/* right MIC input control register (InterWave only) */
+#define AD1845_LWR_FREQ_SEL	0x17	/* lower byte of frequency select */
 #define CS4236_EXT_REG		0x17	/* extended register access */
 #define CS4231_IRQ_STATUS	0x18	/* irq status register */
 #define CS4231_LINE_LEFT_OUTPUT	0x19	/* left line output control register (InterWave only) */
 #define CS4231_VERSION		0x19	/* CS4231(A) - version values */
 #define CS4231_MONO_CTRL	0x1a	/* mono input/output control */
 #define CS4231_LINE_RIGHT_OUTPUT 0x1b	/* right line output control register (InterWave only) */
+#define AD1845_PWR_DOWN		0x1b	/* power down control */
 #define CS4235_LEFT_MASTER	0x1b	/* left master output control */
 #define CS4231_REC_FORMAT	0x1c	/* clock and data format - record - bits 7-0 MCE */
 #define CS4231_PLY_VAR_FREQ	0x1d	/* playback variable frequency */
+#define AD1845_CLOCK		0x1d	/* crystal clock select and total power down */
 #define CS4235_RIGHT_MASTER	0x1d	/* right master output control */
 #define CS4231_REC_UPR_CNT	0x1e	/* record upper count */
 #define CS4231_REC_LWR_CNT	0x1f	/* record lower count */
@@ -191,6 +197,7 @@
 #define CS4231_HW_CS4231_MASK   0x0100	/* CS4231 serie */
 #define CS4231_HW_CS4231        0x0100	/* CS4231 chip */
 #define CS4231_HW_CS4231A       0x0101	/* CS4231A chip */
+#define CS4231_HW_AD1845	0x0102	/* AD1845 chip */
 #define CS4231_HW_CS4232_MASK   0x0200	/* CS4232 serie (has control ports) */
 #define CS4231_HW_CS4232        0x0200	/* CS4232 */
 #define CS4231_HW_CS4232A       0x0201	/* CS4232A */
diff -Nru a/include/sound/opl3.h b/include/sound/opl3.h
--- a/include/sound/opl3.h	Tue Oct  1 17:11:59 2002
+++ b/include/sound/opl3.h	Tue Oct  1 17:11:59 2002
@@ -288,7 +288,7 @@
 	snd_midi_channel_set_t * chset;
 
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	snd_seq_device_t *oss_seq_dev;	/* OSS sequencer device, WIP */
+	snd_seq_device_t *oss_seq_dev;	/* OSS sequencer device */
 	snd_midi_channel_set_t * oss_chset;
 #endif
  
diff -Nru a/include/sound/sscape_ioctl.h b/include/sound/sscape_ioctl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/sound/sscape_ioctl.h	Tue Oct  1 17:11:59 2002
@@ -0,0 +1,19 @@
+#ifndef SSCAPE_IOCTL_H
+#define SSCAPE_IOCTL_H
+
+
+struct sscape_bootblock
+{
+  unsigned char code[256];
+  unsigned version;
+};
+
+struct sscape_microcode
+{
+  unsigned char code[65536];
+};
+
+#define SND_SSCAPE_LOAD_BOOTB  _IOWR('P', 100, struct sscape_bootblock)
+#define SND_SSCAPE_LOAD_MCODE  _IOW('P', 101, struct sscape_microcode)
+
+#endif
diff -Nru a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h	Tue Oct  1 17:11:59 2002
+++ b/include/sound/version.h	Tue Oct  1 17:11:59 2002
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated automatically by configure.  */
 #define CONFIG_SND_VERSION "0.9.0rc3"
-#define CONFIG_SND_DATE " (Tue Sep 17 13:46:32 2002 UTC)"
+#define CONFIG_SND_DATE " (Tue Oct 01 14:40:23 2002 UTC)"
diff -Nru a/sound/core/Makefile b/sound/core/Makefile
--- a/sound/core/Makefile	Tue Oct  1 17:11:59 2002
+++ b/sound/core/Makefile	Tue Oct  1 17:11:59 2002
@@ -101,6 +101,9 @@
   obj-$(CONFIG_SND_SBAWE) += snd-hwdep.o
 endif
 obj-$(CONFIG_SND_USB_AUDIO) += snd-pcm.o snd-timer.o snd.o
+ifeq ($(subst m,y,$(CONFIG_SND_SEQUENCER)),y)
+obj-$(CONFIG_SND_USB_AUDIO) += snd-rawmidi.o
+endif
 
 obj-m := $(sort $(obj-m))
 
diff -Nru a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c	Tue Oct  1 17:11:59 2002
+++ b/sound/core/control.c	Tue Oct  1 17:11:59 2002
@@ -160,7 +160,7 @@
 				goto _found;
 			}
 		}
-		ev = snd_kcalloc(sizeof(*ev), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+		ev = snd_kcalloc(sizeof(*ev), GFP_ATOMIC);
 		if (ev) {
 			ev->id = *id;
 			ev->mask = mask;
@@ -486,12 +486,15 @@
 			}
 			read_unlock(&card->control_owner_lock);
 			if (result > 0) {
-				result = 0;
+				read_unlock(&card->control_rwlock);
 				snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
+				result = 0;
+				goto __unlocked;
 			}
 		}
 	}
 	read_unlock(&card->control_rwlock);
+      __unlocked:
 	if (result >= 0)
 		if (copy_to_user(_control, &control, sizeof(control)))
 			return -EFAULT;
diff -Nru a/sound/core/hwdep.c b/sound/core/hwdep.c
--- a/sound/core/hwdep.c	Tue Oct  1 17:11:59 2002
+++ b/sound/core/hwdep.c	Tue Oct  1 17:11:59 2002
@@ -338,10 +338,8 @@
 						    &snd_hwdep_reg, hwdep->oss_dev) < 0) {
 				snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n",
 					   hwdep->card->number, hwdep->device);
-			} else {
-				snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, hwdep->card->number, hwdep->name);
+			} else
 				hwdep->ossreg = 1;
-			}
 		}
 	}
 #endif
@@ -362,10 +360,8 @@
 		return -EINVAL;
 	}
 #ifdef CONFIG_SND_OSSEMUL
-	if (hwdep->ossreg) {
+	if (hwdep->ossreg)
 		snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
-		snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, hwdep->card->number);
-	}
 #endif
 	snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
 	snd_hwdep_devices[idx] = NULL;
diff -Nru a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
--- a/sound/core/seq/oss/seq_oss_synth.c	Tue Oct  1 17:11:59 2002
+++ b/sound/core/seq/oss/seq_oss_synth.c	Tue Oct  1 17:11:59 2002
@@ -179,7 +179,7 @@
 	}
 	spin_unlock_irqrestore(&register_lock, flags);
 	if (rec->seq_device < SNDRV_CARDS)
-		snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device, NULL);
+		snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_SYNTH, rec->seq_device);
 
 	snd_use_lock_sync(&rec->use_lock);
 	kfree(rec);
diff -Nru a/sound/core/sound.c b/sound/core/sound.c
--- a/sound/core/sound.c	Tue Oct  1 17:11:59 2002
+++ b/sound/core/sound.c	Tue Oct  1 17:11:59 2002
@@ -367,6 +367,9 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
 		master = devfs_find_handle(NULL, controlname, strlen(controlname), 0, 0, DEVFS_SPECIAL_CHR, 0);
 		devfs_unregister(master);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		master = devfs_find_handle(NULL, controlname, 0, 0, DEVFS_SPECIAL_CHR, 0);
+		devfs_unregister(master);
 #else
 		devfs_find_and_unregister(NULL, controlname, 0, 0, DEVFS_SPECIAL_CHR, 0);
 #endif
diff -Nru a/sound/core/wrappers.c b/sound/core/wrappers.c
--- a/sound/core/wrappers.c	Tue Oct  1 17:11:59 2002
+++ b/sound/core/wrappers.c	Tue Oct  1 17:11:59 2002
@@ -67,6 +67,11 @@
 
 #include <linux/pci.h>
 
+/* to be sure... */
+#ifdef HACK_PCI_ALLOC_CONSISTENT
+#error pci_alloc_consistent hack is already defined!!
+#endif
+
 /*
  * A dirty hack... when the kernel code is fixed this should be removed.
  *
@@ -93,13 +98,19 @@
 	rmask = ~((unsigned long)dma_mask);
 	hwdev->dma_mask = 0xffffffff; /* do without masking */
 	ret = pci_alloc_consistent(hwdev, size, dma_handle);
-	if (ret && ((*dma_handle + size - 1) & rmask)) {
-		pci_free_consistent(hwdev, size, ret, *dma_handle);
-		ret = 0;
-	}
 	hwdev->dma_mask = dma_mask; /* restore */
-	if (! ret)
-		ret = pci_alloc_consistent(hwdev, size, dma_handle);
+	if (ret) {
+		/* obtained address is out of range? */
+		if (((unsigned long)*dma_handle + size - 1) & rmask) {
+			/* reallocate with the proper mask */
+			pci_free_consistent(hwdev, size, ret, *dma_handle);
+			ret = pci_alloc_consistent(hwdev, size, dma_handle);
+		}
+	} else {
+		/* wish to success now with the proper mask... */
+		if (dma_mask != 0xffffffff)
+			ret = pci_alloc_consistent(hwdev, size, dma_handle);
+	}
 	return ret;
 }
 
diff -Nru a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
--- a/sound/isa/ad1848/ad1848_lib.c	Tue Oct  1 17:11:59 2002
+++ b/sound/isa/ad1848/ad1848_lib.c	Tue Oct  1 17:11:59 2002
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
 #include <sound/core.h>
 #include <sound/ad1848.h>
 #include <sound/pcm_params.h>
diff -Nru a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
--- a/sound/isa/cs423x/cs4231_lib.c	Tue Oct  1 17:11:59 2002
+++ b/sound/isa/cs423x/cs4231_lib.c	Tue Oct  1 17:11:59 2002
@@ -998,7 +998,12 @@
 		rev = snd_cs4231_in(chip, CS4231_VERSION) & 0xe7;
 		snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
 		if (rev == 0x80) {
-			chip->hardware = CS4231_HW_CS4231;
+			unsigned char tmp = snd_cs4231_in(chip, 23);
+			snd_cs4231_out(chip, 23, ~tmp);
+			if (snd_cs4231_in(chip, 23) != tmp)
+				chip->hardware = CS4231_HW_AD1845;
+			else
+				chip->hardware = CS4231_HW_CS4231;
 		} else if (rev == 0xa0) {
 			chip->hardware = CS4231_HW_CS4231A;
 		} else if (rev == 0xa2) {
@@ -1382,6 +1387,7 @@
 	case CS4231_HW_CS4239:	return "CS4239";
 	case CS4231_HW_INTERWAVE: return "AMD InterWave";
 	case CS4231_HW_OPL3SA2: return chip->card->shortname;
+	case CS4231_HW_AD1845: return "AD1845";
 	default: return "???";
 	}
 }
diff -Nru a/sound/pci/Makefile b/sound/pci/Makefile
--- a/sound/pci/Makefile	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/Makefile	Tue Oct  1 17:11:59 2002
@@ -11,7 +11,6 @@
 snd-es1938-objs := es1938.o
 snd-es1968-objs := es1968.o
 snd-fm801-objs := fm801.o
-snd-ice1712-objs := ice1712.o
 snd-intel8x0-objs := intel8x0.o
 snd-maestro3-objs := maestro3.o
 snd-rme32-objs := rme32.o
@@ -28,7 +27,6 @@
 obj-$(CONFIG_SND_ES1938) += snd-es1938.o
 obj-$(CONFIG_SND_ES1968) += snd-es1968.o
 obj-$(CONFIG_SND_FM801) += snd-fm801.o
-obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o
 obj-$(CONFIG_SND_INTEL8X0) += snd-intel8x0.o
 obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
 obj-$(CONFIG_SND_RME32) += snd-rme32.o
@@ -36,6 +34,6 @@
 obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
 obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
 
-obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/
+obj-$(CONFIG_SND) += ac97/ ali5451/ cs46xx/ emu10k1/ korg1212/ nm256/ rme9652/ trident/ ymfpci/ ice1712/
 
 include $(TOPDIR)/Rules.make
diff -Nru a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/ac97/ac97_codec.c	Tue Oct  1 17:11:59 2002
@@ -119,7 +119,8 @@
 { 0x43525948, 0xfffffff8, "CS4201",		NULL },
 { 0x43525958, 0xfffffff8, "CS4205",		patch_cirrus_spdif },
 { 0x43525960, 0xfffffff8, "CS4291",		NULL },
-{ 0x43585429, 0xffffffff, "Cx20468",		patch_conexant },
+{ 0x43585421, 0xffffffff, "HSD11246",		NULL },	// SmartMC II
+{ 0x43585428, 0xfffffff8, "Cx20468",		patch_conexant }, // SmartAMC fixme: the mask might be different
 { 0x454d4328, 0xffffffff, "28028",		NULL },  // same as TR28028?
 { 0x45838308, 0xffffffff, "ESS1988",		NULL },
 { 0x48525300, 0xffffff00, "HMP9701",		NULL },
@@ -1668,6 +1669,9 @@
 	id |= snd_ac97_read(ac97, AC97_VENDOR_ID2);
 	snd_ac97_get_name(NULL, id, name);
 	snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
+	if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
+		goto __modem;
+
 	val = snd_ac97_read(ac97, AC97_RESET);
 	snd_iprintf(buffer, "Capabilities     :%s%s%s%s%s%s\n",
 	    	    val & AC97_BC_DEDICATED_MIC ? " -dedicated MIC PCM IN channel-" : "",
@@ -1788,7 +1792,7 @@
 	if (mext == 0)
 		return;
 	
-	snd_iprintf(buffer, "Extended modem ID: codec=%i %s%s%s%s%s\n",
+	snd_iprintf(buffer, "Extended modem ID: codec=%i%s%s%s%s%s\n",
 			(mext & AC97_MEI_ADDR_MASK) >> AC97_MEI_ADDR_SHIFT,
 			mext & AC97_MEI_CID2 ? " CID2" : "",
 			mext & AC97_MEI_CID1 ? " CID1" : "",
diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/cmipci.c	Tue Oct  1 17:11:59 2002
@@ -205,9 +205,9 @@
 #define CM_SFILENB		0x00001000
 #define CM_MMODE_MASK		0x00000E00
 #define CM_SPDIF_SELECT2	0x00000100	/* for model > 039 ? */
-#define CM_ENCENTER		0x00000080	/* shared with FLINKON? */
-#define CM_FLINKON		0x00000080
-#define CM_FLINKOFF		0x00000040
+#define CM_ENCENTER		0x00000080
+#define CM_FLINKON		0x00000040
+#define CM_FLINKOFF		0x00000020
 #define CM_MIDSMP		0x00000010
 #define CM_UPDDMA_MASK		0x0000000C
 #define CM_TWAIT_MASK		0x00000003
@@ -625,7 +625,7 @@
 	/* program sample counts */
 	reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
 	snd_cmipci_write_w(cm, reg, rec->dma_size - 1);
-	snd_cmipci_write_w(cm, reg + 2, rec->period_size - 1);
+	snd_cmipci_write_w(cm, reg + 2, rec->period_size); /* FIXME: or period_size-1 ?? */
 
 	/* set adc/dac flag */
 	val = rec->ch ? CM_CHADC1 : CM_CHADC0;
@@ -1088,7 +1088,7 @@
 }
 
 /* spinlock held! */
-static void setup_ac3(cmipci_t *cm, int do_ac3, int rate)
+static void setup_ac3(cmipci_t *cm, snd_pcm_substream_t *subs, int do_ac3, int rate)
 {
 	cm->channel[CM_CH_PLAY].ac3_shift = 0;
 	cm->spdif_counter = 0;
@@ -1112,7 +1112,7 @@
 			/* set 176K sample rate to fix 033 HW bug */
 			if (cm->chip_version == 33) {
 				if (rate >= 48000) {
-					snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_176K);
+					snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
 				} else {
 					snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_PLAYBACK_SRATE_176K);
 				}
@@ -1153,7 +1153,7 @@
 		/* snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
 		if (cm->spdif_playback_enabled)
 			snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
-		setup_ac3(cm, do_ac3, rate);
+		setup_ac3(cm, subs, do_ac3, rate);
 
 		if (rate == 48000)
 			snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K | CM_SPDF_AC97);
@@ -1165,7 +1165,7 @@
 		/* snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT); */
 		/* snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_SPDO2DAC); */
 		snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
-		setup_ac3(cm, 0, 0);
+		setup_ac3(cm, subs, 0, 0);
 	}
 	spin_unlock_irqrestore(&cm->reg_lock, flags);
 }
@@ -1286,7 +1286,7 @@
 static snd_pcm_hardware_t snd_cmipci_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
@@ -1306,7 +1306,7 @@
 static snd_pcm_hardware_t snd_cmipci_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
@@ -1326,7 +1326,7 @@
 static snd_pcm_hardware_t snd_cmipci_playback2 =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
@@ -1346,7 +1346,7 @@
 static snd_pcm_hardware_t snd_cmipci_playback_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER),
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE /*| SNDRV_PCM_FMTBIT_S32_LE*/,
 	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
 	.rate_min =		44100,
@@ -1365,7 +1365,7 @@
 static snd_pcm_hardware_t snd_cmipci_capture_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =	        SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
diff -Nru a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
--- a/sound/pci/ice1712/ews.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/ice1712/ews.c	Tue Oct  1 17:11:59 2002
@@ -325,6 +325,7 @@
 static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
 {
 	int err;
+	ak4524_t *ak;
 
 	/* set the analog DACs */
 	switch (ice->eeprom.subvendor) {
@@ -400,7 +401,7 @@
 	}
 
 	/* analog section */
-	ak4524_t *ak = &ice->ak4524;
+	ak = &ice->ak4524;
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_EWS88MT:
 		ak->num_adcs = ak->num_dacs = 8;
diff -Nru a/sound/pci/ice1712.c b/sound/pci/ice1712.c
--- a/sound/pci/ice1712.c	Tue Oct  1 17:11:59 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,4441 +0,0 @@
-/*
- *   ALSA driver for ICEnsemble ICE1712 (Envy24)
- *
- *	Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */      
-
-/*
-  NOTES:
-  - spdif nonaudio consumer mode does not work (at least with my
-    Sony STR-DB830)
-*/
-
-#include <sound/driver.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/pcm.h>
-#include <sound/ac97_codec.h>
-#include <sound/mpu401.h>
-#include <sound/i2c.h>
-#include <sound/cs8427.h>
-#include <sound/info.h>
-#define SNDRV_GET_ID
-#include <sound/initval.h>
-
-#include <sound/asoundef.h>
-
-#define SND_CS8403
-#define SND_CS8404
-#include <sound/cs8403.h>
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("ICEnsemble ICE1712 (Envy24)");
-MODULE_LICENSE("GPL");
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{Hoontech SoundTrack DSP 24},"
-		"{MidiMan M Audio,Delta 1010},"
-		"{MidiMan M Audio,Delta DiO 2496},"
-		"{MidiMan M Audio,Delta 66},"
-		"{MidiMan M Audio,Delta 44},"
-		"{MidiMan M Audio,Audiophile 24/96},"
-		"{TerraTec,EWX 24/96},"
-		"{TerraTec,EWS 88MT},"
-		"{TerraTec,EWS 88D},"
-		"{TerraTec,DMX 6Fire},"
-		"{ICEnsemble,Generic ICE1712},"
-		"{ICEnsemble,Generic Envy24}}");
-
-static int snd_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
-static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
-static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;		/* Enable this card */
-static int snd_omni[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 0};	/* Delta44 & 66 Omni I/O support */
-
-MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_index, "Index value for ICE1712 soundcard.");
-MODULE_PARM_SYNTAX(snd_index, SNDRV_INDEX_DESC);
-MODULE_PARM(snd_id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
-MODULE_PARM_DESC(snd_id, "ID string for ICE1712 soundcard.");
-MODULE_PARM_SYNTAX(snd_id, SNDRV_ID_DESC);
-MODULE_PARM(snd_enable, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_enable, "Enable ICE1712 soundcard.");
-MODULE_PARM_SYNTAX(snd_enable, SNDRV_ENABLE_DESC);
-MODULE_PARM(snd_omni, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(snd_omni, "Enable Midiman M-Audio Delta Omni I/O support.");
-MODULE_PARM_SYNTAX(snd_omni, SNDRV_ENABLED "," SNDRV_ENABLE_DESC);
-
-#ifndef PCI_VENDOR_ID_ICE
-#define PCI_VENDOR_ID_ICE		0x1412
-#endif
-#ifndef PCI_DEVICE_ID_ICE_1712
-#define PCI_DEVICE_ID_ICE_1712		0x1712
-#endif
-
-#define ICE1712_SUBDEVICE_STDSP24	0x12141217	/* Hoontech SoundTrack Audio DSP 24 */
-#define ICE1712_SUBDEVICE_DELTA1010	0x121430d6
-#define ICE1712_SUBDEVICE_DELTADIO2496	0x121431d6
-#define ICE1712_SUBDEVICE_DELTA66	0x121432d6
-#define ICE1712_SUBDEVICE_DELTA44	0x121433d6
-#define ICE1712_SUBDEVICE_AUDIOPHILE	0x121434d6
-#define ICE1712_SUBDEVICE_DELTA1010LT	0x12143bd6
-#define ICE1712_SUBDEVICE_EWX2496	0x3b153011
-#define ICE1712_SUBDEVICE_EWS88MT	0x3b151511
-#define ICE1712_SUBDEVICE_EWS88D	0x3b152b11
-#define ICE1712_SUBDEVICE_DMX6FIRE	0x3b153811
-
-/*
- *  Direct registers
- */
-
-#define ICEREG(ice, x) ((ice)->port + ICE1712_REG_##x)
-
-#define ICE1712_REG_CONTROL		0x00	/* byte */
-#define   ICE1712_RESET			0x80	/* reset whole chip */
-#define   ICE1712_SERR_LEVEL		0x04	/* SERR# level otherwise edge */
-#define   ICE1712_NATIVE		0x01	/* native mode otherwise SB */
-#define ICE1712_REG_IRQMASK		0x01	/* byte */
-#define   ICE1712_IRQ_MPU1		0x80
-#define   ICE1712_IRQ_TIMER		0x40
-#define   ICE1712_IRQ_MPU2		0x20
-#define   ICE1712_IRQ_PROPCM		0x10
-#define   ICE1712_IRQ_FM		0x08	/* FM/MIDI - legacy */
-#define   ICE1712_IRQ_PBKDS		0x04	/* playback DS channels */
-#define   ICE1712_IRQ_CONCAP		0x02	/* consumer capture */
-#define   ICE1712_IRQ_CONPBK		0x01	/* consumer playback */
-#define ICE1712_REG_IRQSTAT		0x02	/* byte */
-/* look to ICE1712_IRQ_* */
-#define ICE1712_REG_INDEX		0x03	/* byte - indirect CCIxx regs */
-#define ICE1712_REG_DATA		0x04	/* byte - indirect CCIxx regs */
-#define ICE1712_REG_NMI_STAT1		0x05	/* byte */
-#define ICE1712_REG_NMI_DATA		0x06	/* byte */
-#define ICE1712_REG_NMI_INDEX		0x07	/* byte */
-#define ICE1712_REG_AC97_INDEX		0x08	/* byte */
-#define ICE1712_REG_AC97_CMD		0x09	/* byte */
-#define   ICE1712_AC97_COLD		0x80	/* cold reset */
-#define   ICE1712_AC97_WARM		0x40	/* warm reset */
-#define   ICE1712_AC97_WRITE		0x20	/* W: write, R: write in progress */
-#define   ICE1712_AC97_READ		0x10	/* W: read, R: read in progress */
-#define   ICE1712_AC97_READY		0x08	/* codec ready status bit */
-#define   ICE1712_AC97_PBK_VSR		0x02	/* playback VSR */
-#define   ICE1712_AC97_CAP_VSR		0x01	/* capture VSR */
-#define ICE1712_REG_AC97_DATA		0x0a	/* word (little endian) */
-#define ICE1712_REG_MPU1_CTRL		0x0c	/* byte */
-#define ICE1712_REG_MPU1_DATA		0x0d	/* byte */
-#define ICE1712_REG_I2C_DEV_ADDR	0x10	/* byte */
-#define   ICE1712_I2C_WRITE		0x01	/* write direction */
-#define ICE1712_REG_I2C_BYTE_ADDR	0x11	/* byte */
-#define ICE1712_REG_I2C_DATA		0x12	/* byte */
-#define ICE1712_REG_I2C_CTRL		0x13	/* byte */
-#define   ICE1712_I2C_EEPROM		0x80	/* EEPROM exists */
-#define   ICE1712_I2C_BUSY		0x01	/* busy bit */
-#define ICE1712_REG_CONCAP_ADDR		0x14	/* dword - consumer capture */
-#define ICE1712_REG_CONCAP_COUNT	0x18	/* word - current/base count */
-#define ICE1712_REG_SERR_SHADOW		0x1b	/* byte */
-#define ICE1712_REG_MPU2_CTRL		0x1c	/* byte */
-#define ICE1712_REG_MPU2_DATA		0x1d	/* byte */
-#define ICE1712_REG_TIMER		0x1e	/* word */
-
-/*
- *  Indirect registers
- */
-
-#define ICE1712_IREG_PBK_COUNT_HI	0x00
-#define ICE1712_IREG_PBK_COUNT_LO	0x01
-#define ICE1712_IREG_PBK_CTRL		0x02
-#define ICE1712_IREG_PBK_LEFT		0x03	/* left volume */
-#define ICE1712_IREG_PBK_RIGHT		0x04	/* right volume */
-#define ICE1712_IREG_PBK_SOFT		0x05	/* soft volume */
-#define ICE1712_IREG_PBK_RATE_LO	0x06
-#define ICE1712_IREG_PBK_RATE_MID	0x07
-#define ICE1712_IREG_PBK_RATE_HI	0x08
-#define ICE1712_IREG_CAP_COUNT_HI	0x10
-#define ICE1712_IREG_CAP_COUNT_LO	0x11
-#define ICE1712_IREG_CAP_CTRL		0x12
-#define ICE1712_IREG_GPIO_DATA		0x20
-#define ICE1712_IREG_GPIO_WRITE_MASK	0x21
-#define ICE1712_IREG_GPIO_DIRECTION	0x22
-#define ICE1712_IREG_CONSUMER_POWERDOWN	0x30
-#define ICE1712_IREG_PRO_POWERDOWN	0x31
-
-/*
- *  Consumer section direct DMA registers
- */
-
-#define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x)
- 
-#define ICE1712_DS_INTMASK		0x00	/* word - interrupt mask */
-#define ICE1712_DS_INTSTAT		0x02	/* word - interrupt status */
-#define ICE1712_DS_DATA			0x04	/* dword - channel data */
-#define ICE1712_DS_INDEX		0x08	/* dword - channel index */
-
-/*
- *  Consumer section channel registers
- */
- 
-#define ICE1712_DSC_ADDR0		0x00	/* dword - base address 0 */
-#define ICE1712_DSC_COUNT0		0x01	/* word - count 0 */
-#define ICE1712_DSC_ADDR1		0x02	/* dword - base address 1 */
-#define ICE1712_DSC_COUNT1		0x03	/* word - count 1 */
-#define ICE1712_DSC_CONTROL		0x04	/* byte - control & status */
-#define   ICE1712_BUFFER1		0x80	/* buffer1 is active */
-#define   ICE1712_BUFFER1_AUTO		0x40	/* buffer1 auto init */
-#define   ICE1712_BUFFER0_AUTO		0x20	/* buffer0 auto init */
-#define   ICE1712_FLUSH			0x10	/* flush FIFO */
-#define   ICE1712_STEREO		0x08	/* stereo */
-#define   ICE1712_16BIT			0x04	/* 16-bit data */
-#define   ICE1712_PAUSE			0x02	/* pause */
-#define   ICE1712_START			0x01	/* start */
-#define ICE1712_DSC_RATE		0x05	/* dword - rate */
-#define ICE1712_DSC_VOLUME		0x06	/* word - volume control */
-
-/* 
- *  Professional multi-track direct control registers
- */
-
-#define ICEMT(ice, x) ((ice)->profi_port + ICE1712_MT_##x)
-
-#define ICE1712_MT_IRQ			0x00	/* byte - interrupt mask */
-#define   ICE1712_MULTI_CAPTURE		0x80	/* capture IRQ */
-#define   ICE1712_MULTI_PLAYBACK	0x40	/* playback IRQ */
-#define   ICE1712_MULTI_CAPSTATUS	0x02	/* capture IRQ status */
-#define   ICE1712_MULTI_PBKSTATUS	0x01	/* playback IRQ status */
-#define ICE1712_MT_RATE			0x01	/* byte - sampling rate select */
-#define   ICE1712_SPDIF_MASTER		0x10	/* S/PDIF input is master clock */
-#define ICE1712_MT_I2S_FORMAT		0x02	/* byte - I2S data format */
-#define ICE1712_MT_AC97_INDEX		0x04	/* byte - AC'97 index */
-#define ICE1712_MT_AC97_CMD		0x05	/* byte - AC'97 command & status */
-/* look to ICE1712_AC97_* */
-#define ICE1712_MT_AC97_DATA		0x06	/* word - AC'97 data */
-#define ICE1712_MT_PLAYBACK_ADDR	0x10	/* dword - playback address */
-#define ICE1712_MT_PLAYBACK_SIZE	0x14	/* word - playback size */
-#define ICE1712_MT_PLAYBACK_COUNT	0x16	/* word - playback count */
-#define ICE1712_MT_PLAYBACK_CONTROL	0x18	/* byte - control */
-#define   ICE1712_CAPTURE_START_SHADOW	0x04	/* capture start */
-#define   ICE1712_PLAYBACK_PAUSE	0x02	/* playback pause */
-#define   ICE1712_PLAYBACK_START	0x01	/* playback start */
-#define ICE1712_MT_CAPTURE_ADDR		0x20	/* dword - capture address */
-#define ICE1712_MT_CAPTURE_SIZE		0x24	/* word - capture size */
-#define ICE1712_MT_CAPTURE_COUNT	0x26	/* word - capture count */
-#define ICE1712_MT_CAPTURE_CONTROL	0x28	/* byte - control */
-#define   ICE1712_CAPTURE_START		0x01	/* capture start */
-#define ICE1712_MT_ROUTE_PSDOUT03	0x30	/* word */
-#define ICE1712_MT_ROUTE_SPDOUT		0x32	/* word */
-#define ICE1712_MT_ROUTE_CAPTURE	0x34	/* dword */
-#define ICE1712_MT_MONITOR_VOLUME	0x38	/* word */
-#define ICE1712_MT_MONITOR_INDEX	0x3a	/* byte */
-#define ICE1712_MT_MONITOR_RATE		0x3b	/* byte */
-#define ICE1712_MT_MONITOR_ROUTECTRL	0x3c	/* byte */
-#define   ICE1712_ROUTE_AC97		0x01	/* route digital mixer output to AC'97 */
-#define ICE1712_MT_MONITOR_PEAKINDEX	0x3e	/* byte */
-#define ICE1712_MT_MONITOR_PEAKDATA	0x3f	/* byte */
-
-/*
- *  Codec configuration bits
- */
-
-/* PCI[60] System Configuration */
-#define ICE1712_CFG_CLOCK	0xc0
-#define   ICE1712_CFG_CLOCK512	0x00	/* 22.5692Mhz, 44.1kHz*512 */
-#define   ICE1712_CFG_CLOCK384  0x40	/* 16.9344Mhz, 44.1kHz*384 */
-#define   ICE1712_CFG_EXT	0x80	/* external clock */
-#define ICE1712_CFG_2xMPU401	0x20	/* two MPU401 UARTs */
-#define ICE1712_CFG_NO_CON_AC97 0x10	/* consumer AC'97 codec is not present */
-#define ICE1712_CFG_ADC_MASK	0x0c	/* one, two, three, four stereo ADCs */
-#define ICE1712_CFG_DAC_MASK	0x03	/* one, two, three, four stereo DACs */
-/* PCI[61] AC-Link Configuration */
-#define ICE1712_CFG_PRO_I2S	0x80	/* multitrack converter: I2S or AC'97 */
-#define ICE1712_CFG_AC97_PACKED	0x01	/* split or packed mode - AC'97 */
-/* PCI[62] I2S Features */
-#define ICE1712_CFG_I2S_VOLUME	0x80	/* volume/mute capability */
-#define ICE1712_CFG_I2S_96KHZ	0x40	/* supports 96kHz sampling */
-#define ICE1712_CFG_I2S_RESMASK	0x30	/* resolution mask, 16,18,20,24-bit */
-#define ICE1712_CFG_I2S_OTHER	0x0f	/* other I2S IDs */
-/* PCI[63] S/PDIF Configuration */
-#define ICE1712_CFG_I2S_CHIPID	0xfc	/* I2S chip ID */
-#define ICE1712_CFG_SPDIF_IN	0x02	/* S/PDIF input is present */
-#define ICE1712_CFG_SPDIF_OUT	0x01	/* S/PDIF output is present */
-
-/*
- *  MidiMan M-Audio Delta GPIO definitions
- */
-
-/* MidiMan M-Audio Delta1010 */
-#define ICE1712_DELTA_DFS 0x01		/* fast/slow sample rate mode */
-					/* (>48kHz must be 1) */
-#define ICE1712_DELTA_SPDIF_IN_STAT 0x02
-					/* S/PDIF input status */
-					/* 0 = valid signal is present */
-					/* all except Delta44 */
-					/* look to CS8414 datasheet */
-#define ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK 0x04
-					/* S/PDIF output status clock */
-					/* (writting on rising edge - 0->1) */
-					/* all except Delta44 */
-					/* look to CS8404A datasheet */
-#define ICE1712_DELTA_SPDIF_OUT_STAT_DATA 0x08
-					/* S/PDIF output status data */
-					/* all except Delta44 */
-					/* look to CS8404A datasheet */
-/* MidiMan M-Audio DeltaDiO */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_SPDIF_INPUT_SELECT 0x10
-					/* coaxial (0), optical (1) */
-					/* S/PDIF input select*/
-
-/* MidiMan M-Audio Delta1010 */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_WORD_CLOCK_SELECT 0x10
-					/* 1 - clock are taken from S/PDIF input */
-					/* 0 - clock are taken from Word Clock input */
-					/* affected SPMCLKIN pin of Envy24 */
-#define ICE1712_DELTA_WORD_CLOCK_STATUS	0x20
-					/* 0 = valid word clock signal is present */
-
-/* MidiMan M-Audio Delta66 */
-/* 0x01 = DFS */
-/* 0x02 = SPDIF_IN_STAT */
-/* 0x04 = SPDIF_OUT_STAT_CLOCK */
-/* 0x08 = SPDIF_OUT_STAT_DATA */
-#define ICE1712_DELTA_CODEC_SERIAL_DATA 0x10
-					/* AKM4524 serial data */
-#define ICE1712_DELTA_CODEC_SERIAL_CLOCK 0x20
-					/* AKM4524 serial clock */
-					/* (writting on rising edge - 0->1 */
-#define ICE1712_DELTA_CODEC_CHIP_A	0x40
-#define ICE1712_DELTA_CODEC_CHIP_B	0x80
-					/* 1 - select chip A or B */
-
-/* MidiMan M-Audio Delta44 */
-/* 0x01 = DFS */
-/* 0x10 = CODEC_SERIAL_DATA */
-/* 0x20 = CODEC_SERIAL_CLOCK */
-/* 0x40 = CODEC_CHIP_A */
-/* 0x80 = CODEC_CHIP_B */
-
-/* MidiMan M-Audio Audiophile definitions */
-/* 0x01 = DFS */
-#define ICE1712_DELTA_AP_CCLK	0x02	/* SPI clock */
-					/* (clocking on rising edge - 0->1) */
-#define ICE1712_DELTA_AP_DIN	0x04	/* data input */
-#define ICE1712_DELTA_AP_DOUT	0x08	/* data output */
-#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */
-					/* low signal = select */
-#define ICE1712_DELTA_AP_CS_CODEC 0x20	/* AK4528 chip select */
-					/* low signal = select */
-
-/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
-
-#define ICE1712_STDSP24_0_BOX(r, x)	r[0] = ((r[0] & ~3) | ((x)&3))
-#define ICE1712_STDSP24_0_DAREAR(r, x)	r[0] = ((r[0] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_1_CHN1(r, x)	r[1] = ((r[1] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_1_CHN2(r, x)	r[1] = ((r[1] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_1_CHN3(r, x)	r[1] = ((r[1] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_2_CHN4(r, x)	r[2] = ((r[2] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_2_MIDIIN(r, x)	r[2] = ((r[2] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_2_MIDI1(r, x)	r[2] = ((r[2] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_3_MIDI2(r, x)	r[3] = ((r[3] & ~1) | ((x)&1))
-#define ICE1712_STDSP24_3_MUTE(r, x)	r[3] = ((r[3] & ~2) | (((x)&1)<<1))
-#define ICE1712_STDSP24_3_INSEL(r, x)	r[3] = ((r[3] & ~4) | (((x)&1)<<2))
-#define ICE1712_STDSP24_SET_ADDR(r, a)	r[a&3] = ((r[a&3] & ~0x18) | (((a)&3)<<3))
-#define ICE1712_STDSP24_CLOCK(r, a, c)	r[a&3] = ((r[a&3] & ~0x20) | (((c)&1)<<5))
-#define ICE1712_STDSP24_CLOCK_BIT	(1<<5)
-
-/* Hoontech SoundTrack Audio DSP 24 box configuration definitions */
-
-#define ICE1712_STDSP24_DAREAR		(1<<0)
-#define ICE1712_STDSP24_MUTE		(1<<1)
-#define ICE1712_STDSP24_INSEL		(1<<2)
-
-#define ICE1712_STDSP24_BOX_CHN1	(1<<0)	/* input channel 1 */
-#define ICE1712_STDSP24_BOX_CHN2	(1<<1)	/* input channel 2 */
-#define ICE1712_STDSP24_BOX_CHN3	(1<<2)	/* input channel 3 */
-#define ICE1712_STDSP24_BOX_CHN4	(1<<3)	/* input channel 4 */
-#define ICE1712_STDSP24_BOX_MIDI1	(1<<8)
-#define ICE1712_STDSP24_BOX_MIDI2	(1<<9)
-
-/* TerraTec EWX 24/96 configuration definitions */
-
-#define ICE1712_EWX2496_AK4524_CS	0x01	/* AK4524 chip select; low = active */
-#define ICE1712_EWX2496_AIN_SEL		0x02	/* input sensitivity switch; high = louder */
-#define ICE1712_EWX2496_AOUT_SEL	0x04	/* output sensitivity switch; high = louder */
-#define ICE1712_EWX2496_RW		0x08	/* read/write switch for i2c; high = write  */
-#define ICE1712_EWX2496_SERIAL_DATA	0x10	/* i2c & ak4524 data */
-#define ICE1712_EWX2496_SERIAL_CLOCK	0x20	/* i2c & ak4524 clock */
-#define ICE1712_EWX2496_TX2		0x40	/* MIDI2 (not used) */
-#define ICE1712_EWX2496_RX2		0x80	/* MIDI2 (not used) */
-
-/* TerraTec EWS 88MT/D configuration definitions */
-/* RW, SDA snd SCLK are identical with EWX24/96 */
-#define ICE1712_EWS88_CS8414_RATE	0x07	/* CS8414 sample rate: gpio 0-2 */
-#define ICE1712_EWS88_RW		0x08	/* read/write switch for i2c; high = write  */
-#define ICE1712_EWS88_SERIAL_DATA	0x10	/* i2c & ak4524 data */
-#define ICE1712_EWS88_SERIAL_CLOCK	0x20	/* i2c & ak4524 clock */
-#define ICE1712_EWS88_TX2		0x40	/* MIDI2 (only on 88D) */
-#define ICE1712_EWS88_RX2		0x80	/* MIDI2 (only on 88D) */
-
-/* i2c address */
-#define ICE1712_EWS88MT_CS8404_ADDR	(0x40>>1)
-#define ICE1712_EWS88MT_INPUT_ADDR	(0x46>>1)
-#define ICE1712_EWS88MT_OUTPUT_ADDR	(0x48>>1)
-#define ICE1712_EWS88MT_OUTPUT_SENSE	0x40	/* mask */
-#define ICE1712_EWS88D_PCF_ADDR		(0x40>>1)
-
-/* TerraTec DMX 6Fire configuration definitions */
-#define ICE1712_6FIRE_AK4524_CS_MASK	0x07	/* AK4524 chip select #1-#3 */
-#define ICE1712_6FIRE_RW		0x08	/* read/write switch for i2c; high = write  */
-#define ICE1712_6FIRE_SERIAL_DATA	0x10	/* i2c & ak4524 data */
-#define ICE1712_6FIRE_SERIAL_CLOCK	0x20	/* i2c & ak4524 clock */
-#define ICE1712_6FIRE_TX2		0x40	/* MIDI2 */
-#define ICE1712_6FIRE_RX2		0x80	/* MIDI2 */
-
-#define ICE1712_6FIRE_PCF9554_ADDR	(0x40>>1)
-#define ICE1712_6FIRE_CS8427_ADDR	(0x22>>1)
-
-/*
- * DMA mode values
- * identical with DMA_XXX on i386 architecture.
- */
-#define ICE1712_DMA_MODE_WRITE		0x48
-#define ICE1712_DMA_AUTOINIT		0x10
-
-
-/*
- *  
- */
-
-typedef struct _snd_ice1712 ice1712_t;
-
-typedef struct {
-	unsigned int subvendor;	/* PCI[2c-2f] */
-	unsigned char size;	/* size of EEPROM image in bytes */
-	unsigned char version;	/* must be 1 */
-	unsigned char codec;	/* codec configuration PCI[60] */
-	unsigned char aclink;	/* ACLink configuration PCI[61] */
-	unsigned char i2sID;	/* PCI[62] */
-	unsigned char spdif;	/* S/PDIF configuration PCI[63] */
-	unsigned char gpiomask;	/* GPIO initial mask, 0 = write, 1 = don't */
-	unsigned char gpiostate; /* GPIO initial state */
-	unsigned char gpiodir;	/* GPIO direction state */
-	unsigned short ac97main;
-	unsigned short ac97pcm;
-	unsigned short ac97rec;
-	unsigned char ac97recsrc;
-	unsigned char dacID[4];	/* I2S IDs for DACs */
-	unsigned char adcID[4];	/* I2S IDs for ADCs */
-	unsigned char extra[4];
-} ice1712_eeprom_t;
-
-struct _snd_ice1712 {
-	unsigned long conp_dma_size;
-	unsigned long conc_dma_size;
-	unsigned long prop_dma_size;
-	unsigned long proc_dma_size;
-	int irq;
-
-	unsigned long port;
-	struct resource *res_port;
-	unsigned long ddma_port;
-	struct resource *res_ddma_port;
-	unsigned long dmapath_port;
-	struct resource *res_dmapath_port;
-	unsigned long profi_port;
-	struct resource *res_profi_port;
-
-	unsigned int config;	/* system configuration */
-
-	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_t *pcm_ds;
-	snd_pcm_t *pcm_pro;
-        snd_pcm_substream_t *playback_con_substream;
-        snd_pcm_substream_t *playback_con_substream_ds[6];
-        snd_pcm_substream_t *capture_con_substream;
-        snd_pcm_substream_t *playback_pro_substream;
-        snd_pcm_substream_t *capture_pro_substream;
-	unsigned int playback_pro_size;
-	unsigned int capture_pro_size;
-	unsigned int playback_con_virt_addr[6];
-	unsigned int playback_con_active_buf[6];
-	unsigned int capture_con_virt_addr;
-	unsigned int ac97_ext_id;
-	ac97_t *ac97;
-	snd_rawmidi_t *rmidi[2];
-
-	spinlock_t reg_lock;
-	struct semaphore gpio_mutex;
-	snd_info_entry_t *proc_entry;
-
-	ice1712_eeprom_t eeprom;
-
-	unsigned int pro_volumes[20];
-	int ak4528: 1,			/* AK4524 or AK4528 */
-	    omni: 1;			/* Delta Omni I/O */
-	int num_adcs;			/* AK4524 or AK4528 ADCs */
-	int num_dacs;			/* AK4524 or AK4528 DACs */
-	int num_total_dacs;		/* total DACs */
-	unsigned char ak4524_images[4][8];
-	unsigned char ak4524_ipga_gain[4][2];
-	unsigned char hoontech_boxbits[4];
-	unsigned int hoontech_config;
-	unsigned short hoontech_boxconfig[4];
-
-	snd_i2c_bus_t *i2c;		/* I2C bus */
-	snd_i2c_device_t *cs8404;	/* CS8404A I2C device */
-	snd_i2c_device_t *cs8427;	/* CS8427 I2C device */
-	snd_i2c_device_t *pcf8574[2];	/* PCF8574 Output/Input (EWS88MT) */
-	snd_i2c_device_t *pcf8575;	/* PCF8575 (EWS88D) / PCF9554 (6Fire) */
-	
-	unsigned char cs8403_spdif_bits;
-	unsigned char cs8403_spdif_stream_bits;
-	snd_kcontrol_t *spdif_stream_ctl;
-
-	unsigned char gpio_direction, gpio_write_mask;
-};
-
-#define chip_t ice1712_t
-
-static struct pci_device_id snd_ice1712_ids[] __devinitdata = {
-	{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ICE1712 */
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
-
-static int snd_ice1712_build_pro_mixer(ice1712_t *ice);
-static int snd_ice1712_build_controls(ice1712_t *ice);
-
-/*
- *  Basic I/O
- */
- 
-static inline void snd_ice1712_write(ice1712_t * ice, u8 addr, u8 data)
-{
-	outb(addr, ICEREG(ice, INDEX));
-	outb(data, ICEREG(ice, DATA));
-}
-
-static inline u8 snd_ice1712_read(ice1712_t * ice, u8 addr)
-{
-	outb(addr, ICEREG(ice, INDEX));
-	return inb(ICEREG(ice, DATA));
-}
-
-static inline void snd_ice1712_ds_write(ice1712_t * ice, u8 channel, u8 addr, u32 data)
-{
-	outb((channel << 4) | addr, ICEDS(ice, INDEX));
-	outl(data, ICEDS(ice, DATA));
-}
-
-static inline u32 snd_ice1712_ds_read(ice1712_t * ice, u8 channel, u8 addr)
-{
-	outb((channel << 4) | addr, ICEDS(ice, INDEX));
-	return inl(ICEDS(ice, DATA));
-}
-
-static void snd_ice1712_ac97_write(ac97_t *ac97,
-				   unsigned short reg,
-				   unsigned short val)
-{
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
-	int tm;
-	unsigned char old_cmd = 0;
-
-	for (tm = 0; tm < 0x10000; tm++) {
-		old_cmd = inb(ICEREG(ice, AC97_CMD));
-		if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
-			continue;
-		if (!(old_cmd & ICE1712_AC97_READY))
-			continue;
-		break;
-	}
-	outb(reg, ICEREG(ice, AC97_INDEX));
-	outw(val, ICEREG(ice, AC97_DATA));
-	old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
-	outb(old_cmd | ICE1712_AC97_WRITE, ICEREG(ice, AC97_CMD));
-	for (tm = 0; tm < 0x10000; tm++)
-		if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
-			break;
-}
-
-static unsigned short snd_ice1712_ac97_read(ac97_t *ac97,
-					    unsigned short reg)
-{
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
-	int tm;
-	unsigned char old_cmd = 0;
-
-	for (tm = 0; tm < 0x10000; tm++) {
-		old_cmd = inb(ICEREG(ice, AC97_CMD));
-		if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
-			continue;
-		if (!(old_cmd & ICE1712_AC97_READY))
-			continue;
-		break;
-	}
-	outb(reg, ICEREG(ice, AC97_INDEX));
-	outb(old_cmd | ICE1712_AC97_READ, ICEREG(ice, AC97_CMD));
-	for (tm = 0; tm < 0x10000; tm++)
-		if ((inb(ICEREG(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
-			break;
-	if (tm >= 0x10000)		/* timeout */
-		return ~0;
-	return inw(ICEREG(ice, AC97_DATA));
-}
-
-/*
- * pro ac97 section
- */
-
-static void snd_ice1712_pro_ac97_write(ac97_t *ac97,
-				       unsigned short reg,
-				       unsigned short val)
-{
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
-	int tm;
-	unsigned char old_cmd = 0;
-
-	for (tm = 0; tm < 0x10000; tm++) {
-		old_cmd = inb(ICEMT(ice, AC97_CMD));
-		if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
-			continue;
-		if (!(old_cmd & ICE1712_AC97_READY))
-			continue;
-		break;
-	}
-	outb(reg, ICEMT(ice, AC97_INDEX));
-	outw(val, ICEMT(ice, AC97_DATA));
-	old_cmd &= ~(ICE1712_AC97_PBK_VSR | ICE1712_AC97_CAP_VSR);
-	outb(old_cmd | ICE1712_AC97_WRITE, ICEMT(ice, AC97_CMD));
-	for (tm = 0; tm < 0x10000; tm++)
-		if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_WRITE) == 0)
-			break;
-}
-
-
-static unsigned short snd_ice1712_pro_ac97_read(ac97_t *ac97,
-						unsigned short reg)
-{
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
-	int tm;
-	unsigned char old_cmd = 0;
-
-	for (tm = 0; tm < 0x10000; tm++) {
-		old_cmd = inb(ICEMT(ice, AC97_CMD));
-		if (old_cmd & (ICE1712_AC97_WRITE | ICE1712_AC97_READ))
-			continue;
-		if (!(old_cmd & ICE1712_AC97_READY))
-			continue;
-		break;
-	}
-	outb(reg, ICEMT(ice, AC97_INDEX));
-	outb(old_cmd | ICE1712_AC97_READ, ICEMT(ice, AC97_CMD));
-	for (tm = 0; tm < 0x10000; tm++)
-		if ((inb(ICEMT(ice, AC97_CMD)) & ICE1712_AC97_READ) == 0)
-			break;
-	if (tm >= 0x10000)		/* timeout */
-		return ~0;
-	return inw(ICEMT(ice, AC97_DATA));
-}
-
-static int snd_ice1712_digmix_route_ac97_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 snd_ice1712_digmix_route_ac97_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_digmix_route_ac97_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char val, nval;
-	unsigned long flags;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	val = inb(ICEMT(ice, MONITOR_ROUTECTRL));
-	nval = val & ~ICE1712_ROUTE_AC97;
-	if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97;
-	outb(nval, ICEMT(ice, MONITOR_ROUTECTRL));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return val != nval;
-}
-
-static snd_kcontrol_new_t snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Digital Mixer To AC97",
-	.info = snd_ice1712_digmix_route_ac97_info,
-	.get = snd_ice1712_digmix_route_ac97_get,
-	.put = snd_ice1712_digmix_route_ac97_put,
-};
-
-
-/*
- */
-
-static void snd_ice1712_delta_cs8403_spdif_write(ice1712_t *ice, unsigned char bits)
-{
-	unsigned char tmp, mask1, mask2;
-	int idx;
-	/* send byte to transmitter */
-	mask1 = ICE1712_DELTA_SPDIF_OUT_STAT_CLOCK;
-	mask2 = ICE1712_DELTA_SPDIF_OUT_STAT_DATA;
-	down(&ice->gpio_mutex);
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-	for (idx = 7; idx >= 0; idx--) {
-		tmp &= ~(mask1 | mask2);
-		if (bits & (1 << idx))
-			tmp |= mask2;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(100);
-		tmp |= mask1;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(100);
-	}
-	tmp &= ~mask1;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-	up(&ice->gpio_mutex);
-}
-
-
-/*
- * set gpio direction, write mask and data
- */
-static void snd_ice1712_gpio_write_bits(ice1712_t *ice, int mask, int bits)
-{
-	ice->gpio_direction |= mask;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio_direction);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, mask & bits);
-}
-
-/*
- */
-static void save_gpio_status(ice1712_t *ice, unsigned char *tmp)
-{
-	down(&ice->gpio_mutex);
-	tmp[0] = ice->gpio_direction;
-	tmp[1] = ice->gpio_write_mask;
-}
-
-static void restore_gpio_status(ice1712_t *ice, unsigned char *tmp)
-{
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, tmp[0]);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, tmp[1]);
-	ice->gpio_direction = tmp[0];
-	ice->gpio_write_mask = tmp[1];
-	up(&ice->gpio_mutex);
-}
-
-/*
- * CS8427 via SPI mode (for Audiophile), emulated I2C
- */
-
-/* send 8 bits */
-static void ap_cs8427_write_byte(ice1712_t *ice, unsigned char data, unsigned char tmp)
-{
-	int idx;
-
-	for (idx = 7; idx >= 0; idx--) {
-		tmp &= ~(ICE1712_DELTA_AP_DOUT|ICE1712_DELTA_AP_CCLK);
-		if (data & (1 << idx))
-			tmp |= ICE1712_DELTA_AP_DOUT;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(5);
-		tmp |= ICE1712_DELTA_AP_CCLK;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(5);
-	}
-}
-
-/* read 8 bits */
-static unsigned char ap_cs8427_read_byte(ice1712_t *ice, unsigned char tmp)
-{
-	unsigned char data = 0;
-	int idx;
-	
-	for (idx = 7; idx >= 0; idx--) {
-		tmp &= ~ICE1712_DELTA_AP_CCLK;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(5);
-		if (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_DELTA_AP_DIN)
-			data |= 1 << idx;
-		tmp |= ICE1712_DELTA_AP_CCLK;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(5);
-	}
-	return data;
-}
-
-/* assert chip select */
-static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
-{
-	unsigned char tmp;
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-	tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
-	tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-	udelay(5);
-	return tmp;
-}
-
-/* deassert chip select */
-static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
-{
-	tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-}
-
-/* sequential write */
-static int ap_cs8427_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, device->bus->private_data, return -EIO);
-	int res = count;
-	unsigned char tmp;
-
-	down(&ice->gpio_mutex);
-	tmp = ap_cs8427_codec_select(ice);
-	ap_cs8427_write_byte(ice, (device->addr << 1) | 0, tmp); /* address + write mode */
-	while (count-- > 0)
-		ap_cs8427_write_byte(ice, *bytes++, tmp);
-	ap_cs8427_codec_deassert(ice, tmp);
-	up(&ice->gpio_mutex);
-	return res;
-}
-
-/* sequential read */
-static int ap_cs8427_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, device->bus->private_data, return -EIO);
-	int res = count;
-	unsigned char tmp;
-	
-	down(&ice->gpio_mutex);
-	tmp = ap_cs8427_codec_select(ice);
-	ap_cs8427_write_byte(ice, (device->addr << 1) | 1, tmp); /* address + read mode */
-	while (count-- > 0)
-		*bytes++ = ap_cs8427_read_byte(ice, tmp);
-	ap_cs8427_codec_deassert(ice, tmp);
-	up(&ice->gpio_mutex);
-	return res;
-}
-
-static int ap_cs8427_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
-{
-	if (addr == 0x10)
-		return 1;
-	return -ENOENT;
-}
-
-static snd_i2c_ops_t ap_cs8427_i2c_ops = {
-	.sendbytes = ap_cs8427_sendbytes,
-	.readbytes = ap_cs8427_readbytes,
-	.probeaddr = ap_cs8427_probeaddr,
-};
-
-/*
- * access via i2c mode (for EWX 24/96, EWS 88MT&D)
- */
-
-/* send SDA and SCL */
-static void ewx_i2c_setlines(snd_i2c_bus_t *bus, int clk, int data)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
-	unsigned char tmp = 0;
-	if (clk)
-		tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
-	if (data)
-		tmp |= ICE1712_EWX2496_SERIAL_DATA;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-	udelay(5);
-}
-
-static int ewx_i2c_getclock(snd_i2c_bus_t *bus)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return -EIO);
-	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
-}
-
-static int ewx_i2c_getdata(snd_i2c_bus_t *bus, int ack)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return -EIO);
-	int bit;
-	/* set RW pin to low */
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, 0);
-	if (ack)
-		udelay(5);
-	bit = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_DATA ? 1 : 0;
-	/* set RW pin to high */
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_EWX2496_RW);
-	/* reset write mask */
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_SERIAL_CLOCK);
-	return bit;
-}
-
-static void ewx_i2c_start(snd_i2c_bus_t *bus)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
-	unsigned char mask;
-
-	save_gpio_status(ice, (unsigned char *)&bus->private_value);
-	/* set RW high */
-	mask = ICE1712_EWX2496_RW;
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWX2496:
-		mask |= ICE1712_EWX2496_AK4524_CS; /* CS high also */
-		break;
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		mask |= ICE1712_6FIRE_AK4524_CS_MASK; /* CS high also */
-		break;
-	}
-	snd_ice1712_gpio_write_bits(ice, mask, mask);
-}
-
-static void ewx_i2c_stop(snd_i2c_bus_t *bus)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
-	restore_gpio_status(ice, (unsigned char *)&bus->private_value);
-}
-
-static void ewx_i2c_direction(snd_i2c_bus_t *bus, int clock, int data)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, bus->private_data, return);
-	unsigned char mask = 0;
-
-	if (clock)
-		mask |= ICE1712_EWX2496_SERIAL_CLOCK; /* write SCL */
-	if (data)
-		mask |= ICE1712_EWX2496_SERIAL_DATA; /* write SDA */
-	ice->gpio_direction &= ~(ICE1712_EWX2496_SERIAL_CLOCK|ICE1712_EWX2496_SERIAL_DATA);
-	ice->gpio_direction |= mask;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->gpio_direction);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
-}
-
-static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = {
-	.start = ewx_i2c_start,
-	.stop = ewx_i2c_stop,
-	.direction = ewx_i2c_direction,
-	.setlines = ewx_i2c_setlines,
-	.getclock = ewx_i2c_getclock,
-	.getdata = ewx_i2c_getdata,
-};
-
-/* AK4524 chip select; address 0x48 bit 0-3 */
-static int snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask)
-{
-	unsigned char data, ndata;
-
-	snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1)
-		goto __error;
-	ndata = (data & 0xf0) | chip_mask;
-	if (ndata != data)
-		if (snd_i2c_sendbytes(ice->pcf8574[1], &ndata, 1) != 1)
-			goto __error;
-	snd_i2c_unlock(ice->i2c);
-	return 0;
-
-     __error:
-	snd_i2c_unlock(ice->i2c);
-	snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n");
-	return -EIO;
-}
-
-/*
- * write AK4524 register
- */
-static void snd_ice1712_ak4524_write(ice1712_t *ice, int chip,
-				     unsigned char addr, unsigned char data)
-{
-	unsigned char tmp, data_mask, clk_mask, saved[2];
-	unsigned char codecs_mask;
-	int idx, cif;
-	unsigned int addrdata;
-
-	snd_assert(chip >= 0 && chip < 4, return);
-
-	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_EWS88MT) {
-		/* assert AK4524 CS */
-		if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
-			return;
-		//snd_ice1712_ews88mt_chip_select(ice, 0x0f);
-	}
-
-	cif = 0; /* the default level of the CIF pin from AK4524 */
-	save_gpio_status(ice, saved);
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-		data_mask = ICE1712_DELTA_AP_DOUT;
-		clk_mask = ICE1712_DELTA_AP_CCLK;
-		codecs_mask = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528 codec */
-		tmp |= ICE1712_DELTA_AP_CS_DIGITAL; /* assert digital high */
-		break;
-	case ICE1712_SUBDEVICE_EWX2496:
-		data_mask = ICE1712_EWX2496_SERIAL_DATA;
-		clk_mask = ICE1712_EWX2496_SERIAL_CLOCK;
-		codecs_mask = ICE1712_EWX2496_AK4524_CS;
-		tmp |= ICE1712_EWX2496_RW; /* set rw bit high */
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-				  ice->gpio_direction | data_mask | clk_mask |
-				  codecs_mask | ICE1712_EWX2496_RW);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
-				  ~(data_mask | clk_mask |
-				    codecs_mask | ICE1712_EWX2496_RW));
-		cif = 1; /* CIF high */
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-		data_mask = ICE1712_EWS88_SERIAL_DATA;
-		clk_mask = ICE1712_EWS88_SERIAL_CLOCK;
-		codecs_mask = 0; /* no chip select on gpio */
-		tmp |= ICE1712_EWS88_RW; /* set rw bit high */
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-				  ice->gpio_direction | data_mask | clk_mask |
-				  codecs_mask | ICE1712_EWS88_RW);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
-				  ~(data_mask | clk_mask |
-				    codecs_mask | ICE1712_EWS88_RW));
-		cif = 1; /* CIF high */
-		break;
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		data_mask = ICE1712_6FIRE_SERIAL_DATA;
-		clk_mask = ICE1712_6FIRE_SERIAL_CLOCK;
-		codecs_mask = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
-		tmp |= ICE1712_6FIRE_RW; /* set rw bit high */
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
-				  ice->gpio_direction | data_mask | clk_mask |
-				  codecs_mask | ICE1712_6FIRE_RW);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
-				  ~(data_mask | clk_mask |
-				    codecs_mask | ICE1712_6FIRE_RW));
-		cif = 1; /* CIF high */
-		break;
-	default:
-		data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA;
-		clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK;
-		codecs_mask = chip == 0 ? ICE1712_DELTA_CODEC_CHIP_A : ICE1712_DELTA_CODEC_CHIP_B;
-		break;
-	}
-
-	if (cif) {
-		tmp |= codecs_mask; /* start without chip select */
-	} else {
-		tmp &= ~codecs_mask; /* chip select low */
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(1);
-	}
-
-	addr &= 0x07;
-	/* build I2C address + data byte */
-	addrdata = 0xa000 | (addr << 8) | data;
-	for (idx = 15; idx >= 0; idx--) {
-		tmp &= ~(data_mask|clk_mask);
-		if (addrdata & (1 << idx))
-			tmp |= data_mask;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		//udelay(200);
-		udelay(1);
-		tmp |= clk_mask;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(1);
-	}
-
-	if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_EWS88MT) {
-		restore_gpio_status(ice, saved);
-		//snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f);
-		udelay(1);
-		snd_ice1712_ews88mt_chip_select(ice, 0x0f);
-	} else {
-		if (cif) {
-			/* assert a cs pulse to trigger */
-			tmp &= ~codecs_mask;
-			snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-			udelay(1);
-		}
-		tmp |= codecs_mask; /* chip select high to trigger */
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-		udelay(1);
-		restore_gpio_status(ice, saved);
-	}
-
-	if ((addr != 0x04 && addr != 0x05) || (data & 0x80) == 0)
-		ice->ak4524_images[chip][addr] = data;
-	else
-		ice->ak4524_ipga_gain[chip][addr-4] = data;
-}
-
-static void snd_ice1712_ak4524_reset(ice1712_t *ice, int state)
-{
-	int chip;
-	unsigned char reg;
-	
-	for (chip = 0; chip < ice->num_dacs/2; chip++) {
-		snd_ice1712_ak4524_write(ice, chip, 0x01, state ? 0x00 : 0x03);
-		if (state)
-			continue;
-		for (reg = 0x04; reg < (ice->ak4528 ? 0x06 : 0x08); reg++)
-			snd_ice1712_ak4524_write(ice, chip, reg, ice->ak4524_images[chip][reg]);
-		if (ice->ak4528)
-			continue;
-		for (reg = 0x04; reg < 0x06; reg++)
-			snd_ice1712_ak4524_write(ice, chip, reg, ice->ak4524_ipga_gain[chip][reg-4]);
-	}
-}
-
-static void snd_ice1712_ews_cs8404_spdif_write(ice1712_t *ice, unsigned char bits)
-{
-	unsigned char bytes[2];
-
-	snd_i2c_lock(ice->i2c);
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWS88MT:
-		snd_runtime_check(snd_i2c_sendbytes(ice->cs8404, &bits, 1) == 1, snd_i2c_unlock(ice->i2c); return);
-		break;
-	case ICE1712_SUBDEVICE_EWS88D:
-		snd_runtime_check(snd_i2c_readbytes(ice->pcf8575, bytes, 2) == 2, snd_i2c_unlock(ice->i2c); return);
-		if (bits != bytes[1]) {
-			bytes[1] = bits;
-			snd_runtime_check(snd_i2c_readbytes(ice->pcf8575, bytes, 2) == 2, snd_i2c_unlock(ice->i2c); return);
-		}
-		break;
-	}
-	snd_i2c_unlock(ice->i2c);
-}
-
-
-/*
- * change the input clock selection
- * spdif_clock = 1 - IEC958 input, 0 - Envy24
- */
-static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
-{
-	unsigned char reg[2] = { 0x80 | 4, 0 };   /* CS8427 auto increment | register number 4 + data */
-	unsigned char val, nval;
-	int res = 0;
-	
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	nval = val & 0xf0;
-	if (spdif_clock)
-		nval |= 0x01;
-	else
-		nval |= 0x04;
-	if (val != nval) {
-		reg[1] = nval;
-		if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
-			res = -EIO;
-		} else {
-			res++;
-		}
-	}
-	snd_i2c_unlock(ice->i2c);
-	return res;
-}
-
-/*
- */
-static void snd_ice1712_set_pro_rate(ice1712_t *ice, snd_pcm_substream_t *substream)
-{
-	unsigned long flags;
-	unsigned int rate;
-	unsigned char val, tmp, tmp2;
-
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW|
-						 ICE1712_PLAYBACK_PAUSE|
-						 ICE1712_PLAYBACK_START))
-		goto __end;
-	if (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)
-		goto __end;
-	rate = substream->runtime->rate;
-	switch (rate) {
-	case 8000: val = 6; break;
-	case 9600: val = 3; break;
-	case 11025: val = 10; break;
-	case 12000: val = 2; break;
-	case 16000: val = 5; break;
-	case 22050: val = 9; break;
-	case 24000: val = 1; break;
-	case 32000: val = 4; break;
-	case 44100: val = 8; break;
-	case 48000: val = 0; break;
-	case 64000: val = 15; break;
-	case 88200: val = 11; break;
-	case 96000: val = 7; break;
-	default:
-		snd_BUG();
-		val = 0;
-		break;
-	}
-	outb(val, ICEMT(ice, RATE));
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTA1010LT:	// check it --jk
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_DELTA44:
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-		spin_unlock_irqrestore(&ice->reg_lock, flags);
-		down(&ice->gpio_mutex);
-		tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-		up(&ice->gpio_mutex);
-		tmp2 = tmp;
-		tmp2 &= ~ICE1712_DELTA_DFS; 
-		if (val == 15 || val == 11 || val == 7)
-			tmp2 |= ICE1712_DELTA_DFS;
-		if (tmp != tmp2) {
-			snd_ice1712_ak4524_reset(ice, 1);
-			down(&ice->gpio_mutex);
-			tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-			if (val == 15 || val == 11 || val == 7)
-				tmp |= ICE1712_DELTA_DFS;
-			else
-				tmp &= ~ICE1712_DELTA_DFS;
-			snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
-			up(&ice->gpio_mutex);
-			snd_ice1712_ak4524_reset(ice, 0);
-		}
-		return;
-	}
-      __end:
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-}
-
-/*
- *  Interrupt handler
- */
-
-static void snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, dev_id, return);
-	unsigned char status;
-
-	while (1) {
-		status = inb(ICEREG(ice, IRQSTAT));
-		if (status == 0)
-			break;
-		if (status & ICE1712_IRQ_MPU1) {
-			if (ice->rmidi[0])
-				snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
-			outb(ICE1712_IRQ_MPU1, ICEREG(ice, IRQSTAT));
-			status &= ~ICE1712_IRQ_MPU1;
-		}
-		if (status & ICE1712_IRQ_TIMER)
-			outb(ICE1712_IRQ_TIMER, ICEREG(ice, IRQSTAT));
-		if (status & ICE1712_IRQ_MPU2) {
-			if (ice->rmidi[1])
-				snd_mpu401_uart_interrupt(irq, ice->rmidi[1]->private_data, regs);
-			outb(ICE1712_IRQ_MPU2, ICEREG(ice, IRQSTAT));
-			status &= ~ICE1712_IRQ_MPU2;
-		}
-		if (status & ICE1712_IRQ_PROPCM) {
-			unsigned char mtstat = inb(ICEMT(ice, IRQ));
-			if (mtstat & ICE1712_MULTI_PBKSTATUS) {
-				if (ice->playback_pro_substream)
-					snd_pcm_period_elapsed(ice->playback_pro_substream);
-				outb(ICE1712_MULTI_PBKSTATUS, ICEMT(ice, IRQ));
-			}
-			if (mtstat & ICE1712_MULTI_CAPSTATUS) {
-				if (ice->capture_pro_substream)
-					snd_pcm_period_elapsed(ice->capture_pro_substream);
-				outb(ICE1712_MULTI_CAPSTATUS, ICEMT(ice, IRQ));
-			}
-		}
-		if (status & ICE1712_IRQ_FM)
-			outb(ICE1712_IRQ_FM, ICEREG(ice, IRQSTAT));
-		if (status & ICE1712_IRQ_PBKDS) {
-			u32 idx;
-			u16 pbkstatus;
-			snd_pcm_substream_t *substream;
-			pbkstatus = inw(ICEDS(ice, INTSTAT));
-			//printk("pbkstatus = 0x%x\n", pbkstatus);
-			for (idx = 0; idx < 6; idx++) {
-				if ((pbkstatus & (3 << (idx * 2))) == 0)
-					continue;
-				if ((substream = ice->playback_con_substream_ds[idx]) != NULL)
-					snd_pcm_period_elapsed(substream);
-				outw(3 << (idx * 2), ICEDS(ice, INTSTAT));
-			}
-			outb(ICE1712_IRQ_PBKDS, ICEREG(ice, IRQSTAT));
-		}
-		if (status & ICE1712_IRQ_CONCAP) {
-			if (ice->capture_con_substream)
-				snd_pcm_period_elapsed(ice->capture_con_substream);
-			outb(ICE1712_IRQ_CONCAP, ICEREG(ice, IRQSTAT));
-		}
-		if (status & ICE1712_IRQ_CONPBK) {
-			if (ice->playback_con_substream)
-				snd_pcm_period_elapsed(ice->playback_con_substream);
-			outb(ICE1712_IRQ_CONPBK, ICEREG(ice, IRQSTAT));
-		}
-	}
-}
-
-/*
- *  PCM part - misc
- */
-
-static int snd_ice1712_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
-{
-	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
-static int snd_ice1712_hw_free(snd_pcm_substream_t * substream)
-{
-	return snd_pcm_lib_free_pages(substream);
-}
-
-/*
- *  PCM part - consumer I/O
- */
-
-static int snd_ice1712_playback_trigger(snd_pcm_substream_t * substream,
-					int cmd)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	int result = 0;
-	u32 tmp;
-	
-	spin_lock(&ice->reg_lock);
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL);
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
-		tmp |= 1;
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		tmp &= ~1;
-	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
-		tmp |= 2;
-	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
-		tmp &= ~2;
-	} else {
-		result = -EINVAL;
-	}
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
-	spin_unlock(&ice->reg_lock);
-	return result;
-}
-
-static int snd_ice1712_playback_ds_trigger(snd_pcm_substream_t * substream,
-					   int cmd)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	int result = 0;
-	u32 tmp;
-	
-	spin_lock(&ice->reg_lock);
-	tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL);
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
-		tmp |= 1;
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		tmp &= ~1;
-	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH) {
-		tmp |= 2;
-	} else if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) {
-		tmp &= ~2;
-	} else {
-		result = -EINVAL;
-	}
-	snd_ice1712_ds_write(ice, substream->number * 2, ICE1712_DSC_CONTROL, tmp);
-	spin_unlock(&ice->reg_lock);
-	return result;
-}
-
-static int snd_ice1712_capture_trigger(snd_pcm_substream_t * substream,
-				       int cmd)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	int result = 0;
-	u8 tmp;
-	
-	spin_lock(&ice->reg_lock);
-	tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL);
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
-		tmp |= 1;
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		tmp &= ~1;
-	} else {
-		result = -EINVAL;
-	}
-	snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
-	spin_unlock(&ice->reg_lock);
-	return result;
-}
-
-static int snd_ice1712_playback_prepare(snd_pcm_substream_t * substream)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	u32 period_size, buf_size, rate, tmp;
-
-	period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
-	buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
-	tmp = 0x0000;
-	if (snd_pcm_format_width(runtime->format) == 16)
-		tmp |= 0x10;
-	if (runtime->channels == 2)
-		tmp |= 0x08;
-	rate = (runtime->rate * 8192) / 375;
-	if (rate > 0x000fffff)
-		rate = 0x000fffff;
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	outb(0, ice->ddma_port + 15);
-	outb(ICE1712_DMA_MODE_WRITE | ICE1712_DMA_AUTOINIT, ice->ddma_port + 0x0b);
-	outl(runtime->dma_addr, ice->ddma_port + 0);
-	outw(buf_size, ice->ddma_port + 4);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_LO, rate & 0xff);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_MID, (rate >> 8) & 0xff);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_RATE_HI, (rate >> 16) & 0xff);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_CTRL, tmp);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_LO, period_size & 0xff);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_COUNT_HI, period_size >> 8);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_LEFT, 0);
-	snd_ice1712_write(ice, ICE1712_IREG_PBK_RIGHT, 0);
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_playback_ds_prepare(snd_pcm_substream_t * substream)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	u32 period_size, buf_size, rate, tmp, chn;
-
-	period_size = snd_pcm_lib_period_bytes(substream) - 1;
-	buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
-	tmp = 0x0064;
-	if (snd_pcm_format_width(runtime->format) == 16)
-		tmp &= ~0x04;
-	if (runtime->channels == 2)
-		tmp |= 0x08;
-	rate = (runtime->rate * 8192) / 375;
-	if (rate > 0x000fffff)
-		rate = 0x000fffff;
-	ice->playback_con_active_buf[substream->number] = 0;
-	ice->playback_con_virt_addr[substream->number] = runtime->dma_addr;
-	chn = substream->number * 2;
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR0, runtime->dma_addr);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT0, period_size);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_ADDR1, runtime->dma_addr + (runtime->periods > 1 ? period_size + 1 : 0));
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_COUNT1, period_size);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_RATE, rate);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_VOLUME, 0);
-	snd_ice1712_ds_write(ice, chn, ICE1712_DSC_CONTROL, tmp);
-	if (runtime->channels == 2) {
-		snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_RATE, rate);
-		snd_ice1712_ds_write(ice, chn + 1, ICE1712_DSC_VOLUME, 0);
-	}
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_capture_prepare(snd_pcm_substream_t * substream)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	u32 period_size, buf_size;
-	u8 tmp;
-
-	period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
-	buf_size = snd_pcm_lib_buffer_bytes(substream) - 1;
-	tmp = 0x06;
-	if (snd_pcm_format_width(runtime->format) == 16)
-		tmp &= ~0x04;
-	if (runtime->channels == 2)
-		tmp &= ~0x02;
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	outl(ice->capture_con_virt_addr = runtime->dma_addr, ICEREG(ice, CONCAP_ADDR));
-	outw(buf_size, ICEREG(ice, CONCAP_COUNT));
-	snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_HI, period_size >> 8);
-	snd_ice1712_write(ice, ICE1712_IREG_CAP_COUNT_LO, period_size & 0xff);
-	snd_ice1712_write(ice, ICE1712_IREG_CAP_CTRL, tmp);
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	snd_ac97_set_rate(ice->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
-	return 0;
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_pointer(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	size_t ptr;
-
-	if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))
-		return 0;
-	ptr = runtime->buffer_size - inw(ice->ddma_port + 4);
-	return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	u8 addr;
-	size_t ptr;
-
-	if (!(snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL) & 1))
-		return 0;
-	if (ice->playback_con_active_buf[substream->number])
-		addr = ICE1712_DSC_ADDR1;
-	else
-		addr = ICE1712_DSC_ADDR0;
-	ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) -
-		ice->playback_con_virt_addr[substream->number];
-	return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_capture_pointer(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	size_t ptr;
-
-	if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))
-		return 0;
-	ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr;
-	return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_hardware_t snd_ice1712_playback =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE),
-	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
-	.rate_min =		4000,
-	.rate_max =		48000,
-	.channels_min =		1,
-	.channels_max =		2,
-	.buffer_bytes_max =	(64*1024),
-	.period_bytes_min =	64,
-	.period_bytes_max =	(64*1024),
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
-static snd_pcm_hardware_t snd_ice1712_playback_ds =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE),
-	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
-	.rate_min =		4000,
-	.rate_max =		48000,
-	.channels_min =		1,
-	.channels_max =		2,
-	.buffer_bytes_max =	(128*1024),
-	.period_bytes_min =	64,
-	.period_bytes_max =	(128*1024),
-	.periods_min =		2,
-	.periods_max =		2,
-	.fifo_size =		0,
-};
-
-static snd_pcm_hardware_t snd_ice1712_capture =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
-	.rate_min =		4000,
-	.rate_max =		48000,
-	.channels_min =		1,
-	.channels_max =		2,
-	.buffer_bytes_max =	(64*1024),
-	.period_bytes_min =	64,
-	.period_bytes_max =	(64*1024),
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
-static int snd_ice1712_playback_open(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->playback_con_substream = substream;
-	runtime->hw = snd_ice1712_playback;
-	return 0;
-}
-
-static int snd_ice1712_playback_ds_open(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	unsigned long flags;
-	u32 tmp;
-
-	ice->playback_con_substream_ds[substream->number] = substream;
-	runtime->hw = snd_ice1712_playback_ds;
-	spin_lock_irqsave(&ice->reg_lock, flags); 
-	tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2));
-	outw(tmp, ICEDS(ice, INTMASK));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_capture_open(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->capture_con_substream = substream;
-	runtime->hw = snd_ice1712_capture;
-	runtime->hw.rates = ice->ac97->rates[AC97_RATES_ADC];
-	if (!(runtime->hw.rates & SNDRV_PCM_RATE_8000))
-		runtime->hw.rate_min = 48000;
-	return 0;
-}
-
-static int snd_ice1712_playback_close(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->playback_con_substream = NULL;
-	return 0;
-}
-
-static int snd_ice1712_playback_ds_close(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	unsigned long flags;
-	u32 tmp;
-
-	spin_lock_irqsave(&ice->reg_lock, flags); 
-	tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2));
-	outw(tmp, ICEDS(ice, INTMASK));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	ice->playback_con_substream_ds[substream->number] = NULL;
-	return 0;
-}
-
-static int snd_ice1712_capture_close(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->capture_con_substream = NULL;
-	return 0;
-}
-
-static snd_pcm_ops_t snd_ice1712_playback_ops = {
-	.open =		snd_ice1712_playback_open,
-	.close =	snd_ice1712_playback_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
-	.hw_free =	snd_ice1712_hw_free,
-	.prepare =	snd_ice1712_playback_prepare,
-	.trigger =	snd_ice1712_playback_trigger,
-	.pointer =	snd_ice1712_playback_pointer,
-};
-
-static snd_pcm_ops_t snd_ice1712_playback_ds_ops = {
-	.open =		snd_ice1712_playback_ds_open,
-	.close =	snd_ice1712_playback_ds_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
-	.hw_free =	snd_ice1712_hw_free,
-	.prepare =	snd_ice1712_playback_ds_prepare,
-	.trigger =	snd_ice1712_playback_ds_trigger,
-	.pointer =	snd_ice1712_playback_ds_pointer,
-};
-
-static snd_pcm_ops_t snd_ice1712_capture_ops = {
-	.open =		snd_ice1712_capture_open,
-	.close =	snd_ice1712_capture_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
-	.hw_free =	snd_ice1712_hw_free,
-	.prepare =	snd_ice1712_capture_prepare,
-	.trigger =	snd_ice1712_capture_trigger,
-	.pointer =	snd_ice1712_capture_pointer,
-};
-
-static void snd_ice1712_pcm_free(snd_pcm_t *pcm)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, pcm->private_data, return);
-	ice->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ice1712_pcm(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
-	int err;
-
-	if (rpcm)
-		*rpcm = NULL;
-	err = snd_pcm_new(ice->card, "ICE1712 consumer", device, 1, 1, &pcm);
-	if (err < 0)
-		return err;
-
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);
-
-	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_free;
-	pcm->info_flags = 0;
-	strcpy(pcm->name, "ICE1712 consumer");
-	ice->pcm = pcm;
-
-	snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 64*1024, 64*1024);
-
-	if (rpcm)
-		*rpcm = pcm;
-
-	printk(KERN_WARNING "Consumer PCM code does not work well at the moment --jk\n");
-
-	return 0;
-}
-
-static void snd_ice1712_pcm_free_ds(snd_pcm_t *pcm)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, pcm->private_data, return);
-	ice->pcm_ds = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ice1712_pcm_ds(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
-	int err;
-
-	if (rpcm)
-		*rpcm = NULL;
-	err = snd_pcm_new(ice->card, "ICE1712 consumer (DS)", device, 6, 0, &pcm);
-	if (err < 0)
-		return err;
-
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);
-
-	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_free_ds;
-	pcm->info_flags = 0;
-	strcpy(pcm->name, "ICE1712 consumer (DS)");
-	ice->pcm_ds = pcm;
-
-	snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 64*1024, 128*1024);
-
-	if (rpcm)
-		*rpcm = pcm;
-
-	return 0;
-}
-
-/*
- *  PCM code - professional part (multitrack)
- */
-
-static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,
-				32000, 44100, 48000, 64000, 88200, 96000 };
-
-#define RATES sizeof(rates) / sizeof(rates[0])
-
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
-	.count = RATES,
-	.list = rates,
-	.mask = 0,
-};
-
-#if 0
-
-static int snd_ice1712_playback_pro_ioctl(snd_pcm_substream_t * substream,
-					  unsigned int cmd,
-					  void *arg)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	switch (cmd) {
-	case SNDRV_PCM_IOCTL1_DIG_INFO:
-	{
-		snd_pcm_dig_info_t *info = arg;
-		switch (ice->eeprom.subvendor) {
-		case ICE1712_SUBDEVICE_DELTA1010:
-		case ICE1712_SUBDEVICE_DELTADIO2496:
-		case ICE1712_SUBDEVICE_DELTA66:
-			return snd_ice1712_dig_cs8403_info(substream, info);
-		}
-	}
-	case SNDRV_PCM_IOCTL1_DIG_PARAMS:
-	{
-		snd_pcm_dig_params_t *params = arg;
-		switch (ice->eeprom.subvendor) {
-		case ICE1712_SUBDEVICE_DELTA1010:
-		case ICE1712_SUBDEVICE_DELTADIO2496:
-		case ICE1712_SUBDEVICE_DELTA66:
-			return snd_ice1712_dig_cs8403_params(substream, params);
-		}
-	}
-	default:
-		break;
-	}
-	return snd_pcm_lib_ioctl(substream, cmd, arg);
-}
-
-#endif
-
-static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,
-				   int cmd)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-	{
-		unsigned int what;
-		unsigned int old;
-		if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
-			return -EINVAL;
-		what = ICE1712_PLAYBACK_PAUSE;
-		snd_pcm_trigger_done(substream, substream);
-		spin_lock(&ice->reg_lock);
-		old = inl(ICEMT(ice, PLAYBACK_CONTROL));
-		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
-			old |= what;
-		else
-			old &= ~what;
-		outl(old, ICEMT(ice, PLAYBACK_CONTROL));
-		spin_unlock(&ice->reg_lock);
-		break;
-	}
-	case SNDRV_PCM_TRIGGER_START:
-	case SNDRV_PCM_TRIGGER_STOP:
-	{
-		unsigned int what = 0;
-		unsigned int old;
-		snd_pcm_substream_t *s = substream;
-		do {
-			if (s == ice->playback_pro_substream) {
-				what |= ICE1712_PLAYBACK_START;
-				snd_pcm_trigger_done(s, substream);
-			} else if (s == ice->capture_pro_substream) {
-				what |= ICE1712_CAPTURE_START_SHADOW;
-				snd_pcm_trigger_done(s, substream);
-			}
-			s = s->link_next;
-		} while (s != substream);
-		spin_lock(&ice->reg_lock);
-		old = inl(ICEMT(ice, PLAYBACK_CONTROL));
-		if (cmd == SNDRV_PCM_TRIGGER_START)
-			old |= what;
-		else
-			old &= ~what;
-		outl(old, ICEMT(ice, PLAYBACK_CONTROL));
-		spin_unlock(&ice->reg_lock);
-		break;
-	}
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	unsigned int tmp;
-	int change;
-
-	ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
-	snd_ice1712_set_pro_rate(ice, substream);
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	outl(substream->runtime->dma_addr, ICEMT(ice, PLAYBACK_ADDR));
-	outw((ice->playback_pro_size >> 2) - 1, ICEMT(ice, PLAYBACK_SIZE));
-	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, PLAYBACK_COUNT));
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		/* setup S/PDIF */
-		tmp = ice->cs8403_spdif_stream_bits;
-		if (tmp & 0x01)		/* consumer */
-			tmp &= (tmp & 0x01) ? ~0x06 : ~0x18;
-		switch (substream->runtime->rate) {
-		case 32000: tmp |= (tmp & 0x01) ? 0x04 : 0x00; break;
-		case 44100: tmp |= (tmp & 0x01) ? 0x00 : 0x10; break;
-		case 48000: tmp |= (tmp & 0x01) ? 0x02 : 0x08; break;
-		default: tmp |= (tmp & 0x01) ? 0x00 : 0x18; break;
-		}
-		change = ice->cs8403_spdif_stream_bits != tmp;
-		ice->cs8403_spdif_stream_bits = tmp;
-		spin_unlock_irqrestore(&ice->reg_lock, flags);
-		if (change)
-			snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif_stream_ctl->id);
-		snd_ice1712_delta_cs8403_spdif_write(ice, tmp);
-		return 0;
-	case ICE1712_SUBDEVICE_EWX2496:
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-		snd_cs8427_iec958_pcm(ice->cs8427, substream->runtime->rate);
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		/* setup S/PDIF */
-		tmp = ice->cs8403_spdif_stream_bits;
-		if (tmp & 0x10)		/* consumer */
-			tmp &= (tmp & 0x01) ? ~0x06 : ~0x60;
-		switch (substream->runtime->rate) {
-		case 32000: tmp |= (tmp & 0x01) ? 0x02 : 0x00; break;
-		case 44100: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
-		case 48000: tmp |= (tmp & 0x01) ? 0x04 : 0x20; break;
-		default: tmp |= (tmp & 0x01) ? 0x06 : 0x40; break;
-		}
-		change = ice->cs8403_spdif_stream_bits != tmp;
-		ice->cs8403_spdif_stream_bits = tmp;
-		spin_unlock_irqrestore(&ice->reg_lock, flags);
-		if (change)
-			snd_ctl_notify(ice->card, SNDRV_CTL_EVENT_MASK_VALUE, &ice->spdif_stream_ctl->id);
-		snd_ice1712_ews_cs8404_spdif_write(ice, tmp);
-		return 0;
-	}
-
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
-	snd_ice1712_set_pro_rate(ice, substream);
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	outl(substream->runtime->dma_addr, ICEMT(ice, CAPTURE_ADDR));
-	outw((ice->capture_pro_size >> 2) - 1, ICEMT(ice, CAPTURE_SIZE));
-	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ICEMT(ice, CAPTURE_COUNT));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	size_t ptr;
-
-	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
-		return 0;
-	ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2);
-	return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	size_t ptr;
-
-	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))
-		return 0;
-	ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2);
-	return bytes_to_frames(substream->runtime, ptr);
-}
-
-static snd_pcm_hardware_t snd_ice1712_playback_pro =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
-	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
-	.rate_min =		4000,
-	.rate_max =		96000,
-	.channels_min =		10,
-	.channels_max =		10,
-	.buffer_bytes_max =	(256*1024),
-	.period_bytes_min =	10 * 4 * 2,
-	.period_bytes_max =	131040,
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
-static snd_pcm_hardware_t snd_ice1712_capture_pro =
-{
-	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP_VALID |
-				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
-	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000,
-	.rate_min =		4000,
-	.rate_max =		96000,
-	.channels_min =		12,
-	.channels_max =		12,
-	.buffer_bytes_max =	(256*1024),
-	.period_bytes_min =	12 * 4 * 2,
-	.period_bytes_max =	131040,
-	.periods_min =		1,
-	.periods_max =		1024,
-	.fifo_size =		0,
-};
-
-static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->playback_pro_substream = substream;
-	runtime->hw = snd_ice1712_playback_pro;
-	snd_pcm_set_sync(substream);
-	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
-	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
-
-	ice->cs8403_spdif_stream_bits = ice->cs8403_spdif_bits;
-	if (ice->cs8427)
-		snd_cs8427_iec958_active(ice->cs8427, 1);
-
-	return 0;
-}
-
-static int snd_ice1712_capture_pro_open(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-
-	ice->capture_pro_substream = substream;
-	runtime->hw = snd_ice1712_capture_pro;
-	snd_pcm_set_sync(substream);
-	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
-	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
-	return 0;
-}
-
-static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->playback_pro_substream = NULL;
-	if (ice->cs8427)
-		snd_cs8427_iec958_active(ice->cs8427, 0);
-
-	return 0;
-}
-
-static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream)
-{
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-
-	ice->capture_pro_substream = NULL;
-	return 0;
-}
-
-static void snd_ice1712_pcm_profi_free(snd_pcm_t *pcm)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, pcm->private_data, return);
-	ice->pcm_pro = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static snd_pcm_ops_t snd_ice1712_playback_pro_ops = {
-	.open =		snd_ice1712_playback_pro_open,
-	.close =	snd_ice1712_playback_pro_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
-	.hw_free =	snd_ice1712_hw_free,
-	.prepare =	snd_ice1712_playback_pro_prepare,
-	.trigger =	snd_ice1712_pro_trigger,
-	.pointer =	snd_ice1712_playback_pro_pointer,
-};
-
-static snd_pcm_ops_t snd_ice1712_capture_pro_ops = {
-	.open =		snd_ice1712_capture_pro_open,
-	.close =	snd_ice1712_capture_pro_close,
-	.ioctl =	snd_pcm_lib_ioctl,
-	.hw_params =	snd_ice1712_hw_params,
-	.hw_free =	snd_ice1712_hw_free,
-	.prepare =	snd_ice1712_capture_pro_prepare,
-	.trigger =	snd_ice1712_pro_trigger,
-	.pointer =	snd_ice1712_capture_pro_pointer,
-};
-
-static int __devinit snd_ice1712_pcm_profi(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
-	int err;
-
-	if (rpcm)
-		*rpcm = NULL;
-	err = snd_pcm_new(ice->card, "ICE1712 multi", device, 1, 1, &pcm);
-	if (err < 0)
-		return err;
-
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_pro_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);
-
-	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_profi_free;
-	pcm->info_flags = 0;
-	strcpy(pcm->name, "ICE1712 multi");
-
-	snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 256*1024, 256*1024);
-
-	ice->pcm_pro = pcm;
-	if (rpcm)
-		*rpcm = pcm;
-	
-	if (ice->cs8427) {
-		/* assign channels to iec958 */
-		err = snd_cs8427_iec958_build(ice->cs8427,
-					      pcm->streams[0].substream,
-					      pcm->streams[1].substream);
-		if (err < 0)
-			return err;
-	}
-
-	if ((err = snd_ice1712_build_pro_mixer(ice)) < 0)
-		return err;
-	return 0;
-}
-
-/*
- *  Mixer section
- */
-
-static void snd_ice1712_update_volume(ice1712_t *ice, int index)
-{
-	unsigned int vol = ice->pro_volumes[index];
-	unsigned short val = 0;
-
-	val |= (vol & 0x8000) == 0 ? (96 - (vol & 0x7f)) : 0x7f;
-	val |= ((vol & 0x80000000) == 0 ? (96 - ((vol >> 16) & 0x7f)) : 0x7f) << 8;
-	outb(index, ICEMT(ice, MONITOR_INDEX));
-	outw(val, ICEMT(ice, MONITOR_VOLUME));
-}
-
-static int snd_ice1712_pro_mixer_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 2;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
-
-static int snd_ice1712_pro_mixer_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	int index = kcontrol->private_value;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	ucontrol->value.integer.value[0] = !((ice->pro_volumes[index] >> 15) & 1);
-	ucontrol->value.integer.value[1] = !((ice->pro_volumes[index] >> 31) & 1);
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_pro_mixer_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int index = kcontrol->private_value;
-	unsigned int nval, change;
-
-	nval = (ucontrol->value.integer.value[0] ? 0 : 0x00008000) |
-	       (ucontrol->value.integer.value[1] ? 0 : 0x80000000);
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	nval |= ice->pro_volumes[index] & ~0x80008000;
-	change = nval != ice->pro_volumes[index];
-	ice->pro_volumes[index] = nval;
-	snd_ice1712_update_volume(ice, index);
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return change;
-}
-
-static int snd_ice1712_pro_mixer_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 2;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 96;
-	return 0;
-}
-
-static int snd_ice1712_pro_mixer_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	int index = kcontrol->private_value;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	ucontrol->value.integer.value[0] = (ice->pro_volumes[index] >> 0) & 127;
-	ucontrol->value.integer.value[1] = (ice->pro_volumes[index] >> 16) & 127;
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_pro_mixer_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int index = kcontrol->private_value;
-	unsigned int nval, change;
-
-	nval = (ucontrol->value.integer.value[0] & 127) |
-	       ((ucontrol->value.integer.value[1] & 127) << 16);
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	nval |= ice->pro_volumes[index] & ~0x007f007f;
-	change = nval != ice->pro_volumes[index];
-	ice->pro_volumes[index] = nval;
-	snd_ice1712_update_volume(ice, index);
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return change;
-}
-
-static int snd_ice1712_ak4524_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 127;
-	return 0;
-}
-
-static int snd_ice1712_ak4524_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->private_value / 8;
-	int addr = kcontrol->private_value % 8;
-	ucontrol->value.integer.value[0] = ice->ak4524_images[chip][addr];
-	return 0;
-}
-
-static int snd_ice1712_ak4524_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->private_value / 8;
-	int addr = kcontrol->private_value % 8;
-	unsigned char nval = ucontrol->value.integer.value[0];
-	int change = ice->ak4524_images[chip][addr] != nval;
-	if (change)
-		snd_ice1712_ak4524_write(ice, chip, addr, nval);
-	return change;
-}
-
-static int snd_ice1712_ak4524_ipga_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 36;
-	return 0;
-}
-
-static int snd_ice1712_ak4524_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->private_value / 8;
-	int addr = kcontrol->private_value % 8;
-	ucontrol->value.integer.value[0] = ice->ak4524_ipga_gain[chip][addr-4] & 0x7f;
-	return 0;
-}
-
-static int snd_ice1712_ak4524_ipga_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->private_value / 8;
-	int addr = kcontrol->private_value % 8;
-	unsigned char nval = (ucontrol->value.integer.value[0] % 37) | 0x80;
-	int change = ice->ak4524_ipga_gain[chip][addr] != nval;
-	if (change)
-		snd_ice1712_ak4524_write(ice, chip, addr, nval);
-	return change;
-}
-
-static int snd_ice1712_ak4524_deemphasis_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
-{
-	static char *texts[4] = {
-		"44.1kHz", "Off", "48kHz", "32kHz",
-	};
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 4;
-	if (uinfo->value.enumerated.item >= 4)
-		uinfo->value.enumerated.item = 3;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int snd_ice1712_ak4524_deemphasis_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->id.index;
-	ucontrol->value.enumerated.item[0] = ice->ak4524_images[chip][3] & 3;
-	return 0;
-}
-
-static int snd_ice1712_ak4524_deemphasis_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int chip = kcontrol->id.index;
-	unsigned char nval = ucontrol->value.enumerated.item[0];
-	int change;
-	nval |= (nval & 3) | (ice->ak4524_images[chip][3] & ~3);
-	change = ice->ak4524_images[chip][3] != nval;
-	if (change)
-		snd_ice1712_ak4524_write(ice, chip, 3, nval);
-	return change;
-}
-
-static int __init snd_ice1712_build_pro_mixer(ice1712_t *ice)
-{
-	snd_card_t * card = ice->card;
-	snd_kcontrol_t ctl;
-	int idx, err;
-
-	/* PCM playback */
-	for (idx = 0; idx < 10; idx++) {
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Multi Playback Switch");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_pro_mixer_switch_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_pro_mixer_switch_get;
-		ctl.put = snd_ice1712_pro_mixer_switch_put;
-		ctl.private_value = idx;
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(card, snd_ctl_new(&ctl))) < 0)
-			return err;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Multi Playback Volume");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_pro_mixer_volume_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_pro_mixer_volume_get;
-		ctl.put = snd_ice1712_pro_mixer_volume_put;
-		ctl.private_value = idx;
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(card, snd_ctl_new(&ctl))) < 0)
-			return err;
-	}
-
-	/* PCM capture */
-	for (idx = 0; idx < 10; idx++) {
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Multi Capture Switch");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_pro_mixer_switch_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_pro_mixer_switch_get;
-		ctl.put = snd_ice1712_pro_mixer_switch_put;
-		ctl.private_value = idx + 10;
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(card, snd_ctl_new(&ctl))) < 0)
-			return err;
-		memset(&ctl, 0, sizeof(ctl));
-		strcpy(ctl.id.name, "Multi Capture Volume");
-		ctl.id.index = idx;
-		ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-		ctl.info = snd_ice1712_pro_mixer_volume_info;
-		ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-		ctl.get = snd_ice1712_pro_mixer_volume_get;
-		ctl.put = snd_ice1712_pro_mixer_volume_put;
-		ctl.private_value = idx + 10;
-		ctl.private_data = ice;
-		if ((err = snd_ctl_add(card, snd_ctl_new(&ctl))) < 0)
-			return err;
-	}
-	
-	/* initialize volumes */
-	for (idx = 0; idx < 20; idx++) {
-		ice->pro_volumes[idx] = 0x80008000;	/* mute */
-		snd_ice1712_update_volume(ice, idx);
-	}
-	return 0;
-}
-
-static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, ac97->private_data, return);
-	ice->ac97 = NULL;
-}
-
-static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
-{
-	int err;
-
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97)) {
-		ac97_t ac97;
-		memset(&ac97, 0, sizeof(ac97));
-		ac97.write = snd_ice1712_ac97_write;
-		ac97.read = snd_ice1712_ac97_read;
-		ac97.private_data = ice;
-		ac97.private_free = snd_ice1712_mixer_free_ac97;
-		if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0)
-			printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n");
-		else {
-			if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0)
-				return err;
-			return 0;
-		}
-	}
-	/* hmm.. can we have both consumer and pro ac97 mixers? */
-	if (! (ice->eeprom.aclink & ICE1712_CFG_PRO_I2S)) {
-		ac97_t ac97;
-		memset(&ac97, 0, sizeof(ac97));
-		ac97.write = snd_ice1712_pro_ac97_write;
-		ac97.read = snd_ice1712_pro_ac97_read;
-		ac97.private_data = ice;
-		ac97.private_free = snd_ice1712_mixer_free_ac97;
-		if ((err = snd_ac97_mixer(ice->card, &ac97, &ice->ac97)) < 0)
-			printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n");
-		else
-			return 0;
-	}
-	/* I2S mixer only */
-	strcat(ice->card->mixername, "ICE1712 - multitrack");
-	return 0;
-}
-
-/*
- *
- */
-
-static void snd_ice1712_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, entry->private_data, return);
-	unsigned int idx;
-
-	snd_iprintf(buffer, "ICE1712\n\n");
-	snd_iprintf(buffer, "EEPROM:\n");
-	snd_iprintf(buffer, "  Subvendor        : 0x%x\n", ice->eeprom.subvendor);
-	snd_iprintf(buffer, "  Size             : %i bytes\n", ice->eeprom.size);
-	snd_iprintf(buffer, "  Version          : %i\n", ice->eeprom.version);
-	snd_iprintf(buffer, "  Codec            : 0x%x\n", ice->eeprom.codec);
-	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.aclink);
-	snd_iprintf(buffer, "  I2S ID           : 0x%x\n", ice->eeprom.i2sID);
-	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.spdif);
-	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n", ice->eeprom.gpiomask);
-	snd_iprintf(buffer, "  GPIO state       : 0x%x\n", ice->eeprom.gpiostate);
-	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n", ice->eeprom.gpiodir);
-	snd_iprintf(buffer, "  AC'97 main       : 0x%x\n", ice->eeprom.ac97main);
-	snd_iprintf(buffer, "  AC'97 pcm        : 0x%x\n", ice->eeprom.ac97pcm);
-	snd_iprintf(buffer, "  AC'97 record     : 0x%x\n", ice->eeprom.ac97rec);
-	snd_iprintf(buffer, "  AC'97 record src : 0x%x\n", ice->eeprom.ac97recsrc);
-	for (idx = 0; idx < 4; idx++)
-		snd_iprintf(buffer, "  DAC ID #%i        : 0x%x\n", idx, ice->eeprom.dacID[idx]);
-	for (idx = 0; idx < 4; idx++)
-		snd_iprintf(buffer, "  ADC ID #%i        : 0x%x\n", idx, ice->eeprom.adcID[idx]);
-	for (idx = 0x1c; idx < ice->eeprom.size && idx < 0x1c + sizeof(ice->eeprom.extra); idx++)
-		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.extra[idx - 0x1c]);
-}
-
-static void __devinit snd_ice1712_proc_init(ice1712_t * ice)
-{
-	snd_info_entry_t *entry;
-
-	if ((entry = snd_info_create_card_entry(ice->card, "ice1712", ice->card->proc_root)) != NULL) {
-		entry->content = SNDRV_INFO_CONTENT_TEXT;
-		entry->private_data = ice;
-		entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
-		entry->c.text.read_size = 2048;
-		entry->c.text.read = snd_ice1712_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	ice->proc_entry = entry;
-}
-
-static void snd_ice1712_proc_done(ice1712_t * ice)
-{
-	if (ice->proc_entry) {
-		snd_info_unregister(ice->proc_entry);
-		ice->proc_entry = NULL;
-	}
-}
-
-/*
- *
- */
-
-static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-	uinfo->count = 32;
-	return 0;
-}
-
-static int snd_ice1712_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	
-	memcpy(ucontrol->value.bytes.data, &ice->eeprom, 32);
-	return 0;
-}
-
-static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
-	.name = "ICE1712 EEPROM",
-	.access = SNDRV_CTL_ELEM_ACCESS_READ,
-	.info = snd_ice1712_eeprom_info,
-	.get = snd_ice1712_eeprom_get
-};
-
-/*
- */
-static int snd_ice1712_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-	uinfo->count = 1;
-	return 0;
-}
-
-static int snd_ice1712_spdif_default_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->cs8403_spdif_bits);
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->cs8403_spdif_bits);
-		break;
-	}
-	return 0;
-}
-
-static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	unsigned int val;
-	int change;
-
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
-		spin_lock_irqsave(&ice->reg_lock, flags);
-		change = ice->cs8403_spdif_bits != val;
-		ice->cs8403_spdif_bits = val;
-		if (change && ice->playback_pro_substream == NULL) {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-			snd_ice1712_delta_cs8403_spdif_write(ice, val);
-		} else {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-		}
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
-		spin_lock_irqsave(&ice->reg_lock, flags);
-		change = ice->cs8403_spdif_bits != val;
-		ice->cs8403_spdif_bits = val;
-		if (change && ice->playback_pro_substream == NULL) {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-			snd_ice1712_ews_cs8404_spdif_write(ice, val);
-		} else {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-		}
-		break;
-	default:
-		change = 0;
-	}
-	return change;
-}
-
-static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata =
-{
-	.iface =		SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =           SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
-	.info =		snd_ice1712_spdif_default_info,
-	.get =		snd_ice1712_spdif_default_get,
-	.put =		snd_ice1712_spdif_default_put
-};
-
-static int snd_ice1712_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-	uinfo->count = 1;
-	return 0;
-}
-
-static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
-						     IEC958_AES0_PROFESSIONAL |
-						     IEC958_AES0_CON_NOT_COPYRIGHT |
-						     IEC958_AES0_CON_EMPHASIS;
-		ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL |
-						     IEC958_AES1_CON_CATEGORY;
-		ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
-		break;
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-	case ICE1712_SUBDEVICE_EWX2496:
-		ucontrol->value.iec958.status[0] = 0xff;
-		ucontrol->value.iec958.status[1] = 0xff;
-		ucontrol->value.iec958.status[2] = 0xff;
-		ucontrol->value.iec958.status[3] = 0xff;
-		ucontrol->value.iec958.status[4] = 0xff;
-		break;
-	}
-	return 0;
-}
-
-static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
-						     IEC958_AES0_PROFESSIONAL |
-						     IEC958_AES0_PRO_FS |
-						     IEC958_AES0_PRO_EMPHASIS;
-		ucontrol->value.iec958.status[1] = IEC958_AES1_PRO_MODE;
-		break;
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-	case ICE1712_SUBDEVICE_EWX2496:
-		ucontrol->value.iec958.status[0] = 0xff;
-		ucontrol->value.iec958.status[1] = 0xff;
-		ucontrol->value.iec958.status[2] = 0xff;
-		ucontrol->value.iec958.status[3] = 0xff;
-		ucontrol->value.iec958.status[4] = 0xff;
-		break;
-	}
-	return 0;
-}
-
-static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata =
-{
-	.access =		SNDRV_CTL_ELEM_ACCESS_READ,
-	.iface =		SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =           SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
-	.info =		snd_ice1712_spdif_mask_info,
-	.get =		snd_ice1712_spdif_maskc_get,
-};
-
-static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata =
-{
-	.access =		SNDRV_CTL_ELEM_ACCESS_READ,
-	.iface =		SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =           SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
-	.info =		snd_ice1712_spdif_mask_info,
-	.get =		snd_ice1712_spdif_maskp_get,
-};
-
-static int snd_ice1712_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
-	uinfo->count = 1;
-	return 0;
-}
-
-static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->cs8403_spdif_stream_bits);
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->cs8403_spdif_stream_bits);
-		break;
-	}
-	return 0;
-}
-
-static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	unsigned int val;
-	int change;
-
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		val = snd_cs8403_encode_spdif_bits(&ucontrol->value.iec958);
-		spin_lock_irqsave(&ice->reg_lock, flags);
-		change = ice->cs8403_spdif_stream_bits != val;
-		ice->cs8403_spdif_stream_bits = val;
-		if (change && ice->playback_pro_substream != NULL) {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-			snd_ice1712_delta_cs8403_spdif_write(ice, val);
-		} else {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-		}
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		val = snd_cs8404_encode_spdif_bits(&ucontrol->value.iec958);
-		spin_lock_irqsave(&ice->reg_lock, flags);
-		change = ice->cs8403_spdif_stream_bits != val;
-		ice->cs8403_spdif_stream_bits = val;
-		if (change && ice->playback_pro_substream != NULL) {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-			snd_ice1712_ews_cs8404_spdif_write(ice, val);
-		} else {
-			spin_unlock_irqrestore(&ice->reg_lock, flags);
-		}
-		break;
-	default:
-		change = 0;
-	}
-	return change;
-}
-
-static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata =
-{
-	.access =		SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
-	.iface =		SNDRV_CTL_ELEM_IFACE_PCM,
-	.name =           SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
-	.info =		snd_ice1712_spdif_stream_info,
-	.get =		snd_ice1712_spdif_stream_get,
-	.put =		snd_ice1712_spdif_stream_put
-};
-
-#define ICE1712_GPIO(xiface, xname, xindex, mask, invert, xaccess) \
-{ .iface = xiface, .name = xname, .access = xaccess, .info = snd_ice1712_gpio_info, \
-  .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
-  .private_value = mask | (invert << 24) }
-
-static int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * 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 snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char mask = kcontrol->private_value & 0xff;
-	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
-	unsigned char saved[2];
-	
-	save_gpio_status(ice, saved);
-	ucontrol->value.integer.value[0] = (snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0) ^ invert;
-	restore_gpio_status(ice, saved);
-	return 0;
-}
-
-static int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char mask = kcontrol->private_value & 0xff;
-	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
-	unsigned char saved[2];
-	int val, nval;
-
-	if (kcontrol->private_value & (1 << 31))
-		return -EPERM;
-	nval = (ucontrol->value.integer.value[0] ? mask : 0) ^ invert;
-	save_gpio_status(ice, saved);
-	val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-	nval |= val & ~mask;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
-	restore_gpio_status(ice, saved);
-	return val != nval;
-}
-
-static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata =
-ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_PCM, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-
-static int snd_ice1712_pro_spdif_master_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * 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 snd_ice1712_pro_spdif_master_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	ucontrol->value.integer.value[0] = inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER ? 1 : 0;
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_pro_spdif_master_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int nval, change;
-
-	nval = ucontrol->value.integer.value[0] ? ICE1712_SPDIF_MASTER : 0;
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	nval |= inb(ICEMT(ice, RATE)) & ~ICE1712_SPDIF_MASTER;
-	change = inb(ICEMT(ice, RATE)) != nval;
-	outb(nval, ICEMT(ice, RATE));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-
-	if (ice->cs8427) {
-		/* change CS8427 clock source too */
-		snd_ice1712_cs8427_set_input_clock(ice, ucontrol->value.integer.value[0]);
-	}
-
-	return change;
-}
-
-static snd_kcontrol_new_t snd_ice1712_pro_spdif_master __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Multi Track IEC958 Master",
-	.info = snd_ice1712_pro_spdif_master_info,
-	.get = snd_ice1712_pro_spdif_master_get,
-	.put = snd_ice1712_pro_spdif_master_put
-};
-
-/*
- * routing
- */
-static int snd_ice1712_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	static char *texts[] = {
-		"PCM Out", /* 0 */
-		"H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */
-		"H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */
-		"IEC958 In L", "IEC958 In R", /* 9-10 */
-		"Digital Mixer", /* 11 - optional */
-	};
-	
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = kcontrol->id.index < 2 ? 12 : 11;
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int snd_ice1712_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx = kcontrol->id.index;
-	unsigned int val, cval;
-	val = inw(ICEMT(ice, ROUTE_PSDOUT03));
-	val >>= ((idx % 2) * 8) + ((idx / 2) * 2);
-	val &= 3;
-	cval = inl(ICEMT(ice, ROUTE_CAPTURE));
-	cval >>= ((idx / 2) * 8) + ((idx % 2) * 4);
-	if (val == 1 && idx < 2)
-		ucontrol->value.enumerated.item[0] = 11;
-	else if (val == 2)
-		ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
-	else if (val == 3)
-		ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
-	else
-		ucontrol->value.enumerated.item[0] = 0;
-	return 0;
-}
-
-static int snd_ice1712_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int change, shift;
-	int idx = kcontrol->id.index;
-	unsigned int val, old_val, nval;
-	
-	/* update PSDOUT */
-	if (ucontrol->value.enumerated.item[0] >= 11)
-		nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */
-	else if (ucontrol->value.enumerated.item[0] >= 9)
-		nval = 3; /* spdif in */
-	else if (ucontrol->value.enumerated.item[0] >= 1)
-		nval = 2; /* analog in */
-	else
-		nval = 0; /* pcm */
-	shift = ((idx % 2) * 8) + ((idx / 2) * 2);
-	val = old_val = inw(ICEMT(ice, ROUTE_PSDOUT03));
-	val &= ~(0x03 << shift);
-	val |= nval << shift;
-	change = val != old_val;
-	if (change)
-		outw(val, ICEMT(ice, ROUTE_PSDOUT03));
-	if (nval < 2) /* dig mixer of pcm */
-		return change;
-
-	/* update CAPTURE */
-	val = old_val = inl(ICEMT(ice, ROUTE_CAPTURE));
-	shift = ((idx / 2) * 8) + ((idx % 2) * 4);
-	if (nval == 2) { /* analog in */
-		nval = ucontrol->value.enumerated.item[0] - 1;
-		val &= ~(0x07 << shift);
-		val |= nval << shift;
-	} else { /* spdif in */
-		nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
-		val &= ~(0x08 << shift);
-		val |= nval << shift;
-	}
-	if (val != old_val) {
-		change = 1;
-		outl(val, ICEMT(ice, ROUTE_CAPTURE));
-	}
-	return change;
-}
-
-static int snd_ice1712_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx = kcontrol->id.index;
-	unsigned int val, cval;
-	val = inw(ICEMT(ice, ROUTE_SPDOUT));
-	cval = (val >> (idx * 4 + 8)) & 0x0f;
-	val = (val >> (idx * 2)) & 0x03;
-	if (val == 1)
-		ucontrol->value.enumerated.item[0] = 11;
-	else if (val == 2)
-		ucontrol->value.enumerated.item[0] = (cval & 7) + 1;
-	else if (val == 3)
-		ucontrol->value.enumerated.item[0] = ((cval >> 3) & 1) + 9;
-	else
-		ucontrol->value.enumerated.item[0] = 0;
-	return 0;
-}
-
-static int snd_ice1712_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int change, shift;
-	int idx = kcontrol->id.index;
-	unsigned int val, old_val, nval;
-	
-	/* update SPDOUT */
-	val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT));
-	if (ucontrol->value.enumerated.item[0] >= 11)
-		nval = 1;
-	else if (ucontrol->value.enumerated.item[0] >= 9)
-		nval = 3;
-	else if (ucontrol->value.enumerated.item[0] >= 1)
-		nval = 2;
-	else
-		nval = 0;
-	shift = idx * 2;
-	val &= ~(0x03 << shift);
-	val |= nval << shift;
-	shift = idx * 4 + 8;
-	if (nval == 2) {
-		nval = ucontrol->value.enumerated.item[0] - 1;
-		val &= ~(0x07 << shift);
-		val |= nval << shift;
-	} else if (nval == 3) {
-		nval = (ucontrol->value.enumerated.item[0] - 9) << 3;
-		val &= ~(0x08 << shift);
-		val |= nval << shift;
-	}
-	change = val != old_val;
-	if (change)
-		outw(val, ICEMT(ice, ROUTE_SPDOUT));
-	return change;
-}
-
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "H/W Playback Route",
-	.info = snd_ice1712_pro_route_info,
-	.get = snd_ice1712_pro_route_analog_get,
-	.put = snd_ice1712_pro_route_analog_put,
-};
-
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "IEC958 Playback Route",
-	.info = snd_ice1712_pro_route_info,
-	.get = snd_ice1712_pro_route_spdif_get,
-	.put = snd_ice1712_pro_route_spdif_put,
-};
-
-
-static int snd_ice1712_pro_volume_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 255;
-	return 0;
-}
-
-static int snd_ice1712_pro_volume_rate_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static int snd_ice1712_pro_volume_rate_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	unsigned long flags;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int change;
-
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	change = inb(ICEMT(ice, MONITOR_RATE)) != ucontrol->value.integer.value[0];
-	outb(ucontrol->value.integer.value[0], ICEMT(ice, MONITOR_RATE));
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return change;
-}
-
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_volume_rate __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Multi Track Volume Rate",
-	.info = snd_ice1712_pro_volume_rate_info,
-	.get = snd_ice1712_pro_volume_rate_get,
-	.put = snd_ice1712_pro_volume_rate_put
-};
-
-static int snd_ice1712_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 22;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 255;
-	return 0;
-}
-
-static int snd_ice1712_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
-	int idx;
-	
-	spin_lock_irqsave(&ice->reg_lock, flags);
-	for (idx = 0; idx < 22; idx++) {
-		outb(idx, ICEMT(ice, MONITOR_PEAKINDEX));
-		ucontrol->value.integer.value[idx] = inb(ICEMT(ice, MONITOR_PEAKDATA));
-	}
-	spin_unlock_irqrestore(&ice->reg_lock, flags);
-	return 0;
-}
-
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Multi Track Peak",
-	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
-	.info = snd_ice1712_pro_peak_info,
-	.get = snd_ice1712_pro_peak_get
-};
-
-/*
- * EWX 24/96
- */
-
-static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){
-
-	static char *texts[2] = {
-		"+4dBu", "-10dBV",
-	};
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 2;
-	if (uinfo->value.enumerated.item >= 2)
-		uinfo->value.enumerated.item = 1;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int snd_ice1712_ewx_io_sense_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char mask = kcontrol->private_value & 0xff;
-	unsigned char saved[2];
-	
-	save_gpio_status(ice, saved);
-	ucontrol->value.enumerated.item[0] = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & mask ? 1 : 0;
-	restore_gpio_status(ice, saved);
-	return 0;
-}
-
-static int snd_ice1712_ewx_io_sense_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char mask = kcontrol->private_value & 0xff;
-	unsigned char saved[2];
-	int val, nval;
-
-	if (kcontrol->private_value & (1 << 31))
-		return -EPERM;
-	nval = ucontrol->value.enumerated.item[0] ? mask : 0;
-	save_gpio_status(ice, saved);
-	val = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
-	nval |= val & ~mask;
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, nval);
-	restore_gpio_status(ice, saved);
-	return val != nval;
-}
-
-static snd_kcontrol_new_t snd_ice1712_ewx_input_sense __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Input Sensitivity Switch",
-	.info = snd_ice1712_ewx_io_sense_info,
-	.get = snd_ice1712_ewx_io_sense_get,
-	.put = snd_ice1712_ewx_io_sense_put,
-	.private_value = ICE1712_EWX2496_AIN_SEL,
-};
-
-static snd_kcontrol_new_t snd_ice1712_ewx_output_sense __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Output Sensitivity Switch",
-	.info = snd_ice1712_ewx_io_sense_info,
-	.get = snd_ice1712_ewx_io_sense_get,
-	.put = snd_ice1712_ewx_io_sense_put,
-	.private_value = ICE1712_EWX2496_AOUT_SEL,
-};
-
-
-/*
- * EWS88MT
- */
-/* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char data;
-
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
-	return 0;
-}
-
-/* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	unsigned char data, ndata;
-
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->pcf8574[1], &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->pcf8574[1], &ndata, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	return ndata != data;
-}
-
-/* analog input sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int channel = kcontrol->id.index;
-	unsigned char data;
-
-	snd_assert(channel >= 0 && channel <= 7, return 0);
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->pcf8574[0], &data, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	/* reversed; high = +4dBu, low = -10dBV */
-	ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
-	return 0;
-}
-
-/* analog output sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int channel = kcontrol->id.index;
-	unsigned char data, ndata;
-
-	snd_assert(channel >= 0 && channel <= 7, return 0);
-	snd_i2c_lock(ice->i2c);
-	if (snd_i2c_readbytes(ice->pcf8574[0], &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->pcf8574[0], &ndata, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	return ndata != data;
-}
-
-static snd_kcontrol_new_t snd_ice1712_ews88mt_input_sense __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Input Sensitivity Switch",
-	.info = snd_ice1712_ewx_io_sense_info,
-	.get = snd_ice1712_ews88mt_input_sense_get,
-	.put = snd_ice1712_ews88mt_input_sense_put,
-};
-
-static snd_kcontrol_new_t snd_ice1712_ews88mt_output_sense __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Output Sensitivity Switch",
-	.info = snd_ice1712_ewx_io_sense_info,
-	.get = snd_ice1712_ews88mt_output_sense_get,
-	.put = snd_ice1712_ews88mt_output_sense_put,
-};
-
-
-/*
- * EWS88D controls
- */
-
-static int snd_ice1712_ews88d_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	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->pcf8575, data, 2) != 2) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
-	if (invert)
-		data[0] ^= 0x01;
-	ucontrol->value.integer.value[0] = data[0];
-	return 0;
-}
-
-static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	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->pcf8575, data, 2) != 2) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
-	if (invert) {
-		if (! ucontrol->value.integer.value[0])
-			ndata[shift >> 3] |= (1 << (shift & 7));
-	} else {
-		if (ucontrol->value.integer.value[0])
-			ndata[shift >> 3] |= (1 << (shift & 7));
-	}
-	change = (data[shift >> 3] != ndata[shift >> 3]);
-	if (change && snd_i2c_sendbytes(ice->pcf8575, data, 2) != 2) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	return change;
-}
-
-#define EWS88D_CONTROL(xiface, xname, xshift, xinvert, xaccess) \
-{ .iface = xiface,\
-  .name = xname,\
-  .access = xaccess,\
-  .info = snd_ice1712_ews88d_control_info,\
-  .get = snd_ice1712_ews88d_control_get,\
-  .put = snd_ice1712_ews88d_control_put,\
-  .private_value = xshift | (xinvert << 8),\
-}
-
-static snd_kcontrol_new_t 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),
-	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "Enable ADAT", 3, 0, 0),
-	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Through", 4, 1, 0),
-};
-
-
-/*
- * DMX 6Fire controls
- */
-
-#define PCF9554_REG_INPUT	0
-#define PCF9554_REG_OUTPUT	1
-#define PCF9554_REG_POLARITY	2
-#define PCF9554_REG_CONFIG	3
-
-static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
-{
-	unsigned char byte;
-	snd_i2c_lock(ice->i2c);
-	byte = reg;
-	snd_i2c_sendbytes(ice->pcf8575, &byte, 1);
-	byte = 0;
-	if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) {
-		snd_i2c_unlock(ice->i2c);
-		printk("cannot read pca\n");
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	return byte;
-}
-
-static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data)
-{
-	unsigned char bytes[2];
-	snd_i2c_lock(ice->i2c);
-	bytes[0] = reg;
-	bytes[1] = data;
-	if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) {
-		snd_i2c_unlock(ice->i2c);
-		return -EIO;
-	}
-	snd_i2c_unlock(ice->i2c);
-	return 0;
-}
-
-static int snd_ice1712_6fire_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *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 snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int shift = kcontrol->private_value & 0xff;
-	int invert = (kcontrol->private_value >> 8) & 1;
-	int data;
-	
-	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
-		return data;
-	data = (data >> shift) & 1;
-	if (invert)
-		data ^= 1;
-	ucontrol->value.integer.value[0] = data;
-	return 0;
-}
-
-static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int shift = kcontrol->private_value & 0xff;
-	int invert = (kcontrol->private_value >> 8) & 1;
-	int data, ndata;
-	
-	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
-		return data;
-	ndata = data & ~(1 << shift);
-	if (ucontrol->value.integer.value[0])
-		ndata |= (1 << shift);
-	if (invert)
-		ndata ^= (1 << shift);
-	if (data != ndata) {
-		snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
-		return 1;
-	}
-	return 0;
-}
-
-static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
-{
-	static char *texts[4] = {
-		"Internal", "Front Input", "Rear Input", "Wave Table"
-	};
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 4;
-	if (uinfo->value.enumerated.item >= 4)
-		uinfo->value.enumerated.item = 1;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-     
-static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int data;
-	
-	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
-		return data;
-	ucontrol->value.integer.value[0] = data & 3;
-	return 0;
-}
-
-static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int data, ndata;
-	
-	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
-		return data;
-	ndata = data & ~3;
-	ndata |= (ucontrol->value.integer.value[0] & 3);
-	if (data != ndata) {
-		snd_ice1712_6fire_write_pca(ice, PCF9554_REG_OUTPUT, (unsigned char)ndata);
-		return 1;
-	}
-	return 0;
-}
-
-
-#define DMX6FIRE_CONTROL(xname, xshift, xinvert) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\
-  .name = xname,\
-  .info = snd_ice1712_6fire_control_info,\
-  .get = snd_ice1712_6fire_control_get,\
-  .put = snd_ice1712_6fire_control_put,\
-  .private_value = xshift | (xinvert << 8),\
-}
-
-static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Analog Input Select",
-		.info = snd_ice1712_6fire_select_input_info,
-		.get = snd_ice1712_6fire_select_input_get,
-		.put = snd_ice1712_6fire_select_input_put,
-	},
-	DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0),
-	// DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
-	DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
-	DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
-	DMX6FIRE_CONTROL("Breakbox LED", 6, 0),
-};
-
-/*
- *
- */
-
-static unsigned char __devinit snd_ice1712_read_i2c(ice1712_t *ice,
-						 unsigned char dev,
-						 unsigned char addr)
-{
-	long t = 0x10000;
-
-	outb(addr, ICEREG(ice, I2C_BYTE_ADDR));
-	outb(dev & ~ICE1712_I2C_WRITE, ICEREG(ice, I2C_DEV_ADDR));
-	while (t-- > 0 && (inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_BUSY)) ;
-	return inb(ICEREG(ice, I2C_DATA));
-}
-
-static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice)
-{
-	int dev = 0xa0;		/* EEPROM device address */
-	unsigned int idx;
-
-	if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) == 0) {
-		snd_printk("ICE1712 has not detected EEPROM\n");
-		return -EIO;
-	}
-	ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) |
-				(snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | 
-				(snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 
-				(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
-	ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
-	if (ice->eeprom.size < 28) {
-		snd_printk("invalid EEPROM (size = %i)\n", ice->eeprom.size);
-		return -EIO;
-	}
-	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
-	if (ice->eeprom.version != 1) {
-		snd_printk("invalid EEPROM version %i\n", ice->eeprom.version);
-		return -EIO;
-	}
-	ice->eeprom.codec = snd_ice1712_read_i2c(ice, dev, 0x06);
-	ice->eeprom.aclink = snd_ice1712_read_i2c(ice, dev, 0x07);
-	ice->eeprom.i2sID = snd_ice1712_read_i2c(ice, dev, 0x08);
-	ice->eeprom.spdif = snd_ice1712_read_i2c(ice, dev, 0x09);
-	ice->eeprom.gpiomask = snd_ice1712_read_i2c(ice, dev, 0x0a);
-	ice->eeprom.gpiostate = snd_ice1712_read_i2c(ice, dev, 0x0b);
-	ice->eeprom.gpiodir = snd_ice1712_read_i2c(ice, dev, 0x0c);
-	ice->eeprom.ac97main = (snd_ice1712_read_i2c(ice, dev, 0x0d) << 0) |
-			       (snd_ice1712_read_i2c(ice, dev, 0x0e) << 8);
-	ice->eeprom.ac97pcm = (snd_ice1712_read_i2c(ice, dev, 0x0f) << 0) |
-			      (snd_ice1712_read_i2c(ice, dev, 0x10) << 8);
-	ice->eeprom.ac97rec = (snd_ice1712_read_i2c(ice, dev, 0x11) << 0) |
-			      (snd_ice1712_read_i2c(ice, dev, 0x12) << 8);
-	ice->eeprom.ac97recsrc = snd_ice1712_read_i2c(ice, dev, 0x13) << 0;
-	for (idx = 0; idx < 4; idx++) {
-		ice->eeprom.dacID[idx] = snd_ice1712_read_i2c(ice, dev, 0x14 + idx);
-		ice->eeprom.adcID[idx] = snd_ice1712_read_i2c(ice, dev, 0x18 + idx);
-	}
-	for (idx = 0x1c; idx < ice->eeprom.size && idx < 0x1c + sizeof(ice->eeprom.extra); idx++)
-		ice->eeprom.extra[idx - 0x1c] = snd_ice1712_read_i2c(ice, dev, idx);
-	return 0;
-}
-
-static void __devinit snd_ice1712_ak4524_init(ice1712_t *ice)
-{
-	static unsigned char inits[] = {
-		0x00, 0x07, /* 0: all power up */
-		0x01, 0x00, /* 1: ADC/DAC reset */
-		0x02, 0x60, /* 2: 24bit I2S */
-		0x03, 0x19, /* 3: deemphasis off */
-		0x01, 0x03, /* 1: ADC/DAC enable */
-		0x04, 0x00, /* 4: ADC left muted */
-		0x05, 0x00, /* 5: ADC right muted */
-		0x04, 0x80, /* 4: ADC IPGA gain 0dB */
-		0x05, 0x80, /* 5: ADC IPGA gain 0dB */
-		0x06, 0x00, /* 6: DAC left muted */
-		0x07, 0x00, /* 7: DAC right muted */
-		0xff, 0xff
-	};
-	int chip, idx;
-	unsigned char *ptr, reg, data;
-
-	for (chip = idx = 0; chip < ice->num_dacs/2; chip++) {
-		ptr = inits;
-		while (*ptr != 0xff) {
-			reg = *ptr++;
-			data = *ptr++;
-			if (ice->ak4528) {
-				if (reg > 5)
-					continue;
-				if (reg >= 4 && (data & 0x80))
-					continue;
-			}
-			if (reg == 0x03 && ice->ak4528)
-				data = 0x0d;	/* deemphasis off, turn LR highpass filters on */
-			snd_ice1712_ak4524_write(ice, chip, reg, data);
-		}
-	}
-}
-
-static void __devinit snd_ice1712_stdsp24_gpio_write(ice1712_t *ice, unsigned char byte)
-{
-	byte |= ICE1712_STDSP24_CLOCK_BIT;
-	udelay(100);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
-	byte &= ~ICE1712_STDSP24_CLOCK_BIT;
-	udelay(100);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
-	byte |= ICE1712_STDSP24_CLOCK_BIT;
-	udelay(100);
-	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
-}
-
-static void __devinit snd_ice1712_stdsp24_darear(ice1712_t *ice, int activate)
-{
-	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_0_DAREAR(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
-	up(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_mute(ice1712_t *ice, int activate)
-{
-	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_MUTE(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
-	up(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_insel(ice1712_t *ice, int activate)
-{
-	down(&ice->gpio_mutex);
-	ICE1712_STDSP24_3_INSEL(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
-	up(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_box_channel(ice1712_t *ice, int box, int chn, int activate)
-{
-	down(&ice->gpio_mutex);
-
-	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
-
-	/* prepare for write */
-	if (chn == 3)
-		ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, activate);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	udelay(100);
-	if (chn == 3) {
-		ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 0);
-		snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	} else {
-		switch (chn) {
-		case 0:	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 0); break;
-		case 1:	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 0); break;
-		case 2:	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 0); break;
-		}
-		snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
-	}
-	udelay(100);
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[1]);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	udelay(100);
-
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-
-	up(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_box_midi(ice1712_t *ice, int box, int master, int slave)
-{
-	down(&ice->gpio_mutex);
-
-	/* select box */
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, box);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[0]);
-
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, master);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-
-	udelay(100);
-	
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 0);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-	
-	udelay(100);
-	
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[2]);
-
-	udelay(100);
-
-	/* MIDI2 is direct */
-	ICE1712_STDSP24_3_MIDI2(ice->hoontech_boxbits, slave);
-	snd_ice1712_stdsp24_gpio_write(ice, ice->hoontech_boxbits[3]);
-
-	up(&ice->gpio_mutex);
-}
-
-static void __devinit snd_ice1712_stdsp24_init(ice1712_t *ice)
-{
-	int box, chn;
-
-	ice->hoontech_boxbits[0] = 
-	ice->hoontech_boxbits[1] = 
-	ice->hoontech_boxbits[2] = 
-	ice->hoontech_boxbits[3] = 0;	/* should be already */
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 0, 1);
-	ICE1712_STDSP24_0_BOX(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_0_DAREAR(ice->hoontech_boxbits, 0);
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 1, 1);
-	ICE1712_STDSP24_1_CHN1(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN2(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_1_CHN3(ice->hoontech_boxbits, 1);
-	
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 2);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 2, 1);
-	ICE1712_STDSP24_2_CHN4(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDIIN(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_2_MIDI1(ice->hoontech_boxbits, 0);
-
-	ICE1712_STDSP24_SET_ADDR(ice->hoontech_boxbits, 3);
-	ICE1712_STDSP24_CLOCK(ice->hoontech_boxbits, 3, 1);
-	ICE1712_STDSP24_3_MIDI2(ice->hoontech_boxbits, 0);
-	ICE1712_STDSP24_3_MUTE(ice->hoontech_boxbits, 1);
-	ICE1712_STDSP24_3_INSEL(ice->hoontech_boxbits, 0);
-
-	/* let's go - activate only functions in first box */
-	ice->hoontech_config = 0;
-			    /* ICE1712_STDSP24_MUTE |
-			       ICE1712_STDSP24_INSEL |
-			       ICE1712_STDSP24_DAREAR; */
-	ice->hoontech_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->hoontech_boxconfig[1] = 
-	ice->hoontech_boxconfig[2] = 
-	ice->hoontech_boxconfig[3] = 0;
-	snd_ice1712_stdsp24_darear(ice, (ice->hoontech_config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
-	snd_ice1712_stdsp24_mute(ice, (ice->hoontech_config & ICE1712_STDSP24_MUTE) ? 1 : 0);
-	snd_ice1712_stdsp24_insel(ice, (ice->hoontech_config & ICE1712_STDSP24_INSEL) ? 1 : 0);
-	for (box = 0; box < 4; box++) {
-		for (chn = 0; chn < 4; chn++)
-			snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->hoontech_boxconfig[box] & (1 << chn)) ? 1 : 0);
-		snd_ice1712_stdsp24_box_midi(ice, box,
-				(ice->hoontech_boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0,
-				(ice->hoontech_boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2) ? 1 : 0);
-	}
-}
-
-static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
-{
-	int err, has_i2c = 0;
-
-	outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
-	udelay(200);
-	outb(ICE1712_NATIVE, ICEREG(ice, CONTROL));
-	udelay(200);
-	pci_write_config_byte(ice->pci, 0x60, ice->eeprom.codec);
-	pci_write_config_byte(ice->pci, 0x61, ice->eeprom.aclink);
-	pci_write_config_byte(ice->pci, 0x62, ice->eeprom.i2sID);
-	pci_write_config_byte(ice->pci, 0x63, ice->eeprom.spdif);
-	if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
-		ice->gpio_write_mask = ice->eeprom.gpiomask;
-		ice->gpio_direction = ice->eeprom.gpiodir;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
-	} else {
-		ice->gpio_write_mask = 0xc0;
-		ice->gpio_direction = 0xff;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_STDSP24_CLOCK_BIT);
-	}
-	snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97)) {
-		outb(ICE1712_AC97_WARM, ICEREG(ice, AC97_CMD));
-		udelay(100);
-		outb(0, ICEREG(ice, AC97_CMD));
-		udelay(200);
-		snd_ice1712_write(ice, ICE1712_IREG_CONSUMER_POWERDOWN, 0);
-	}
-
-	/* determine I2C, DACs and ADCs */
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-		ice->ak4528 = 1;
-		/* follow thru */
-	case ICE1712_SUBDEVICE_EWX2496:
-		has_i2c = 1;
-		ice->num_adcs = ice->num_dacs = ice->num_total_dacs = 2;
-		break;	
-	case ICE1712_SUBDEVICE_DELTA44:
-	case ICE1712_SUBDEVICE_DELTA66:
-		ice->num_adcs = ice->num_dacs = ice->num_total_dacs = 4;
-		if (ice->omni)
-			ice->num_total_dacs = 8;
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-		has_i2c = 1;
-		/* follow thru */
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_STDSP24:
-		ice->num_adcs = ice->num_dacs = ice->num_total_dacs = 8;
-		break;
-	case ICE1712_SUBDEVICE_EWS88D:
-		has_i2c = 1;
-		break;
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		has_i2c = 1;
-		ice->num_adcs = ice->num_dacs = ice->num_total_dacs = 6;
-		break;
-	}
-
-	if (has_i2c) {
-		if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
-			snd_printk("unable to create I2C bus\n");
-			return err;
-		}
-		ice->i2c->private_data = ice;
-		switch (ice->eeprom.subvendor) {
-		case ICE1712_SUBDEVICE_AUDIOPHILE:
-			ice->i2c->ops = &ap_cs8427_i2c_ops;
-			break;
-		case ICE1712_SUBDEVICE_EWX2496:
-		case ICE1712_SUBDEVICE_EWS88MT:
-		case ICE1712_SUBDEVICE_EWS88D:
-		case ICE1712_SUBDEVICE_DMX6FIRE:
-			ice->i2c->hw_ops.bit = &snd_ice1712_ewx_cs8427_bit_ops;
-			break;
-		}
-		switch (ice->eeprom.subvendor) {
-		case ICE1712_SUBDEVICE_AUDIOPHILE:
-		case ICE1712_SUBDEVICE_EWX2496:
-			if ((err = snd_cs8427_create(ice->i2c, CS8427_BASE_ADDR, &ice->cs8427)) < 0) {
-				snd_printk("CS8427 initialization failed\n");
-				return err;
-			}
-			break;
-		case ICE1712_SUBDEVICE_DMX6FIRE:
-			if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->pcf8575)) < 0) {
-				snd_printk("PCF9554 initialization failed\n");
-				return err;
-			}
-#if 0 // XXX not working...
-			if ((err = snd_cs8427_create(ice->i2c, ICE1712_6FIRE_CS8427_ADDR, &ice->cs8427)) < 0) {
-				snd_printk("CS8427 initialization failed\n");
-				return err;
-			}
-#endif
-			break;
-		case ICE1712_SUBDEVICE_EWS88MT:
-			if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->cs8404)) < 0)
-				return err;
-			if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->pcf8574[0])) < 0)
-				return err;
-			if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->pcf8574[1])) < 0)
-				return err;
-			break;
-		case ICE1712_SUBDEVICE_EWS88D:
-			if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->pcf8575)) < 0)
-				return err;
-			break;
-		}
-	}
-	/* second stage of initialization, analog parts and others */
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWS88MT:
-		/* Check if the front module is connected */
-		if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
-			return err;
-		/* Fall through */
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_DELTA44:
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-	case ICE1712_SUBDEVICE_EWX2496:
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		snd_ice1712_ak4524_init(ice);
-		break;
-	case ICE1712_SUBDEVICE_STDSP24:
-		snd_ice1712_stdsp24_init(ice);
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		/* Set spdif defaults */
-		snd_ice1712_delta_cs8403_spdif_write(ice, ice->cs8403_spdif_bits);
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		/* Set spdif defaults */
-		snd_ice1712_ews_cs8404_spdif_write(ice, ice->cs8403_spdif_bits);
-		break;
-	}
-	return 0;
-}
-
-static int __init snd_ice1712_build_controls(ice1712_t *ice)
-{
-	unsigned int idx;
-	snd_kcontrol_t *kctl;
-	int err;
-
-	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_eeprom, ice));
-	if (err < 0)
-		return err;
-	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_pro_spdif_master, ice));
-	if (err < 0)
-		return err;
-	for (idx = 0; idx < ice->num_total_dacs; idx++) {
-		kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_analog_route, ice);
-		if (kctl == NULL)
-			return -ENOMEM;
-		kctl->id.index = idx;
-		err = snd_ctl_add(ice->card, kctl);
-		if (err < 0)
-			return err;
-	}
-	for (idx = 0; idx < 2; idx++) {
-		kctl = snd_ctl_new1(&snd_ice1712_mixer_pro_spdif_route, ice);
-		if (kctl == NULL)
-			return -ENOMEM;
-		kctl->id.index = idx;
-		err = snd_ctl_add(ice->card, kctl);
-		if (err < 0)
-			return err;
-	}
-	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_volume_rate, ice));
-	if (err < 0)
-		return err;
-	err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_pro_peak, ice));
-	if (err < 0)
-		return err;
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_select, ice));
-		if (err < 0)
-			return err;
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta1010_wordclock_status, ice));
-		if (err < 0)
-			return err;
-		break;
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_deltadio2496_spdif_in_select, ice));
-		if (err < 0)
-			return err;
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-	case ICE1712_SUBDEVICE_EWX2496:
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_EWS88D:
-		snd_assert(ice->pcm_pro != NULL, return -EIO);
-		err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
-		if (err < 0)
-			return err;
-		kctl->id.device = ice->pcm_pro->device;
-		err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice));
-		if (err < 0)
-			return err;
-		kctl->id.device = ice->pcm_pro->device;
-		err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice));
-		if (err < 0)
-			return err;
-		kctl->id.device = ice->pcm_pro->device;
-		err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice));
-		if (err < 0)
-			return err;
-		kctl->id.device = ice->pcm_pro->device;
-		ice->spdif_stream_ctl = kctl;
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_DELTA1010:
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-	case ICE1712_SUBDEVICE_DELTA66:
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_delta_spdif_in_status, ice));
-		if (err < 0)
-			return err;
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWX2496:
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-	case ICE1712_SUBDEVICE_DELTA44:
-	case ICE1712_SUBDEVICE_DELTA66:
-	case ICE1712_SUBDEVICE_EWS88MT:
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		for (idx = 0; idx < ice->num_dacs; ++idx) {
-			snd_kcontrol_t ctl;
-			memset(&ctl, 0, sizeof(ctl));
-			strcpy(ctl.id.name, "DAC Volume");
-			ctl.id.index = idx;
-			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-			ctl.info = snd_ice1712_ak4524_volume_info;
-			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-			ctl.get = snd_ice1712_ak4524_volume_get;
-			ctl.put = snd_ice1712_ak4524_volume_put;
-			if (ice->ak4528)
-				ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */
-			else
-				ctl.private_value = (idx / 2) * 8 + (idx % 2) + 6; /* register 6 & 7 */
-			ctl.private_data = ice;
-			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-				return err;
-		}
-		for (idx = 0; idx < ice->num_adcs && !ice->ak4528; ++idx) {
-			snd_kcontrol_t ctl;
-			memset(&ctl, 0, sizeof(ctl));
-			strcpy(ctl.id.name, "ADC Volume");
-			ctl.id.index = idx;
-			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-			ctl.info = snd_ice1712_ak4524_volume_info;
-			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-			ctl.get = snd_ice1712_ak4524_volume_get;
-			ctl.put = snd_ice1712_ak4524_volume_put;
-			ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */
-			ctl.private_data = ice;
-			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-				return err;
-			memset(&ctl, 0, sizeof(ctl));
-			strcpy(ctl.id.name, "IPGA Analog Capture Volume");
-			ctl.id.index = idx;
-			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-			ctl.info = snd_ice1712_ak4524_ipga_gain_info;
-			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-			ctl.get = snd_ice1712_ak4524_ipga_gain_get;
-			ctl.put = snd_ice1712_ak4524_ipga_gain_put;
-			ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */
-			ctl.private_data = ice;
-			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-				return err;
-		}
-		for (idx = 0; idx < ice->num_dacs/2; idx++) {
-			snd_kcontrol_t ctl;
-			memset(&ctl, 0, sizeof(ctl));
-			strcpy(ctl.id.name, "Deemphasis");
-			ctl.id.index = idx;
-			ctl.id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
-			ctl.info = snd_ice1712_ak4524_deemphasis_info;
-			ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE;
-			ctl.get = snd_ice1712_ak4524_deemphasis_get;
-			ctl.put = snd_ice1712_ak4524_deemphasis_put;
-			ctl.private_data = ice;
-			if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0)
-				return err;
-		}
-		break;
-	}
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_EWX2496:
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx_input_sense, ice));
-		if (err < 0)
-			return err;
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ewx_output_sense, ice));
-		if (err < 0)
-			return err;
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-		for (idx = 0; idx < 8; idx++) {
-			kctl = snd_ctl_new1(&snd_ice1712_ews88mt_input_sense, ice);
-			kctl->id.index = idx;
-			err = snd_ctl_add(ice->card, kctl);
-			if (err < 0)
-				return err;
-		}
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88mt_output_sense, ice));
-		if (err < 0)
-			return err;
-		break;
-	case ICE1712_SUBDEVICE_EWS88D:
-		for (idx = 0; idx < sizeof(snd_ice1712_ews88d_controls)/sizeof(snd_ice1712_ews88d_controls[0]); idx++) {
-			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_ews88d_controls[idx], ice));
-			if (err < 0)
-				return err;
-		}
-		break;
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		for (idx = 0; idx < sizeof(snd_ice1712_6fire_controls)/sizeof(snd_ice1712_6fire_controls[0]); idx++) {
-			err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_6fire_controls[idx], ice));
-			if (err < 0)
-				return err;
-		}
-		break;
-	}
-
-	return 0;
-}
-
-static int snd_ice1712_free(ice1712_t *ice)
-{
-	if (ice->res_port == NULL)
-		goto __hw_end;
-	/* mask all interrupts */
-	outb(0xc0, ICEMT(ice, IRQ));
-	outb(0xff, ICEREG(ice, IRQMASK));
-	/* --- */
-      __hw_end:
-	snd_ice1712_proc_done(ice);
-	if (ice->irq >= 0) {
-		synchronize_irq(ice->irq);
-		free_irq(ice->irq, (void *) ice);
-	}
-	if (ice->res_port) {
-		release_resource(ice->res_port);
-		kfree_nocheck(ice->res_port);
-	}
-	if (ice->res_ddma_port) {
-		release_resource(ice->res_ddma_port);
-		kfree_nocheck(ice->res_ddma_port);
-	}
-	if (ice->res_dmapath_port) {
-		release_resource(ice->res_dmapath_port);
-		kfree_nocheck(ice->res_dmapath_port);
-	}
-	if (ice->res_profi_port) {
-		release_resource(ice->res_profi_port);
-		kfree_nocheck(ice->res_profi_port);
-	}
-	snd_magic_kfree(ice);
-	return 0;
-}
-
-static int snd_ice1712_dev_free(snd_device_t *device)
-{
-	ice1712_t *ice = snd_magic_cast(ice1712_t, device->device_data, return -ENXIO);
-	return snd_ice1712_free(ice);
-}
-
-static int __devinit snd_ice1712_create(snd_card_t * card,
-				     struct pci_dev *pci,
-				     int omni,
-				     ice1712_t ** r_ice1712)
-{
-	ice1712_t *ice;
-	int err;
-	static snd_device_ops_t ops = {
-		.dev_free =	snd_ice1712_dev_free,
-	};
-
-	*r_ice1712 = NULL;
-
-        /* enable PCI device */
-	if ((err = pci_enable_device(pci)) < 0)
-		return err;
-	/* check, if we can restrict PCI DMA transfers to 28 bits */
-	if (!pci_dma_supported(pci, 0x0fffffff)) {
-		snd_printk("architecture does not support 28bit PCI busmaster DMA\n");
-		return -ENXIO;
-	}
-	pci_set_dma_mask(pci, 0x0fffffff);
-
-	ice = snd_magic_kcalloc(ice1712_t, 0, GFP_KERNEL);
-	if (ice == NULL)
-		return -ENOMEM;
-	ice->omni = omni ? 1 : 0;
-	spin_lock_init(&ice->reg_lock);
-	init_MUTEX(&ice->gpio_mutex);
-	ice->cs8403_spdif_bits =
-	ice->cs8403_spdif_stream_bits = (0x01 |	/* consumer format */
-					 0x10 |	/* no emphasis */
-					 0x20);	/* PCM encoder/decoder */
-	ice->card = card;
-	ice->pci = pci;
-	ice->irq = -1;
-	ice->port = pci_resource_start(pci, 0);
-	ice->ddma_port = pci_resource_start(pci, 1);
-	ice->dmapath_port = pci_resource_start(pci, 2);
-	ice->profi_port = pci_resource_start(pci, 3);
-	pci_set_master(pci);
-	pci_write_config_word(ice->pci, 0x40, 0x807f);
-	pci_write_config_word(ice->pci, 0x42, 0x0006);
-	snd_ice1712_proc_init(ice);
-	synchronize_irq(pci->irq);
-
-	if ((ice->res_port = request_region(ice->port, 32, "ICE1712 - Controller")) == NULL) {
-		snd_ice1712_free(ice);
-		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->port, ice->port + 32 - 1);
-		return -EIO;
-	}
-	if ((ice->res_ddma_port = request_region(ice->ddma_port, 16, "ICE1712 - DDMA")) == NULL) {
-		snd_ice1712_free(ice);
-		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->ddma_port, ice->ddma_port + 16 - 1);
-		return -EIO;
-	}
-	if ((ice->res_dmapath_port = request_region(ice->dmapath_port, 16, "ICE1712 - DMA path")) == NULL) {
-		snd_ice1712_free(ice);
-		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->dmapath_port, ice->dmapath_port + 16 - 1);
-		return -EIO;
-	}
-	if ((ice->res_profi_port = request_region(ice->profi_port, 64, "ICE1712 - Professional")) == NULL) {
-		snd_ice1712_free(ice);
-		snd_printk("unable to grab ports 0x%lx-0x%lx\n", ice->profi_port, ice->profi_port + 16 - 1);
-		return -EIO;
-	}
-	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
-		snd_ice1712_free(ice);
-		snd_printk("unable to grab IRQ %d\n", pci->irq);
-		return -EIO;
-	}
-	ice->irq = pci->irq;
-
-	if (snd_ice1712_read_eeprom(ice) < 0) {
-		snd_ice1712_free(ice);
-		return -EIO;
-	}
-	if (snd_ice1712_chip_init(ice) < 0) {
-		snd_ice1712_free(ice);
-		return -EIO;
-	}
-
-	/* unmask used interrupts */
-	outb((ice->eeprom.codec & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
-	     (ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
-	     ICEREG(ice, IRQMASK));
-	outb(0x00, ICEMT(ice, IRQ));
-
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
-		snd_ice1712_free(ice);
-		return err;
-	}
-
-	*r_ice1712 = ice;
-	return 0;
-}
-
-static int __devinit snd_ice1712_probe(struct pci_dev *pci,
-				       const struct pci_device_id *id)
-{
-	static int dev;
-	snd_card_t *card;
-	ice1712_t *ice;
-	int pcm_dev = 0, err;
-
-	if (dev >= SNDRV_CARDS)
-		return -ENODEV;
-	if (!snd_enable[dev]) {
-		dev++;
-		return -ENOENT;
-	}
-
-	card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, 0);
-	if (card == NULL)
-		return -ENOMEM;
-
-	if ((err = snd_ice1712_create(card, pci, snd_omni[dev], &ice)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-
-	if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97))
-		if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-
-	if ((err = snd_ice1712_ac97_mixer(ice)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-
-	if ((err = snd_ice1712_build_controls(ice)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-
-	if (!(ice->eeprom.codec & ICE1712_CFG_NO_CON_AC97))
-		if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-
-	strcpy(card->driver, "ICE1712");
-	strcpy(card->shortname, "ICEnsemble ICE1712");
-	
-	switch (ice->eeprom.subvendor) {
-	case ICE1712_SUBDEVICE_STDSP24:
-		strcpy(card->shortname, "Hoontech SoundTrack Audio DSP24");
-		break;
-	case ICE1712_SUBDEVICE_DELTA1010:
-		strcpy(card->shortname, "M Audio Delta 1010");
-		break;
-	case ICE1712_SUBDEVICE_DELTADIO2496:
-		strcpy(card->shortname, "M Audio Delta DiO 2496");
-		goto __no_mpu401;
-	case ICE1712_SUBDEVICE_DELTA66:
-		strcpy(card->shortname, "M Audio Delta 66");
-		goto __no_mpu401;
-	case ICE1712_SUBDEVICE_DELTA44:
-		strcpy(card->shortname, "M Audio Delta 44");
-		goto __no_mpu401;
-	case ICE1712_SUBDEVICE_AUDIOPHILE:
-		strcpy(card->shortname, "M Audio Audiophile 24/96");
-		break;
-	case ICE1712_SUBDEVICE_DELTA1010LT:
-		strcpy(card->shortname, "M Audio Delta 1010LT");
-		break;
-	case ICE1712_SUBDEVICE_EWX2496:
-		strcpy(card->shortname, "TerraTec EWX 24/96");
-		break;
-	case ICE1712_SUBDEVICE_EWS88MT:
-		strcpy(card->shortname, "TerraTec EWS 88MT");
-		break;
-	case ICE1712_SUBDEVICE_EWS88D:
-		strcpy(card->shortname, "TerraTec EWS 88D");
-		break;
-	case ICE1712_SUBDEVICE_DMX6FIRE:
-		strcpy(card->shortname, "TerraTec DMX 6Fire");
-		break;
-	}
-
-	if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
-				       ICEREG(ice, MPU1_CTRL), 1,
-				       ice->irq, 0,
-				       &ice->rmidi[0])) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-
-	if (ice->eeprom.codec & ICE1712_CFG_2xMPU401)
-		if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712,
-					       ICEREG(ice, MPU2_CTRL), 1,
-					       ice->irq, 0,
-					       &ice->rmidi[1])) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-
-      __no_mpu401:
-	sprintf(card->longname, "%s at 0x%lx, irq %i",
-		card->shortname, ice->port, ice->irq);
-
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	pci_set_drvdata(pci, card);
-	dev++;
-	return 0;
-}
-
-static void __devexit snd_ice1712_remove(struct pci_dev *pci)
-{
-	snd_card_free(pci_get_drvdata(pci));
-	pci_set_drvdata(pci, NULL);
-}
-
-static struct pci_driver driver = {
-	.name = "ICE1712",
-	.id_table = snd_ice1712_ids,
-	.probe = snd_ice1712_probe,
-	.remove = __devexit_p(snd_ice1712_remove),
-};
-
-static int __init alsa_card_ice1712_init(void)
-{
-	int err;
-
-	if ((err = pci_module_init(&driver)) < 0) {
-#ifdef MODULE
-		printk(KERN_ERR "ICE1712 soundcard not found or device busy\n");
-#endif
-		return err;
-	}
-	return 0;
-}
-
-static void __exit alsa_card_ice1712_exit(void)
-{
-	pci_unregister_driver(&driver);
-}
-
-module_init(alsa_card_ice1712_init)
-module_exit(alsa_card_ice1712_exit)
-
-#ifndef MODULE
-
-/* format is: snd-ice1712=snd_enable,snd_index,snd_id */
-
-static int __init alsa_card_ice1712_setup(char *str)
-{
-	static unsigned __initdata nr_dev = 0;
-
-	if (nr_dev >= SNDRV_CARDS)
-		return 0;
-	(void)(get_option(&str,&snd_enable[nr_dev]) == 2 &&
-	       get_option(&str,&snd_index[nr_dev]) == 2 &&
-	       get_id(&str,&snd_id[nr_dev]) == 2);
-	nr_dev++;
-	return 1;
-}
-
-__setup("snd-ice1712=", alsa_card_ice1712_setup);
-
-#endif /* ifndef MODULE */
diff -Nru a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/intel8x0.c	Tue Oct  1 17:11:59 2002
@@ -1430,7 +1430,7 @@
 
 	if (rpcm)
 		*rpcm = NULL;
-	err = snd_pcm_new(chip->card, "ALI - AC97 IEC958", device, 0, 1, &pcm);
+	err = snd_pcm_new(chip->card, "ALI - AC97 IEC958", device, 1, 0, &pcm);
 	if (err < 0)
 		return err;
 
@@ -1550,6 +1550,16 @@
 		ac97.read = snd_intel8x0_ali_codec_read;
 		channels = 6;
 		codecs = 1;
+		/* detect the secondary codec */
+		for (i = 0; i < 100; i++) {
+			unsigned int reg = igetdword(chip, ICHREG(ALI_RTSR));
+			if (reg & 0x40) {
+				codecs = 2;
+				break;
+			}
+			iputdword(chip, ICHREG(ALI_RTSR), reg | 0x40);
+			udelay(1);
+		}
 	}
 	if ((err = snd_ac97_mixer(chip->card, &ac97, &x97)) < 0)
 		return err;
@@ -1567,9 +1577,6 @@
 	/* make sure, that we have DACs at right slot for rev2.2 */
 	if (ac97_is_rev22(x97))
 		snd_ac97_update_bits(x97, AC97_EXTENDED_ID, AC97_EI_DACS_SLOT_MASK, 0);
-	/* can we have more AC'97 codecs with ALI chipset? */
-	if (chip->device_type == DEVICE_ALI)
-		goto __end;
 	/* AnalogDevices CNR boards uses special codec chaining */
 	/* skip standard test method for secondary codecs in this case */
 	if (x97->flags & AC97_AD_MULTI) {
@@ -1586,24 +1593,28 @@
 			break;
 		}
 		chip->ac97[i] = x97;
-		if (chip->device_type == DEVICE_INTEL_ICH4 && chip->ichd[ICHD_PCM2IN].ac97 == NULL)
-			chip->ichd[ICHD_PCM2IN].ac97 = x97;
-		if (x97->ext_id & AC97_EI_VRM) {
-			if (chip->ichd[ICHD_MIC].ac97 == NULL)
-				chip->ichd[ICHD_MIC].ac97 = x97;
-			else if (chip->device_type == DEVICE_INTEL_ICH4 &&
-				 chip->ichd[ICHD_MIC2].ac97 == NULL &&
-				 chip->ichd[ICHD_PCM2IN].ac97 == x97)
-				chip->ichd[ICHD_MIC2].ac97 = x97;
-		}
-		if (x97->ext_id & AC97_EI_SPDIF) {
-			if (chip->device_type != DEVICE_ALI) {
+		switch (chip->device_type) {
+		case DEVICE_INTEL_ICH4:
+			if (chip->ichd[ICHD_PCM2IN].ac97 == NULL)
+				chip->ichd[ICHD_PCM2IN].ac97 = x97;
+			if (x97->ext_id & AC97_EI_VRM) {
+				if (chip->ichd[ICHD_MIC].ac97 == NULL)
+					chip->ichd[ICHD_MIC].ac97 = x97;
+				else if (chip->ichd[ICHD_MIC2].ac97 == NULL &&
+					 chip->ichd[ICHD_PCM2IN].ac97 == x97)
+					chip->ichd[ICHD_MIC2].ac97 = x97;
+			}
+			if (x97->ext_id & AC97_EI_SPDIF) {
 				if (chip->ichd[ICHD_SPBAR].ac97 == NULL)
 					chip->ichd[ICHD_SPBAR].ac97 = x97;
-			} else {
-				if (chip->ichd[ALID_AC97SPDIFOUT].ac97 == NULL)
-					chip->ichd[ALID_AC97SPDIFOUT].ac97 = x97;
 			}
+			break;
+		default:
+			if (x97->ext_id & AC97_EI_VRM) {
+				if (chip->ichd[ICHD_MIC].ac97 == NULL)
+					chip->ichd[ICHD_MIC].ac97 = x97;
+			}
+			break;
 		}
 	}
 	
@@ -1672,7 +1683,6 @@
 			}
 		}
 	}
-      __end:
 	chip->in_ac97_init = 0;
 	return 0;
 }
@@ -2147,11 +2157,11 @@
 	chip->pci = pci;
 	chip->irq = -1;
 	snd_intel8x0_proc_init(chip);
-	if (chip->device_type == DEVICE_INTEL_ICH4 &&
-	    (pci_resource_flags(pci, 2) & IORESOURCE_MEM)) {	/* ICH4 and higher */
-		chip->mmio = chip->bm_mmio = 1;
+	sprintf(chip->ac97_name, "%s - AC'97", card->shortname);
+	sprintf(chip->ctrl_name, "%s - Controller", card->shortname);
+	if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) {	/* ICH4 and Nforce */
+		chip->mmio = 1;
 		chip->addr = pci_resource_start(pci, 2);
-		sprintf(chip->ac97_name, "%s - AC'97", card->shortname);
 		if ((chip->res = request_mem_region(chip->addr, 512, chip->ac97_name)) == NULL) {
 			snd_intel8x0_free(chip);
 			snd_printk("unable to grab I/O memory 0x%lx-0x%lx\n", chip->addr, chip->addr + 512 - 1);
@@ -2163,7 +2173,16 @@
 			snd_printk("AC'97 space ioremap problem\n");
 			return -EIO;
 		}
-		sprintf(chip->ctrl_name, "%s - Controller", card->shortname);
+	} else {
+		chip->addr = pci_resource_start(pci, 0);
+		if ((chip->res = request_region(chip->addr, 256, chip->ac97_name)) == NULL) {
+			snd_intel8x0_free(chip);
+			snd_printk("unable to grab ports 0x%lx-0x%lx\n", chip->addr, chip->addr + 256 - 1);
+			return -EBUSY;
+		}
+	}
+	if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) {	/* ICH4 */
+		chip->bm_mmio = 1;
 		chip->bmaddr = pci_resource_start(pci, 3);
 		if ((chip->res_bm = request_mem_region(chip->bmaddr, 256, chip->ctrl_name)) == NULL) {
 			snd_intel8x0_free(chip);
@@ -2177,14 +2196,6 @@
 			return -EIO;
 		}
 	} else {
-		chip->addr = pci_resource_start(pci, 0);
-		sprintf(chip->ac97_name, "%s - AC'97", card->shortname);
-		if ((chip->res = request_region(chip->addr, 256, chip->ac97_name)) == NULL) {
-			snd_intel8x0_free(chip);
-			snd_printk("unable to grab ports 0x%lx-0x%lx\n", chip->addr, chip->addr + 256 - 1);
-			return -EBUSY;
-		}
-		sprintf(chip->ctrl_name, "%s - Controller", card->shortname);
 		chip->bmaddr = pci_resource_start(pci, 1);
 		if ((chip->res_bm = request_region(chip->bmaddr, 64, chip->ctrl_name)) == NULL) {
 			snd_intel8x0_free(chip);
diff -Nru a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/rme32.c	Tue Oct  1 17:11:59 2002
@@ -859,6 +859,10 @@
 	spin_unlock_irqrestore(&rme32->lock, flags);
 
 	runtime->hw = snd_rme32_capture_spdif_info;
+	if (RME32_PRO_WITH_8414(rme32)) {
+		runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
+		runtime->hw.rate_max = 96000;
+	}
 
 	snd_pcm_hw_constraint_minmax(runtime,
 				     SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c	Tue Oct  1 17:11:59 2002
+++ b/sound/pci/via82xx.c	Tue Oct  1 17:11:59 2002
@@ -217,7 +217,7 @@
 			return -ENOMEM;
 	}
 	if (! dev->idx_table) {
-		dev->idx_table = kmalloc(sizeof(unsigned int) * VIA_TABLE_SIZE, GFP_KERNEL);
+		dev->idx_table = kmalloc(sizeof(*dev->idx_table) * VIA_TABLE_SIZE, GFP_KERNEL);
 		if (! dev->idx_table)
 			return -ENOMEM;
 	}
@@ -268,7 +268,7 @@
 			    struct pci_dev *pci)
 {
 	if (dev->table) {
-		snd_free_pci_pages(pci, PAGE_ALIGN(dev->tbl_entries * 8), dev->table, dev->table_addr);
+		snd_free_pci_pages(pci, PAGE_ALIGN(VIA_TABLE_SIZE * 2 * 8), dev->table, dev->table_addr);
 		dev->table = NULL;
 	}
 	if (dev->idx_table) {
diff -Nru a/sound/ppc/awacs.c b/sound/ppc/awacs.c
--- a/sound/ppc/awacs.c	Tue Oct  1 17:11:59 2002
+++ b/sound/ppc/awacs.c	Tue Oct  1 17:11:59 2002
@@ -82,9 +82,18 @@
 	snd_pmac_awacs_write(chip, val | (reg << 12));
 }
 
+static void do_mdelay(int msec, int can_schedule)
+{
+	if (can_schedule) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout((msec * HZ + 999) / 1000);
+	} else
+		mdelay(msec);
+}
+
 #ifdef CONFIG_PMAC_PBOOK
 /* Recalibrate chip */
-static void screamer_recalibrate(pmac_t *chip)
+static void screamer_recalibrate(pmac_t *chip, int can_schedule)
 {
 	if (chip->model != PMAC_SCREAMER)
 		return;
@@ -92,15 +101,15 @@
 	/* Sorry for the horrible delays... I hope to get that improved
 	 * by making the whole PM process asynchronous in a future version
 	 */
-	mdelay(750);
+	do_mdelay(750, can_schedule);
 	snd_pmac_awacs_write_noreg(chip, 1,
 				   chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE);
-	mdelay(1000);
+	do_mdelay(1000, can_schedule);
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
 }
 
 #else
-#define screamer_recalibrate(chip) /* NOP */
+#define screamer_recalibrate(chip, can_schedule) /* NOP */
 #endif
 
 
@@ -609,7 +618,7 @@
 /*
  * restore all registers
  */
-static void awacs_restore_all_regs(pmac_t *chip)
+static void awacs_restore_all_regs(pmac_t *chip, int can_schedule)
 {
 	snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
@@ -617,7 +626,7 @@
 	snd_pmac_awacs_write_noreg(chip, 4, chip->awacs_reg[4]);
 	if (chip->model == PMAC_SCREAMER) {
 		snd_pmac_awacs_write_noreg(chip, 5, chip->awacs_reg[5]);
-		mdelay(100);
+		do_mdelay(100, can_schedule);
 		snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
 		mdelay(2);
 		snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
@@ -629,8 +638,8 @@
 #ifdef CONFIG_PMAC_PBOOK
 static void snd_pmac_awacs_resume(pmac_t *chip)
 {
-	awacs_restore_all_regs(chip);
-	screamer_recalibrate(chip);
+	awacs_restore_all_regs(chip, 0);
+	screamer_recalibrate(chip, 0);
 #ifdef PMAC_AMP_AVAIL
 	if (chip->mixer_data) {
 		awacs_amp_t *amp = chip->mixer_data;
@@ -738,8 +747,8 @@
 		chip->awacs_reg[7] = 0;
 	}
 
-	awacs_restore_all_regs(chip);
-	screamer_recalibrate(chip);
+	awacs_restore_all_regs(chip, 1);
+	screamer_recalibrate(chip, 1);
 
 	chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
 #ifdef PMAC_AMP_AVAIL
@@ -849,6 +858,10 @@
 	chip->update_automute = snd_pmac_awacs_update_automute;
 	snd_pmac_awacs_update_automute(chip, 0); /* update the status only */
 #endif
+	if (chip->model == PMAC_SCREAMER) {
+		snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
+		snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
+	}
 
 	return 0;
 }
diff -Nru a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c	Tue Oct  1 17:11:59 2002
+++ b/sound/usb/usbaudio.c	Tue Oct  1 17:11:59 2002
@@ -150,8 +150,8 @@
 	unsigned int phase;      /* phase accumulator */
 	unsigned int maxpacksize;	/* max packet size in bytes */
 	unsigned int maxframesize;	/* max packet size in frames */
-	unsigned int curpacksize;	/* current packet size in bytes */
-	unsigned int curframesize;	/* current packet size in frames */
+	unsigned int curpacksize;	/* current packet size in bytes (for capture) */
+	unsigned int curframesize;	/* current packet size in frames (for capture) */
 	unsigned int fill_max: 1;	/* fill max packet size always */
 
 	unsigned int running: 1;	/* running status */
@@ -941,13 +941,18 @@
 	alts = &iface->altsetting[fmt->altset_idx];
 	snd_assert(alts->bAlternateSetting == fmt->altsetting, return -EINVAL);
 
+	/* close the old interface */
+	if (subs->interface >= 0 && subs->interface != fmt->iface) {
+		usb_set_interface(subs->dev, subs->interface, 0);
+		subs->interface = -1;
+	}
+
 	/* create a data pipe */
 	ep = alts->endpoint[0].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
 	if (is_playback)
 		subs->datapipe = usb_sndisocpipe(dev, ep);
 	else
 		subs->datapipe = usb_rcvisocpipe(dev, ep);
-	subs->interface = fmt->iface;
 	subs->format = fmt->altset_idx;
 	subs->syncpipe = subs->syncinterval = 0;
 	subs->maxpacksize = alts->endpoint[0].wMaxPacketSize;
@@ -963,14 +968,14 @@
 		    alts->endpoint[1].bmAttributes != 0x01 ||
 		    alts->endpoint[1].bSynchAddress != 0) {
 			snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
-				   dev->devnum, subs->interface, fmt->altsetting);
+				   dev->devnum, fmt->iface, fmt->altsetting);
 			return -EINVAL;
 		}
 		ep = alts->endpoint[1].bEndpointAddress;
 		if ((is_playback && ep != (alts->endpoint[0].bSynchAddress | USB_DIR_IN)) ||
 		    (! is_playback && ep != (alts->endpoint[0].bSynchAddress & ~USB_DIR_IN))) {
 			snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
-				   dev->devnum, subs->interface, fmt->altsetting);
+				   dev->devnum, fmt->iface, fmt->altsetting);
 			return -EINVAL;
 		}
 		ep &= USB_ENDPOINT_NUMBER_MASK;
@@ -982,13 +987,15 @@
 	}
 
 	/* set interface */
-	if (usb_set_interface(dev, subs->interface, fmt->altset_idx) < 0) {
+	if (usb_set_interface(dev, fmt->iface, fmt->altset_idx) < 0) {
 		snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
-			   dev->devnum, subs->interface, fmt->altsetting);
+			   dev->devnum, fmt->iface, fmt->altsetting);
 		return -EIO;
 	}
+	snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altset_idx);
+	subs->interface = fmt->iface;
 
-	ep = usb_pipeendpoint(subs->datapipe) | (subs->datapipe & USB_DIR_IN);
+	ep = alts->endpoint[0].bEndpointAddress;
 	/* if endpoint has pitch control, enable it */
 	if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) {
 		data[0] = 1;
@@ -1829,6 +1836,10 @@
 			continue;
 		}
 		iface = &config->interface[j];
+		if (usb_interface_claimed(iface)) {
+			snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j);
+			continue;
+		}
 		if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
 		    iface->altsetting[0].bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
 			if (snd_usb_create_midi_interface(chip, j, NULL) < 0) {
@@ -1845,6 +1856,7 @@
 			continue;
 		}
 		parse_audio_endpoints(chip, buffer, buflen, j);
+		usb_set_interface(dev, j, 0); /* reset the current interface */
 		usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
 	}
 

===================================================================


This BitKeeper patch contains the following changesets:
1.655
## Wrapped with gzip_uu ##


begin 664 bkpatch23281
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
K0\J*_J!M*B@WS^>!_M&+'9W@C\101N5HTMM5-=?)*TYI_3_U]&X3GV8`````
`
end
