فهرست منبع

Merge branch 'topic/misc-next' into topic/misc

Takashi Iwai 16 سال پیش
والد
کامیت
4fc85e451f

+ 2 - 2
sound/core/device.c

@@ -98,7 +98,7 @@ int snd_device_free(struct snd_card *card, void *device_data)
 		kfree(dev);
 		kfree(dev);
 		return 0;
 		return 0;
 	}
 	}
-	snd_printd("device free %p (from %p), not found\n", device_data,
+	snd_printd("device free %p (from %pF), not found\n", device_data,
 		   __builtin_return_address(0));
 		   __builtin_return_address(0));
 	return -ENXIO;
 	return -ENXIO;
 }
 }
@@ -135,7 +135,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
 		}
 		}
 		return 0;
 		return 0;
 	}
 	}
-	snd_printd("device disconnect %p (from %p), not found\n", device_data,
+	snd_printd("device disconnect %p (from %pF), not found\n", device_data,
 		   __builtin_return_address(0));
 		   __builtin_return_address(0));
 	return -ENXIO;
 	return -ENXIO;
 }
 }

+ 3 - 5
sound/drivers/pcsp/pcsp.c

@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ;
+	pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE;
 	pcsp_chip.timer.function = pcsp_do_timer;
 	pcsp_chip.timer.function = pcsp_do_timer;
 
 
 	card = snd_card_new(index, id, THIS_MODULE, 0);
 	card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -188,10 +188,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
 
 
 static void pcsp_stop_beep(struct snd_pcsp *chip)
 static void pcsp_stop_beep(struct snd_pcsp *chip)
 {
 {
-	spin_lock_irq(&chip->substream_lock);
-	if (!chip->playback_substream)
-		pcspkr_stop_sound();
-	spin_unlock_irq(&chip->substream_lock);
+	pcsp_sync_stop(chip);
+	pcspkr_stop_sound();
 }
 }
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM

+ 1 - 0
sound/drivers/pcsp/pcsp.h

