瀏覽代碼

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: Allow to force model to intel-mac-v3 in snd_hda_intel (sigmatel).
  ALSA: cs4232: fix crash during chip PNP detection
  ALSA: hda - Add automatic model setting for the Acer Aspire 5920G laptop
  ALSA: make snd_ac97_add_vmaster() static
  ALSA: sound/pci/azt3328.h: no variables for enums
  ALSA: soc - wm9712 mono mixer
  ALSA: hda - Add support of ASUS Eeepc P90*
  ALSA: opti9xx: no isapnp param for !CONFIG_PNP
  ALSA: opti93x - Fix NULL dereference
  ALSA: hda - Added support for Asus V1Sn
  ALSA: ASoC: Factor PGA DAPM handling into main
  ALSA: ASoC: Refactor DAPM event handler
  ALSA: ALSA: ens1370: communicate PCI device to AC97
  ALSA: ens1370: SRC stands for Sample Rate Converter
  ALSA: hda - Align BDL position adjustment parameter
  ALSA: Au1xpsc: psc not disabled when TX is idle
  ALSA: add TriTech 28023 AC97 codec ID and Wolfson 9701 name.
Linus Torvalds 17 年之前
父節點
當前提交
3756144225

+ 1 - 0
Documentation/sound/alsa/ALSA-Configuration.txt

@@ -1024,6 +1024,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
 	  intel-mac-v3	Intel Mac Type 3
 	  intel-mac-v4	Intel Mac Type 4
 	  intel-mac-v5	Intel Mac Type 5
+	  intel-mac-auto Intel Mac (detect type according to subsystem id)
 	  macmini	Intel Mac Mini (equivalent with type 3)
 	  macbook	Intel Mac Book (eq. type 5)
 	  macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)

+ 1 - 0
sound/isa/cs423x/cs4236.c

@@ -325,6 +325,7 @@ static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev)
 static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard,
 					 struct pnp_dev *pdev)
 {
+	acard->wss = pdev;
 	if (snd_cs423x_pnp_init_wss(dev, acard->wss) < 0)
 		return -EBUSY;
 	cport[dev] = -1;

+ 5 - 1
sound/isa/opti9xx/opti92x-ad1848.c

@@ -68,7 +68,9 @@ MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)},"
 static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
 static char *id = SNDRV_DEFAULT_STR1;		/* ID for this card */
 //static int enable = SNDRV_DEFAULT_ENABLE1;	/* Enable this card */
+#ifdef CONFIG_PNP
 static int isapnp = 1;			/* Enable ISA PnP detection */
+#endif
 static long port = SNDRV_DEFAULT_PORT1; 	/* 0x530,0xe80,0xf40,0x604 */
 static long mpu_port = SNDRV_DEFAULT_PORT1;	/* 0x300,0x310,0x320,0x330 */
 static long fm_port = SNDRV_DEFAULT_PORT1;	/* 0x388 */
@@ -85,8 +87,10 @@ module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for opti9xx based soundcard.");
 //module_param(enable, bool, 0444);
 //MODULE_PARM_DESC(enable, "Enable opti9xx soundcard.");
+#ifdef CONFIG_PNP
 module_param(isapnp, bool, 0444);
 MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
+#endif
 module_param(port, long, 0444);
 MODULE_PARM_DESC(port, "WSS port # for opti9xx driver.");
 module_param(mpu_port, long, 0444);
