summary refs log tree commit diff
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-12-20 23:39:47 +0100
committerTakashi Iwai <tiwai@suse.de>2008-12-20 23:39:47 +0100
commit55fa518867978e1f5fd8353098f80d125ac734d7 (patch)
tree3502b331c1f9ec4cac25dc8ba30b6a0a324e350c /sound
parentbb1f24bf00a85f666b56a09b7cdbfd221af16c2c (diff)
parenteea0579fc85e64e9f05361d5aacf496fe7a151aa (diff)
downloadlinux-55fa518867978e1f5fd8353098f80d125ac734d7.tar.gz
Merge branch 'topic/pcsp-fix' into topic/misc
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/soundbus/soundbus.h2
-rw-r--r--sound/arm/pxa2xx-ac97.c4
-rw-r--r--sound/core/control.c1
-rw-r--r--sound/core/init.c11
-rw-r--r--sound/core/memalloc.c48
-rw-r--r--sound/core/oss/pcm_oss.c2
-rw-r--r--sound/core/pcm_native.c1
-rw-r--r--sound/core/sound.c5
-rw-r--r--sound/core/timer.c1
-rw-r--r--sound/drivers/pcsp/pcsp.h2
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c86
-rw-r--r--sound/i2c/other/tea575x-tuner.c23
-rw-r--r--sound/isa/Kconfig2
-rw-r--r--sound/oss/au1550_ac97.c2
-rw-r--r--sound/oss/dmasound/dmasound.h4
-rw-r--r--sound/oss/dmasound/dmasound_atari.c4
-rw-r--r--sound/oss/dmasound/dmasound_core.c14
-rw-r--r--sound/oss/msnd.h2
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/sound_config.h20
-rw-r--r--sound/oss/soundcard.c15
-rw-r--r--sound/oss/swarm_cs4297a.c2
-rw-r--r--sound/oss/vwsnd.c2
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0.c3
-rw-r--r--sound/pci/bt87x.c3
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs5530.c2
-rw-r--r--sound/pci/hda/hda_beep.c8
-rw-r--r--sound/pci/hda/hda_beep.h1
-rw-r--r--sound/pci/hda/hda_codec.c1
-rw-r--r--sound/pci/hda/hda_intel.c31
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c3
-rw-r--r--sound/pci/hda/patch_nvhdmi.c1
-rw-r--r--sound/pci/hda/patch_realtek.c129
-rw-r--r--sound/pci/hda/patch_sigmatel.c206
-rw-r--r--sound/pci/mixart/mixart.c3
-rw-r--r--sound/pci/pcxhr/pcxhr.c5
-rw-r--r--sound/pci/rme9652/hdsp.c27
-rw-r--r--sound/ppc/snd_ps3.c96
-rw-r--r--sound/ppc/snd_ps3.h1
-rw-r--r--sound/soc/at32/playpaq_wm8510.c12
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c34
-rw-r--r--sound/soc/codecs/tlv320aic3x.c16
-rw-r--r--sound/soc/codecs/wm9713.c2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c14
-rw-r--r--sound/soc/omap/omap-mcbsp.c19
-rw-r--r--sound/soc/pxa/corgi.c34
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c10
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c43
-rw-r--r--sound/soc/pxa/spitz.c46
-rw-r--r--sound/soc/soc-core.c2
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/sound_core.c5
-rw-r--r--sound/sparc/amd7930.c85
-rw-r--r--sound/sparc/cs4231.c199
-rw-r--r--sound/sparc/dbri.c91
60 files changed, 855 insertions, 546 deletions
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
index 622cd37a0118..a0f223c13f66 100644
--- a/sound/aoa/soundbus/soundbus.h
+++ b/sound/aoa/soundbus/soundbus.h
@@ -8,7 +8,7 @@
 #ifndef __SOUNDBUS_H
 #define __SOUNDBUS_H
 
-#include <asm/of_device.h>
+#include <linux/of_device.h>
 #include <sound/pcm.h>
 #include <linux/list.h>
 
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index cba71d867542..c2635beb4c88 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -44,7 +44,7 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
 	.name			= "AC97 PCM out",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRTXPCDR,
+	.drcmr			= &DRCMR(12),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -52,7 +52,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
 	.name			= "AC97 PCM in",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRRXPCDR,
+	.drcmr			= &DRCMR(11),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
diff --git a/sound/core/control.c b/sound/core/control.c
index b0bf42691047..636b3b52ef8b 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -113,7 +113,6 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
 	unsigned int idx;
 
 	ctl = file->private_data;
-	fasync_helper(-1, file, 0, &ctl->fasync);
 	file->private_data = NULL;
 	card = ctl->card;
 	write_lock_irqsave(&card->ctl_files_rwlock, flags);
diff --git a/sound/core/init.c b/sound/core/init.c
index 8af467df9245..b47ff8b44be8 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -264,8 +264,11 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
 	}
 	spin_unlock(&shutdown_lock);
 
-	if (likely(df))
+	if (likely(df)) {
+		if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync)
+			df->disconnected_f_op->fasync(-1, file, 0);
 		return df->disconnected_f_op->release(inode, file);
+	}
 
 	panic("%s(%p, %p) failed!", __func__, inode, file);
 }
@@ -549,9 +552,9 @@ int snd_card_register(struct snd_card *card)
 		return -EINVAL;
 #ifndef CONFIG_SYSFS_DEPRECATED
 	if (!card->card_dev) {
-		card->card_dev = device_create_drvdata(sound_class, card->dev,
-						       MKDEV(0, 0), NULL,
-						       "card%i", card->number);
+		card->card_dev = device_create(sound_class, card->dev,
+					       MKDEV(0, 0), NULL,
+					       "card%i", card->number);
 		if (IS_ERR(card->card_dev))
 			card->card_dev = NULL;
 	}
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index a7b46ec72f32..1b3534d67686 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -33,9 +33,6 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <sound/memalloc.h>
-#ifdef CONFIG_SBUS
-#include <asm/sbus.h>
-#endif
 
 
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
@@ -162,39 +159,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
 }
 #endif /* CONFIG_HAS_DMA */
 
-#ifdef CONFIG_SBUS
-
-static void *snd_malloc_sbus_pages(struct device *dev, size_t size,
-				   dma_addr_t *dma_addr)
-{
-	struct sbus_dev *sdev = (struct sbus_dev *)dev;
-	int pg;
-	void *res;
-
-	if (WARN_ON(!dma_addr))
-		return NULL;
-	pg = get_order(size);
-	res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
-	if (res != NULL)
-		inc_snd_pages(pg);
-	return res;
-}
-
-static void snd_free_sbus_pages(struct device *dev, size_t size,
-				void *ptr, dma_addr_t dma_addr)
-{
-	struct sbus_dev *sdev = (struct sbus_dev *)dev;
-	int pg;
-
-	if (ptr == NULL)
-		return;
-	pg = get_order(size);
-	dec_snd_pages(pg);
-	sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
-}
-
-#endif /* CONFIG_SBUS */
-
 /*
  *
  *  ALSA generic memory management
@@ -231,11 +195,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
 		dmab->area = snd_malloc_pages(size, (unsigned long)device);
 		dmab->addr = 0;
 		break;
-#ifdef CONFIG_SBUS
-	case SNDRV_DMA_TYPE_SBUS:
-		dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr);
-		break;
-#endif
 #ifdef CONFIG_HAS_DMA
 	case SNDRV_DMA_TYPE_DEV:
 		dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
@@ -306,11 +265,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
 	case SNDRV_DMA_TYPE_CONTINUOUS:
 		snd_free_pages(dmab->area, dmab->bytes);
 		break;
-#ifdef CONFIG_SBUS
-	case SNDRV_DMA_TYPE_SBUS:
-		snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
-		break;
-#endif
 #ifdef CONFIG_HAS_DMA
 	case SNDRV_DMA_TYPE_DEV:
 		snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
@@ -419,7 +373,7 @@ static int snd_mem_proc_read(struct seq_file *seq, void *offset)
 	long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
 	struct snd_mem_list *mem;
 	int devno;
-	static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
+	static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" };
 
 	mutex_lock(&list_mutex);
 	seq_printf(seq, "pages  : %li bytes (%li pages per %likB)\n",
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 1af62b8b86c6..e17836680f49 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file,
 	int idx, err;
 	struct snd_pcm_oss_file *pcm_oss_file;
 	struct snd_pcm_substream *substream;
-	unsigned int f_mode = file->f_mode;
+	fmode_t f_mode = file->f_mode;
 
 	if (rpcm_oss_file)
 		*rpcm_oss_file = NULL;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index aef18682c035..a789efc9df39 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2169,7 +2169,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
 	if (snd_BUG_ON(!substream))
 		return -ENXIO;
 	pcm = substream->pcm;
-	fasync_helper(-1, file, 0, &substream->runtime->fasync);
 	mutex_lock(&pcm->open_mutex);
 	snd_pcm_release_substream(substream);
 	kfree(pcm_file);
diff --git a/sound/core/sound.c b/sound/core/sound.c
index c0685e2f0afa..44a69bb8d4f0 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
 		return minor;
 	}
 	snd_minors[minor] = preg;
-	preg->dev = device_create_drvdata(sound_class, device,
-					  MKDEV(major, minor),
-					  private_data, "%s", name);
+	preg->dev = device_create(sound_class, device, MKDEV(major, minor),
+				  private_data, "%s", name);
 	if (IS_ERR(preg->dev)) {
 		snd_minors[minor] = NULL;
 		mutex_unlock(&sound_mutex);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index e582face89d2..c584408c9f17 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1263,7 +1263,6 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
 	if (file->private_data) {
 		tu = file->private_data;
 		file->private_data = NULL;
-		fasync_helper(-1, file, 0, &tu->fasync);
 		if (tu->timeri)
 			snd_timer_close(tu->timeri);
 		kfree(tu->queue);
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 70533a333b5b..cdef2664218f 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -62,6 +62,8 @@ struct snd_pcsp {
 	unsigned short port, irq, dma;
 	spinlock_t substream_lock;
 	struct snd_pcm_substream *playback_substream;
+	unsigned int fmt_size;
+	unsigned int is_signed;
 	size_t playback_ptr;
 	size_t period_ptr;
 	atomic_t timer_active;
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 40f95f549d2b..84cc2658c05b 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -36,12 +36,13 @@ static void pcsp_call_pcm_elapsed(unsigned long priv)
 
 static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
 
-enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+/* write the port and returns the next expire time in ns;
+ * called at the trigger-start and in hrtimer callback
+ */
+static unsigned long pcsp_timer_update(struct hrtimer *handle)
 {
 	unsigned char timer_cnt, val;
-	int fmt_size, periods_elapsed;
 	u64 ns;
-	size_t period_bytes, buffer_bytes;
 	struct snd_pcm_substream *substream;
 	struct snd_pcm_runtime *runtime;
 	struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
@@ -51,28 +52,25 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 		outb(chip->val61, 0x61);
 		chip->thalf = 0;
 		if (!atomic_read(&chip->timer_active))
-			goto stop;
-		hrtimer_forward(&chip->timer, chip->timer.expires,
-				ktime_set(0, chip->ns_rem));
-		return HRTIMER_RESTART;
+			return 0;
+		return chip->ns_rem;
 	}
 
 	if (!atomic_read(&chip->timer_active))
-		goto stop;
+		return 0;
 	substream = chip->playback_substream;
 	if (!substream)
-		goto stop;
+		return 0;
 
 	runtime = substream->runtime;
-	fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
 	/* assume it is mono! */
-	val = runtime->dma_area[chip->playback_ptr + fmt_size - 1];
-	if (snd_pcm_format_signed(runtime->format))
+	val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
+	if (chip->is_signed)
 		val ^= 0x80;
 	timer_cnt = val * CUR_DIV() / 256;
 
 	if (timer_cnt && chip->enable) {
-		spin_lock(&i8253_lock);
+		spin_lock_irqsave(&i8253_lock, flags);
 		if (!nforce_wa) {
 			outb_p(chip->val61, 0x61);
 			outb_p(timer_cnt, 0x42);
@@ -81,14 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 			outb(chip->val61 ^ 2, 0x61);
 			chip->thalf = 1;
 		}
-		spin_unlock(&i8253_lock);
+		spin_unlock_irqrestore(&i8253_lock, flags);
 	}
 
