--- /dev/null
+From 76ecb4f2d7ea5c3aac8970b9529775316507c6d2 Mon Sep 17 00:00:00 2001
+From: Zhang, Rui <rui.zhang@intel.com>
+Date: Thu, 10 Apr 2008 16:20:23 +0800
+Subject: ACPI: update thermal temperature
+
+From: Zhang, Rui <rui.zhang@intel.com>
+
+commit 76ecb4f2d7ea5c3aac8970b9529775316507c6d2 upstream
+
+Fix the problem that thermal_get_temp returns the cached value,
+which causes the temperature in generic thermal never updates.
+
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Acked-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Len Brown <len.brown@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/acpi/thermal.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/acpi/thermal.c
++++ b/drivers/acpi/thermal.c
+@@ -891,10 +891,15 @@ static void acpi_thermal_check(void *dat
+ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+ {
+ struct acpi_thermal *tz = thermal->devdata;
++ int result;
+
+ if (!tz)
+ return -EINVAL;
+
++ result = acpi_thermal_get_temperature(tz);
++ if (result)
++ return result;
++
+ return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+ }
+
--- /dev/null
+From e48d6d97bb6bd8c008045ea0522ea8278fdccc55 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 29 May 2008 08:16:56 +0200
+Subject: ALSA: ac97 - Fix ASUS A9T laptop output
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit e48d6d97bb6bd8c008045ea0522ea8278fdccc55 upstream
+
+ASUS A9T laptop uses line-out pin as the real front-output while
+other devices use it as the surround.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/sound/ac97_codec.h | 1
+ sound/pci/ac97/ac97_patch.c | 48 +++++++++++++++++++++++++++++++-------------
+ 2 files changed, 35 insertions(+), 14 deletions(-)
+
+--- a/include/sound/ac97_codec.h
++++ b/include/sound/ac97_codec.h
+@@ -504,6 +504,7 @@ struct snd_ac97 {
+ unsigned short pcmreg[3]; // PCM registers
+ unsigned short codec_cfg[3]; // CODEC_CFG bits
+ unsigned char swap_mic_linein; // AD1986/AD1986A only
++ unsigned char lo_as_master; /* LO as master */
+ } ad18xx;
+ unsigned int dev_flags; /* device specific */
+ } spec;
+--- a/sound/pci/ac97/ac97_patch.c
++++ b/sound/pci/ac97/ac97_patch.c
+@@ -1960,6 +1960,9 @@ static int snd_ac97_ad1888_lohpsel_get(s
+
+ val = ac97->regs[AC97_AD_MISC];
+ ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL);
++ if (ac97->spec.ad18xx.lo_as_master)
++ ucontrol->value.integer.value[0] =
++ !ucontrol->value.integer.value[0];
+ return 0;
+ }
+
+@@ -1968,8 +1971,10 @@ static int snd_ac97_ad1888_lohpsel_put(s
+ struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
+ unsigned short val;
+
+- val = !ucontrol->value.integer.value[0]
+- ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
++ val = !ucontrol->value.integer.value[0];
++ if (ac97->spec.ad18xx.lo_as_master)
++ val = !val;
++ val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0;
+ return snd_ac97_update_bits(ac97, AC97_AD_MISC,
+ AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
+ }
+@@ -2020,7 +2025,7 @@ static void ad1888_update_jacks(struct s
+ {
+ unsigned short val = 0;
+ /* clear LODIS if shared jack is to be used for Surround out */
+- if (is_shared_linein(ac97))
++ if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97))
+ val |= (1 << 12);
+ /* clear CLDIS if shared jack is to be used for C/LFE out */
+ if (is_shared_micin(ac97))
+@@ -2056,9 +2061,13 @@ static const struct snd_kcontrol_new snd
+
+ static int patch_ad1888_specific(struct snd_ac97 *ac97)
+ {
+- /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
+- snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback");
+- snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
++ if (!ac97->spec.ad18xx.lo_as_master) {
++ /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
++ snd_ac97_rename_vol_ctl(ac97, "Master Playback",
++ "Master Surround Playback");
++ snd_ac97_rename_vol_ctl(ac97, "Headphone Playback",
++ "Master Playback");
++ }
+ return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
+ }
+
+@@ -2077,16 +2086,27 @@ static int patch_ad1888(struct snd_ac97
+
+ patch_ad1881(ac97);
+ ac97->build_ops = &patch_ad1888_build_ops;
+- /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
+- /* it seems that most vendors connect line-out connector to headphone out of AC'97 */
++
++ /*
++ * LO can be used as a real line-out on some devices,
++ * and we need to revert the front/surround mixer switches
++ */
++ if (ac97->subsystem_vendor == 0x1043 &&
++ ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */
++ ac97->spec.ad18xx.lo_as_master = 1;
++
++ misc = snd_ac97_read(ac97, AC97_AD_MISC);
+ /* AD-compatible mode */
+ /* Stereo mutes enabled */
+- misc = snd_ac97_read(ac97, AC97_AD_MISC);
+- snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
+- AC97_AD198X_LOSEL |
+- AC97_AD198X_HPSEL |
+- AC97_AD198X_MSPLT |
+- AC97_AD198X_AC97NC);
++ misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC;
++ if (!ac97->spec.ad18xx.lo_as_master)
++ /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */
++ /* it seems that most vendors connect line-out connector to
++ * headphone out of AC'97
++ */
++ misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL;
++
++ snd_ac97_write_cache(ac97, AC97_AD_MISC, misc);
+ ac97->flags |= AC97_STEREO_MUTES;
+ return 0;
+ }
--- /dev/null
+From 6c4cc3a8ed15aacc06a5fd369639fef633cee2bc Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 4 Feb 2008 12:44:11 +0100
+Subject: ALSA: Add more fallbacks to OSS PHONEOUT mixer map
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 6c4cc3a8ed15aacc06a5fd369639fef633cee2bc upstream
+
+Added more fallbacks to OSS PHONEOUT mixer mapping. This corresponds
+to the speaker output in general, so now "Mono" and "Speaker" are
+assigned.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/core/oss/mixer_oss.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/core/oss/mixer_oss.c
++++ b/sound/core/oss/mixer_oss.c
+@@ -1257,6 +1257,8 @@ static void snd_mixer_oss_build(struct s
+ { SOUND_MIXER_DIGITAL3, "Digital", 2 },
+ { SOUND_MIXER_PHONEIN, "Phone", 0 },
+ { SOUND_MIXER_PHONEOUT, "Master Mono", 0 },
++ { SOUND_MIXER_PHONEOUT, "Speaker", 0 }, /*fallback*/
++ { SOUND_MIXER_PHONEOUT, "Mono", 0 }, /*fallback*/
+ { SOUND_MIXER_PHONEOUT, "Phone", 0 }, /* fallback */
+ { SOUND_MIXER_VIDEO, "Video", 0 },
+ { SOUND_MIXER_RADIO, "Radio", 0 },
--- /dev/null
+From d2cd74b158d7214a556226e3312f9fb1de64d7ae Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 2 Jun 2008 11:45:53 +0200
+Subject: ALSA: emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit d2cd74b158d7214a556226e3312f9fb1de64d7ae upstream
+
+On Audigy2 Platinum, the Analog/Digital mixer switch is inverted.
+ https://bugzilla.novell.com/show_bug.cgi?id=396204
+
+The patch adds a simple workaround.
+
+There might be another device requiring a similar fix, too (or fix for
+audigy2 generically), but right now I fix only the known broken one.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/sound/emu10k1.h | 1 +
+ sound/pci/emu10k1/emu10k1_main.c | 1 +
+ sound/pci/emu10k1/emumixer.c | 13 ++++++++++---
+ 3 files changed, 12 insertions(+), 3 deletions(-)
+
+--- a/include/sound/emu10k1.h
++++ b/include/sound/emu10k1.h
+@@ -1670,6 +1670,7 @@ struct snd_emu_chip_details {
+ unsigned char spi_dac; /* SPI interface for DAC */
+ unsigned char i2c_adc; /* I2C interface for ADC */
+ unsigned char adc_1361t; /* Use Philips 1361T ADC */
++ unsigned char invert_shared_spdif; /* analog/digital switch inverted */
+ const char *driver;
+ const char *name;
+ const char *id; /* for backward compatibility - can be NULL if not needed */
+--- a/sound/pci/emu10k1/emu10k1_main.c
++++ b/sound/pci/emu10k1/emu10k1_main.c
+@@ -1527,6 +1527,7 @@ static struct snd_emu_chip_details emu_c
+ .ca0151_chip = 1,
+ .spk71 = 1,
+ .spdif_bug = 1,
++ .invert_shared_spdif = 1, /* digital/analog switch swapped */
+ .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
+ .ac97_chip = 1} ,
+ {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
+--- a/sound/pci/emu10k1/emumixer.c
++++ b/sound/pci/emu10k1/emumixer.c
+@@ -1578,6 +1578,10 @@ static int snd_emu10k1_shared_spdif_get(
+ ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
+ else
+ ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
++ if (emu->card_capabilities->invert_shared_spdif)
++ ucontrol->value.integer.value[0] =
++ !ucontrol->value.integer.value[0];
++
+ return 0;
+ }
+
+@@ -1586,15 +1590,18 @@ static int snd_emu10k1_shared_spdif_put(
+ {
+ unsigned long flags;
+ struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+- unsigned int reg, val;
++ unsigned int reg, val, sw;
+ int change = 0;
+
++ sw = ucontrol->value.integer.value[0];
++ if (emu->card_capabilities->invert_shared_spdif)
++ sw = !sw;
+ spin_lock_irqsave(&emu->reg_lock, flags);
+ if ( emu->card_capabilities->i2c_adc) {
+ /* Do nothing for Audigy 2 ZS Notebook */
+ } else if (emu->audigy) {
+ reg = inl(emu->port + A_IOCFG);
+- val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
++ val = sw ? A_IOCFG_GPOUT0 : 0;
+ change = (reg & A_IOCFG_GPOUT0) != val;
+ if (change) {
+ reg &= ~A_IOCFG_GPOUT0;
+@@ -1603,7 +1610,7 @@ static int snd_emu10k1_shared_spdif_put(
+ }
+ }
+ reg = inl(emu->port + HCFG);
+- val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
++ val = sw ? HCFG_GPOUT0 : 0;
+ change |= (reg & HCFG_GPOUT0) != val;
+ if (change) {
+ reg &= ~HCFG_GPOUT0;
--- /dev/null
+From foo@baz Tue Apr 9 12:12:43 2002
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 17 Apr 2008 12:53:26 +0200
+Subject: ALSA: Fix Oops with usb-audio reconnection
+
+From: Takashi Iwai <tiwai@suse.de>
+
+Backport fixes for usb-audio Oops at reconnection.
+
+9eb70e6... [ALSA] usb-audio - Fix race in reconnection
+f18638d... [ALSA] Clean up snd_card_free*()
+73d38b1... [ALSA] Fix the race of card instance unregistration
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/core/init.c | 36 ++++++++++--------------
+ sound/usb/usbaudio.c | 35 +++++++++++++++++------
+ sound/usb/usbquirks.h | 75 +++++++++++++++++++++++++-------------------------
+ 3 files changed, 79 insertions(+), 67 deletions(-)
+
+--- a/sound/core/init.c
++++ b/sound/core/init.c
+@@ -311,6 +311,9 @@ int snd_card_disconnect(struct snd_card
+ struct file *file;
+ int err;
+
++ if (!card)
++ return -EINVAL;
++
+ spin_lock(&card->files_lock);
+ if (card->shutdown) {
+ spin_unlock(&card->files_lock);
+@@ -322,6 +325,7 @@ int snd_card_disconnect(struct snd_card
+ /* phase 1: disable fops (user space) operations for ALSA API */
+ mutex_lock(&snd_card_mutex);
+ snd_cards[card->number] = NULL;
++ snd_cards_lock &= ~(1 << card->number);
+ mutex_unlock(&snd_card_mutex);
+
+ /* phase 2: replace file->f_op with special dummy operations */
+@@ -360,6 +364,15 @@ int snd_card_disconnect(struct snd_card
+ snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
+
+ snd_info_card_disconnect(card);
++#ifndef CONFIG_SYSFS_DEPRECATED
++ if (card->card_dev) {
++ device_unregister(card->card_dev);
++ card->card_dev = NULL;
++ }
++#endif
++#ifdef CONFIG_PM
++ wake_up(&card->power_sleep);
++#endif
+ return 0;
+ }
+
+@@ -401,33 +414,14 @@ static int snd_card_do_free(struct snd_c
+ snd_printk(KERN_WARNING "unable to free card info\n");
+ /* Not fatal error */
+ }
+-#ifndef CONFIG_SYSFS_DEPRECATED
+- if (card->card_dev)
+- device_unregister(card->card_dev);
+-#endif
+ kfree(card);
+ return 0;
+ }
+
+-static int snd_card_free_prepare(struct snd_card *card)
+-{
+- if (card == NULL)
+- return -EINVAL;
+- (void) snd_card_disconnect(card);
+- mutex_lock(&snd_card_mutex);
+- snd_cards[card->number] = NULL;
+- snd_cards_lock &= ~(1 << card->number);
+- mutex_unlock(&snd_card_mutex);
+-#ifdef CONFIG_PM
+- wake_up(&card->power_sleep);
+-#endif
+- return 0;
+-}
+-
+ int snd_card_free_when_closed(struct snd_card *card)
+ {
+ int free_now = 0;
+- int ret = snd_card_free_prepare(card);
++ int ret = snd_card_disconnect(card);
+ if (ret)
+ return ret;
+
+@@ -447,7 +441,7 @@ EXPORT_SYMBOL(snd_card_free_when_closed)
+
+ int snd_card_free(struct snd_card *card)
+ {
+- int ret = snd_card_free_prepare(card);
++ int ret = snd_card_disconnect(card);
+ if (ret)
+ return ret;
+
+--- a/sound/usb/usbaudio.c
++++ b/sound/usb/usbaudio.c
+@@ -1762,8 +1762,10 @@ static int check_hw_params_convention(st
+
+ channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
+ rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL);
+- if (!channels || !rates)
++ if (!channels || !rates) {
++ err = -ENOMEM;
+ goto __out;
++ }
+
+ list_for_each(p, &subs->fmt_list) {
+ struct audioformat *f;
+@@ -1916,7 +1918,10 @@ static int setup_hw_info(struct snd_pcm_
+ 1000 * MIN_PACKS_URB,
+ /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX);
+
+- if (check_hw_params_convention(subs)) {
++ err = check_hw_params_convention(subs);
++ if (err < 0)
++ return err;
++ else if (err) {
+ hwc_debug("setting extra hw constraints...\n");
+ if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ hw_rule_rate, subs,
+@@ -2463,11 +2468,12 @@ static int parse_audio_format_i_type(str
+ }
+ break;
+ case USB_AUDIO_FORMAT_PCM8:
+- /* Dallas DS4201 workaround */
++ pcm_format = SNDRV_PCM_FORMAT_U8;
++
++ /* Dallas DS4201 workaround: it advertises U8 format, but really
++ supports S8. */
+ if (chip->usb_id == USB_ID(0x04fa, 0x4201))
+ pcm_format = SNDRV_PCM_FORMAT_S8;
+- else
+- pcm_format = SNDRV_PCM_FORMAT_U8;
+ break;
+ case USB_AUDIO_FORMAT_IEEE_FLOAT:
+ pcm_format = SNDRV_PCM_FORMAT_FLOAT_LE;
+@@ -2671,12 +2677,23 @@ static int parse_audio_endpoints(struct
+ int format;
+ struct audioformat *fp;
+ unsigned char *fmt, *csep;
++ int num;
+
+ dev = chip->dev;
+
+ /* parse the interface's altsettings */
+ iface = usb_ifnum_to_if(dev, iface_no);
+- for (i = 0; i < iface->num_altsetting; i++) {
++
++ num = iface->num_altsetting;
++
++ /*
++ * Dallas DS4201 workaround: It presents 5 altsettings, but the last
++ * one misses syncpipe, and does not produce any sound.
++ */
++ if (chip->usb_id == USB_ID(0x04fa, 0x4201))
++ num = 4;
++
++ for (i = 0; i < num; i++) {
+ alts = &iface->altsetting[i];
+ altsd = get_iface_desc(alts);
+ /* skip invalid one */
+@@ -3406,7 +3423,6 @@ static void snd_usb_audio_create_proc(st
+
+ static int snd_usb_audio_free(struct snd_usb_audio *chip)
+ {
+- usb_chip[chip->index] = NULL;
+ kfree(chip);
+ return 0;
+ }
+@@ -3600,8 +3616,8 @@ static void *snd_usb_audio_probe(struct
+ snd_card_set_dev(chip->card, &intf->dev);
+ break;
+ }
+- if (! chip) {
+- snd_printk(KERN_ERR "no available usb audio device\n");
++ if (!chip) {
++ printk(KERN_ERR "no available usb audio device\n");
+ goto __error;
+ }
+ }
+@@ -3671,6 +3687,7 @@ static void snd_usb_audio_disconnect(str
+ list_for_each(p, &chip->mixer_list) {
+ snd_usb_mixer_disconnect(p);
+ }
++ usb_chip[chip->index] = NULL;
+ mutex_unlock(®ister_mutex);
+ snd_card_free_when_closed(card);
+ } else {
+--- a/sound/usb/usbquirks.h
++++ b/sound/usb/usbquirks.h
+@@ -39,6 +39,30 @@
+ .idProduct = prod, \
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC
+
++/* Creative/E-Mu devices */
++{
++ USB_DEVICE(0x041e, 0x3010),
++ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
++ .vendor_name = "Creative Labs",
++ .product_name = "Sound Blaster MP3+",
++ .ifnum = QUIRK_NO_INTERFACE
++ }
++},
++{
++ /* E-Mu 0202 USB */
++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
++ .idVendor = 0x041e,
++ .idProduct = 0x3f02,
++ .bInterfaceClass = USB_CLASS_AUDIO,
++},
++{
++ /* E-Mu 0404 USB */
++ .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
++ .idVendor = 0x041e,
++ .idProduct = 0x3f04,
++ .bInterfaceClass = USB_CLASS_AUDIO,
++},
++
+ /*
+ * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
+ * class matches do not take effect without an explicit ID match.
+@@ -97,19 +121,7 @@
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+ },
+-/* E-Mu devices */
+-{
+- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+- .idVendor = 0x041e,
+- .idProduct = 0x3f02,
+- .bInterfaceClass = USB_CLASS_AUDIO,
+-},
+-{
+- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+- .idVendor = 0x041e,
+- .idProduct = 0x3f04,
+- .bInterfaceClass = USB_CLASS_AUDIO,
+-},
++
+ /*
+ * Yamaha devices
+ */
+@@ -1165,19 +1177,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ }
+ }
+ },
+-{
+- USB_DEVICE(0x582, 0x00a6),
+- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+- .vendor_name = "Roland",
+- .product_name = "Juno-G",
+- .ifnum = 0,
+- .type = QUIRK_MIDI_FIXED_ENDPOINT,
+- .data = & (const struct snd_usb_midi_endpoint_info) {
+- .out_cables = 0x0001,
+- .in_cables = 0x0001
+- }
+- }
+-},
+ { /*
+ * This quirk is for the "Advanced" modes of the Edirol UA-25.
+ * If the switch is not in an advanced setting, the UA-25 has
+@@ -1336,6 +1335,19 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ },
+ /* TODO: add Edirol MD-P1 support */
+ {
++ USB_DEVICE(0x582, 0x00a6),
++ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
++ .vendor_name = "Roland",
++ .product_name = "Juno-G",
++ .ifnum = 0,
++ .type = QUIRK_MIDI_FIXED_ENDPOINT,
++ .data = & (const struct snd_usb_midi_endpoint_info) {
++ .out_cables = 0x0001,
++ .in_cables = 0x0001
++ }
++ }
++},
++{
+ /* Roland SH-201 */
+ USB_DEVICE(0x0582, 0x00ad),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+@@ -1719,17 +1731,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ }
+ },
+
+-{
+- /* Creative Sound Blaster MP3+ */
+- USB_DEVICE(0x041e, 0x3010),
+- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+- .vendor_name = "Creative Labs",
+- .product_name = "Sound Blaster MP3+",
+- .ifnum = QUIRK_NO_INTERFACE
+- }
+-
+-},
+-
+ /* Emagic devices */
+ {
+ USB_DEVICE(0x086a, 0x0001),
--- /dev/null
+From 470eaf6be78424fc499a5039e5d5fe58bace2bc3 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 30 Jun 2008 16:40:10 +0200
+Subject: ALSA: hda - Add missing Thinkpad Z60m support
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 470eaf6be78424fc499a5039e5d5fe58bace2bc3 upstream
+
+Added the missing SSID of Thinkpad Z60m for model=thinkpad with
+AD1981HD.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Jaroslav Kysela <perex@perex.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/patch_analog.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_analog.c
++++ b/sound/pci/hda/patch_analog.c
+@@ -1563,6 +1563,7 @@ static const char *ad1981_models[AD1981_
+
+ static struct snd_pci_quirk ad1981_cfg_tbl[] = {
+ SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
++ SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
+ /* All HP models */
+ SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
+ SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
--- /dev/null
+From 43785eaeb1cfb8aed3cf8027f298b242f88fdc45 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 16 Jun 2008 15:47:26 +0200
+Subject: ALSA: hda - Fix wrong volumes in AD1988 auto-probe mode
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 43785eaeb1cfb8aed3cf8027f298b242f88fdc45 upstream
+
+Don't create mixer volume elements for Headphone and Speaker if they
+use the same DAC as normal line-outs on AD1988. Otherwise the amp
+value gets screwed up, e.g.
+ https://bugzilla.novell.com/show_bug.cgi?id=398255
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Jaroslav Kysela <perex@perex.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/patch_analog.c | 32 +++++++++++++++++++++-----------
+ 1 file changed, 21 insertions(+), 11 deletions(-)
+
+--- a/sound/pci/hda/patch_analog.c
++++ b/sound/pci/hda/patch_analog.c
+@@ -2558,7 +2558,7 @@ static int ad1988_auto_create_extra_out(
+ {
+ struct ad198x_spec *spec = codec->spec;
+ hda_nid_t nid;
+- int idx, err;
++ int i, idx, err;
+ char name[32];
+
+ if (! pin)
+@@ -2566,16 +2566,26 @@ static int ad1988_auto_create_extra_out(
+
+ idx = ad1988_pin_idx(pin);
+ nid = ad1988_idx_to_dac(codec, idx);
+- /* specify the DAC as the extra output */
+- if (! spec->multiout.hp_nid)
+- spec->multiout.hp_nid = nid;
+- else
+- spec->multiout.extra_out_nid[0] = nid;
+- /* control HP volume/switch on the output mixer amp */
+- sprintf(name, "%s Playback Volume", pfx);
+- if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
+- HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+- return err;
++ /* check whether the corresponding DAC was already taken */
++ for (i = 0; i < spec->autocfg.line_outs; i++) {
++ hda_nid_t pin = spec->autocfg.line_out_pins[i];
++ hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
++ if (dac == nid)
++ break;
++ }
++ if (i >= spec->autocfg.line_outs) {
++ /* specify the DAC as the extra output */
++ if (!spec->multiout.hp_nid)
++ spec->multiout.hp_nid = nid;
++ else
++ spec->multiout.extra_out_nid[0] = nid;
++ /* control HP volume/switch on the output mixer amp */
++ sprintf(name, "%s Playback Volume", pfx);
++ err = add_control(spec, AD_CTL_WIDGET_VOL, name,
++ HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
++ if (err < 0)
++ return err;
++ }
+ nid = ad1988_mixer_nids[idx];
+ sprintf(name, "%s Playback Switch", pfx);
+ if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
--- /dev/null
+From 90d95ef617a535a8832bdcb8dee07bf591e5dd82 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Tue, 17 Jun 2008 11:56:55 -0400
+Subject: Input: appletouch - implement reset-resume logic
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 90d95ef617a535a8832bdcb8dee07bf591e5dd82 upstream
+
+On some boxes the touchpad needs to be reinitialized after resume to make
+it function again. This fixes bugzilla #10825.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/input/mouse/appletouch.c | 49 ++++++++++++++++++++++++++++++++-------
+ drivers/usb/core/quirks.c | 3 ++
+ 2 files changed, 44 insertions(+), 8 deletions(-)
+
+--- a/drivers/input/mouse/appletouch.c
++++ b/drivers/input/mouse/appletouch.c
+@@ -589,6 +589,21 @@ static void atp_close(struct input_dev *
+ dev->open = 0;
+ }
+
++static int atp_handle_geyser(struct atp *dev)
++{
++ struct usb_device *udev = dev->udev;
++
++ if (!atp_is_fountain(dev)) {
++ /* switch to raw sensor mode */
++ if (atp_geyser_init(udev))
++ return -EIO;
++
++ printk(KERN_INFO "appletouch: Geyser mode initialized.\n");
++ }
++
++ return 0;
++}
++
+ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
+ {
+ struct atp *dev;
+@@ -633,14 +648,6 @@ static int atp_probe(struct usb_interfac
+ else
+ dev->datalen = 81;
+
+- if (!atp_is_fountain(dev)) {
+- /* switch to raw sensor mode */
+- if (atp_geyser_init(udev))
+- goto err_free_devs;
+-
+- printk(KERN_INFO "appletouch: Geyser mode initialized.\n");
+- }
+-
+ dev->urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->urb)
+ goto err_free_devs;
+@@ -654,6 +661,10 @@ static int atp_probe(struct usb_interfac
+ usb_rcvintpipe(udev, int_in_endpointAddr),
+ dev->data, dev->datalen, atp_complete, dev, 1);
+
++ error = atp_handle_geyser(dev);
++ if (error)
++ goto err_free_buffer;
++
+ usb_make_path(udev, dev->phys, sizeof(dev->phys));
+ strlcat(dev->phys, "/input0", sizeof(dev->phys));
+
+@@ -744,6 +755,20 @@ static void atp_disconnect(struct usb_in
+ printk(KERN_INFO "input: appletouch disconnected\n");
+ }
+
++static int atp_recover(struct atp *dev)
++{
++ int error;
++
++ error = atp_handle_geyser(dev);
++ if (error)
++ return error;
++
++ if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
++ return -EIO;
++
++ return 0;
++}
++
+ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
+ {
+ struct atp *dev = usb_get_intfdata(iface);
+@@ -764,12 +789,20 @@ static int atp_resume(struct usb_interfa
+ return 0;
+ }
+
++static int atp_reset_resume(struct usb_interface *iface)
++{
++ struct atp *dev = usb_get_intfdata(iface);
++
++ return atp_recover(dev);
++}
++
+ static struct usb_driver atp_driver = {
+ .name = "appletouch",
+ .probe = atp_probe,
+ .disconnect = atp_disconnect,
+ .suspend = atp_suspend,
+ .resume = atp_resume,
++ .reset_resume = atp_reset_resume,
+ .id_table = atp_table,
+ };
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -47,6 +47,9 @@ static const struct usb_device_id usb_qu
+ /* Edirol SD-20 */
+ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME },
+
++ /* appletouch */
++ { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ /* M-Systems Flash Disk Pioneers */
+ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
+
--- /dev/null
+From 66d715c95a39e84cd25204a665915621457d9691 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 4 Jul 2008 09:59:32 -0700
+Subject: pci: VT3336 can't do MSI either
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 66d715c95a39e84cd25204a665915621457d9691 upstream
+
+It seems VT3336 can't do msi either as with its bro 3351. Disable it.
+Reported in the following SUSE bug.
+
+ https://bugzilla.novell.com/show_bug.cgi?id=300001
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -1675,6 +1675,7 @@ static void __init quirk_disable_all_msi
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi);
+ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
+
+ /* Disable MSI on chipsets that are known to not support it */
ath5k-use-software-encryption-for-now.patch
add-compat-handler-for-ptrace_getsiginfo.patch
acpi-reject-below-freezing-temperatures-as-invalid-critical-temperatures.patch
+acpi-update-thermal-temperature.patch
+input-appletouch-implement-reset-resume-logic.patch
+usb-ehci-fix-remote-wakeup-regression.patch
+pci-vt3336-can-t-do-msi-either.patch
+alsa-ac97-fix-asus-a9t-laptop-output.patch
+alsa-add-more-fallbacks-to-oss-phoneout-mixer-map.patch
+alsa-emu10k1-fix-inverted-analog-digital-mixer-switch-on-audigy2.patch
+alsa-fix-oops-with-usb-audio-reconnection.patch
+alsa-hda-add-missing-thinkpad-z60m-support.patch
+alsa-hda-fix-wrong-volumes-in-ad1988-auto-probe-mode.patch
--- /dev/null
+From d1f114d12bb4db3147e1b1342ae31083c5a79c84 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 20 May 2008 16:58:58 -0400
+Subject: [PATCH] USB: EHCI: fix remote-wakeup regression
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit d1f114d12bb4db3147e1b1342ae31083c5a79c84 upstream
+
+This patch (as1097) fixes a bug in the remote-wakeup handling in
+ehci-hcd. The driver currently does not keep track of whether the
+change-suspend feature is enabled for each port; the feature is
+automatically reset the first time it is read. But recent changes to
+the hub driver require that the feature be read at least twice in
+order to work properly.
+
+A bit-vector is added for storing the change-suspend feature values.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hub.c | 6 ++++--
+ drivers/usb/host/ehci.h | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controlle
+ dedicated to the companion controller */
+ unsigned long owned_ports; /* which ports are
+ owned by the companion during a bus suspend */
++ unsigned long port_c_suspend; /* which ports have
++ the change-suspend feature turned on */
+
+ /* per-HC memory pools (could be per-bus, but ...) */
+ struct dma_pool *qh_pool; /* qh per active urb */
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -621,7 +621,7 @@ static int ehci_hub_control (
+ }
+ break;
+ case USB_PORT_FEAT_C_SUSPEND:
+- /* we auto-clear this feature */
++ clear_bit(wIndex, &ehci->port_c_suspend);
+ break;
+ case USB_PORT_FEAT_POWER:
+ if (HCS_PPC (ehci->hcs_params))
+@@ -700,7 +700,7 @@ static int ehci_hub_control (
+ /* resume completed? */
+ else if (time_after_eq(jiffies,
+ ehci->reset_done[wIndex])) {
+- status |= 1 << USB_PORT_FEAT_C_SUSPEND;
++ set_bit(wIndex, &ehci->port_c_suspend);
+ ehci->reset_done[wIndex] = 0;
+
+ /* stop resume signaling */
+@@ -777,6 +777,8 @@ static int ehci_hub_control (
+ status |= 1 << USB_PORT_FEAT_RESET;
+ if (temp & PORT_POWER)
+ status |= 1 << USB_PORT_FEAT_POWER;
++ if (test_bit(wIndex, &ehci->port_c_suspend))
++ status |= 1 << USB_PORT_FEAT_C_SUSPEND;
+
+ #ifndef EHCI_VERBOSE_DEBUG
+ if (status & ~0xffff) /* only if wPortChange is interesting */