Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: usb-audio: automatically detect feedback format
  ASoC: sound/wm9090: add missing __devexit marker
  ASoC: sound/max98088: add missing __devexit marker
  ASoC: sound/ad73311: add missing __devexit marker
  ASoC: fsl - fix build error in pcm030-audio-fabric.c
  sound/oss/sb_ess.c: delete double assignment
  ALSA: hda - Change BTL amp level on some HP notebooks
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 51a3d38..9890cf2 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -1722,7 +1722,6 @@
 				right = (value & 0x0000ff00) >> 8;
 			} else {				/* Turn it off (3)  */
 				left  = 0;
-				left  = 0;
 				right = 0;
 			}
 			sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 82ebeb9..93fa59c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -5326,6 +5326,82 @@
 	return 0;
 }
 
+static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec)
+{
+	if (codec->vendor_id != 0x111d7605 &&
+	    codec->vendor_id != 0x111d76d1)
+		return 0;
+
+	switch (codec->subsystem_id) {
+	case 0x103c1618:
+	case 0x103c1619:
+	case 0x103c161a:
+	case 0x103c161b:
+	case 0x103c161c:
+	case 0x103c161d:
+	case 0x103c161e:
+	case 0x103c161f:
+	case 0x103c1620:
+	case 0x103c1621:
+	case 0x103c1622:
+	case 0x103c1623:
+
+	case 0x103c162a:
+	case 0x103c162b:
+
+	case 0x103c1630:
+	case 0x103c1631:
+
+	case 0x103c1633:
+
+	case 0x103c1635:
+
+	case 0x103c164f:
+
+	case 0x103c1676:
+	case 0x103c1677:
+	case 0x103c1678:
+	case 0x103c1679:
+	case 0x103c167a:
+	case 0x103c167b:
+	case 0x103c167c:
+	case 0x103c167d:
+	case 0x103c167e:
+	case 0x103c167f:
+	case 0x103c1680:
+	case 0x103c1681:
+	case 0x103c1682:
+	case 0x103c1683:
+	case 0x103c1684:
+	case 0x103c1685:
+	case 0x103c1686:
+	case 0x103c1687:
+	case 0x103c1688:
+	case 0x103c1689:
+	case 0x103c168a:
+	case 0x103c168b:
+	case 0x103c168c:
+	case 0x103c168d:
+	case 0x103c168e:
+	case 0x103c168f:
+	case 0x103c1690:
+	case 0x103c1691:
+	case 0x103c1692:
+
+	case 0x103c3587:
+	case 0x103c3588:
+	case 0x103c3589:
+	case 0x103c358a:
+
+	case 0x103c3667:
+	case 0x103c3668:
+		/* set BTL amp level to 13.43dB for louder speaker output */
+		return snd_hda_codec_write_cache(codec, codec->afg, 0,
+						 0x7F4, 0x14);
+	}
+	return 0;
+}
+
 static int patch_stac92hd83xxx(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec;
@@ -5452,6 +5528,8 @@
 			AC_VERB_SET_CONNECT_SEL, num_dacs);
 	}
 
+	stac92hd83xxx_set_system_btl_amp(codec);
+
 	codec->proc_widget_hook = stac92hd_proc_hook;
 
 	return 0;
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index c53955f..de799cd 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -47,7 +47,7 @@
 			&soc_codec_dev_ad73311, &ad73311_dai, 1);
 }
 
-static int ad73311_remove(struct platform_device *pdev)
+static int __devexit ad73311_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index e7a40d1..bc22ee9 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -2051,7 +2051,7 @@
        return ret;
 }
 
-static int max98088_i2c_remove(struct i2c_client *client)
+static int __devexit max98088_i2c_remove(struct i2c_client *client)
 {
        snd_soc_unregister_codec(&client->dev);
        kfree(i2c_get_clientdata(client));
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 7a18254..99c046b 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -665,7 +665,7 @@
 	return ret;
 }
 
-static int wm9090_i2c_remove(struct i2c_client *i2c)
+static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
 {
 	struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
 
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index fe15bb2..25f27ec 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -24,7 +24,6 @@
 #include <sound/pcm_params.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
-#include <sound/soc-of-simple.h>
 
 #include "mpc5200_dma.h"
 #include "mpc5200_psc_ac97.h"
@@ -49,7 +48,7 @@
 	.codec_dai_name = "wm9712-aux",
 	.cpu_dai_name = "mpc5200-psc-ac97.1",
 	.platform_name = "mpc5200-pcm-audio",
-	..codec_name = "wm9712-codec",
+	.codec_name = "wm9712-codec",
 },
 };
 
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 1febf2f..ae4251d 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -62,12 +62,14 @@
 	unsigned int syncinterval;  /* P for adaptive mode, 0 otherwise */
 	unsigned int freqn;      /* nominal sampling rate in fs/fps in Q16.16 format */
 	unsigned int freqm;      /* momentary sampling rate in fs/fps in Q16.16 format */