@@ -688,7 +692,7 @@ static void snd_card_opti9xx_free(struct snd_card *card)
 	if (chip) {
 #ifdef OPTi93X
 		struct snd_cs4231 *codec = chip->codec;
-		if (codec->irq > 0) {
+		if (codec && codec->irq > 0) {
 			disable_irq(codec->irq);
 			free_irq(codec->irq, codec);
 		}

+ 2 - 1
sound/pci/ac97/ac97_codec.c

@@ -161,6 +161,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
 { 0x50534304, 0xffffffff, "UCB1400",		patch_ucb1400,	NULL },
 { 0x53494c20, 0xffffffe0, "Si3036,8",		mpatch_si3036,	mpatch_si3036, AC97_MODEM_PATCH },
 { 0x54524102, 0xffffffff, "TR28022",		NULL,		NULL },
+{ 0x54524103, 0xffffffff, "TR28023",		NULL,		NULL },
 { 0x54524106, 0xffffffff, "TR28026",		NULL,		NULL },
 { 0x54524108, 0xffffffff, "TR28028",		patch_tritech_tr28028,	NULL }, // added by xin jin [07/09/99]
 { 0x54524123, 0xffffffff, "TR28602",		NULL,		NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
@@ -169,7 +170,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
 { 0x56494170, 0xffffffff, "VIA1617A",		patch_vt1617a,	NULL }, // modified VT1616 with S/PDIF
 { 0x56494182, 0xffffffff, "VIA1618",		NULL,		NULL },
 { 0x57454301, 0xffffffff, "W83971D",		NULL,		NULL },
-{ 0x574d4c00, 0xffffffff, "WM9701A",		NULL,		NULL },
+{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A",	NULL,		NULL },
 { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
 { 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q",	patch_wolfson04, NULL},
 { 0x574d4C05, 0xffffffff, "WM9705,WM9710",	patch_wolfson05, NULL},

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

@@ -3381,8 +3381,8 @@ static struct snd_kcontrol *snd_ac97_find_mixer_ctl(struct snd_ac97 *ac97,
 }
 
 /* create a virtual master control and add slaves */
-int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
-			 const unsigned int *tlv, const char **slaves)
+static int snd_ac97_add_vmaster(struct snd_ac97 *ac97, char *name,
+				const unsigned int *tlv, const char **slaves)
 {
 	struct snd_kcontrol *kctl;
 	const char **s;

+ 2 - 2
sound/pci/azt3328.h

@@ -94,7 +94,7 @@ enum azf_freq_t {
   AZF_FREQ(48000),
   AZF_FREQ(66200),
 #undef AZF_FREQ
-} AZF_FREQUENCIES;
+};
 
 /** recording area (see also: playback bit flag definitions) **/
 #define IDX_IO_REC_FLAGS	0x20 /* ??, PU:0x0000 */
@@ -210,7 +210,7 @@ enum azf_freq_t {
 
 enum {
 	AZF_GAME_LEGACY_IO_PORT = 0x200
-} AZF_GAME_CONFIGS;
+};
 
 #define IDX_GAME_LEGACY_COMPATIBLE	0x00
 	/* in some operation mode, writing anything to this port

+ 2 - 1
sound/pci/ens1370.c

@@ -522,7 +522,7 @@ static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
 			return r;
 		cond_resched();
 	}
-	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n",
+	snd_printk(KERN_ERR "wait src ready timeout 0x%lx [0x%x]\n",
 		   ES_REG(ensoniq, 1371_SMPRATE), r);
 	return 0;
 }
@@ -1629,6 +1629,7 @@ static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = ensoniq;
 	ac97.private_free = snd_ensoniq_mixer_free_ac97;
+	ac97.pci = ensoniq->pci;
 	ac97.scaps = AC97_SCAP_AUDIO;
 	if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
 		return err;

+ 5 - 1
sound/pci/hda/hda_intel.c

@@ -1047,9 +1047,13 @@ static int azx_setup_periods(struct azx *chip,
 	pos_adj = bdl_pos_adj[chip->dev_index];
 	if (pos_adj > 0) {
 		struct snd_pcm_runtime *runtime = substream->runtime;
+		int pos_align = pos_adj;
 		pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
 		if (!pos_adj)
-			pos_adj = 1;
+			pos_adj = pos_align;
+		else
+			pos_adj = ((pos_adj + pos_align - 1) / pos_align) *
+				pos_align;
 		pos_adj = frames_to_bytes(runtime, pos_adj);
 		if (pos_adj >= period_bytes) {
 			snd_printk(KERN_WARNING "Too big adjustment %d\n",

+ 174 - 7
sound/pci/hda/patch_realtek.c

@@ -122,6 +122,8 @@ enum {
 /* ALC269 models */
 enum {
 	ALC269_BASIC,
+	ALC269_ASUS_EEEPC_P703,
+	ALC269_ASUS_EEEPC_P901,
 	ALC269_AUTO,
 	ALC269_MODEL_LAST /* last tag */
 };
@@ -7905,6 +7907,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", 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), 
 	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
 	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
 	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -10946,7 +10949,23 @@ static int patch_alc268(struct hda_codec *codec)
 
 static hda_nid_t alc269_adc_nids[1] = {
 	/* ADC1 */
-	0x07,
+	0x08,
+};
+
+static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "i-Mic", 0x5 },
+		{ "e-Mic", 0x0 },
+	},
+};
+
+static struct hda_input_mux alc269_eeepc_amic_capture_source = {
+	.num_items = 2,
+	.items = {
+		{ "i-Mic", 0x1 },
+		{ "e-Mic", 0x0 },
+	},
 };
 
 #define alc269_modes		alc260_modes
@@ -10968,10 +10987,27 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
 	{ } /* end */
 };
 
+/* bind volumes of both NID 0x0c and 0x0d */
+static struct hda_bind_ctls alc269_epc_bind_vol = {
+	.ops = &snd_hda_bind_vol,
+	.values = {
+		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
+		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
+		0
+	},
+};
+
+static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
+	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
+	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	{ } /* end */
+};
+
 /* capture mixer elements */
 static struct snd_kcontrol_new alc269_capture_mixer[] = {
-	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		/* The multiple "Capture Source" controls confuse alsamixer
@@ -10987,6 +11023,13 @@ static struct snd_kcontrol_new alc269_capture_mixer[] = {
 	{ } /* end */
 };
 