+	chip->ns_rem = PCSP_PERIOD_NS();
+	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
+	chip->ns_rem -= ns;
+	return ns;
+}
+
+enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
+{
+	struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
+	struct snd_pcm_substream *substream;
+	int periods_elapsed, pointer_update;
+	size_t period_bytes, buffer_bytes;
+	unsigned long ns;
+	unsigned long flags;
+
+	pointer_update = !chip->thalf;
+	ns = pcsp_timer_update(handle);
+	if (!ns)
+		return HRTIMER_NORESTART;
+
+	/* update the playback position */
+	substream = chip->playback_substream;
+	if (!substream)
+		return HRTIMER_NORESTART;
+
 	period_bytes = snd_pcm_lib_period_bytes(substream);
 	buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
 
 	spin_lock_irqsave(&chip->substream_lock, flags);
-	chip->playback_ptr += PCSP_INDEX_INC() * fmt_size;
+	chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
 	periods_elapsed = chip->playback_ptr - chip->period_ptr;
 	if (periods_elapsed < 0) {
 #if PCSP_DEBUG
@@ -106,31 +129,27 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 	if (periods_elapsed) {
 		chip->period_ptr += periods_elapsed * period_bytes;
 		chip->period_ptr %= buffer_bytes;
-		tasklet_schedule(&pcsp_pcm_tasklet);
 	}
 	spin_unlock_irqrestore(&chip->substream_lock, flags);
 
-	if (!atomic_read(&chip->timer_active))
-		goto stop;
+	if (periods_elapsed)
+		tasklet_schedule(&pcsp_pcm_tasklet);
 
-	chip->ns_rem = PCSP_PERIOD_NS();
-	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
-	chip->ns_rem -= ns;
-	hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns));
-	return HRTIMER_RESTART;
+	hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
 
- stop:
-	return HRTIMER_NORESTART;
+	return HRTIMER_RESTART;
 }
 
-static void pcsp_start_playing(struct snd_pcsp *chip)
+static int pcsp_start_playing(struct snd_pcsp *chip)
 {
+	unsigned long ns;
+
 #if PCSP_DEBUG
 	printk(KERN_INFO "PCSP: start_playing called\n");
 #endif
 	if (atomic_read(&chip->timer_active)) {
 		printk(KERN_ERR "PCSP: Timer already active\n");
-		return;
+		return -EIO;
 	}
 
 	spin_lock(&i8253_lock);
@@ -140,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip)
 	atomic_set(&chip->timer_active, 1);
 	chip->thalf = 0;
 
-	hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+	ns = pcsp_timer_update(&pcsp_chip.timer);
+	if (!ns)
+		return -EIO;
+
+	hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
+	return 0;
 }
 
 static void pcsp_stop_playing(struct snd_pcsp *chip)
@@ -220,6 +244,9 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
 	pcsp_sync_stop(chip);
 	chip->playback_ptr = 0;
 	chip->period_ptr = 0;
+	chip->fmt_size =
+		snd_pcm_format_physical_width(substream->runtime->format) >> 3;
+	chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
 	return 0;
 }
 
@@ -232,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
-		pcsp_start_playing(chip);
-		break;
+		return pcsp_start_playing(chip);
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 		pcsp_stop_playing(chip);
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 83e90057270e..c13a178383ba 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -87,8 +87,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
 static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
 			     unsigned int cmd, unsigned long data)
 {
-	struct video_device *dev = video_devdata(file);
-	struct snd_tea575x *tea = video_get_drvdata(dev);
+	struct snd_tea575x *tea = video_drvdata(file);
 	void __user *arg = (void __user *)data;
 	
 	switch(cmd) {
@@ -175,6 +174,21 @@ static void snd_tea575x_release(struct video_device *vfd)
 {
 }
 
+static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file)
+{
+	struct snd_tea575x *tea = video_drvdata(file);
+
+	return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
+}
+
+static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file)
+{
+	struct snd_tea575x *tea = video_drvdata(file);
+
+	clear_bit(0, &tea->in_use);
+	return 0;
+}
+
 /*
  * initialize all the tea575x chips
  */
@@ -193,9 +207,10 @@ void snd_tea575x_init(struct snd_tea575x *tea)
 	tea->vd.release = snd_tea575x_release;
 	video_set_drvdata(&tea->vd, tea);
 	tea->vd.fops = &tea->fops;
+	tea->in_use = 0;
 	tea->fops.owner = tea->card->module;
-	tea->fops.open = video_exclusive_open;
-	tea->fops.release = video_exclusive_release;
+	tea->fops.open = snd_tea575x_exclusive_open;
+	tea->fops.release = snd_tea575x_exclusive_release;
 	tea->fops.ioctl = snd_tea575x_ioctl;
 	if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) {
 		snd_printk(KERN_ERR "unable to register tea575x tuner\n");
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 660beb41f767..ce0aa044e274 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -211,7 +211,7 @@ config SND_GUSCLASSIC
 
 config SND_GUSEXTREME
 	tristate "Gravis UltraSound Extreme"
-	select SND_HWDEP
+	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
 	help
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 23018a7c063a..81e1f443d094 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -93,7 +93,7 @@ static struct au1550_state {
 	spinlock_t      lock;
 	struct mutex open_mutex;
 	struct mutex sem;
-	mode_t          open_mode;
+	fmode_t          open_mode;
 	wait_queue_head_t open_wait;
 
 	struct dmabuf {
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index d978b0096564..1308d8d34186 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -129,7 +129,7 @@ typedef struct {
     int (*mixer_ioctl)(u_int, u_long);	/* optional */
     int (*write_sq_setup)(void);	/* optional */
     int (*read_sq_setup)(void);		/* optional */
-    int (*sq_open)(mode_t);		/* optional */
+    int (*sq_open)(fmode_t);		/* optional */
     int (*state_info)(char *, size_t);	/* optional */
     void (*abort_read)(void);		/* optional */
     int min_dsp_speed;
@@ -235,7 +235,7 @@ struct sound_queue {
      */
     int active;
     wait_queue_head_t action_queue, open_queue, sync_queue;
-    int open_mode;
+    int non_blocking;
     int busy, syncing, xruns, died;
 };
 
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 285239d64b82..4d45bd63718b 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg);
 static int TTMixerIoctl(u_int cmd, u_long arg);
 static int FalconMixerIoctl(u_int cmd, u_long arg);
 static int AtaWriteSqSetup(void);
-static int AtaSqOpen(mode_t mode);
+static int AtaSqOpen(fmode_t mode);
 static int TTStateInfo(char *buffer, size_t space);
 static int FalconStateInfo(char *buffer, size_t space);
 
@@ -1461,7 +1461,7 @@ static int AtaWriteSqSetup(void)
 	return 0 ;
 }
 
-static int AtaSqOpen(mode_t mode)
+static int AtaSqOpen(fmode_t mode)
 {
 	write_sq_ignore_int = 1;
 	return 0 ;
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 95fc5c681755..793b7f478433 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -212,7 +212,7 @@ static int irq_installed;
 #endif /* MODULE */
 
 /* control over who can modify resources shared between play/record */
-static mode_t shared_resource_owner;
+static fmode_t shared_resource_owner;
 static int shared_resources_initialised;
 
     /*
@@ -603,7 +603,7 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
 	while (uLeft) {
 		while (write_sq.count >= write_sq.max_active) {
 			sq_play();
-			if (write_sq.open_mode & O_NONBLOCK)
+			if (write_sq.non_blocking)
 				return uWritten > 0 ? uWritten : -EAGAIN;
 			SLEEP(write_sq.action_queue);
 			if (signal_pending(current))
@@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq)
 
 #if 0 /* blocking open() */
 static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
-			      mode_t mode)
+			      fmode_t mode)
 {
 	if (file->f_mode & mode) {
 		sq->busy = 0; /* CHECK: IS THIS OK??? */
@@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
 }
 #endif
 
-static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
+static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
 		    int numbufs, int bufsize)
 {
 	int rc = 0;
@@ -718,7 +718,7 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
 			return rc;
 		}
 
-		sq->open_mode = file->f_mode;
+		sq->non_blocking = file->f_flags & O_NONBLOCK;
 	}
 	return rc;
 }
@@ -891,10 +891,10 @@ static int sq_release(struct inode *inode, struct file *file)
    is the owner - if we have problems.
 */
 