+	int          freqshift;  /* how much to shift the feedback value to get Q16.16 */
 	unsigned int freqmax;    /* maximum sampling rate, used for buffer management */
 	unsigned int phase;      /* phase accumulator */
 	unsigned int maxpacksize;	/* max packet size in bytes */
 	unsigned int maxframesize;	/* max packet size in frames */
 	unsigned int curpacksize;	/* current packet size in bytes (for capture) */
 	unsigned int curframesize;	/* current packet size in frames (for capture) */
+	unsigned int syncmaxsize;	/* sync endpoint packet size */
 	unsigned int fill_max: 1;	/* fill max packet size always */
 	unsigned int txfr_quirk:1;	/* allow sub-frame alignment */
 	unsigned int fmt_type;		/* USB audio format type (1-3) */
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f49756c..cff3a3c 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -237,6 +237,7 @@
 	subs->datainterval = fmt->datainterval;
 	subs->syncpipe = subs->syncinterval = 0;
 	subs->maxpacksize = fmt->maxpacksize;
+	subs->syncmaxsize = 0;
 	subs->fill_max = 0;
 
 	/* we need a sync pipe in async OUT or adaptive IN mode */
@@ -283,6 +284,7 @@
 			subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
 		else
 			subs->syncinterval = 3;
+		subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
 	}
 
 	/* always fill max packet size */
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index 3c650ab..961c9a2 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -132,6 +132,11 @@
 			    ? get_full_speed_hz(subs->freqm)
 			    : get_high_speed_hz(subs->freqm),
 			    subs->freqm >> 16, subs->freqm & 0xffff);
+		if (subs->freqshift != INT_MIN)
+			snd_iprintf(buffer, "    Feedback Format = %d.%d\n",
+				    (subs->syncmaxsize > 3 ? 32 : 24)
+						- (16 - subs->freqshift),
+				    16 - subs->freqshift);
 	} else {
 		snd_iprintf(buffer, "  Status: Stop\n");
 	}
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index 8deeaad..e184349 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -225,6 +225,7 @@
 	else
 		subs->freqn = get_usb_high_speed_rate(rate);
 	subs->freqm = subs->freqn;
+	subs->freqshift = INT_MIN;
 	/* calculate max. frequency */
 	if (subs->maxpacksize) {
 		/* whatever fits into a max. size packet */
@@ -513,11 +514,10 @@
 
 
 /*
- * prepare urb for full speed playback sync pipe
+ * prepare urb for playback sync pipe
  *
  * set up the offset and length to receive the current frequency.
  */
-
 static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
 				     struct snd_pcm_runtime *runtime,
 				     struct urb *urb)
