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

Commit 2fc07efa authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound updates #2 from Takashi Iwai:
 "This update contains a few cleanup works, regression/stable fixes
  gathered since the last pull request.

   - Clean up with generic hd-audio jack handling code by David
     Henningsson
   - A few regression fixes for standardized HD-audio auto-parser
   - Misc clean-up and small fixes"

* tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda - do not detect jack on internal speakers for Realtek
  ALSA: hda - Fix missing beep on ASUS X43U notebook
  ALSA: hda - Remove AZX_DCAPS_POSFIX_COMBO
  ALSA: hda - Warn an allocation for an uninitialized array
  ALSA: hda/cirrus - Add missing init/free of hda_gen_spec
  ALSA: hda - Fix memory leaks at error path in patch_cirrus.c
  ALSA: hda - Add missing hda_gen_spec to struct via_spec
  ALSA: hda - remove "Mic Jack Mode" for headset jacks (Latitude Exx30)
  ALSA: hda - make Cirrus codec use generic unsol event handler
  ALSA: hda - make VIA codec use generic unsol event handler
  ALSA: hda - Remove dead GPIO code for VIA codec
  ALSA: usb-audio: Add TASCAM US122 MKII playback
parents 79360ddd f7f4b232
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -5168,6 +5168,8 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
 */
 */
void *snd_array_new(struct snd_array *array)
void *snd_array_new(struct snd_array *array)
{
{
	if (snd_BUG_ON(!array->elem_size))
		return NULL;
	if (array->used >= array->alloced) {
	if (array->used >= array->alloced) {
		int num = array->alloced + array->alloc_align;
		int num = array->alloced + array->alloc_align;
		int size = (num + 1) * array->elem_size;
		int size = (num + 1) * array->elem_size;
+0 −5
Original line number Original line Diff line number Diff line
@@ -554,7 +554,6 @@ enum {
#define AZX_DCAPS_BUFSIZE	(1 << 21)	/* no buffer size alignment */
#define AZX_DCAPS_BUFSIZE	(1 << 21)	/* no buffer size alignment */
#define AZX_DCAPS_ALIGN_BUFSIZE	(1 << 22)	/* buffer size alignment */
#define AZX_DCAPS_ALIGN_BUFSIZE	(1 << 22)	/* buffer size alignment */
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23)	/* BDLE in 4k boundary */
#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23)	/* BDLE in 4k boundary */
#define AZX_DCAPS_POSFIX_COMBO  (1 << 24)	/* Use COMBO as default */
#define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)	/* Take LPIB as delay */
#define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)	/* Take LPIB as delay */


/* quirks for ATI SB / AMD Hudson */
/* quirks for ATI SB / AMD Hudson */
@@ -2858,10 +2857,6 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
		snd_printd(SFX "Using LPIB position fix\n");
		snd_printd(SFX "Using LPIB position fix\n");
		return POS_FIX_LPIB;
		return POS_FIX_LPIB;
	}
	}
	if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
		snd_printd(SFX "Using COMBO position fix\n");
		return POS_FIX_COMBO;
	}
	return POS_FIX_AUTO;
	return POS_FIX_AUTO;
}
}


+17 −41
Original line number Original line Diff line number Diff line
@@ -897,7 +897,7 @@ static int build_digital_input(struct hda_codec *codec)
 * HP/SPK/SPDIF
 * HP/SPK/SPDIF
 */
 */


static void cs_automute(struct hda_codec *codec)
static void cs_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
{
{
	struct cs_spec *spec = codec->spec;
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -973,7 +973,7 @@ static void cs_automute(struct hda_codec *codec)
 * Switch max 3 inputs of a single ADC (nid 3)
 * Switch max 3 inputs of a single ADC (nid 3)
*/
*/


static void cs_automic(struct hda_codec *codec)
static void cs_automic(struct hda_codec *codec, struct hda_jack_tbl *tbl)
{
{
	struct cs_spec *spec = codec->spec;
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -1035,7 +1035,7 @@ static void init_output(struct hda_codec *codec)
		if (!cfg->speaker_outs)
		if (!cfg->speaker_outs)
			continue;
			continue;
		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
			snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
			snd_hda_jack_detect_enable_callback(codec, nid, HP_EVENT, cs_automute);
			spec->hp_detect = 1;
			spec->hp_detect = 1;
		}
		}
	}
	}
@@ -1046,7 +1046,7 @@ static void init_output(struct hda_codec *codec)


	/* SPDIF is enabled on presence detect for CS421x */
	/* SPDIF is enabled on presence detect for CS421x */
	if (spec->hp_detect || spec->spdif_detect)
	if (spec->hp_detect || spec->spdif_detect)
		cs_automute(codec);
		cs_automute(codec, NULL);
}
}