-static int shared_resources_are_mine(mode_t md)
+static int shared_resources_are_mine(fmode_t md)
 {
 	if (shared_resource_owner)
-		return (shared_resource_owner & md ) ;
+		return (shared_resource_owner & md) != 0;
 	else {
 		shared_resource_owner = md ;
 		return 1 ;
diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h
index 61b3955481c5..c8be47ec2b7e 100644
--- a/sound/oss/msnd.h
+++ b/sound/oss/msnd.h
@@ -211,7 +211,7 @@ typedef struct multisound_dev {
 
 	/* State variables */
 	enum { msndClassic, msndPinnacle } type;
-	mode_t mode;
+	fmode_t mode;
 	unsigned long flags;
 #define F_RESETTING			0
 #define F_HAVEDIGITAL			1
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index b493660deb36..e5d423994918 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -26,7 +26,7 @@
 #include <asm/cpu/dac.h>
 #include <asm/cpu/timer.h>
 #include <asm/machvec.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
 #include <asm/hd64461.h>
 
 #define MODNAME "sh_dac_audio"
diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h
index 1a00a3210616..55271fbe7f49 100644
--- a/sound/oss/sound_config.h
+++ b/sound/oss/sound_config.h
@@ -110,24 +110,16 @@ struct channel_info {
 #define OPEN_WRITE	PCM_ENABLE_OUTPUT
 #define OPEN_READWRITE	(OPEN_READ|OPEN_WRITE)
 
-#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE
-
-static inline int translate_mode(struct file *file)
-{
-	return file->f_mode;
-}
-
-#else
-
 static inline int translate_mode(struct file *file)
 {
-	return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
-		((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
+	if (OPEN_READ == (__force int)FMODE_READ &&
+	    OPEN_WRITE == (__force int)FMODE_WRITE)
+		return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE));
+	else
+		return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
+			((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
 }
 
-#endif
-
-
 #include "sound_calls.h"
 #include "dev_table.h"
 
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 7d89c081a086..61aaedae6b7e 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -560,19 +560,18 @@ static int __init oss_init(void)
 	sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
 	for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
-		device_create_drvdata(sound_class, NULL,
-				      MKDEV(SOUND_MAJOR, dev_list[i].minor),
-				      NULL, "%s", dev_list[i].name);
+		device_create(sound_class, NULL,
+			      MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL,
+			      "%s", dev_list[i].name);
 
 		if (!dev_list[i].num)
 			continue;
 
 		for (j = 1; j < *dev_list[i].num; j++)
-			device_create_drvdata(sound_class, NULL,
-					      MKDEV(SOUND_MAJOR,
-						    dev_list[i].minor + (j*0x10)),
-					      NULL,
-					      "%s%d", dev_list[i].name, j);
+			device_create(sound_class, NULL,
+				      MKDEV(SOUND_MAJOR,
+					    dev_list[i].minor + (j*0x10)),
+				      NULL, "%s%d", dev_list[i].name, j);
 	}
 
 	if (sound_nblocks >= 1024)
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 044453a4ee5b..41562ecde5bb 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -295,7 +295,7 @@ struct cs4297a_state {
 	struct mutex open_mutex;
 	struct mutex open_sem_adc;
 	struct mutex open_sem_dac;
-	mode_t open_mode;
+	fmode_t open_mode;
 	wait_queue_head_t open_wait;
 	wait_queue_head_t open_wait_adc;
 	wait_queue_head_t open_wait_dac;
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index dcbb3f739e61..78b8acc7c3b9 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -1509,7 +1509,7 @@ typedef struct vwsnd_dev {
 	struct mutex open_mutex;
 	struct mutex io_mutex;
 	struct mutex mix_mutex;
-	mode_t		open_mode;
+	fmode_t		open_mode;
 	wait_queue_head_t open_wait;
 
 	lithium_t	lith;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 92f3a976ef2e..a7f38e63303f 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -932,7 +932,7 @@ snd_ad1889_create(struct snd_card *card,
 		goto free_and_ret;
 
 	chip->bar = pci_resource_start(pci, 0);
-	chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0));
+	chip->iobase = pci_ioremap_bar(pci, 0);
 	if (chip->iobase == NULL) {
 		printk(KERN_ERR PFX "unable to reserve region.\n");
 		err = -EBUSY;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 085a52b8c807..226fe8237d31 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1609,7 +1609,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
 		return err;
 	}
 	chip->addr = pci_resource_start(pci, 0);
-	chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
+	chip->remap_addr = pci_ioremap_bar(pci, 0);
 	if (chip->remap_addr == NULL) {
 		snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 		snd_atiixp_free(chip);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 2f106306c7fe..0e6e5cc1c501 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1252,7 +1252,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
 		return err;
 	}
 	chip->addr = pci_resource_start(pci, 0);
-	chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0));
+	chip->remap_addr = pci_ioremap_bar(pci, 0);
 	if (chip->remap_addr == NULL) {
 		snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
 		snd_atiixp_free(chip);
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 68368e490074..a36d4d1fd419 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -180,8 +180,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 	if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
 		goto regions_out;
 
-	chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
-	                             pci_resource_len(pci, 0));
+	chip->mmio = pci_ioremap_bar(pci, 0);
 	if (!chip->mmio) {
 		printk(KERN_ERR "MMIO area remap failed.\n");
 		err = -ENOMEM;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 3aa8d973540a..1aa1c0402540 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -749,8 +749,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
 		pci_disable_device(pci);
 		return err;
 	}
-	chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
-				     pci_resource_len(pci, 0));
+	chip->mmio = pci_ioremap_bar(pci, 0);
 	if (!chip->mmio) {
 		snd_printk(KERN_ERR "cannot remap io memory\n");
 		err = -ENOMEM;
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index ef9308f7c45b..192e7842e181 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1382,8 +1382,8 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
 	chip->ba0_addr = pci_resource_start(pci, 0);
 	chip->ba1_addr = pci_resource_start(pci, 1);
 
-	chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0));
-	chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1));
+	chip->ba0 = pci_ioremap_bar(pci, 0);
+	chip->ba1 = pci_ioremap_bar(pci, 1);
 	if (!chip->ba0 || !chip->ba1) {
 		snd_cs4281_free(chip);
 		return -ENOMEM;
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index 4ba2db2f4250..6dea5b5cc774 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -132,7 +132,7 @@ static int __devinit snd_cs5530_create(struct snd_card *card,
 	}
 	chip->pci_base = pci_resource_start(pci, 0);
 
-	mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0));
+	mem = pci_ioremap_bar(pci, 0);
 	if (mem == NULL) {
 		kfree(chip);
 		pci_disable_device(pci);
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 9b77b3e0fa98..3ecd7e797dee 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -37,6 +37,9 @@ static void snd_hda_generate_beep(struct work_struct *work)
 		container_of(work, struct hda_beep, beep_work);
 	struct hda_codec *codec = beep->codec;
 
+	if (!beep->enabled)
+		return;
+
 	/* generate tone */
 	snd_hda_codec_write_cache(codec, beep->nid, 0,
 			AC_VERB_SET_BEEP_CONTROL, beep->tone);
@@ -85,6 +88,10 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
 	snprintf(beep->phys, sizeof(beep->phys),
 		"card%d/codec#%d/beep0", codec->bus->card->number, codec->addr);
 	input_dev = input_allocate_device();
+	if (!input_dev) {
+		kfree(beep);
+		return -ENOMEM;
+	}
 
 	/* setup digital beep device */
 	input_dev->name = "HDA Digital PCBeep";
@@ -115,6 +122,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
 	beep->nid = nid;
 	beep->dev = input_dev;
 	beep->codec = codec;
+	beep->enabled = 1;
 	codec->beep = beep;
 
 	INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index de4036e6e710..b9679f081cae 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -31,6 +31,7 @@ struct hda_beep {
 	char phys[32];
 	int tone;
 	int nid;
+	int enabled;
 	struct work_struct beep_work; /* scheduled task for beep event */
 };
 
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 6447754ae56e..ba1ab737b55f 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -64,6 +64,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
 	{ 0x14f1, "Conexant" },
 	{ 0x17e8, "Chrontel" },
 	{ 0x1854, "LG" },
+	{ 0x1aec, "Wolfson Microelectronics" },
 	{ 0x434d, "C-Media" },
 	{ 0x8384, "SigmaTel" },
 	{} /* terminator */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 9f316c1b2790..35722ec920cb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -45,6 +45,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/mutex.h>
+#include <linux/reboot.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "hda_codec.h"
@@ -397,6 +398,9 @@ struct azx {
 
 	/* for pending irqs */
 	struct work_struct irq_pending_work;
+
+	/* reboot notifier (for mysterious hangup problem at power-down) */
+	struct notifier_block reboot_notifier;
 };
 
 /* driver types */
@@ -1979,12 +1983,36 @@ static int azx_resume(struct pci_dev *pci)
 
 
 /*
+ * reboot notifier for hang-up problem at power-down
+ */
+static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
+{
+	struct azx *chip = container_of(nb, struct azx, reboot_notifier);
+	azx_stop_chip(chip);
+	return NOTIFY_OK;
+}
+
+static void azx_notifier_register(struct azx *chip)
+{
+	chip->reboot_notifier.notifier_call = azx_halt;
+	register_reboot_notifier(&chip->reboot_notifier);
+}
+
+static void azx_notifier_unregister(struct azx *chip)
+{
+	if (chip->reboot_notifier.notifier_call)
+		unregister_reboot_notifier(&chip->reboot_notifier);
+}
+
+/*
  * destructor
  */
 static int azx_free(struct azx *chip)
 {
 	int i;
 
+	azx_notifier_unregister(chip);
+
 	if (chip->initialized) {
 		azx_clear_irq_pending(chip);
 		for (i = 0; i < chip->num_streams; i++)
@@ -2158,7 +2186,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 	}
 
 	chip->addr = pci_resource_start(pci, 0);
-	chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0));
+	chip->remap_addr = pci_ioremap_bar(pci, 0);
 	if (chip->remap_addr == NULL) {
 		snd_printk(KERN_ERR SFX "ioremap error\n");
 		err = -ENXIO;
@@ -2348,6 +2376,7 @@ static int __devinit azx_probe(struct pci_dev *pci,
 	pci_set_drvdata(pci, card);
 	chip->running = 1;
 	power_down_all_codecs(chip);
+	azx_notifier_register(chip);
 
 	dev++;
 	return err;
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 743d77922bce..c39af986bff1 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -483,6 +483,8 @@ static void print_gpio(struct snd_info_buffer *buffer,
 		    (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
 		    (gpio & AC_GPIO_WAKE) ? 1 : 0);
 	max = gpio & AC_GPIO_IO_COUNT;
+	if (!max || max > 8)
+		return;
 	enable = snd_hda_codec_read(codec, nid, 0,
 				    AC_VERB_GET_GPIO_MASK, 0);
 	direction = snd_hda_codec_read(codec, nid, 0,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 2b00c4afdf97..686c77491dea 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3860,6 +3860,9 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
 
 static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
+	SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
+	SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
+	SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
 	SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
 	{}
 };
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 1a65775d28e1..2eed2c8b98da 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -116,6 +116,7 @@ static int nvhdmi_build_pcms(struct hda_codec *codec)
 	codec->pcm_info = info;
 
 	info->name = "NVIDIA HDMI";
+	info->pcm_type = HDA_PCM_TYPE_HDMI;
 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback;
 
 	return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e72707cb60a3..a378c0145125 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -307,6 +307,13 @@ struct alc_spec {
 	/* for PLL fix */
 	hda_nid_t pll_nid;
 	unsigned int pll_coef_idx, pll_coef_bit;
+
+#ifdef SND_HDA_NEEDS_RESUME
+#define ALC_MAX_PINS	16
+	unsigned int num_pins;
+	hda_nid_t pin_nids[ALC_MAX_PINS];
+	unsigned int pin_cfgs[ALC_MAX_PINS];
+#endif
 };
 
 /*
@@ -822,6 +829,7 @@ static void alc_sku_automute(struct hda_codec *codec)
 			    spec->jack_present ? 0 : PIN_OUT);
 }
 
+#if 0 /* it's broken in some acses -- temporarily disabled */
 static void alc_mic_automute(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
@@ -842,6 +850,9 @@ static void alc_mic_automute(struct hda_codec *codec)
 	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
 			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 }
+#else
+#define alc_mic_automute(codec) /* NOP */
+#endif /* disabled */
 
 /* unsolicited event for HP jack sensing */
 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1051,12 +1062,14 @@ do_sku:
 			AC_VERB_SET_UNSOLICITED_ENABLE,
 			AC_USRSP_EN | ALC880_HP_EVENT);
 
+#if 0 /* it's broken in some acses -- temporarily disabled */
 	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
 		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
 		snd_hda_codec_write(codec,
 			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
 			AC_VERB_SET_UNSOLICITED_ENABLE,
 			AC_USRSP_EN | ALC880_MIC_EVENT);
+#endif /* disabled */
 
 	spec->unsol_event = alc_sku_unsol_event;
 }
@@ -2778,6 +2791,64 @@ static void alc_free(struct hda_codec *codec)
 	codec->spec = NULL; /* to be sure */
 }
 
+#ifdef SND_HDA_NEEDS_RESUME
+static void store_pin_configs(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t nid, end_nid;
+
+	end_nid = codec->start_nid + codec->num_nodes;
+	for (nid = codec->start_nid; nid < end_nid; nid++) {
+		unsigned int wid_caps = get_wcaps(codec, nid);
+		unsigned int wid_type =
+			(wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		if (wid_type != AC_WID_PIN)
+			continue;
+		if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
+			break;
+		spec->pin_nids[spec->num_pins] = nid;
+		spec->pin_cfgs[spec->num_pins] =
+			snd_hda_codec_read(codec, nid, 0,
+					   AC_VERB_GET_CONFIG_DEFAULT, 0);
+		spec->num_pins++;
+	}
+}
+
+static void resume_pin_configs(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->num_pins; i++) {
+		hda_nid_t pin_nid = spec->pin_nids[i];
+		unsigned int pin_config = spec->pin_cfgs[i];
+		snd_hda_codec_write(codec, pin_nid, 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
+				    pin_config & 0x000000ff);
+		snd_hda_codec_write(codec, pin_nid, 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
+				    (pin_config & 0x0000ff00) >> 8);
+		snd_hda_codec_write(codec, pin_nid, 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
+				    (pin_config & 0x00ff0000) >> 16);
+		snd_hda_codec_write(codec, pin_nid, 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
+				    pin_config >> 24);
+	}
+}
+
+static int alc_resume(struct hda_codec *codec)
+{
+	resume_pin_configs(codec);
+	codec->patch_ops.init(codec);
+	snd_hda_codec_resume_amp(codec);
+	snd_hda_codec_resume_cache(codec);
+	return 0;
+}
+#else
+#define store_pin_configs(codec)
+#endif
+
 /*
  */
 static struct hda_codec_ops alc_patch_ops = {
@@ -2786,6 +2857,9 @@ static struct hda_codec_ops alc_patch_ops = {
 	.init = alc_init,
 	.free = alc_free,
 	.unsol_event = alc_unsol_event,
+#ifdef SND_HDA_NEEDS_RESUME
+	.resume = alc_resume,
+#endif
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	.check_power_status = alc_check_power_status,
 #endif
@@ -3832,6 +3906,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
 	spec->num_mux_defs = 1;
 	spec->input_mux = &spec->private_imux;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -4996,7 +5071,7 @@ static struct hda_verb alc260_test_init_verbs[] = {
  */
 
 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
-					const char *pfx)
+					const char *pfx, int *vol_bits)
 {
 	hda_nid_t nid_vol;
 	unsigned long vol_val, sw_val;
@@ -5018,10 +5093,14 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
 	} else
 		return 0; /* N/A */
 
-	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
-	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
-	if (err < 0)
-		return err;
+	if (!(*vol_bits & (1 << nid_vol))) {
+		/* first control for the volume widget */
+		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
+		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
+		if (err < 0)
+			return err;
+		*vol_bits |= (1 << nid_vol);
+	}
 	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
 	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
 	if (err < 0)
@@ -5035,6 +5114,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 {
 	hda_nid_t nid;
 	int err;
+	int vols = 0;
 
 	spec->multiout.num_dacs = 1;
 	spec->multiout.dac_nids = spec->private_dac_nids;
@@ -5042,21 +5122,22 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 
 	nid = cfg->line_out_pins[0];
 	if (nid) {
-		err = alc260_add_playback_controls(spec, nid, "Front");
+		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
 		if (err < 0)
 			return err;
 	}
 
 	nid = cfg->speaker_pins[0];
 	if (nid) {
-		err = alc260_add_playback_controls(spec, nid, "Speaker");
+		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
 		if (err < 0)
 			return err;
 	}
 
 	nid = cfg->hp_pins[0];
 	if (nid) {
-		err = alc260_add_playback_controls(spec, nid, "Headphone");
+		err = alc260_add_playback_controls(spec, nid, "Headphone",
+						   &vols);
 		if (err < 0)
 			return err;
 	}
@@ -5244,6 +5325,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
 	}
 	spec->num_mixers++;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -8332,6 +8414,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
 static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
+	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
 	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
 	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
 	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
@@ -8386,6 +8469,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
 	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
 	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
+	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
 	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
 	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
@@ -10307,6 +10391,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -11441,6 +11526,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -12160,8 +12246,26 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
 	return 0;
 }
 