@@ -525,103 +525,78 @@
 	struct snd_urb_ctx *ctx = urb->context;
 
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	urb->iso_frame_desc[0].length = 3;
+	urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
 	urb->iso_frame_desc[0].offset = 0;
 	return 0;
 }
 
 /*
- * prepare urb for high speed playback sync pipe
+ * process after playback sync complete
  *
- * set up the offset and length to receive the current frequency.
- */
-
-static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
-					struct snd_pcm_runtime *runtime,
-					struct urb *urb)
-{
-	struct snd_urb_ctx *ctx = urb->context;
-
-	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	urb->iso_frame_desc[0].length = 4;
-	urb->iso_frame_desc[0].offset = 0;
-	return 0;
-}
-
-/*
- * process after full speed playback sync complete
- *
- * retrieve the current 10.14 frequency from pipe, and set it.
- * the value is referred in prepare_playback_urb().
+ * Full speed devices report feedback values in 10.14 format as samples per
+ * frame, high speed devices in 16.16 format as samples per microframe.
+ * Because the Audio Class 1 spec was written before USB 2.0, many high speed
+ * devices use a wrong interpretation, some others use an entirely different
+ * format.  Therefore, we cannot predict what format any particular device uses
+ * and must detect it automatically.
  */
 static int retire_playback_sync_urb(struct snd_usb_substream *subs,
 				    struct snd_pcm_runtime *runtime,
 				    struct urb *urb)
 {
 	unsigned int f;
+	int shift;
 	unsigned long flags;
 
-	if (urb->iso_frame_desc[0].status == 0 &&
-	    urb->iso_frame_desc[0].actual_length == 3) {
-		f = combine_triple((u8*)urb->transfer_buffer) << 2;
-		if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
-			spin_lock_irqsave(&subs->lock, flags);
-			subs->freqm = f;
-			spin_unlock_irqrestore(&subs->lock, flags);
+	if (urb->iso_frame_desc[0].status != 0 ||
+	    urb->iso_frame_desc[0].actual_length < 3)
+		return 0;
+
+	f = le32_to_cpup(urb->transfer_buffer);
+	if (urb->iso_frame_desc[0].actual_length == 3)
+		f &= 0x00ffffff;
+	else
+		f &= 0x0fffffff;
+	if (f == 0)
+		return 0;
+
+	if (unlikely(subs->freqshift == INT_MIN)) {
+		/*
+		 * The first time we see a feedback value, determine its format
+		 * by shifting it left or right until it matches the nominal
+		 * frequency value.  This assumes that the feedback does not
+		 * differ from the nominal value more than +50% or -25%.
+		 */
+		shift = 0;
+		while (f < subs->freqn - subs->freqn / 4) {
+			f <<= 1;
+			shift++;
 		}
+		while (f > subs->freqn + subs->freqn / 2) {
+			f >>= 1;
+			shift--;
+		}
+		subs->freqshift = shift;
 	}
+	else if (subs->freqshift >= 0)
+		f <<= subs->freqshift;
+	else
+		f >>= -subs->freqshift;
 
-	return 0;
-}
-
-/*
- * process after high speed playback sync complete
- *
- * retrieve the current 12.13 frequency from pipe, and set it.
- * the value is referred in prepare_playback_urb().
- */
-static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
-				       struct snd_pcm_runtime *runtime,
-				       struct urb *urb)
-{
-	unsigned int f;
-	unsigned long flags;
-
-	if (urb->iso_frame_desc[0].status == 0 &&
-	    urb->iso_frame_desc[0].actual_length == 4) {
-		f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
-		if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
-			spin_lock_irqsave(&subs->lock, flags);
-			subs->freqm = f;
-			spin_unlock_irqrestore(&subs->lock, flags);
-		}
-	}
-
-	return 0;
-}
-
-/*
- * process after E-Mu 0202/0404/Tracker Pre high speed playback sync complete
- *
- * These devices return the number of samples per packet instead of the number
- * of samples per microframe.
- */
-static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs,
-					   struct snd_pcm_runtime *runtime,
-					   struct urb *urb)
-{
-	unsigned int f;
-	unsigned long flags;
-
-	if (urb->iso_frame_desc[0].status == 0 &&
-	    urb->iso_frame_desc[0].actual_length == 4) {
-		f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
-		f >>= subs->datainterval;
-		if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
-			spin_lock_irqsave(&subs->lock, flags);
-			subs->freqm = f;
-			spin_unlock_irqrestore(&subs->lock, flags);
-		}
+	if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
+		/*
+		 * If the frequency looks valid, set it.
+		 * This value is referred to in prepare_playback_urb().
+		 */
+		spin_lock_irqsave(&subs->lock, flags);
+		subs->freqm = f;
+		spin_unlock_irqrestore(&subs->lock, flags);
+	} else {
+		/*
+		 * Out of range; maybe the shift value is wrong.
+		 * Reset it so that we autodetect again the next time.
+		 */
+		subs->freqshift = INT_MIN;
 	}
 
 	return 0;
@@ -878,21 +853,6 @@
 	},
 };
 
-static struct snd_urb_ops audio_urb_ops_high_speed[2] = {
-	{
-		.prepare =	prepare_nodata_playback_urb,
-		.retire =	retire_playback_urb,
-		.prepare_sync =	prepare_playback_sync_urb_hs,
-		.retire_sync =	retire_playback_sync_urb_hs,
-	},
-	{
-		.prepare =	prepare_capture_urb,
-		.retire =	retire_capture_urb,
-		.prepare_sync =	prepare_capture_sync_urb_hs,
-		.retire_sync =	retire_capture_sync_urb,
-	},
-};
-
 /*
  * initialize the substream instance.
  */
@@ -909,23 +869,9 @@
 	subs->direction = stream;
 	subs->dev = as->chip->dev;
 	subs->txfr_quirk = as->chip->txfr_quirk;
-	if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) {
-		subs->ops = audio_urb_ops[stream];
-	} else {
-		subs->ops = audio_urb_ops_high_speed[stream];
-		switch (as->chip->usb_id) {
-		case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
-		case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
-		case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
-			subs->ops.retire_sync = retire_playback_sync_urb_hs_emu;
-			break;
-		case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8  */
-		case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
-			subs->ops.prepare_sync = prepare_playback_sync_urb;
-			subs->ops.retire_sync = retire_playback_sync_urb;
-			break;
-		}
-	}
+	subs->ops = audio_urb_ops[stream];
+	if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
+		subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
 
 	snd_usb_set_pcm_ops(as->pcm, stream);