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

Commit 76165a30 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'fix/hda' into for-linus

parents 56385a12 c69aefab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3049,6 +3049,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
	SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
		      CXT5066_DELL_LAPTOP),
	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
	SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTO),
	SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
	SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
+144 −32
Original line number Diff line number Diff line
@@ -19030,6 +19030,7 @@ static int patch_alc888(struct hda_codec *codec)
/*
 * ALC680 support
 */
#define ALC680_DIGIN_NID	ALC880_DIGIN_NID
#define ALC680_DIGOUT_NID	ALC880_DIGOUT_NID
#define alc680_modes		alc260_modes
@@ -19044,23 +19045,93 @@ static hda_nid_t alc680_adc_nids[3] = {
	0x07, 0x08, 0x09
};
/*
 * Analog capture ADC cgange
 */
static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
				      struct hda_codec *codec,
				      unsigned int stream_tag,
				      unsigned int format,
				      struct snd_pcm_substream *substream)
{
	struct alc_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int pre_mic, pre_line;
	pre_mic  = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
	pre_line = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_LINE]);
	spec->cur_adc_stream_tag = stream_tag;
	spec->cur_adc_format = format;
	if (pre_mic || pre_line) {
		if (pre_mic)
			snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0,
									format);
		else
			snd_hda_codec_setup_stream(codec, 0x09, stream_tag, 0,
									format);
	} else
		snd_hda_codec_setup_stream(codec, 0x07, stream_tag, 0, format);
	return 0;
}
static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
				      struct hda_codec *codec,
				      struct snd_pcm_substream *substream)
{
	snd_hda_codec_cleanup_stream(codec, 0x07);
	snd_hda_codec_cleanup_stream(codec, 0x08);
	snd_hda_codec_cleanup_stream(codec, 0x09);
	return 0;
}
static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
	.substreams = 1, /* can be overridden */
	.channels_min = 2,
	.channels_max = 2,
	/* NID is set in alc_build_pcms */
	.ops = {
		.prepare = alc680_capture_pcm_prepare,
		.cleanup = alc680_capture_pcm_cleanup
	},
};
static struct snd_kcontrol_new alc680_base_mixer[] = {
	/* output mixer control */
	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
	HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
	HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
	HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
	{ }
};
static struct snd_kcontrol_new alc680_capture_mixer[] = {
	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
static struct hda_bind_ctls alc680_bind_cap_vol = {
	.ops = &snd_hda_bind_vol,
	.values = {
		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
		0
	},
};
static struct hda_bind_ctls alc680_bind_cap_switch = {
	.ops = &snd_hda_bind_sw,
	.values = {
		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
		0
	},
};
static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
	HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
	HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
	{ } /* end */
};
@@ -19068,25 +19139,73 @@ static struct snd_kcontrol_new alc680_capture_mixer[] = {
 * generic initialization of ADC, input mixers and output mixers
 */
static struct hda_verb alc680_init_verbs[] = {
	/* Unmute DAC0-1 and set vol = 0 */
	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT   | AC_USRSP_EN},
	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
	{ }
};
/* toggle speaker-output according to the hp-jack state */
static void alc680_base_setup(struct hda_codec *codec)
{
	struct alc_spec *spec = codec->spec;
	spec->autocfg.hp_pins[0] = 0x16;
	spec->autocfg.speaker_pins[0] = 0x14;
	spec->autocfg.speaker_pins[1] = 0x15;
	spec->autocfg.input_pins[AUTO_PIN_MIC] = 0x18;
	spec->autocfg.input_pins[AUTO_PIN_LINE] = 0x19;
}
static void alc680_rec_autoswitch(struct hda_codec *codec)
{
	struct alc_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int present;
	hda_nid_t new_adc;
	present = snd_hda_jack_detect(codec, cfg->input_pins[AUTO_PIN_MIC]);
	new_adc = present ? 0x8 : 0x7;
	__snd_hda_codec_cleanup_stream(codec, !present ? 0x8 : 0x7, 1);
	snd_hda_codec_setup_stream(codec, new_adc,
				   spec->cur_adc_stream_tag, 0,
				   spec->cur_adc_format);
}
static void alc680_unsol_event(struct hda_codec *codec,
					   unsigned int res)
{
	if ((res >> 26) == ALC880_HP_EVENT)
		alc_automute_amp(codec);
	if ((res >> 26) == ALC880_MIC_EVENT)
		alc680_rec_autoswitch(codec);
}
static void alc680_inithook(struct hda_codec *codec)
{
	alc_automute_amp(codec);
	alc680_rec_autoswitch(codec);
}
/* create input playback/capture controls for the given pin */
static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
				    const char *ctlname, int idx)
@@ -19197,13 +19316,7 @@ static void alc680_auto_init_hp_out(struct hda_codec *codec)
#define alc680_pcm_analog_capture	alc880_pcm_analog_capture
#define alc680_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
#define alc680_pcm_digital_playback	alc880_pcm_digital_playback
static struct hda_input_mux alc680_capture_source = {
	.num_items = 1,
	.items = {
		{ "Mic", 0x0 },
	},
};
#define alc680_pcm_digital_capture	alc880_pcm_digital_capture
/*
 * BIOS auto configuration
@@ -19218,6 +19331,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
					   alc680_ignore);
	if (err < 0)
		return err;
	if (!spec->autocfg.line_outs) {
		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
			spec->multiout.max_channels = 2;
@@ -19239,8 +19353,6 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
		add_mixer(spec, spec->kctls.list);
	add_verb(spec, alc680_init_verbs);
	spec->num_mux_defs = 1;
	spec->input_mux = &alc680_capture_source;
	err = alc_auto_add_mic_boost(codec);
	if (err < 0)
@@ -19279,17 +19391,17 @@ static struct snd_pci_quirk alc680_cfg_tbl[] = {
static struct alc_config_preset alc680_presets[] = {
	[ALC680_BASE] = {
		.mixers = { alc680_base_mixer },
		.cap_mixer =  alc680_capture_mixer,
		.cap_mixer =  alc680_master_capture_mixer,
		.init_verbs = { alc680_init_verbs },
		.num_dacs = ARRAY_SIZE(alc680_dac_nids),
		.dac_nids = alc680_dac_nids,
		.num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
		.adc_nids = alc680_adc_nids,
		.hp_nid = 0x04,
		.dig_out_nid = ALC680_DIGOUT_NID,
		.num_channel_mode = ARRAY_SIZE(alc680_modes),
		.channel_mode = alc680_modes,
		.input_mux = &alc680_capture_source,
		.unsol_event = alc680_unsol_event,
		.setup = alc680_base_setup,
		.init_hook = alc680_inithook,
	},
};
@@ -19333,9 +19445,9 @@ static int patch_alc680(struct hda_codec *codec)
		setup_preset(codec, &alc680_presets[board_config]);
	spec->stream_analog_playback = &alc680_pcm_analog_playback;
	spec->stream_analog_capture = &alc680_pcm_analog_capture;
	spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
	spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
	spec->stream_digital_playback = &alc680_pcm_digital_playback;
	spec->stream_digital_capture = &alc680_pcm_digital_capture;
	if (!spec->adc_nids) {
		spec->adc_nids = alc680_adc_nids;