-#define alc269_auto_create_analog_input_ctls \
-	alc880_auto_create_analog_input_ctls
+static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
+						const struct auto_pin_cfg *cfg)
+{
+	int err;
+
+	err = alc880_auto_create_analog_input_ctls(spec, cfg);
+	if (err < 0)
+		return err;
+	/* digital-mic input pin is excluded in alc880_auto_create..()
+	 * because it's under 0x18
+	 */
+	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
+	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
+		struct hda_input_mux *imux = &spec->private_imux;
+		imux->items[imux->num_items].label = "Int Mic";
+		imux->items[imux->num_items].index = 0x05;
+		imux->num_items++;
+	}
+	return 0;
+}
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #define alc269_loopbacks	alc880_loopbacks
@@ -12224,6 +12328,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
 	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
 	spec->num_mixers++;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -13310,6 +13415,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
 	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
 	spec->num_mixers++;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -14421,6 +14527,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	store_pin_configs(codec);
 	return 1;
 }
 
@@ -16252,6 +16359,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
 
 	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
 	spec->num_mixers++;
+
+	store_pin_configs(codec);
 	return 1;
 }
 
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index a2ac7205d45d..9563b5bbb272 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -36,9 +36,11 @@
 #include "hda_beep.h"
 
 #define NUM_CONTROL_ALLOC	32
+
+#define STAC_VREF_EVENT		0x00
+#define STAC_INSERT_EVENT	0x10
 #define STAC_PWR_EVENT		0x20
 #define STAC_HP_EVENT		0x30
-#define STAC_VREF_EVENT		0x40
 
 enum {
 	STAC_REF,
@@ -69,6 +71,7 @@ enum {
 enum {
 	STAC_92HD73XX_REF,
 	STAC_DELL_M6,
+	STAC_DELL_EQ,
 	STAC_92HD73XX_MODELS
 };
 
@@ -211,7 +214,7 @@ struct sigmatel_spec {
 	/* i/o switches */
 	unsigned int io_switch[2];
 	unsigned int clfe_swap;
-	unsigned int hp_switch;
+	unsigned int hp_switch; /* NID of HP as line-out */
 	unsigned int aloopback;
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
@@ -566,10 +569,8 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
 			nid = codec->slave_dig_outs[smux_idx - 1];
 		if (spec->cur_smux[smux_idx] == smux->num_items - 1)
 			val = AMP_OUT_MUTE;
-		if (smux_idx == 0)
-			nid = spec->multiout.dig_out_nid;
 		else
-			nid = codec->slave_dig_outs[smux_idx - 1];
+			val = AMP_OUT_UNMUTE;
 		/* un/mute SPDIF out */
 		snd_hda_codec_write_cache(codec, nid, 0,
 			AC_VERB_SET_AMP_GAIN_MUTE, val);
@@ -775,9 +776,7 @@ static struct hda_verb dell_eq_core_init[] = {
 };
 
 static struct hda_verb dell_m6_core_init[] = {
-	/* set master volume to max value without distortion
-	 * and direct control */
-	{ 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
+	{ 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
 	/* setup audio connections */
 	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
 	{ 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -1282,7 +1281,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
 			return err;
 		spec->multiout.share_spdif = 1;
 	}
-	if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) {
+	if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) {
 		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
 		if (err < 0)
 			return err;
@@ -1602,11 +1601,13 @@ static unsigned int dell_m6_pin_configs[13] = {
 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
 	[STAC_92HD73XX_REF]	= ref92hd73xx_pin_configs,
 	[STAC_DELL_M6]	= dell_m6_pin_configs,
+	[STAC_DELL_EQ]	= dell_m6_pin_configs,
 };
 
 static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
 	[STAC_92HD73XX_REF] = "ref",
 	[STAC_DELL_M6] = "dell-m6",
+	[STAC_DELL_EQ] = "dell-eq",
 };
 
 static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
@@ -1687,6 +1688,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
 	/* SigmaTel reference board */
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
 		      "DFI LanParty", STAC_92HD71BXX_REF),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
+		      "HP dv5", STAC_HP_M4),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
+		      "HP dv7", STAC_HP_M4),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
 				"unknown HP", STAC_HP_M4),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2444,7 +2449,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
 
-	ucontrol->value.integer.value[0] = spec->hp_switch;
+	ucontrol->value.integer.value[0] = !!spec->hp_switch;
 	return 0;
 }
 
@@ -2453,8 +2458,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
-
-	spec->hp_switch = ucontrol->value.integer.value[0];
+	int nid = kcontrol->private_value;
+ 
+	spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;
 
 	/* check to be sure that the ports are upto date with
 	 * switch changes
@@ -2587,8 +2593,10 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
 };
 
 /* add dynamic controls */
-static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
-		int idx, const char *name, unsigned long val)
+static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
+				     struct snd_kcontrol_new *ktemp,
+				     int idx, const char *name,
+				     unsigned long val)
 {
 	struct snd_kcontrol_new *knew;
 
@@ -2607,20 +2615,29 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
 	}
 
 	knew = &spec->kctl_alloc[spec->num_kctl_used];
-	*knew = stac92xx_control_templates[type];
+	*knew = *ktemp;
 	knew->index = idx;
 	knew->name = kstrdup(name, GFP_KERNEL);
-	if (! knew->name)
+	if (!knew->name)
 		return -ENOMEM;
 	knew->private_value = val;
 	spec->num_kctl_used++;
 	return 0;
 }
 
+static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
+					   int type, int idx, const char *name,
+					   unsigned long val)
+{
+	return stac92xx_add_control_temp(spec,
+					 &stac92xx_control_templates[type],
+					 idx, name, val);
+}
+
 
 /* add dynamic controls */
-static int stac92xx_add_control(struct sigmatel_spec *spec, int type,
-		const char *name, unsigned long val)
+static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
+				       const char *name, unsigned long val)
 {
 	return stac92xx_add_control_idx(spec, type, 0, name, val);
 }
@@ -2863,7 +2880,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
 	if (cfg->hp_outs > 1) {
 		err = stac92xx_add_control(spec,
 			STAC_CTL_WIDGET_HP_SWITCH,
-			"Headphone as Line Out Switch", 0);
+			"Headphone as Line Out Switch",
+			cfg->hp_pins[cfg->hp_outs - 1]);
 		if (err < 0)
 			return err;
 	}
@@ -3061,6 +3079,43 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
 	return 0;
 }
 
+#ifdef CONFIG_SND_HDA_INPUT_BEEP
+#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
+
+static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = codec->beep->enabled;
+	return 0;
+}
+
+static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	int enabled = !!ucontrol->value.integer.value[0];
+	if (codec->beep->enabled != enabled) {
+		codec->beep->enabled = enabled;
+		return 1;
+	}
+	return 0;
+}
+
+static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.info = stac92xx_dig_beep_switch_info,
+	.get = stac92xx_dig_beep_switch_get,
+	.put = stac92xx_dig_beep_switch_put,
+};
+
+static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
+{
+	return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
+					 0, "PC Beep Playback Switch", 0);
+}
+#endif
+
 static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
@@ -3367,6 +3422,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
 	if (spec->digbeep_nid > 0) {
 		hda_nid_t nid = spec->digbeep_nid;
+		unsigned int caps;
 
 		err = stac92xx_auto_create_beep_ctls(codec, nid);
 		if (err < 0)
@@ -3374,6 +3430,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
 		err = snd_hda_attach_beep_device(codec, nid);
 		if (err < 0)
 			return err;
+		/* if no beep switch is available, make its own one */
+		caps = query_amp_caps(codec, nid, HDA_OUTPUT);
+		if (codec->beep &&
+		    !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) {
+			err = stac92xx_beep_switch_ctl(codec);
+			if (err < 0)
+				return err;
+		}
 	}
 #endif
 
@@ -3531,6 +3595,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
 	if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
 		return err;
 
+	if (spec->num_muxes > 0) {
+		err = stac92xx_auto_create_mux_input_ctls(codec);
+		if (err < 0)
+			return err;
+	}
+
 	if (spec->autocfg.dig_out_pin)
 		spec->multiout.dig_out_nid = 0x05;
 	if (spec->autocfg.dig_in_pin)
@@ -3648,14 +3718,18 @@ static int stac92xx_init(struct hda_codec *codec)
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		hda_nid_t nid = cfg->input_pins[i];
 		if (nid) {
-			unsigned int pinctl = snd_hda_codec_read(codec, nid,
-				0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-			/* if PINCTL already set then skip */
-			if (pinctl & AC_PINCAP_IN)
-				continue;
-			pinctl = AC_PINCTL_IN_EN;
-			if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
-				pinctl |= stac92xx_get_vref(codec, nid);
+			unsigned int pinctl;
+			if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
+				/* for mic pins, force to initialize */
+				pinctl = stac92xx_get_vref(codec, nid);
+			} else {
+				pinctl = snd_hda_codec_read(codec, nid, 0,
+					AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+				/* if PINCTL already set then skip */
+				if (pinctl & AC_PINCTL_IN_EN)
+					continue;
+			}
+			pinctl |= AC_PINCTL_IN_EN;
 			stac92xx_auto_set_pinctl(codec, nid, pinctl);
 		}
 	}
@@ -3777,11 +3851,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
 	return 0;
 }
 
+/* return non-zero if the hp-pin of the given array index isn't
+ * a jack-detection target
+ */
+static int no_hp_sensing(struct sigmatel_spec *spec, int i)
+{
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+
+	/* ignore sensing of shared line and mic jacks */
+	if (spec->line_switch &&
+	    cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
+		return 1;
+	if (spec->mic_switch &&
+	    cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
+		return 1;
+	/* ignore if the pin is set as line-out */
+	if (cfg->hp_pins[i] == spec->hp_switch)
+		return 1;
+	return 0;
+}
+
 static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
-	int nid = cfg->hp_pins[cfg->hp_outs - 1];
 	int i, presence;
 
 	presence = 0;
@@ -3792,15 +3885,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 	for (i = 0; i < cfg->hp_outs; i++) {
 		if (presence)
 			break;
-		if (spec->hp_switch && cfg->hp_pins[i] == nid)
-			break;
+		if (no_hp_sensing(spec, i))
+			continue;
 		presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
 	}
 
 	if (presence) {
-		/* disable lineouts, enable hp */
+		/* disable lineouts */
 		if (spec->hp_switch)
-			stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+			stac92xx_reset_pinctl(codec, spec->hp_switch,
+					      AC_PINCTL_OUT_EN);
 		for (i = 0; i < cfg->line_outs; i++)
 			stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
 						AC_PINCTL_OUT_EN);
@@ -3812,9 +3906,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 				spec->gpio_dir, spec->gpio_data &
 				~spec->eapd_mask);
 	} else {
-		/* enable lineouts, disable hp */
+		/* enable lineouts */
 		if (spec->hp_switch)
-			stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+			stac92xx_set_pinctl(codec, spec->hp_switch,
+					    AC_PINCTL_OUT_EN);
 		for (i = 0; i < cfg->line_outs; i++)
 			stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
 						AC_PINCTL_OUT_EN);
@@ -3826,8 +3921,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
 				spec->gpio_dir, spec->gpio_data |
 				spec->eapd_mask);
 	}
-	if (!spec->hp_switch && cfg->hp_outs > 1 && presence)
-		stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+	/* toggle hp outs */
+	for (i = 0; i < cfg->hp_outs; i++) {
+		unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
+		if (no_hp_sensing(spec, i))
+			continue;
+		if (presence)
+			stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
+		else
+			stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
+	}
 } 
 
 static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