static void init_input(struct hda_codec *codec)
static void init_input(struct hda_codec *codec)
@@ -1070,13 +1070,13 @@ static void init_input(struct hda_codec *codec)
				    AC_VERB_SET_AMP_GAIN_MUTE,
				    AC_VERB_SET_AMP_GAIN_MUTE,
				    AMP_IN_MUTE(spec->adc_idx[i]));
				    AMP_IN_MUTE(spec->adc_idx[i]));
		if (spec->mic_detect && spec->automic_idx == i)
		if (spec->mic_detect && spec->automic_idx == i)
			snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
			snd_hda_jack_detect_enable_callback(codec, pin, MIC_EVENT, cs_automic);
	}
	}
	/* CS420x has multiple ADC, CS421x has single ADC */
	/* CS420x has multiple ADC, CS421x has single ADC */
	if (spec->vendor_nid == CS420X_VENDOR_NID) {
	if (spec->vendor_nid == CS420X_VENDOR_NID) {
		change_cur_input(codec, spec->cur_input, 1);
		change_cur_input(codec, spec->cur_input, 1);
		if (spec->mic_detect)
		if (spec->mic_detect)
			cs_automic(codec);
			cs_automic(codec, NULL);


		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
@@ -1089,7 +1089,7 @@ static void init_input(struct hda_codec *codec)
		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
	} else {
	} else {
		if (spec->mic_detect)
		if (spec->mic_detect)
			cs_automic(codec);
			cs_automic(codec, NULL);
		else  {
		else  {
			spec->cur_adc = spec->adc_nid[spec->cur_input];
			spec->cur_adc = spec->adc_nid[spec->cur_input];
			cs_update_input_select(codec);
			cs_update_input_select(codec);
@@ -1243,28 +1243,16 @@ static void cs_free(struct hda_codec *codec)
	struct cs_spec *spec = codec->spec;
	struct cs_spec *spec = codec->spec;
	kfree(spec->capture_bind[0]);
	kfree(spec->capture_bind[0]);
	kfree(spec->capture_bind[1]);
	kfree(spec->capture_bind[1]);
	snd_hda_gen_free(&spec->gen);
	kfree(codec->spec);
	kfree(codec->spec);
}
}


static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
{
	switch (snd_hda_jack_get_action(codec, res >> 26)) {
	case HP_EVENT:
		cs_automute(codec);
		break;
	case MIC_EVENT:
		cs_automic(codec);
		break;
	}
	snd_hda_jack_report_sync(codec);
}

static const struct hda_codec_ops cs_patch_ops = {
static const struct hda_codec_ops cs_patch_ops = {
	.build_controls = cs_build_controls,
	.build_controls = cs_build_controls,
	.build_pcms = cs_build_pcms,
	.build_pcms = cs_build_pcms,
	.init = cs_init,
	.init = cs_init,
	.free = cs_free,
	.free = cs_free,
	.unsol_event = cs_unsol_event,
	.unsol_event = snd_hda_jack_unsol_event,
};
};


static int cs_parse_auto_config(struct hda_codec *codec)
static int cs_parse_auto_config(struct hda_codec *codec)
@@ -1439,6 +1427,7 @@ static int patch_cs420x(struct hda_codec *codec)
	if (!spec)
	if (!spec)
		return -ENOMEM;
		return -ENOMEM;
	codec->spec = spec;
	codec->spec = spec;
	snd_hda_gen_init(&spec->gen);


	spec->vendor_nid = CS420X_VENDOR_NID;
	spec->vendor_nid = CS420X_VENDOR_NID;


@@ -1457,7 +1446,7 @@ static int patch_cs420x(struct hda_codec *codec)
	return 0;
	return 0;


 error:
 error:
	kfree(codec->spec);
	cs_free(codec);
	codec->spec = NULL;
	codec->spec = NULL;
	return err;
	return err;
}
}
@@ -1674,7 +1663,7 @@ static void init_cs421x_digital(struct hda_codec *codec)
		if (!cfg->speaker_outs)
		if (!cfg->speaker_outs)
			continue;
			continue;
		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
			snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
			snd_hda_jack_detect_enable_callback(codec, nid, SPDIF_EVENT, cs_automute);
			spec->spdif_detect = 1;
			spec->spdif_detect = 1;
		}
		}
	}
	}
@@ -1889,21 +1878,6 @@ static int cs421x_build_controls(struct hda_codec *codec)
	return 0;
	return 0;
}
}


static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
{
	switch (snd_hda_jack_get_action(codec, res >> 26)) {
	case HP_EVENT:
	case SPDIF_EVENT:
		cs_automute(codec);
		break;

	case MIC_EVENT:
		cs_automic(codec);
		break;
	}
	snd_hda_jack_report_sync(codec);
}