@@ -77,6 +77,7 @@ struct snd_pcsp {
 extern struct snd_pcsp pcsp_chip;
 extern struct snd_pcsp pcsp_chip;
 
 
 extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
 extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
+extern void pcsp_sync_stop(struct snd_pcsp *chip);
 
 
 extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
 extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
 extern int snd_pcsp_new_mixer(struct snd_pcsp *chip);
 extern int snd_pcsp_new_mixer(struct snd_pcsp *chip);

+ 52 - 43
sound/drivers/pcsp/pcsp_lib.c

@@ -8,6 +8,7 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/moduleparam.h>
+#include <linux/interrupt.h>
 #include <sound/pcm.h>
 #include <sound/pcm.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include "pcsp.h"
 #include "pcsp.h"
@@ -19,6 +20,22 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
 
 
 #define DMIX_WANTS_S16	1
 #define DMIX_WANTS_S16	1
 
 
+/*
+ * Call snd_pcm_period_elapsed in a tasklet
+ * This avoids spinlock messes and long-running irq contexts
+ */
+static void pcsp_call_pcm_elapsed(unsigned long priv)
+{
+	if (atomic_read(&pcsp_chip.timer_active)) {
+		struct snd_pcm_substream *substream;
+		substream = pcsp_chip.playback_substream;
+		if (substream)
+			snd_pcm_period_elapsed(substream);
+	}
+}
+
+static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
+
 enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 {
 {
 	unsigned char timer_cnt, val;
 	unsigned char timer_cnt, val;
@@ -28,41 +45,23 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 	struct snd_pcm_substream *substream;
 	struct snd_pcm_substream *substream;
 	struct snd_pcm_runtime *runtime;
 	struct snd_pcm_runtime *runtime;
 	struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
 	struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
+	unsigned long flags;
 
 
 	if (chip->thalf) {
 	if (chip->thalf) {
 		outb(chip->val61, 0x61);
 		outb(chip->val61, 0x61);
 		chip->thalf = 0;
 		chip->thalf = 0;
 		if (!atomic_read(&chip->timer_active))
 		if (!atomic_read(&chip->timer_active))
-			return HRTIMER_NORESTART;
+			goto stop;
 		hrtimer_forward(&chip->timer, chip->timer.expires,
 		hrtimer_forward(&chip->timer, chip->timer.expires,
 				ktime_set(0, chip->ns_rem));
 				ktime_set(0, chip->ns_rem));
 		return HRTIMER_RESTART;
 		return HRTIMER_RESTART;
 	}
 	}
 
 
-	spin_lock_irq(&chip->substream_lock);
-	/* Takashi Iwai says regarding this extra lock:
-
-	If the irq handler handles some data on the DMA buffer, it should
-	do snd_pcm_stream_lock().
-	That protects basically against all races among PCM callbacks, yes.
-	However, there are two remaining issues:
-	1. The substream pointer you try to lock isn't protected _before_
-	  this lock yet.
-	2. snd_pcm_period_elapsed() itself acquires the lock.
-	The requirement of another lock is because of 1.  When you get
-	chip->playback_substream, it's not protected.
-	Keeping this lock while snd_pcm_period_elapsed() assures the substream
-	is still protected (at least, not released).  And the other status is
-	handled properly inside snd_pcm_stream_lock() in
-	snd_pcm_period_elapsed().
-
-	*/
-	if (!chip->playback_substream)
-		goto exit_nr_unlock1;
-	substream = chip->playback_substream;
-	snd_pcm_stream_lock(substream);
 	if (!atomic_read(&chip->timer_active))
 	if (!atomic_read(&chip->timer_active))
-		goto exit_nr_unlock2;
+		goto stop;
+	substream = chip->playback_substream;
+	if (!substream)
+		goto stop;
 
 
 	runtime = substream->runtime;
 	runtime = substream->runtime;
 	fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
 	fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
@@ -87,6 +86,8 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 
 
 	period_bytes = snd_pcm_lib_period_bytes(substream);
 	period_bytes = snd_pcm_lib_period_bytes(substream);
 	buffer_bytes = snd_pcm_lib_buffer_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() * fmt_size;
 	periods_elapsed = chip->playback_ptr - chip->period_ptr;
 	periods_elapsed = chip->playback_ptr - chip->period_ptr;
 	if (periods_elapsed < 0) {
 	if (periods_elapsed < 0) {
@@ -102,18 +103,15 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 	 * or ALSA will BUG on us. */
 	 * or ALSA will BUG on us. */
 	chip->playback_ptr %= buffer_bytes;
 	chip->playback_ptr %= buffer_bytes;
 
 
-	snd_pcm_stream_unlock(substream);
-
 	if (periods_elapsed) {
 	if (periods_elapsed) {
-		snd_pcm_period_elapsed(substream);
 		chip->period_ptr += periods_elapsed * period_bytes;
 		chip->period_ptr += periods_elapsed * period_bytes;
 		chip->period_ptr %= buffer_bytes;
 		chip->period_ptr %= buffer_bytes;
+		tasklet_schedule(&pcsp_pcm_tasklet);
 	}
 	}
-
-	spin_unlock_irq(&chip->substream_lock);
+	spin_unlock_irqrestore(&chip->substream_lock, flags);
 
 
 	if (!atomic_read(&chip->timer_active))
 	if (!atomic_read(&chip->timer_active))
-		return HRTIMER_NORESTART;
+		goto stop;
 
 
 	chip->ns_rem = PCSP_PERIOD_NS();
 	chip->ns_rem = PCSP_PERIOD_NS();
 	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
 	ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
@@ -121,10 +119,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
 	hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns));
 	hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns));
 	return HRTIMER_RESTART;
 	return HRTIMER_RESTART;
 
 
-exit_nr_unlock2:
-	snd_pcm_stream_unlock(substream);
-exit_nr_unlock1:
-	spin_unlock_irq(&chip->substream_lock);
+ stop:
 	return HRTIMER_NORESTART;
 	return HRTIMER_NORESTART;
 }
 }
 
 
@@ -164,26 +159,35 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
 	spin_unlock(&i8253_lock);
 	spin_unlock(&i8253_lock);
 }
 }
 
 