@@ -4133,12 +4236,17 @@ again:
 			sizeof(stac92hd73xx_dmux));
 
 	switch (spec->board_config) {
-	case STAC_DELL_M6:
+	case STAC_DELL_EQ:
 		spec->init = dell_eq_core_init;
+		/* fallthru */
+	case STAC_DELL_M6:
 		spec->num_smuxes = 0;
 		spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
 		spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
 		spec->num_amps = 1;
+
+		if (!spec->init)
+			spec->init = dell_m6_core_init;
 		switch (codec->subsystem_id) {
 		case 0x1028025e: /* Analog Mics */
 		case 0x1028025f:
@@ -4148,8 +4256,6 @@ again:
 			break;
 		case 0x10280271: /* Digital Mics */
 		case 0x10280272:
-			spec->init = dell_m6_core_init;
-			/* fall-through */
 		case 0x10280254:
 		case 0x10280255:
 			stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
@@ -4376,6 +4482,13 @@ again:
 		stac92xx_set_config_regs(codec);
 	}
 
+	if (spec->board_config > STAC_92HD71BXX_REF) {
+		/* GPIO0 = EAPD */
+		spec->gpio_mask = 0x01;
+		spec->gpio_dir = 0x01;
+		spec->gpio_data = 0x01;
+	}
+
 	switch (codec->vendor_id) {
 	case 0x111d76b6: /* 4 Port without Analog Mixer */
 	case 0x111d76b7:
@@ -4386,10 +4499,10 @@ again:
 		codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
 		break;
 	case 0x111d7608: /* 5 Port with Analog Mixer */
-		switch (codec->subsystem_id) {
-		case 0x103c361a:
+		switch (spec->board_config) {
+		case STAC_HP_M4:
 			/* Enable VREF power saving on GPIO1 detect */
-			snd_hda_codec_write(codec, codec->afg, 0,
+			snd_hda_codec_write_cache(codec, codec->afg, 0,
 				AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
 			snd_hda_codec_write_cache(codec, codec->afg, 0,
 					AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -4435,13 +4548,6 @@ again:
 	spec->aloopback_mask = 0x50;
 	spec->aloopback_shift = 0;
 
-	if (spec->board_config > STAC_92HD71BXX_REF) {
-		/* GPIO0 = EAPD */
-		spec->gpio_mask = 0x01;
-		spec->gpio_dir = 0x01;
-		spec->gpio_data = 0x01;
-	}
-
 	spec->powerdown_adcs = 1;
 	spec->digbeep_nid = 0x26;
 	spec->mux_nids = stac92hd71bxx_mux_nids;
@@ -4789,7 +4895,7 @@ static int patch_stac9205(struct hda_codec *codec)
 		stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
 
 		/* Enable unsol response for GPIO4/Dock HP connection */
-		snd_hda_codec_write(codec, codec->afg, 0,
+		snd_hda_codec_write_cache(codec, codec->afg, 0,
 			AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
 		snd_hda_codec_write_cache(codec, codec->afg, 0,
 					  AC_VERB_SET_UNSOLICITED_ENABLE,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index fd9a117f37a4..f23a73577c22 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1315,8 +1315,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
 	}
 	for (i = 0; i < 2; i++) {
 		mgr->mem[i].phys = pci_resource_start(pci, i);
-		mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys,
-						   pci_resource_len(pci, i));
+		mgr->mem[i].virt = pci_ioremap_bar(pci, i);
 		if (!mgr->mem[i].virt) {
 		        printk(KERN_ERR "unable to remap resource 0x%lx\n",
 			       mgr->mem[i].phys);
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 58621206a2b3..7d2b136295d5 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1230,8 +1230,11 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
 		return -ENOMEM;
 	}
 
-	if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST))
+	if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) {
+		kfree(mgr);
+		pci_disable_device(pci);
 		return -ENODEV;
+	}
 	card_name = pcxhr_board_params[pci_id->driver_data].board_name;
 	mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips;
 	mgr->capture_chips  = pcxhr_board_params[pci_id->driver_data].capture_chips;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d723543beadd..736246f98acc 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -4548,11 +4548,20 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
 {
 	struct hdsp *hdsp = (struct hdsp *)hw->private_data;	
 	void __user *argp = (void __user *)arg;
+	int err;
 
 	switch (cmd) {
 	case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
 		struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg;
 
+		err = hdsp_check_for_iobox(hdsp);
+		if (err < 0)
+			return err;
+
+		err = hdsp_check_for_firmware(hdsp, 1);
+		if (err < 0)
+			return err;
+
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
 			snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
 			return -EINVAL;
@@ -4572,10 +4581,14 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
 		unsigned long flags;
 		int i;
 		
-		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
-			snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n");	
-			return -EINVAL;
-		}
+		err = hdsp_check_for_iobox(hdsp);
+		if (err < 0)
+			return err;
+
+		err = hdsp_check_for_firmware(hdsp, 1);
+		if (err < 0)
+			return err;
+
 		spin_lock_irqsave(&hdsp->lock, flags);
 		info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
 		info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
@@ -5045,6 +5058,10 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
 		/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
 		ssleep(2);
 
+		err = hdsp_check_for_iobox(hdsp);
+		if (err < 0)
+			return err;
+
 		if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 #ifdef HDSP_FW_LOADER
 			if ((err = hdsp_request_fw_loader(hdsp)) < 0)
@@ -5057,7 +5074,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
 				/* init is complete, we return */
 				return 0;
 #endif
-			/* no iobox connected, we defer initialization */
+			/* we defer initialization */
 			snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
 			if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
 				return err;
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 20d0e328288a..8f9e3859c37c 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -666,6 +666,7 @@ static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
 	card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
 	card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
 	card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
+	memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8);
 
 	ret = snd_ps3_change_avsetting(card);
 
@@ -685,6 +686,7 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
 {
 	struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
 	struct snd_ps3_avsetting_info avs;
+	int ret;
 
 	avs = card->avs;
 
@@ -729,19 +731,92 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
 		return 1;
 	}
 
-	if ((card->avs.avs_audio_width != avs.avs_audio_width) ||
-	    (card->avs.avs_audio_rate != avs.avs_audio_rate)) {
-		card->avs = avs;
-		snd_ps3_change_avsetting(card);
+	memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8);
 
+	if (memcmp(&card->avs, &avs, sizeof(avs))) {
 		pr_debug("%s: after freq=%d width=%d\n", __func__,
 			 card->avs.avs_audio_rate, card->avs.avs_audio_width);
 
-		return 0;
+		card->avs = avs;
+		snd_ps3_change_avsetting(card);
+		ret = 0;
 	} else
+		ret = 1;
+
+	/* check CS non-audio bit and mute accordingly */
+	if (avs.avs_cs_info[0] & 0x02)
+		ps3av_audio_mute_analog(1); /* mute if non-audio */
+	else
+		ps3av_audio_mute_analog(0);
+
+	return ret;
+}
+
+/*
+ * SPDIF status bits controls
+ */
+static int snd_ps3_spdif_mask_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+/* FIXME: ps3av_set_audio_mode() assumes only consumer mode */
+static int snd_ps3_spdif_cmask_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	memset(ucontrol->value.iec958.status, 0xff, 8);
+	return 0;
+}
+
+static int snd_ps3_spdif_pmask_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
+{
+	return 0;
+}
+
+static int snd_ps3_spdif_default_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	memcpy(ucontrol->value.iec958.status, ps3av_mode_cs_info, 8);
+	return 0;
+}
+
+static int snd_ps3_spdif_default_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	if (memcmp(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8)) {
+		memcpy(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8);
 		return 1;
+	}
+	return 0;
 }
 
+static struct snd_kcontrol_new spdif_ctls[] = {
+	{
+		.access = SNDRV_CTL_ELEM_ACCESS_READ,
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+		.info = snd_ps3_spdif_mask_info,
+		.get = snd_ps3_spdif_cmask_get,
+	},
+	{
+		.access = SNDRV_CTL_ELEM_ACCESS_READ,
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+		.info = snd_ps3_spdif_mask_info,
+		.get = snd_ps3_spdif_pmask_get,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+		.info = snd_ps3_spdif_mask_info,
+		.get = snd_ps3_spdif_default_get,
+		.put = snd_ps3_spdif_default_put,
+	},
+};
 
 
 static int snd_ps3_map_mmio(void)
@@ -842,7 +917,7 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
 
 static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
 {
-	int ret;
+	int i, ret;
 	u64 lpar_addr, lpar_size;
 
 	BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1));
@@ -903,6 +978,15 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
 	strcpy(the_card.card->driver, "PS3");
 	strcpy(the_card.card->shortname, "PS3");
 	strcpy(the_card.card->longname, "PS3 sound");
+
+	/* create control elements */
+	for (i = 0; i < ARRAY_SIZE(spdif_ctls); i++) {
+		ret = snd_ctl_add(the_card.card,
+				  snd_ctl_new1(&spdif_ctls[i], &the_card));
+		if (ret < 0)
+			goto clean_card;
+	}
+
 	/* create PCM devices instance */
 	/* NOTE:this driver works assuming pcm:substream = 1:1 */
 	ret = snd_pcm_new(the_card.card,
diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h
index 4b7e6fbbe500..326fb29e82d8 100644
--- a/sound/ppc/snd_ps3.h
+++ b/sound/ppc/snd_ps3.h
@@ -51,6 +51,7 @@ struct snd_ps3_avsetting_info {
 	uint32_t avs_audio_width;
 	uint32_t avs_audio_format; /* fixed */
 	uint32_t avs_audio_source; /* fixed */
+	unsigned char avs_cs_info[8];
 };
 /*
  * PS3 audio 'card' instance
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c
index 98a2d5826a85..b1966e4dfcd3 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/at32/playpaq_wm8510.c
@@ -304,7 +304,7 @@ static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = {
 
 
 
-static const char *intercon[][3] = {
+static const struct snd_soc_dapm_route intercon[] = {
 	/* speaker connected to SPKOUT */
 	{"Ext Spk", NULL, "SPKOUTP"},
 	{"Ext Spk", NULL, "SPKOUTN"},
@@ -312,9 +312,6 @@ static const char *intercon[][3] = {
 	{"Mic Bias", NULL, "Int Mic"},
 	{"MICN", NULL, "Mic Bias"},
 	{"MICP", NULL, "Mic Bias"},
-
-	/* Terminator */
-	{NULL, NULL, NULL},
 };
 
 
@@ -334,11 +331,8 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
 	/*
 	 * Setup audio path interconnects
 	 */
-	for (i = 0; intercon[i][0] != NULL; i++) {
-		snd_soc_dapm_connect_input(codec,
-					   intercon[i][0],
-					   intercon[i][1], intercon[i][2]);
-	}
+	snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
 
 
 	/* always connected pins */
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 827587f08180..e020c160ee44 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -70,12 +70,24 @@ static struct sport_param sport_params[2] = {
 	}
 };
 
-static u16 sport_req[][7] = {
-		{ P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
-		  P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
-		{ P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
-		  P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
-};
+/*
+ * Setting the TFS pin selector for SPORT 0 based on whether the selected
+ * port id F or G. If the port is F then no conflict should exist for the
+ * TFS. When Port G is selected and EMAC then there is a conflict between
+ * the PHY interrupt line and TFS.  Current settings prevent the conflict
+ * by ignoring the TFS pin when Port G is selected. This allows both
+ * ssm2602 using Port G and EMAC concurrently.
+ */
+#ifdef CONFIG_BF527_SPORT0_PORTF
+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
+#else
+#define LOCAL_SPORT0_TFS (0)
+#endif
+
+static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+		P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
+		{P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
+		P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
 
 static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		unsigned int fmt)
@@ -98,23 +110,21 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 		ret = -EINVAL;
 		break;
 	default:
+		printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
 		ret = -EINVAL;
 		break;
 	}
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-	case SND_SOC_DAIFMT_CBS_CFS:
-		ret = -EINVAL;
-		break;
-	case SND_SOC_DAIFMT_CBM_CFS:
-		ret = -EINVAL;
-		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
 		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+	case SND_SOC_DAIFMT_CBM_CFS:
 	case SND_SOC_DAIFMT_CBS_CFM:
 		ret = -EINVAL;
 		break;
 	default:
+		printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
 		ret = -EINVAL;
 		break;
 	}
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 05336ed7e493..cff276ee261e 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -863,17 +863,21 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 	}
 
-	/* interface format */
-	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-	case SND_SOC_DAIFMT_I2S:
+	/*
+	 * match both interface format and signal polarities since they
+	 * are fixed
+	 */
+	switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
+		       SND_SOC_DAIFMT_INV_MASK)) {
+	case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
 		break;
-	case SND_SOC_DAIFMT_DSP_A:
+	case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
 		iface_breg |= (0x01 << 6);
 		break;
-	case SND_SOC_DAIFMT_RIGHT_J:
+	case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
 		iface_breg |= (0x02 << 6);
 		break;
-	case SND_SOC_DAIFMT_LEFT_J:
+	case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
 		iface_breg |= (0x03 << 6);
 		break;
 	default:
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index aba402b3c999..945b32ed9884 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -140,7 +140,7 @@ SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
 
 SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
 SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
-SOC_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
+SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
 SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
 SOC_ENUM("ALC Function", wm9713_enum[6]),
 SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 86923299bc10..94a02eaa4825 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -277,7 +277,7 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
 	u16 imr;
 	u8 psc_cmd;
-	long flags;
+	unsigned long flags;
 
 	if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
 		s = &psc_i2s->capture;
@@ -699,9 +699,11 @@ static ssize_t psc_i2s_stat_store(struct device *dev,
 	return count;
 }
 
-DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL);
-DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
-DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store);
+static DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL);
+static DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show,
+			psc_i2s_stat_store);
+static DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show,
+			psc_i2s_stat_store);
 
 /* ---------------------------------------------------------------------
  * OF platform bus binding code:
@@ -819,8 +821,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
 
 	/* Register the SYSFS files */
 	rc = device_create_file(psc_i2s->dev, &dev_attr_status);
