Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f06db34 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
sound fixes for 3.3-rc3

Most of commits are either regression fixes for varioud HD-audio
codecs or small ASoC fixes.  Also a trivial build fix is included.

* tag 'sound-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - Disable dynamic-power control for VIA as default
  ALSA: hda - Allow analog low-current mode when dynamic power-control is on
  ALSA: hda - Fix the logic to detect VIA analog low-current mode
  ALSA: hda - Check power-state before changing in patch_via.c
  ALSA: HDA: Fix duplicated output to more than one codec
  ALSA: hda - Fix calling cs_automic twice for Cirrus codecs.
  ALSA: HDA: Remove quirk for Toshiba Qosmio G50
  ALSA: HDA: Fix jack creation for codecs with front and rear Line In
  ALSA: hda - Apply 0x0f-VREF fix to all ASUS laptops with ALC861/660
  ASoC: neo1973_wm8753: remove references to the neo1973-gta01 machine
  ALSA: Add #ifdef CONFIG_PCI guard for snd_pci_quirk_* functions
  ASoC: wm_hubs: fix wrong bits for LINEOUT2 N/P mixer
  ALSA: HDA: Remove quirk for Asus N53Jq
  ASoC: wm_hubs: Enable line out VMID buffer for single ended line outputs
  ASoC: wm5100: Mark register cache as dirty when regulators are disabled
  ASoC: wm8962: Mark register cache as dirty when regulators are disabled
  ASoC: wm8996: Mark register cache as dirty when regulators are disabled
  ASoC: wm5100: Fix microphone configuration
  ASoC: wm5100: Make sure we switch to button reporting mode
parents 6c073a7e b5bcc189
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ static inline int __snd_bug_on(int cond)
#define gameport_get_port_data(gp) (gp)->port_data
#endif

#ifdef CONFIG_PCI
/* PCI quirk list helper */
struct snd_pci_quirk {
	unsigned short subvendor;	/* PCI subvendor ID */
@@ -456,5 +457,6 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list);
const struct snd_pci_quirk *
snd_pci_quirk_lookup_id(u16 vendor, u16 device,
			const struct snd_pci_quirk *list);
#endif

#endif /* __SOUND_CORE_H */
+1 −1
Original line number Diff line number Diff line
@@ -1447,7 +1447,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
		for (i = 0; i < c->cvt_setups.used; i++) {
			p = snd_array_elem(&c->cvt_setups, i);
			if (!p->active && p->stream_tag == stream_tag &&
			    get_wcaps_type(get_wcaps(codec, p->nid)) == type)
			    get_wcaps_type(get_wcaps(c, p->nid)) == type)
				p->dirty = 1;
		}
	}
+15 −9
Original line number Diff line number Diff line
@@ -282,7 +282,8 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);

static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
			 const struct auto_pin_cfg *cfg)
			 const struct auto_pin_cfg *cfg,
			 char *lastname, int *lastidx)
{
	unsigned int def_conf, conn;
	char name[44];
@@ -298,6 +299,10 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
		return 0;

	snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
	if (!strcmp(name, lastname) && idx == *lastidx)
		idx++;
	strncpy(lastname, name, 44);
	*lastidx = idx;
	err = snd_hda_jack_add_kctl(codec, nid, name, idx);
	if (err < 0)
		return err;
@@ -311,41 +316,42 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
			   const struct auto_pin_cfg *cfg)
{
	const hda_nid_t *p;
	int i, err;
	int i, err, lastidx = 0;
	char lastname[44] = "";

	for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
		err = add_jack_kctl(codec, *p, cfg);
		err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
		if (err < 0)
			return err;
	}
	for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
		if (*p == *cfg->line_out_pins) /* might be duplicated */
			break;
		err = add_jack_kctl(codec, *p, cfg);
		err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
		if (err < 0)
			return err;
	}
	for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
		if (*p == *cfg->line_out_pins) /* might be duplicated */
			break;
		err = add_jack_kctl(codec, *p, cfg);
		err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
		if (err < 0)
			return err;
	}
	for (i = 0; i < cfg->num_inputs; i++) {
		err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
		err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx);
		if (err < 0)
			return err;
	}
	for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
		err = add_jack_kctl(codec, *p, cfg);
		err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx);
		if (err < 0)
			return err;
	}
	err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
	err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx);
	if (err < 0)
		return err;
	err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
	err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx);
	if (err < 0)
		return err;
	return 0;