+/*
+ * Force to stop and sync the stream
+ */
+void pcsp_sync_stop(struct snd_pcsp *chip)
+{
+	local_irq_disable();
+	pcsp_stop_playing(chip);
+	local_irq_enable();
+	hrtimer_cancel(&chip->timer);
+	tasklet_kill(&pcsp_pcm_tasklet);
+}
+
 static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
 static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
 {
 {
 	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
 	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
 #if PCSP_DEBUG
 #if PCSP_DEBUG
 	printk(KERN_INFO "PCSP: close called\n");
 	printk(KERN_INFO "PCSP: close called\n");
 #endif
 #endif
-	if (atomic_read(&chip->timer_active)) {
-		printk(KERN_ERR "PCSP: timer still active\n");
-		pcsp_stop_playing(chip);
-	}
-	spin_lock_irq(&chip->substream_lock);
+	pcsp_sync_stop(chip);
 	chip->playback_substream = NULL;
 	chip->playback_substream = NULL;
-	spin_unlock_irq(&chip->substream_lock);
 	return 0;
 	return 0;
 }
 }
 
 
 static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
 static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
 				       struct snd_pcm_hw_params *hw_params)
 				       struct snd_pcm_hw_params *hw_params)
 {
 {
+	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
 	int err;
 	int err;
+	pcsp_sync_stop(chip);
 	err = snd_pcm_lib_malloc_pages(substream,
 	err = snd_pcm_lib_malloc_pages(substream,
 				      params_buffer_bytes(hw_params));
 				      params_buffer_bytes(hw_params));
 	if (err < 0)
 	if (err < 0)
@@ -193,9 +197,11 @@ static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
 
 
 static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
 static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
 {
 {
+	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
 #if PCSP_DEBUG
 #if PCSP_DEBUG
 	printk(KERN_INFO "PCSP: hw_free called\n");
 	printk(KERN_INFO "PCSP: hw_free called\n");
 #endif
 #endif
+	pcsp_sync_stop(chip);
 	return snd_pcm_lib_free_pages(substream);
 	return snd_pcm_lib_free_pages(substream);
 }
 }
 
 
@@ -211,6 +217,7 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
 			snd_pcm_lib_period_bytes(substream),
 			snd_pcm_lib_period_bytes(substream),
 			substream->runtime->periods);
 			substream->runtime->periods);
 #endif
 #endif
+	pcsp_sync_stop(chip);
 	chip->playback_ptr = 0;
 	chip->playback_ptr = 0;
 	chip->period_ptr = 0;
 	chip->period_ptr = 0;
 	return 0;
 	return 0;
@@ -241,7 +248,11 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
 						   *substream)
 						   *substream)
 {
 {
 	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
 	struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
-	return bytes_to_frames(substream->runtime, chip->playback_ptr);
+	unsigned int pos;
+	spin_lock(&chip->substream_lock);
+	pos = chip->playback_ptr;
+	spin_unlock(&chip->substream_lock);
+	return bytes_to_frames(substream->runtime, pos);
 }
 }
 
 
 static struct snd_pcm_hardware snd_pcsp_playback = {
 static struct snd_pcm_hardware snd_pcsp_playback = {
@@ -278,9 +289,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 	runtime->hw = snd_pcsp_playback;
 	runtime->hw = snd_pcsp_playback;
-	spin_lock_irq(&chip->substream_lock);
 	chip->playback_substream = substream;
 	chip->playback_substream = substream;
-	spin_unlock_irq(&chip->substream_lock);
 	return 0;
 	return 0;
 }
 }
 
 

+ 2 - 0
sound/pci/ac97/ac97_patch.c

@@ -2832,6 +2832,8 @@ static int patch_alc655(struct snd_ac97 * ac97)
 			val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
 			val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
 		else
 		else
 			val |= (1 << 1); /* Pin 47 is spdif input pin */
 			val |= (1 << 1); /* Pin 47 is spdif input pin */
+		/* this seems missing on some hardwares */
+		ac97->ext_id |= AC97_EI_SPDIF;
 	}
 	}
 	val &= ~(1 << 12); /* vref enable */
 	val &= ~(1 << 12); /* vref enable */
 	snd_ac97_write_cache(ac97, 0x7a, val);
 	snd_ac97_write_cache(ac97, 0x7a, val);

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 212 - 205
sound/pci/emu10k1/emu10k1_main.c


+ 68 - 20
sound/pci/hda/patch_realtek.c

@@ -822,6 +822,27 @@ static void alc_sku_automute(struct hda_codec *codec)
 			    spec->jack_present ? 0 : PIN_OUT);
 			    spec->jack_present ? 0 : PIN_OUT);
 }
 }
 
 