-	rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun);
-	rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun);
+	rc |= device_create_file(psc_i2s->dev, &dev_attr_capture_overrun);
+	rc |= device_create_file(psc_i2s->dev, &dev_attr_playback_underrun);
 	if (rc)
 		dev_info(psc_i2s->dev, "error creating sysfs files\n");
 
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 0a063a98a661..8485a8a9d0ff 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -43,6 +43,7 @@
 struct omap_mcbsp_data {
 	unsigned int			bus_id;
 	struct omap_mcbsp_reg_cfg	regs;
+	unsigned int			fmt;
 	/*
 	 * Flags indicating is the bus already activated and configured by
 	 * another substream
@@ -200,6 +201,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
 	struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
 	struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
 	int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
+	int wlen;
 	unsigned long port;
 
 	if (cpu_class_is_omap1()) {
@@ -244,19 +246,29 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 		/* Set word lengths */
+		wlen = 16;
 		regs->rcr2	|= RWDLEN2(OMAP_MCBSP_WORD_16);
 		regs->rcr1	|= RWDLEN1(OMAP_MCBSP_WORD_16);
 		regs->xcr2	|= XWDLEN2(OMAP_MCBSP_WORD_16);
 		regs->xcr1	|= XWDLEN1(OMAP_MCBSP_WORD_16);
-		/* Set FS period and length in terms of bit clock periods */
-		regs->srgr2	|= FPER(16 * 2 - 1);
-		regs->srgr1	|= FWID(16 - 1);
 		break;
 	default:
 		/* Unsupported PCM format */
 		return -EINVAL;
 	}
 
+	/* Set FS period and length in terms of bit clock periods */
+	switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		regs->srgr2	|= FPER(wlen * 2 - 1);
+		regs->srgr1	|= FWID(wlen - 1);
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+		regs->srgr2	|= FPER(wlen * 2 - 1);
+		regs->srgr1	|= FWID(wlen * 2 - 2);
+		break;
+	}
+
 	omap_mcbsp_config(bus_id, &mcbsp_data->regs);
 	mcbsp_data->configured = 1;
 
@@ -276,6 +288,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
 	if (mcbsp_data->configured)
 		return 0;
 
+	mcbsp_data->fmt = fmt;
 	memset(regs, 0, sizeof(*regs));
 	/* Generic McBSP register settings */
 	regs->spcr2	|= XINTM(3) | FREE;
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index dd7fa0b329c7..2718eaf7895f 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -18,13 +18,13 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/scoop.h>
 #include <mach/pxa-regs.h>
 #include <mach/hardware.h>
 #include <mach/corgi.h>
@@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
 	switch (corgi_jack_func) {
 	case CORGI_HP:
 		/* set = unmute headphone */
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headphone Jack");
@@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
 		break;
 	case CORGI_MIC:
 		/* reset = mute headphone */
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 0);
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		break;
 	case CORGI_LINE:
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 0);
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_enable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		break;
 	case CORGI_HEADSET:
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+		gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+		gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
@@ -114,8 +114,8 @@ static int corgi_shutdown(struct snd_pcm_substream *substream)
 	struct snd_soc_codec *codec = rtd->socdev->codec;
 
 	/* set = unmute headphone */
-	set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-	set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+	gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+	gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 	return 0;
 }
 
@@ -218,22 +218,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
 static int corgi_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-
+	gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
 static int corgi_mic_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-	else
-		reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-
+	gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
 	return 0;
 }
 
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index a80ae074b090..a7a3a9c5c6ff 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -49,7 +49,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
 	.name			= "AC97 PCM Stereo out",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRTXPCDR,
+	.drcmr			= &DRCMR(12),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -57,7 +57,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
 	.name			= "AC97 PCM Stereo in",
 	.dev_addr		= __PREG(PCDR),
-	.drcmr			= &DRCMRRXPCDR,
+	.drcmr			= &DRCMR(11),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -65,7 +65,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
 	.name			= "AC97 Aux PCM (Slot 5) Mono out",
 	.dev_addr		= __PREG(MODR),
-	.drcmr			= &DRCMRTXMODR,
+	.drcmr			= &DRCMR(10),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
@@ -73,7 +73,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
 	.name			= "AC97 Aux PCM (Slot 5) Mono in",
 	.dev_addr		= __PREG(MODR),
-	.drcmr			= &DRCMRRXMODR,
+	.drcmr			= &DRCMR(9),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
@@ -81,7 +81,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
 static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
 	.name			= "AC97 Mic PCM (Slot 6) Mono in",
 	.dev_addr		= __PREG(MCDR),
-	.drcmr			= &DRCMRRXMCDR,
+	.drcmr			= &DRCMR(8),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST16 | DCMD_WIDTH2,
 };
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 64057b1d220d..e758034db5c3 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -39,6 +39,45 @@ struct pxa2xx_gpio {
 	u32 frm;
 };
 
+/*
+ * I2S Controller Register and Bit Definitions
+ */
+#define SACR0		__REG(0x40400000)  /* Global Control Register */
+#define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
+#define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
+#define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
+#define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
+#define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
+#define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
+
+#define SACR0_RFTH(x)	((x) << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_TFTH(x)	((x) << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
+#define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
+#define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
+#define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
+#define SACR0_BCKD	(1 << 2) 	/* Bit Clock Direction */
+#define SACR0_ENB	(1 << 0)	/* Enable I2S Link */
+#define SACR1_ENLBF	(1 << 5)	/* Enable Loopback */
+#define SACR1_DRPL	(1 << 4) 	/* Disable Replaying Function */
+#define SACR1_DREC	(1 << 3)	/* Disable Recording Function */
+#define SACR1_AMSL	(1 << 0)	/* Specify Alternate Mode */
+
+#define SASR0_I2SOFF	(1 << 7)	/* Controller Status */
+#define SASR0_ROR	(1 << 6)	/* Rx FIFO Overrun */
+#define SASR0_TUR	(1 << 5)	/* Tx FIFO Underrun */
+#define SASR0_RFS	(1 << 4)	/* Rx FIFO Service Request */
+#define SASR0_TFS	(1 << 3)	/* Tx FIFO Service Request */
+#define SASR0_BSY	(1 << 2)	/* I2S Busy */
+#define SASR0_RNE	(1 << 1)	/* Rx FIFO Not Empty */
+#define SASR0_TNF	(1 << 0) 	/* Tx FIFO Not Empty */
+
+#define SAICR_ROR	(1 << 6)	/* Clear Rx FIFO Overrun Interrupt */
+#define SAICR_TUR	(1 << 5)	/* Clear Tx FIFO Underrun Interrupt */
+
+#define SAIMR_ROR	(1 << 6)	/* Enable Rx FIFO Overrun Condition Interrupt */
+#define SAIMR_TUR	(1 << 5)	/* Enable Tx FIFO Underrun Condition Interrupt */
+#define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
+#define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
 
 struct pxa_i2s_port {
 	u32 sadiv;
@@ -54,7 +93,7 @@ static struct clk *clk_i2s;
 static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
 	.name			= "I2S PCM Stereo out",
 	.dev_addr		= __PREG(SADR),
-	.drcmr			= &DRCMRTXSADR,
+	.drcmr			= &DRCMR(3),
 	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
@@ -62,7 +101,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
 static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
 	.name			= "I2S PCM Stereo in",
 	.dev_addr		= __PREG(SADR),
-	.drcmr			= &DRCMRRXSADR,
+	.drcmr			= &DRCMR(2),
 	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 8f89188e541e..d307b6757e95 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -19,16 +19,15 @@
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/scoop.h>
 #include <mach/pxa-regs.h>
 #include <mach/hardware.h>
-#include <mach/akita.h>
 #include <mach/spitz.h>
 #include "../codecs/wm8750.h"
 #include "pxa2xx-pcm.h"
@@ -63,8 +62,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headphone Jack");
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
 		break;
 	case SPITZ_MIC:
 		/* enable mic jack and bias, mute hp */
@@ -72,8 +71,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	case SPITZ_LINE:
 		/* enable line jack, disable mic bias and mute hp */
@@ -81,8 +80,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_enable_pin(codec, "Line Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	case SPITZ_HEADSET:
 		/* enable and unmute headset jack enable mic bias, mute L hp */
@@ -90,8 +89,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
 		snd_soc_dapm_enable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
 		snd_soc_dapm_enable_pin(codec, "Headset Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
 		break;
 	case SPITZ_HP_OFF:
 
@@ -100,8 +99,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
 		snd_soc_dapm_disable_pin(codec, "Headset Jack");
 		snd_soc_dapm_disable_pin(codec, "Mic Jack");
 		snd_soc_dapm_disable_pin(codec, "Line Jack");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L);
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R);
+		gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
+		gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
 		break;
 	}
 	snd_soc_dapm_sync(codec);
@@ -215,23 +214,14 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
 static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (machine_is_borzoi() || machine_is_spitz()) {
-		if (SND_SOC_DAPM_EVENT_ON(event))
-			set_scoop_gpio(&spitzscoop2_device.dev,
-				SPITZ_SCP2_MIC_BIAS);
-		else
-			reset_scoop_gpio(&spitzscoop2_device.dev,
-				SPITZ_SCP2_MIC_BIAS);
-	}
+	if (machine_is_borzoi() || machine_is_spitz())
+		gpio_set_value(SPITZ_GPIO_MIC_BIAS,
+				SND_SOC_DAPM_EVENT_ON(event));
+
+	if (machine_is_akita())
+		gpio_set_value(AKITA_GPIO_MIC_BIAS,
+				SND_SOC_DAPM_EVENT_ON(event));
 
-	if (machine_is_akita()) {
-		if (SND_SOC_DAPM_EVENT_ON(event))
-			akita_set_ioexp(&akitaioexp_device.dev,
-				AKITA_IOEXP_MIC_BIAS);
-		else
-			akita_reset_ioexp(&akitaioexp_device.dev,
-				AKITA_IOEXP_MIC_BIAS);
-	}
 	return 0;
 }
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0af3bbde5bbe..16c7453f4946 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1462,7 +1462,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	int max = mc->max;
-	unsigned int shift = mc->min;
+	unsigned int shift = mc->shift;
 	unsigned int rshift = mc->rshift;
 
 	if (max == 1)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index efbd0b37810a..7351db9606e4 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -831,7 +831,7 @@ int snd_soc_dapm_sys_add(struct device *dev)
 		return ret;
 
 	asoc_debugfs = debugfs_create_dir("asoc", NULL);
-	if (!IS_ERR(asoc_debugfs))
+	if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
 		debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
 				   &pop_time);
 	else
diff --git a/sound/sound_core.c b/sound/sound_core.c
index ee66d43f848c..a75b289a5d78 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -220,9 +220,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
 	else
 		sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
 