+/* capture mixer elements */
+static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{ } /* end */
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -10994,7 +11037,7 @@ static struct hda_verb alc269_init_verbs[] = {
 	/*
 	 * Unmute ADC0 and set the default input to mic-in
 	 */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 
 	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
 	 * analog-loopback mixer widget
@@ -11057,6 +11100,98 @@ static struct hda_verb alc269_init_verbs[] = {
 	{ }
 };
 
+static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+	{}
+};
+
+static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
+	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+	{}
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc269_speaker_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+	unsigned int bits;
+
+	present = snd_hda_codec_read(codec, 0x15, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	bits = present ? AMP_IN_MUTE(0) : 0;
+	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
+				 AMP_IN_MUTE(0), bits);
+	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
+				 AMP_IN_MUTE(0), bits);
+}
+
+static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
+		& AC_PINSENSE_PRESENCE;
+	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
+			    present ? 0 : 5);
+}
+
+static void alc269_eeepc_amic_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
+		& AC_PINSENSE_PRESENCE;
+	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0));
+	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+			    present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1));
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
+					  unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc269_speaker_automute(codec);
+
+	if ((res >> 26) == ALC880_MIC_EVENT)
+		alc269_eeepc_dmic_automute(codec);
+}
+
+static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
+{
+	alc269_speaker_automute(codec);
+	alc269_eeepc_dmic_automute(codec);
+}
+
+/* unsolicited event for HP jack sensing */
+static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
+					  unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc269_speaker_automute(codec);
+
+	if ((res >> 26) == ALC880_MIC_EVENT)
+		alc269_eeepc_amic_automute(codec);
+}
+
+static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
+{
+	alc269_speaker_automute(codec);
+	alc269_eeepc_amic_automute(codec);
+}
+
 /* add playback controls from the parsed DAC table */
 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
 					     const struct auto_pin_cfg *cfg)
@@ -11188,6 +11323,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
 	if (err < 0)
 		return err;
 
+	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
+	spec->num_mixers++;
+
 	return 1;
 }
 
@@ -11215,12 +11353,16 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
 };
 
 static struct snd_pci_quirk alc269_cfg_tbl[] = {
+	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
+		      ALC269_ASUS_EEEPC_P703),
+	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
+		      ALC269_ASUS_EEEPC_P901),
 	{}
 };
 
 static struct alc_config_preset alc269_presets[] = {
 	[ALC269_BASIC] = {
-		.mixers = { alc269_base_mixer },
+		.mixers = { alc269_base_mixer, alc269_capture_mixer },
 		.init_verbs = { alc269_init_verbs },
 		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
 		.dac_nids = alc269_dac_nids,
@@ -11229,6 +11371,32 @@ static struct alc_config_preset alc269_presets[] = {
 		.channel_mode = alc269_modes,
 		.input_mux = &alc269_capture_source,
 	},
+	[ALC269_ASUS_EEEPC_P703] = {
+		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
+		.init_verbs = { alc269_init_verbs,
+				alc269_eeepc_amic_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
+		.dac_nids = alc269_dac_nids,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc269_modes),
+		.channel_mode = alc269_modes,
+		.input_mux = &alc269_eeepc_amic_capture_source,
+		.unsol_event = alc269_eeepc_amic_unsol_event,
+		.init_hook = alc269_eeepc_amic_inithook,
+	},
+	[ALC269_ASUS_EEEPC_P901] = {
+		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
+		.init_verbs = { alc269_init_verbs,
+				alc269_eeepc_dmic_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
+		.dac_nids = alc269_dac_nids,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc269_modes),
+		.channel_mode = alc269_modes,
+		.input_mux = &alc269_eeepc_dmic_capture_source,
+		.unsol_event = alc269_eeepc_dmic_unsol_event,
+		.init_hook = alc269_eeepc_dmic_inithook,
+	},
 };
 
 static int patch_alc269(struct hda_codec *codec)
@@ -11282,8 +11450,6 @@ static int patch_alc269(struct hda_codec *codec)
 
 	spec->adc_nids = alc269_adc_nids;
 	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
-	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
-	spec->num_mixers++;
 
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC269_AUTO)
@@ -12994,6 +13160,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
 	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