+static void alc_mic_automute(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	unsigned int present;
+	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
+	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
+	unsigned int mix_nid = spec->capsrc_nids[0];
+	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
+
+	capsrc_idx_mic = mic_nid - 0x18;
+	capsrc_idx_fmic = fmic_nid - 0x18;
+	present = snd_hda_codec_read(codec, mic_nid, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
+	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
+	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
+			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+}
+
 /* unsolicited event for HP jack sensing */
 /* unsolicited event for HP jack sensing */
 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 {
 {
@@ -829,10 +850,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 		res >>= 28;
 		res >>= 28;
 	else
 	else
 		res >>= 26;
 		res >>= 26;
-	if (res != ALC880_HP_EVENT)
-		return;
+	if (res == ALC880_HP_EVENT)
+		alc_sku_automute(codec);
+
+	if (res == ALC880_MIC_EVENT)
+		alc_mic_automute(codec);
+}
 
 
+static void alc_inithook(struct hda_codec *codec)
+{
 	alc_sku_automute(codec);
 	alc_sku_automute(codec);
+	alc_mic_automute(codec);
 }
 }
 
 
 /* additional initialization for ALC888 variants */
 /* additional initialization for ALC888 variants */
@@ -1018,10 +1046,17 @@ do_sku:
 		else
 		else
 			return;
 			return;
 	}
 	}
+	if (spec->autocfg.hp_pins[0])
+		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
+			AC_VERB_SET_UNSOLICITED_ENABLE,
+			AC_USRSP_EN | ALC880_HP_EVENT);
 
 
-	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
-			    AC_VERB_SET_UNSOLICITED_ENABLE,
-			    AC_USRSP_EN | ALC880_HP_EVENT);
+	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);
 
 
 	spec->unsol_event = alc_sku_unsol_event;
 	spec->unsol_event = alc_sku_unsol_event;
 }
 }