static int parse_cs421x_input(struct hda_codec *codec)
static int parse_cs421x_input(struct hda_codec *codec)
{
{
	struct cs_spec *spec = codec->spec;
	struct cs_spec *spec = codec->spec;
@@ -1977,7 +1951,7 @@ static struct hda_codec_ops cs421x_patch_ops = {
	.build_pcms = cs_build_pcms,
	.build_pcms = cs_build_pcms,
	.init = cs421x_init,
	.init = cs421x_init,
	.free = cs_free,
	.free = cs_free,
	.unsol_event = cs421x_unsol_event,
	.unsol_event = snd_hda_jack_unsol_event,
#ifdef CONFIG_PM
#ifdef CONFIG_PM
	.suspend = cs421x_suspend,
	.suspend = cs421x_suspend,
#endif
#endif
@@ -1992,6 +1966,7 @@ static int patch_cs4210(struct hda_codec *codec)
	if (!spec)
	if (!spec)
		return -ENOMEM;
		return -ENOMEM;
	codec->spec = spec;
	codec->spec = spec;
	snd_hda_gen_init(&spec->gen);


	spec->vendor_nid = CS4210_VENDOR_NID;
	spec->vendor_nid = CS4210_VENDOR_NID;


@@ -2017,7 +1992,7 @@ static int patch_cs4210(struct hda_codec *codec)
	return 0;
	return 0;


 error:
 error:
	kfree(codec->spec);
	cs_free(codec);
	codec->spec = NULL;
	codec->spec = NULL;
	return err;
	return err;
}
}
@@ -2031,6 +2006,7 @@ static int patch_cs4213(struct hda_codec *codec)
	if (!spec)
	if (!spec)
		return -ENOMEM;
		return -ENOMEM;
	codec->spec = spec;
	codec->spec = spec;
	snd_hda_gen_init(&spec->gen);


	spec->vendor_nid = CS4213_VENDOR_NID;
	spec->vendor_nid = CS4213_VENDOR_NID;


@@ -2042,7 +2018,7 @@ static int patch_cs4213(struct hda_codec *codec)
	return 0;
	return 0;


 error:
 error:
	kfree(codec->spec);
	cs_free(codec);
	codec->spec = NULL;
	codec->spec = NULL;
	return err;
	return err;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -611,6 +611,8 @@ static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack
{
{
	struct alc_spec *spec = codec->spec;
	struct alc_spec *spec = codec->spec;


	if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
		return;
	/* check LO jack only when it's different from HP */
	/* check LO jack only when it's different from HP */
	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
		return;
		return;
@@ -4245,6 +4247,7 @@ static void alc_auto_init_std(struct hda_codec *codec)
	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))


static const struct snd_pci_quirk beep_white_list[] = {
static const struct snd_pci_quirk beep_white_list[] = {
	SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
+27 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,7 @@ enum {
	STAC_92HD83XXX_HP_LED,
	STAC_92HD83XXX_HP_LED,
	STAC_92HD83XXX_HP_INV_LED,
	STAC_92HD83XXX_HP_INV_LED,
	STAC_92HD83XXX_HP_MIC_LED,
	STAC_92HD83XXX_HP_MIC_LED,
	STAC_92HD83XXX_HEADSET_JACK,
	STAC_92HD83XXX_MODELS
	STAC_92HD83XXX_MODELS
};
};


@@ -204,6 +205,7 @@ struct sigmatel_spec {
	unsigned int check_volume_offset:1;
	unsigned int check_volume_offset:1;
	unsigned int auto_mic:1;
	unsigned int auto_mic:1;
	unsigned int linear_tone_beep:1;
	unsigned int linear_tone_beep:1;
	unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */


	/* gpio lines */
	/* gpio lines */
	unsigned int eapd_mask;
	unsigned int eapd_mask;
@@ -1684,6 +1686,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
	[STAC_92HD83XXX_HP_LED] = "hp-led",
	[STAC_92HD83XXX_HP_LED] = "hp-led",
	[STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
	[STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
	[STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led",
	[STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led",
	[STAC_92HD83XXX_HEADSET_JACK] = "headset-jack",
};
};


static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1694,6 +1697,24 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
		      "DFI LanParty", STAC_92HD83XXX_REF),
		      "DFI LanParty", STAC_92HD83XXX_REF),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
		      "unknown Dell", STAC_DELL_S14),
		      "unknown Dell", STAC_DELL_S14),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
		      "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
		      "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
		      "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
		      "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
		      "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
		      "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
		      "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
		      "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
		      "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
		      "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
		      "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
@@ -2855,6 +2876,9 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
	char name[22];
	char name[22];


	if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
	if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
		if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf)
			!= INPUT_PIN_ATTR_DOCK)
			return 0;
		if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
		if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
			&& nid == spec->line_switch)
			&& nid == spec->line_switch)
			control = STAC_CTL_WIDGET_IO_SWITCH;
			control = STAC_CTL_WIDGET_IO_SWITCH;
@@ -5626,6 +5650,9 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
	case STAC_92HD83XXX_HP_MIC_LED:
	case STAC_92HD83XXX_HP_MIC_LED:
		spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
		spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
		break;
		break;
	case STAC_92HD83XXX_HEADSET_JACK:
		spec->headset_jack = 1;
		break;
	}
	}


	if (find_mute_led_cfg(codec, default_polarity))
	if (find_mute_led_cfg(codec, default_polarity))
Loading