+	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
 	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
 	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),

+ 11 - 3
sound/pci/hda/patch_sigmatel.c

@@ -94,6 +94,9 @@ enum {
 	STAC_INTEL_MAC_V3,
 	STAC_INTEL_MAC_V4,
 	STAC_INTEL_MAC_V5,
+	STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter
+			      * is given, one of the above models will be
+			      * chosen according to the subsystem id. */
 	/* for backward compatibility */
 	STAC_MACMINI,
 	STAC_MACBOOK,
@@ -1483,6 +1486,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
 	[STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs,
 	[STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs,
 	[STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs,
+	[STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs,
 	/* for backward compatibility */
 	[STAC_MACMINI] = intel_mac_v3_pin_configs,
 	[STAC_MACBOOK] = intel_mac_v5_pin_configs,
@@ -1505,6 +1509,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = {
 	[STAC_INTEL_MAC_V3] = "intel-mac-v3",
 	[STAC_INTEL_MAC_V4] = "intel-mac-v4",
 	[STAC_INTEL_MAC_V5] = "intel-mac-v5",
+	[STAC_INTEL_MAC_AUTO] = "intel-mac-auto",
 	/* for backward compatibility */
 	[STAC_MACMINI]	= "macmini",
 	[STAC_MACBOOK]	= "macbook",
@@ -1576,9 +1581,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = {
 	SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
 		      "Intel D945P", STAC_D945GTP5),
 	/* other systems  */
-	/* Apple Mac Mini (early 2006) */
+	/* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */
 	SND_PCI_QUIRK(0x8384, 0x7680,
-		      "Mac Mini", STAC_INTEL_MAC_V3),
+		      "Mac", STAC_INTEL_MAC_AUTO),
 	/* Dell systems  */
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7,
 		      "unknown Dell", STAC_922X_DELL_D81),
@@ -3725,7 +3730,7 @@ static int patch_stac922x(struct hda_codec *codec)
 	spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
 							stac922x_models,
 							stac922x_cfg_tbl);
-	if (spec->board_config == STAC_INTEL_MAC_V3) {
+	if (spec->board_config == STAC_INTEL_MAC_AUTO) {
 		spec->gpio_mask = spec->gpio_dir = 0x03;
 		spec->gpio_data = 0x03;
 		/* Intel Macs have all same PCI SSID, so we need to check
@@ -3757,6 +3762,9 @@ static int patch_stac922x(struct hda_codec *codec)
 		case 0x106b2200:
 			spec->board_config = STAC_INTEL_MAC_V5;
 			break;
+		default:
+			spec->board_config = STAC_INTEL_MAC_V3;
+			break;
 		}
 	}
 

+ 1 - 1
sound/soc/au1x/psc-i2s.c

@@ -231,7 +231,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
 
 	/* if both TX and RX are idle, disable PSC */
 	stat = au_readl(I2S_STAT(pscdata));
-	if (!(stat & (PSC_I2SSTAT_RB | PSC_I2SSTAT_RB))) {
+	if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) {
 		au_writel(0, I2S_CFG(pscdata));
 		au_sync();
 		au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata));

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

@@ -427,20 +427,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"HPOUTR", NULL, "Headphone PGA"},
 	{"Headphone PGA", NULL, "Right HP Mixer"},
 
-	/* mono hp mixer */
-	{"Mono HP Mixer", NULL, "Left HP Mixer"},
-	{"Mono HP Mixer", NULL, "Right HP Mixer"},
+	/* mono mixer */
+	{"Mono Mixer", NULL, "Left HP Mixer"},
+	{"Mono Mixer", NULL, "Right HP Mixer"},
 
 	/* Out3 Mux */
 	{"Out3 Mux", "Left", "Left HP Mixer"},
 	{"Out3 Mux", "Mono", "Phone Mixer"},
-	{"Out3 Mux", "Left + Right", "Mono HP Mixer"},
+	{"Out3 Mux", "Left + Right", "Mono Mixer"},
 	{"Out 3 PGA", NULL, "Out3 Mux"},
 	{"OUT3", NULL, "Out 3 PGA"},
 
 	/* speaker Mux */
 	{"Speaker Mux", "Speaker Mix", "Speaker Mixer"},
-	{"Speaker Mux", "Headphone Mix", "Mono HP Mixer"},
+	{"Speaker Mux", "Headphone Mix", "Mono Mixer"},
 	{"Speaker PGA", NULL, "Speaker Mux"},
 	{"LOUT2", NULL, "Speaker PGA"},
 	{"ROUT2", NULL, "Speaker PGA"},

+ 49 - 56
sound/soc/soc-dapm.c

@@ -523,24 +523,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
 				continue;
 			}
 
-			/* programmable gain/attenuation */
-			if (w->id == snd_soc_dapm_pga) {
-				int on;
-				in = is_connected_input_ep(w);
-				dapm_clear_walk(w->codec);
-				out = is_connected_output_ep(w);
-				dapm_clear_walk(w->codec);
-				w->power = on = (out != 0 && in != 0) ? 1 : 0;
-
-				if (!on)
-					dapm_set_pga(w, on); /* lower volume to reduce pops */
-				dapm_update_bits(w);
-				if (on)
-					dapm_set_pga(w, on); /* restore volume from zero */
-
-				continue;
-			}
-
 			/* pre and post event widgets */
 			if (w->id == snd_soc_dapm_pre) {
 				if (!w->event)
@@ -586,45 +568,56 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
 			power_change = (w->power == power) ? 0: 1;
 			w->power = power;
 
+			if (!power_change)
+				continue;
+
 			/* call any power change event handlers */
-			if (power_change) {
-				if (w->event) {
-					pr_debug("power %s event for %s flags %x\n",
-						 w->power ? "on" : "off", w->name, w->event_flags);
-					if (power) {
-						/* power up event */
-						if (w->event_flags & SND_SOC_DAPM_PRE_PMU) {
-							ret = w->event(w,
-								NULL, SND_SOC_DAPM_PRE_PMU);
-							if (ret < 0)
-								return ret;
-						}
-						dapm_update_bits(w);
-						if (w->event_flags & SND_SOC_DAPM_POST_PMU){
-							ret = w->event(w,
-								NULL, SND_SOC_DAPM_POST_PMU);
-							if (ret < 0)
-								return ret;
-						}
-					} else {
-						/* power down event */
-						if (w->event_flags & SND_SOC_DAPM_PRE_PMD) {
-							ret = w->event(w,
-								NULL, SND_SOC_DAPM_PRE_PMD);
-							if (ret < 0)
-								return ret;
-						}
-						dapm_update_bits(w);
-						if (w->event_flags & SND_SOC_DAPM_POST_PMD) {
-							ret = w->event(w,
-								NULL, SND_SOC_DAPM_POST_PMD);
-							if (ret < 0)
-								return ret;
-						}
-					}
-				} else
-					/* no event handler */
-					dapm_update_bits(w);
+			if (w->event)
+				pr_debug("power %s event for %s flags %x\n",
+					 w->power ? "on" : "off",
+					 w->name, w->event_flags);
+
+			/* power up pre event */
+			if (power && w->event &&
+			    (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
+				ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
+				if (ret < 0)
+					return ret;
+			}
+
+			/* power down pre event */
+			if (!power && w->event &&
+			    (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
+				ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
+				if (ret < 0)
+					return ret;
+			}
+
+			/* Lower PGA volume to reduce pops */
+			if (w->id == snd_soc_dapm_pga && !power)
+				dapm_set_pga(w, power);
+
+			dapm_update_bits(w);
+
+			/* Raise PGA volume to reduce pops */
+			if (w->id == snd_soc_dapm_pga && power)
+				dapm_set_pga(w, power);
+
+			/* power up post event */
+			if (power && w->event &&
+			    (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
+				ret = w->event(w,
+					       NULL, SND_SOC_DAPM_POST_PMU);
+				if (ret < 0)
+					return ret;
+			}
+
+			/* power down post event */
+			if (!power && w->event &&
+			    (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
+				ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
+				if (ret < 0)
+					return ret;
 			}
 		}
 	}