@@ -3808,7 +3843,7 @@ static void alc880_auto_init(struct hda_codec *codec)
 	alc880_auto_init_extra_out(codec);
 	alc880_auto_init_extra_out(codec);
 	alc880_auto_init_analog_input(codec);
 	alc880_auto_init_analog_input(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 /*
 /*
@@ -5219,7 +5254,7 @@ static void alc260_auto_init(struct hda_codec *codec)
 	alc260_auto_init_multi_out(codec);
 	alc260_auto_init_multi_out(codec);
 	alc260_auto_init_analog_input(codec);
 	alc260_auto_init_analog_input(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -6629,7 +6664,7 @@ static void alc882_auto_init(struct hda_codec *codec)
 	alc882_auto_init_analog_input(codec);
 	alc882_auto_init_analog_input(codec);
 	alc882_auto_init_input_src(codec);
 	alc882_auto_init_input_src(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
@@ -8306,8 +8341,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
 	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
+	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
 	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
-	SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
 	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
 	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
 	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
 	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
@@ -8758,7 +8793,7 @@ static void alc883_auto_init(struct hda_codec *codec)
 	alc883_auto_init_analog_input(codec);
 	alc883_auto_init_analog_input(codec);
 	alc883_auto_init_input_src(codec);
 	alc883_auto_init_input_src(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 static int patch_alc883(struct hda_codec *codec)
 static int patch_alc883(struct hda_codec *codec)
@@ -8802,8 +8837,13 @@ static int patch_alc883(struct hda_codec *codec)
 
 
 	switch (codec->vendor_id) {
 	switch (codec->vendor_id) {
 	case 0x10ec0888:
 	case 0x10ec0888:
-		spec->stream_name_analog = "ALC888 Analog";
-		spec->stream_name_digital = "ALC888 Digital";
+		if (codec->revision_id == 0x100101) {
+			spec->stream_name_analog = "ALC1200 Analog";
+			spec->stream_name_digital = "ALC1200 Digital";
+		} else {
+			spec->stream_name_analog = "ALC888 Analog";
+			spec->stream_name_digital = "ALC888 Digital";
+		}
 		break;
 		break;
 	case 0x10ec0889:
 	case 0x10ec0889:
 		spec->stream_name_analog = "ALC889 Analog";
 		spec->stream_name_analog = "ALC889 Analog";
@@ -10285,7 +10325,7 @@ static void alc262_auto_init(struct hda_codec *codec)
 	alc262_auto_init_analog_input(codec);
 	alc262_auto_init_analog_input(codec);
 	alc262_auto_init_input_src(codec);
 	alc262_auto_init_input_src(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 /*
 /*
@@ -10343,7 +10383,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
 	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
 		      ALC262_TOSHIBA_RX1),
 		      ALC262_TOSHIBA_RX1),
-	SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
+	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
 	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
 	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
 	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
 	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
 	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
 	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
@@ -11417,7 +11457,7 @@ static void alc268_auto_init(struct hda_codec *codec)
 	alc268_auto_init_mono_speaker_out(codec);
 	alc268_auto_init_mono_speaker_out(codec);
 	alc268_auto_init_analog_input(codec);
 	alc268_auto_init_analog_input(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 /*
 /*
@@ -12200,7 +12240,7 @@ static void alc269_auto_init(struct hda_codec *codec)
 	alc269_auto_init_hp_out(codec);
 	alc269_auto_init_hp_out(codec);
 	alc269_auto_init_analog_input(codec);
 	alc269_auto_init_analog_input(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 /*
 /*
@@ -13281,7 +13321,7 @@ static void alc861_auto_init(struct hda_codec *codec)
 	alc861_auto_init_hp_out(codec);
 	alc861_auto_init_hp_out(codec);
 	alc861_auto_init_analog_input(codec);
 	alc861_auto_init_analog_input(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 #ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -14393,7 +14433,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
 	alc861vd_auto_init_analog_input(codec);
 	alc861vd_auto_init_analog_input(codec);
 	alc861vd_auto_init_input_src(codec);
 	alc861vd_auto_init_input_src(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 static int patch_alc861vd(struct hda_codec *codec)
 static int patch_alc861vd(struct hda_codec *codec)
@@ -15667,7 +15707,7 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
 
 
 static struct snd_pci_quirk alc662_cfg_tbl[] = {
 static struct snd_pci_quirk alc662_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
 	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
-	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
+	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
 	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
 	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
 	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
 	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
 	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
@@ -15680,6 +15720,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
+	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
 	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
 	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
 	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
 	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
 	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
 	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
@@ -16223,7 +16264,7 @@ static void alc662_auto_init(struct hda_codec *codec)
 	alc662_auto_init_analog_input(codec);
 	alc662_auto_init_analog_input(codec);
 	alc662_auto_init_input_src(codec);
 	alc662_auto_init_input_src(codec);
 	if (spec->unsol_event)
 	if (spec->unsol_event)
-		alc_sku_automute(codec);
+		alc_inithook(codec);
 }
 }
 
 
 static int patch_alc662(struct hda_codec *codec)
 static int patch_alc662(struct hda_codec *codec)
@@ -16268,6 +16309,9 @@ static int patch_alc662(struct hda_codec *codec)
 	if (codec->vendor_id == 0x10ec0663) {
 	if (codec->vendor_id == 0x10ec0663) {
 		spec->stream_name_analog = "ALC663 Analog";
 		spec->stream_name_analog = "ALC663 Analog";
 		spec->stream_name_digital = "ALC663 Digital";
 		spec->stream_name_digital = "ALC663 Digital";
+	} else if (codec->vendor_id == 0x10ec0272) {
+		spec->stream_name_analog = "ALC272 Analog";
+		spec->stream_name_digital = "ALC272 Digital";
 	} else {
 	} else {
 		spec->stream_name_analog = "ALC662 Analog";
 		spec->stream_name_analog = "ALC662 Analog";
 		spec->stream_name_digital = "ALC662 Digital";
 		spec->stream_name_digital = "ALC662 Digital";
@@ -16305,6 +16349,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
 	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
 	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
 	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
 	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
 	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
 	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
+	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
 	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
 	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
 	  .patch = patch_alc861 },
 	  .patch = patch_alc861 },
 	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
 	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
@@ -16323,7 +16368,10 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
 	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
 	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
 	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
 	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
 	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
 	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
+	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
 	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
 	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
+	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
+	  .patch = patch_alc883 },
 	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
 	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
 	{} /* terminator */
 	{} /* terminator */
 };
 };

+ 1 - 1
sound/pci/hda/patch_sigmatel.c

@@ -2816,7 +2816,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
 	static const char *chname[4] = {
 	static const char *chname[4] = {
 		"Front", "Surround", NULL /*CLFE*/, "Side"
 		"Front", "Surround", NULL /*CLFE*/, "Side"
 	};
 	};
-	hda_nid_t nid;
+	hda_nid_t nid = 0;
 	int i, err;
 	int i, err;
 
 
 	struct sigmatel_spec *spec = codec->spec;
 	struct sigmatel_spec *spec = codec->spec;

+ 12 - 8
sound/pci/ice1712/ice1724.c

@@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
 	unsigned char status_mask =
 	unsigned char status_mask =
 		VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
 		VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
 	int handled = 0;
 	int handled = 0;
-#ifdef CONFIG_SND_DEBUG
 	int timeout = 0;
 	int timeout = 0;