+4 −2
Original line number Diff line number Diff line
@@ -988,8 +988,10 @@ static void cs_automic(struct hda_codec *codec)
			change_cur_input(codec, !spec->automic_idx, 0);
	} else {
		if (present) {
			if (spec->cur_input != spec->automic_idx) {
				spec->last_input = spec->cur_input;
				spec->cur_input = spec->automic_idx;
			}
		} else  {
			spec->cur_input = spec->last_input;
		}
+35 −22
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ struct alc_spec {
	unsigned int detect_lo:1;	/* Line-out detection enabled */
	unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
	unsigned int automute_lo_possible:1;	  /* there are line outs and HP */
	unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */

	/* other flags */
	unsigned int no_analog :1; /* digital I/O only */
@@ -495,13 +496,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,

	for (i = 0; i < num_pins; i++) {
		hda_nid_t nid = pins[i];
		unsigned int val;
		if (!nid)
			break;
		switch (spec->automute_mode) {
		case ALC_AUTOMUTE_PIN:
			/* don't reset VREF value in case it's controlling
			 * the amp (see alc861_fixup_asus_amp_vref_0f())
			 */
			if (spec->keep_vref_in_automute) {
				val = snd_hda_codec_read(codec, nid, 0,
					AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
				val &= ~PIN_HP;
			} else
				val = 0;
			val |= pin_bits;
			snd_hda_codec_write(codec, nid, 0,
					    AC_VERB_SET_PIN_WIDGET_CONTROL,
					    pin_bits);
					    val);
			break;
		case ALC_AUTOMUTE_AMP:
			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
@@ -4735,7 +4747,6 @@ enum {
	ALC262_FIXUP_FSC_H270,
	ALC262_FIXUP_HP_Z200,
	ALC262_FIXUP_TYAN,
	ALC262_FIXUP_TOSHIBA_RX1,
	ALC262_FIXUP_LENOVO_3000,
	ALC262_FIXUP_BENQ,
	ALC262_FIXUP_BENQ_T31,
@@ -4765,16 +4776,6 @@ static const struct alc_fixup alc262_fixups[] = {
			{ }
		}
	},
	[ALC262_FIXUP_TOSHIBA_RX1] = {
		.type = ALC_FIXUP_PINS,
		.v.pins = (const struct alc_pincfg[]) {
			{ 0x14, 0x90170110 }, /* speaker */
			{ 0x15, 0x0421101f }, /* HP */
			{ 0x1a, 0x40f000f0 }, /* N/A */
			{ 0x1b, 0x40f000f0 }, /* N/A */
			{ 0x1e, 0x40f000f0 }, /* N/A */
		}
	},
	[ALC262_FIXUP_LENOVO_3000] = {
		.type = ALC_FIXUP_VERBS,
		.v.verbs = (const struct hda_verb[]) {
@@ -4807,8 +4808,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
		      ALC262_FIXUP_TOSHIBA_RX1),
	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
@@ -5377,7 +5376,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
		      ALC269_FIXUP_AMIC),
	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC),
	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
@@ -5589,6 +5587,25 @@ enum {
	PINFIX_ASUS_A6RP,
};

/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
			const struct alc_fixup *fix, int action)
{
	struct alc_spec *spec = codec->spec;
	unsigned int val;

	if (action != ALC_FIXUP_ACT_INIT)
		return;
	val = snd_hda_codec_read(codec, 0x0f, 0,
				 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
	if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
		val |= AC_PINCTL_IN_EN;
	val |= AC_PINCTL_VREF_50;
	snd_hda_codec_write(codec, 0x0f, 0,
			    AC_VERB_SET_PIN_WIDGET_CONTROL, val);
	spec->keep_vref_in_automute = 1;
}

static const struct alc_fixup alc861_fixups[] = {
	[PINFIX_FSC_AMILO_PI1505] = {
		.type = ALC_FIXUP_PINS,
@@ -5599,17 +5616,13 @@ static const struct alc_fixup alc861_fixups[] = {
		}
	},
	[PINFIX_ASUS_A6RP] = {
		.type = ALC_FIXUP_VERBS,
		.v.verbs = (const struct hda_verb[]) {
			/* node 0x0f VREF seems controlling the master output */
			{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
			{ }
		},
		.type = ALC_FIXUP_FUNC,
		.v.func = alc861_fixup_asus_amp_vref_0f,
	},
};

static const struct snd_pci_quirk alc861_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP),
	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
	{}
Loading