-	device_create_drvdata(sound_class, dev,
-			      MKDEV(SOUND_MAJOR, s->unit_minor),
-			      NULL, s->name+6);
+	device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
+		      NULL, s->name+6);
 	return r;
 
  fail:
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 49acee0c4840..f87933e48812 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -1,6 +1,6 @@
 /*
  * Driver for AMD7930 sound chips found on Sparcs.
- * Copyright (C) 2002 David S. Miller <davem@redhat.com>
+ * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
  *
  * Based entirely upon drivers/sbus/audio/amd7930.c which is:
  * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -35,6 +35,8 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -44,7 +46,6 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/sbus.h>
 #include <asm/prom.h>
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
@@ -335,8 +336,8 @@ struct snd_amd7930 {
 	int			pgain;
 	int			mgain;
 
+	struct of_device	*op;
 	unsigned int		irq;
-	unsigned int		regs_size;
 	struct snd_amd7930	*next;
 };
 
@@ -905,13 +906,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
 
 static int snd_amd7930_free(struct snd_amd7930 *amd)
 {
+	struct of_device *op = amd->op;
+
 	amd7930_idle(amd);
 
 	if (amd->irq)
 		free_irq(amd->irq, amd);
 
 	if (amd->regs)
-		sbus_iounmap(amd->regs, amd->regs_size);
+		of_iounmap(&op->resource[0], amd->regs,
+			   resource_size(&op->resource[0]));
 
 	kfree(amd);
 
@@ -930,13 +934,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
 };
 
 static int __devinit snd_amd7930_create(struct snd_card *card,
-					struct resource *rp,
-					unsigned int reg_size,
+					struct of_device *op,
 					int irq, int dev,
 					struct snd_amd7930 **ramd)
 {
-	unsigned long flags;
 	struct snd_amd7930 *amd;
+	unsigned long flags;
 	int err;
 
 	*ramd = NULL;
@@ -946,9 +949,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
 
 	spin_lock_init(&amd->lock);
 	amd->card = card;
-	amd->regs_size = reg_size;
+	amd->op = op;
 
-	amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930");
+	amd->regs = of_ioremap(&op->resource[0], 0,
+			       resource_size(&op->resource[0]), "amd7930");
 	if (!amd->regs) {
 		snd_printk("amd7930-%d: Unable to map chip registers.\n", dev);
 		return -EIO;
@@ -997,12 +1001,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
 	return 0;
 }
 
-static int __devinit amd7930_attach_common(struct resource *rp, int irq)
+static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
+	struct resource *rp = &op->resource[0];
 	static int dev_num;
 	struct snd_card *card;
 	struct snd_amd7930 *amd;
-	int err;
+	int err, irq;
+
+	irq = op->irqs[0];
 
 	if (dev_num >= SNDRV_CARDS)
 		return -ENODEV;
@@ -1023,8 +1030,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq)
 		(unsigned long long)rp->start,
 		irq);
 
-	if ((err = snd_amd7930_create(card, rp,
-				      (rp->end - rp->start) + 1,
+	if ((err = snd_amd7930_create(card, op,
 				      irq, dev_num, &amd)) < 0)
 		goto out_err;
 
@@ -1049,43 +1055,7 @@ out_err:
 	return err;
 }
 
-static int __devinit amd7930_obio_attach(struct device_node *dp)
-{
-	const struct linux_prom_registers *regs;
-	const struct linux_prom_irqs *irqp;
-	struct resource res, *rp;
-	int len;
-
-	irqp = of_get_property(dp, "intr", &len);
-	if (!irqp) {
-		snd_printk("%s: Firmware node lacks IRQ property.\n",
-			   dp->full_name);
-		return -ENODEV;
-	}
-
-	regs = of_get_property(dp, "reg", &len);
-	if (!regs) {
-		snd_printk("%s: Firmware node lacks register property.\n",
-			   dp->full_name);
-		return -ENODEV;
-	}
-
-	rp = &res;
-	rp->start = regs->phys_addr;
-	rp->end = rp->start + regs->reg_size - 1;
-	rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
-
-	return amd7930_attach_common(rp, irqp->pri);
-}
-
-static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
-{
-	struct sbus_dev *sdev = to_sbus_device(&dev->dev);
-
-	return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
-}
-
-static struct of_device_id amd7930_match[] = {
+static const struct of_device_id amd7930_match[] = {
 	{
 		.name = "audio",
 	},
@@ -1100,20 +1070,7 @@ static struct of_platform_driver amd7930_sbus_driver = {
 
 static int __init amd7930_init(void)
 {
-	struct device_node *dp;
-
-	/* Try to find the sun4c "audio" node first. */
-	dp = of_find_node_by_path("/");
-	dp = dp->child;
-	while (dp) {
-		if (!strcmp(dp->name, "audio"))
-			amd7930_obio_attach(dp);
-
-		dp = dp->sibling;
-	}
-
-	/* Probe each SBUS for amd7930 chips. */
-	return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&amd7930_sbus_driver, &of_bus_type);
 }
 
 static void __exit amd7930_exit(void)
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 791d2fb821d1..d44bf98e965e 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1,6 +1,6 @@
 /*
  * Driver for CS4231 sound chips found on Sparcs.
- * Copyright (C) 2002 David S. Miller <davem@redhat.com>
+ * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
  *
  * Based entirely upon drivers/sbus/audio/cs4231.c which is:
  * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -17,7 +17,8 @@
 #include <linux/moduleparam.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -29,13 +30,12 @@
 
 #ifdef CONFIG_SBUS
 #define SBUS_SUPPORT
-#include <asm/sbus.h>
 #endif
 
 #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
 #define EBUS_SUPPORT
 #include <linux/pci.h>
-#include <asm/ebus.h>
+#include <asm/ebus_dma.h>
 #endif
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
@@ -70,8 +70,6 @@ struct cs4231_dma_control {
 	int		(*request)(struct cs4231_dma_control *dma_cont,
 				   dma_addr_t bus_addr, size_t len);
 	unsigned int	(*address)(struct cs4231_dma_control *dma_cont);
-	void		(*preallocate)(struct snd_cs4231 *chip,
-				       struct snd_pcm *pcm);
 #ifdef EBUS_SUPPORT
 	struct		ebus_dma_info	ebus_info;
 #endif
@@ -114,21 +112,12 @@ struct snd_cs4231 {
 	struct mutex		mce_mutex;	/* mutex for mce register */
 	struct mutex		open_mutex;	/* mutex for ALSA open/close */
 
-	union {
-#ifdef SBUS_SUPPORT
-		struct sbus_dev		*sdev;
-#endif
-#ifdef EBUS_SUPPORT
-		struct pci_dev		*pdev;
-#endif
-	} dev_u;
+	struct of_device	*op;
 	unsigned int		irq[2];
 	unsigned int		regs_size;
 	struct snd_cs4231	*next;
 };
 
-static struct snd_cs4231 *cs4231_list;
-
 /* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
  * now....  -DaveM
  */
@@ -267,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] =
 
 static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
 {
-#ifdef EBUS_SUPPORT
 	if (cp->flags & CS4231_FLAG_EBUS)
 		return readb(reg_addr);
 	else
-#endif
-#ifdef SBUS_SUPPORT
 		return sbus_readb(reg_addr);
-#endif
 }
 
 static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
 			    void __iomem *reg_addr)
 {
-#ifdef EBUS_SUPPORT
 	if (cp->flags & CS4231_FLAG_EBUS)
 		return writeb(val, reg_addr);
 	else
-#endif
-#ifdef SBUS_SUPPORT
 		return sbus_writeb(val, reg_addr);
-#endif
 }
 
 /*
@@ -1258,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card)
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 	strcpy(pcm->name, "CS4231");
 
-	chip->p_dma.preallocate(chip, pcm);
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					      &chip->op->dev,
+					      64 * 1024, 128 * 1024);
 
 	chip->pcm = pcm;
 
@@ -1627,8 +1610,7 @@ static int __init cs4231_attach_finish(struct snd_card *card)
 	if (err < 0)
 		goto out_err;
 
-	chip->next = cs4231_list;
-	cs4231_list = chip;
+	dev_set_drvdata(&chip->op->dev, chip);
 
 	dev++;
 	return 0;
@@ -1783,24 +1765,19 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
 	return sbus_readl(base->regs + base->dir + APCVA);
 }
 
-static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
-{
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
-					snd_dma_sbus_data(chip->dev_u.sdev),
-					64 * 1024, 128 * 1024);
-}
-
 /*
  * Init and exit routines
  */
 
 static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
 {
+	struct of_device *op = chip->op;
+
 	if (chip->irq[0])
 		free_irq(chip->irq[0], chip);
 
 	if (chip->port)
-		sbus_iounmap(chip->port, chip->regs_size);
+		of_iounmap(&op->resource[0], chip->port, chip->regs_size);
 
 	return 0;
 }
@@ -1817,7 +1794,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
 };
 
 static int __init snd_cs4231_sbus_create(struct snd_card *card,
-					 struct sbus_dev *sdev,
+					 struct of_device *op,
 					 int dev)
 {
 	struct snd_cs4231 *chip = card->private_data;
@@ -1828,13 +1805,13 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
 	spin_lock_init(&chip->p_dma.sbus_info.lock);
 	mutex_init(&chip->mce_mutex);
 	mutex_init(&chip->open_mutex);
-	chip->dev_u.sdev = sdev;
-	chip->regs_size = sdev->reg_addrs[0].reg_size;
+	chip->op = op;
+	chip->regs_size = resource_size(&op->resource[0]);
 	memcpy(&chip->image, &snd_cs4231_original_image,
 	       sizeof(snd_cs4231_original_image));
 
-	chip->port = sbus_ioremap(&sdev->resource[0], 0,
-				  chip->regs_size, "cs4231");
+	chip->port = of_ioremap(&op->resource[0], 0,
+				chip->regs_size, "cs4231");
 	if (!chip->port) {
 		snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
 		return -EIO;
@@ -1849,22 +1826,20 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
 	chip->p_dma.enable = sbus_dma_enable;
 	chip->p_dma.request = sbus_dma_request;
 	chip->p_dma.address = sbus_dma_addr;
-	chip->p_dma.preallocate = sbus_dma_preallocate;
 
 	chip->c_dma.prepare = sbus_dma_prepare;
 	chip->c_dma.enable = sbus_dma_enable;
 	chip->c_dma.request = sbus_dma_request;
 	chip->c_dma.address = sbus_dma_addr;
-	chip->c_dma.preallocate = sbus_dma_preallocate;
 
-	if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
+	if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt,
 			IRQF_SHARED, "cs4231", chip)) {
 		snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
-			    dev, sdev->irqs[0]);
+			    dev, op->irqs[0]);
 		snd_cs4231_sbus_free(chip);
 		return -EBUSY;
 	}
-	chip->irq[0] = sdev->irqs[0];
+	chip->irq[0] = op->irqs[0];
 
 	if (snd_cs4231_probe(chip) < 0) {
 		snd_cs4231_sbus_free(chip);
@@ -1881,9 +1856,9 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
 	return 0;
 }
 
-static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
+static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct resource *rp = &sdev->resource[0];
+	struct resource *rp = &op->resource[0];
 	struct snd_card *card;
 	int err;
 
@@ -1895,9 +1870,9 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
 		card->shortname,
 		rp->flags & 0xffL,
 		(unsigned long long)rp->start,
-		sdev->irqs[0]);
+		op->irqs[0]);
 
-	err = snd_cs4231_sbus_create(card, sdev, dev);
+	err = snd_cs4231_sbus_create(card, op, dev);
 	if (err < 0) {
 		snd_card_free(card);
 		return err;
@@ -1950,30 +1925,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
 	return ebus_dma_addr(&dma_cont->ebus_info);
 }
 
-static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
-{
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-				      snd_dma_pci_data(chip->dev_u.pdev),
-				      64*1024, 128*1024);
-}
-
 /*
  * Init and exit routines
  */
 
 static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
 {
+	struct of_device *op = chip->op;
+
 	if (chip->c_dma.ebus_info.regs) {
 		ebus_dma_unregister(&chip->c_dma.ebus_info);
-		iounmap(chip->c_dma.ebus_info.regs);
+		of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10);
 	}
 	if (chip->p_dma.ebus_info.regs) {
 		ebus_dma_unregister(&chip->p_dma.ebus_info);
-		iounmap(chip->p_dma.ebus_info.regs);
+		of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10);
 	}
 
 	if (chip->port)
-		iounmap(chip->port);
+		of_iounmap(&op->resource[0], chip->port, 0x10);
 
 	return 0;
 }