-#endif
 
 
 	while (1) {
 	while (1) {
 		status = inb(ICEREG1724(ice, IRQSTAT));
 		status = inb(ICEREG1724(ice, IRQSTAT));
 		status &= status_mask;
 		status &= status_mask;
 		if (status == 0)
 		if (status == 0)
 			break;
 			break;
-#ifdef CONFIG_SND_DEBUG
 		if (++timeout > 10) {
 		if (++timeout > 10) {
-			printk(KERN_ERR
-			       "ice1724: Too long irq loop, status = 0x%x\n",
-			       status);
+			status = inb(ICEREG1724(ice, IRQSTAT));
+			printk(KERN_ERR "ice1724: Too long irq loop, "
+			       "status = 0x%x\n", status);
+			if (status & VT1724_IRQ_MPU_TX) {
+				printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
+				outb(inb(ICEREG1724(ice, IRQMASK)) &
+				     ~VT1724_IRQ_MPU_TX,
+				     ICEREG1724(ice, IRQMASK));
+			}
 			break;
 			break;
 		}
 		}
-#endif
 		handled = 1;
 		handled = 1;
 		if (status & VT1724_IRQ_MPU_TX) {
 		if (status & VT1724_IRQ_MPU_TX) {
 			spin_lock(&ice->reg_lock);
 			spin_lock(&ice->reg_lock);
@@ -2351,7 +2353,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
 {
 {
 	struct snd_ice1712 *ice;
 	struct snd_ice1712 *ice;
 	int err;
 	int err;
-	unsigned char mask;
+	/* unsigned char mask; */
 	static struct snd_device_ops ops = {
 	static struct snd_device_ops ops = {
 		.dev_free =	snd_vt1724_dev_free,
 		.dev_free =	snd_vt1724_dev_free,
 	};
 	};
@@ -2413,8 +2415,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
 	}
 	}
 
 
 	/* unmask used interrupts */
 	/* unmask used interrupts */
+#if 0 /* these are enabled/disabled dynamically */
 	mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
 	mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX;
 	outb(mask, ICEREG1724(ice, IRQMASK));
 	outb(mask, ICEREG1724(ice, IRQMASK));
+#endif
 	/* don't handle FIFO overrun/underruns (just yet),
 	/* don't handle FIFO overrun/underruns (just yet),
 	 * since they cause machine lockups
 	 * since they cause machine lockups
 	 */
 	 */

+ 1 - 1
sound/soc/codecs/Kconfig

@@ -68,7 +68,7 @@ config SND_SOC_TLV320AIC23
 	depends on I2C
 	depends on I2C
 
 
 config SND_SOC_TLV320AIC26
 config SND_SOC_TLV320AIC26
-	tristate "TI TLV320AIC26 Codec support"
+	tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
 	depends on SPI
 	depends on SPI
 
 
 config SND_SOC_TLV320AIC3X
 config SND_SOC_TLV320AIC3X

+ 5 - 5
sound/soc/codecs/tlv320aic23.c

@@ -84,7 +84,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
 			     unsigned int value)
 			     unsigned int value)
 {
 {
 
 
-	u8 data;
+	u8 data[2];
 
 
 	/* TLV320AIC23 has 7 bit address and 9 bits of data
 	/* TLV320AIC23 has 7 bit address and 9 bits of data
 	 * so we need to switch one data bit into reg and rest
 	 * so we need to switch one data bit into reg and rest
@@ -96,12 +96,12 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
 		return -1;
 		return -1;
 	}
 	}
 
 
-	data = (reg << 1) | (value >> 8 & 0x01);
+	data[0] = (reg << 1) | (value >> 8 & 0x01);
+	data[1] = value & 0xff;
 
 
 	tlv320aic23_write_reg_cache(codec, reg, value);
 	tlv320aic23_write_reg_cache(codec, reg, value);
 
 
-	if (codec->hw_write(codec->control_data, data,
-			    (value & 0xff)) == 0)
+	if (codec->hw_write(codec->control_data, data, 2) == 2)
 		return 0;
 		return 0;
 
 
 	printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
 	printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
@@ -674,7 +674,7 @@ static int tlv320aic23_probe(struct platform_device *pdev)
 
 
 	tlv320aic23_socdev = socdev;
 	tlv320aic23_socdev = socdev;
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
+	codec->hw_write = (hw_write_t) i2c_master_send;
 	codec->hw_read = NULL;
 	codec->hw_read = NULL;
 	ret = i2c_add_driver(&tlv320aic23_i2c_driver);
 	ret = i2c_add_driver(&tlv320aic23_i2c_driver);
 	if (ret != 0)
 	if (ret != 0)

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است