@@ -1990,7 +1960,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
 };
 
 static int __init snd_cs4231_ebus_create(struct snd_card *card,
-					 struct linux_ebus_device *edev,
+					 struct of_device *op,
 					 int dev)
 {
 	struct snd_cs4231 *chip = card->private_data;
@@ -2002,35 +1972,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
 	mutex_init(&chip->mce_mutex);
 	mutex_init(&chip->open_mutex);
 	chip->flags |= CS4231_FLAG_EBUS;
-	chip->dev_u.pdev = edev->bus->self;
+	chip->op = op;
 	memcpy(&chip->image, &snd_cs4231_original_image,
 	       sizeof(snd_cs4231_original_image));
 	strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
 	chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
 	chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
 	chip->c_dma.ebus_info.client_cookie = chip;
-	chip->c_dma.ebus_info.irq = edev->irqs[0];
+	chip->c_dma.ebus_info.irq = op->irqs[0];
 	strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
 	chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
 	chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
 	chip->p_dma.ebus_info.client_cookie = chip;
-	chip->p_dma.ebus_info.irq = edev->irqs[1];
+	chip->p_dma.ebus_info.irq = op->irqs[1];
 
 	chip->p_dma.prepare = _ebus_dma_prepare;
 	chip->p_dma.enable = _ebus_dma_enable;
 	chip->p_dma.request = _ebus_dma_request;
 	chip->p_dma.address = _ebus_dma_addr;
-	chip->p_dma.preallocate = _ebus_dma_preallocate;
 
 	chip->c_dma.prepare = _ebus_dma_prepare;
 	chip->c_dma.enable = _ebus_dma_enable;
 	chip->c_dma.request = _ebus_dma_request;
 	chip->c_dma.address = _ebus_dma_addr;
-	chip->c_dma.preallocate = _ebus_dma_preallocate;
 
-	chip->port = ioremap(edev->resource[0].start, 0x10);
-	chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10);
-	chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10);
+	chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231");
+	chip->p_dma.ebus_info.regs =
+		of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma");
+	chip->c_dma.ebus_info.regs =
+		of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma");
 	if (!chip->port || !chip->p_dma.ebus_info.regs ||
 	    !chip->c_dma.ebus_info.regs) {
 		snd_cs4231_ebus_free(chip);
@@ -2078,7 +2048,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
 	return 0;
 }
 
-static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
+static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match)
 {
 	struct snd_card *card;
 	int err;
@@ -2089,10 +2059,10 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
 
 	sprintf(card->longname, "%s at 0x%lx, irq %d",
 		card->shortname,
-		edev->resource[0].start,
-		edev->irqs[0]);
+		op->resource[0].start,
+		op->irqs[0]);
 
-	err = snd_cs4231_ebus_create(card, edev, dev);
+	err = snd_cs4231_ebus_create(card, op, dev);
 	if (err < 0) {
 		snd_card_free(card);
 		return err;
@@ -2102,68 +2072,57 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
 }
 #endif
 
-static int __init cs4231_init(void)
+static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match)
 {
-#ifdef SBUS_SUPPORT
-	struct sbus_bus *sbus;
-	struct sbus_dev *sdev;
-#endif
 #ifdef EBUS_SUPPORT
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev;
+	if (!strcmp(op->node->parent->name, "ebus"))
+		return cs4231_ebus_probe(op, match);
 #endif
-	int found;
-
-	found = 0;
-
 #ifdef SBUS_SUPPORT
-	for_all_sbusdev(sdev, sbus) {
-		if (!strcmp(sdev->prom_name, "SUNW,CS4231")) {
-			if (cs4231_sbus_attach(sdev) == 0)
-				found++;
-		}
-	}
+	if (!strcmp(op->node->parent->name, "sbus") ||
+	    !strcmp(op->node->parent->name, "sbi"))
+		return cs4231_sbus_probe(op, match);
 #endif
-#ifdef EBUS_SUPPORT
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			int match = 0;
-
-			if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
-				match = 1;
-			} else if (!strcmp(edev->prom_node->name, "audio")) {
-				const char *compat;
-
-				compat = of_get_property(edev->prom_node,
-							 "compatible", NULL);
-				if (compat && !strcmp(compat, "SUNW,CS4231"))
-					match = 1;
-			}
+	return -ENODEV;
+}
 
-			if (match &&
-			    cs4231_ebus_attach(edev) == 0)
-				found++;
-		}
-	}
-#endif
+static int __devexit cs4231_remove(struct of_device *op)
+{
+	struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
 
+	snd_card_free(chip->card);
 
-	return (found > 0) ? 0 : -EIO;
+	return 0;
 }
 
-static void __exit cs4231_exit(void)
-{
-	struct snd_cs4231 *p = cs4231_list;
+static const struct of_device_id cs4231_match[] = {
+	{
+		.name = "SUNW,CS4231",
+	},
+	{
+		.name = "audio",
+		.compatible = "SUNW,CS4231",
+	},
+	{},
+};
 
-	while (p != NULL) {
-		struct snd_cs4231 *next = p->next;
+MODULE_DEVICE_TABLE(of, cs4231_match);
 
-		snd_card_free(p->card);
+static struct of_platform_driver cs4231_driver = {
+	.name		= "audio",
+	.match_table	= cs4231_match,
+	.probe		= cs4231_probe,
+	.remove		= __devexit_p(cs4231_remove),
+};
 
-		p = next;
-	}
+static int __init cs4231_init(void)
+{
+	return of_register_driver(&cs4231_driver, &of_bus_type);
+}
 
-	cs4231_list = NULL;
+static void __exit cs4231_exit(void)
+{
+	of_unregister_driver(&cs4231_driver);
 }
 
 module_init(cs4231_init);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index c534a2a849fa..23ed6f04a718 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -57,6 +57,7 @@
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/dma-mapping.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -66,7 +67,7 @@
 #include <sound/initval.h>
 
 #include <linux/of.h>
-#include <asm/sbus.h>
+#include <linux/of_device.h>
 #include <asm/atomic.h>
 
 MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
@@ -297,7 +298,7 @@ struct dbri_streaminfo {
 /* This structure holds the information for both chips (DBRI & CS4215) */
 struct snd_dbri {
 	int regs_size, irq;	/* Needed for unload */
-	struct sbus_dev *sdev;	/* SBUS device info */
+	struct of_device *op;	/* OF device info */
 	spinlock_t lock;
 
 	struct dbri_dma *dma;	/* Pointer to our DMA block */
@@ -2093,14 +2094,15 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
 	 */
 	if (info->dvma_buffer == 0) {
 		if (DBRI_STREAMNO(substream) == DBRI_PLAY)
-			direction = SBUS_DMA_TODEVICE;
+			direction = DMA_TO_DEVICE;
 		else
-			direction = SBUS_DMA_FROMDEVICE;
+			direction = DMA_FROM_DEVICE;
 
-		info->dvma_buffer = sbus_map_single(dbri->sdev,
-					runtime->dma_area,
-					params_buffer_bytes(hw_params),
-					direction);
+		info->dvma_buffer =
+			dma_map_single(&dbri->op->dev,
+				       runtime->dma_area,
+				       params_buffer_bytes(hw_params),
+				       direction);
 	}
 
 	direction = params_buffer_bytes(hw_params);
@@ -2121,12 +2123,12 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
 	 */
 	if (info->dvma_buffer) {
 		if (DBRI_STREAMNO(substream) == DBRI_PLAY)
-			direction = SBUS_DMA_TODEVICE;
+			direction = DMA_TO_DEVICE;
 		else
-			direction = SBUS_DMA_FROMDEVICE;
+			direction = DMA_FROM_DEVICE;
 
-		sbus_unmap_single(dbri->sdev, info->dvma_buffer,
-				  substream->runtime->buffer_size, direction);
+		dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
+				 substream->runtime->buffer_size, direction);
 		info->dvma_buffer = 0;
 	}
 	if (info->pipe != -1) {
@@ -2519,31 +2521,34 @@ static void __devinit snd_dbri_proc(struct snd_card *card)
 static void snd_dbri_free(struct snd_dbri *dbri);
 
 static int __devinit snd_dbri_create(struct snd_card *card,
-				  struct sbus_dev *sdev,
-				  int irq, int dev)
+				     struct of_device *op,
+				     int irq, int dev)
 {
 	struct snd_dbri *dbri = card->private_data;
 	int err;
 
 	spin_lock_init(&dbri->lock);
-	dbri->sdev = sdev;
+	dbri->op = op;
 	dbri->irq = irq;
 
-	dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma),
-					  &dbri->dma_dvma);
+	dbri->dma = dma_alloc_coherent(&op->dev,
+				       sizeof(struct dbri_dma),
+				       &dbri->dma_dvma, GFP_ATOMIC);
+	if (!dbri->dma)
+		return -ENOMEM;
 	memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
 
 	dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
 		dbri->dma, dbri->dma_dvma);
 
 	/* Map the registers into memory. */
-	dbri->regs_size = sdev->reg_addrs[0].reg_size;
-	dbri->regs = sbus_ioremap(&sdev->resource[0], 0,
-				  dbri->regs_size, "DBRI Registers");
+	dbri->regs_size = resource_size(&op->resource[0]);
+	dbri->regs = of_ioremap(&op->resource[0], 0,
+				dbri->regs_size, "DBRI Registers");
 	if (!dbri->regs) {
 		printk(KERN_ERR "DBRI: could not allocate registers\n");
-		sbus_free_consistent(sdev, sizeof(struct dbri_dma),
-				     (void *)dbri->dma, dbri->dma_dvma);
+		dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
+				  (void *)dbri->dma, dbri->dma_dvma);
 		return -EIO;
 	}
 
@@ -2551,9 +2556,9 @@ static int __devinit snd_dbri_create(struct snd_card *card,
 			  "DBRI audio", dbri);
 	if (err) {
 		printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
-		sbus_iounmap(dbri->regs, dbri->regs_size);
-		sbus_free_consistent(sdev, sizeof(struct dbri_dma),
-				     (void *)dbri->dma, dbri->dma_dvma);
+		of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
+		dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
+				  (void *)dbri->dma, dbri->dma_dvma);
 		return err;
 	}
 
@@ -2577,27 +2582,23 @@ static void snd_dbri_free(struct snd_dbri *dbri)
 		free_irq(dbri->irq, dbri);
 
 	if (dbri->regs)
-		sbus_iounmap(dbri->regs, dbri->regs_size);
+		of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
 
 	if (dbri->dma)
-		sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma),
-				     (void *)dbri->dma, dbri->dma_dvma);
+		dma_free_coherent(&dbri->op->dev,
+				  sizeof(struct dbri_dma),
+				  (void *)dbri->dma, dbri->dma_dvma);
 }
 
-static int __devinit dbri_probe(struct of_device *of_dev,
-				const struct of_device_id *match)
+static int __devinit dbri_probe(struct of_device *op, const struct of_device_id *match)
 {
-	struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
 	struct snd_dbri *dbri;
-	int irq;
 	struct resource *rp;
 	struct snd_card *card;
 	static int dev = 0;
+	int irq;
 	int err;
 
-	dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
-		sdev->prom_name, sdev->slot);
-
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 	if (!enable[dev]) {
@@ -2605,7 +2606,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
 		return -ENOENT;
 	}
 
-	irq = sdev->irqs[0];
+	irq = op->irqs[0];
 	if (irq <= 0) {
 		printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
 		return -ENODEV;
@@ -2618,12 +2619,12 @@ static int __devinit dbri_probe(struct of_device *of_dev,
 
 	strcpy(card->driver, "DBRI");
 	strcpy(card->shortname, "Sun DBRI");
-	rp = &sdev->resource[0];
+	rp = &op->resource[0];
 	sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
 		card->shortname,
 		rp->flags & 0xffL, (unsigned long long)rp->start, irq);
 
-	err = snd_dbri_create(card, sdev, irq, dev);
+	err = snd_dbri_create(card, op, irq, dev);
 	if (err < 0) {
 		snd_card_free(card);
 		return err;
@@ -2640,7 +2641,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
 
 	/* /proc file handling */
 	snd_dbri_proc(card);
-	dev_set_drvdata(&of_dev->dev, card);
+	dev_set_drvdata(&op->dev, card);
 
 	err = snd_card_register(card);
 	if (err < 0)
@@ -2648,7 +2649,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
 
 	printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
 	       dev, dbri->regs,
-	       dbri->irq, sdev->prom_name[9], dbri->mm.version);
+	       dbri->irq, op->node->name[9], dbri->mm.version);
 	dev++;
 
 	return 0;
@@ -2659,19 +2660,19 @@ _err:
 	return err;
 }
 
-static int __devexit dbri_remove(struct of_device *dev)
+static int __devexit dbri_remove(struct of_device *op)
 {
-	struct snd_card *card = dev_get_drvdata(&dev->dev);
+	struct snd_card *card = dev_get_drvdata(&op->dev);
 
 	snd_dbri_free(card->private_data);
 	snd_card_free(card);
 
-	dev_set_drvdata(&dev->dev, NULL);
+	dev_set_drvdata(&op->dev, NULL);
 
 	return 0;
 }
 
-static struct of_device_id dbri_match[] = {
+static const struct of_device_id dbri_match[] = {
 	{
 		.name = "SUNW,DBRIe",
 	},
@@ -2693,7 +2694,7 @@ static struct of_platform_driver dbri_sbus_driver = {
 /* Probe for the dbri chip and then attach the driver. */
 static int __init dbri_init(void)
 {
-	return of_register_driver(&dbri_sbus_driver, &sbus_bus_type);
+	return of_register_driver(&dbri_sbus_driver, &of_bus_type);
 }
 
 static void __exit dbri_exit(void)