xref: /openbmc/linux/sound/pci/hda/patch_conexant.c (revision 81d67439)
1 /*
2  * HD audio interface patch for Conexant HDA audio codec
3  *
4  * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5  * 		      Takashi Iwai <tiwai@suse.de>
6  * 		      Tobin Davis  <tdavis@dsl-only.net>
7  *
8  *  This driver is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This driver is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <sound/core.h>
28 #include <sound/jack.h>
29 
30 #include "hda_codec.h"
31 #include "hda_local.h"
32 #include "hda_beep.h"
33 
34 #define CXT_PIN_DIR_IN              0x00
35 #define CXT_PIN_DIR_OUT             0x01
36 #define CXT_PIN_DIR_INOUT           0x02
37 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
38 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
39 
40 #define CONEXANT_HP_EVENT	0x37
41 #define CONEXANT_MIC_EVENT	0x38
42 #define CONEXANT_LINE_EVENT	0x39
43 
44 /* Conexant 5051 specific */
45 
46 #define CXT5051_SPDIF_OUT	0x12
47 #define CXT5051_PORTB_EVENT	0x38
48 #define CXT5051_PORTC_EVENT	0x39
49 
50 #define AUTO_MIC_PORTB		(1 << 1)
51 #define AUTO_MIC_PORTC		(1 << 2)
52 
53 struct pin_dac_pair {
54 	hda_nid_t pin;
55 	hda_nid_t dac;
56 	int type;
57 };
58 
59 struct imux_info {
60 	hda_nid_t pin;		/* input pin NID */
61 	hda_nid_t adc;		/* connected ADC NID */
62 	hda_nid_t boost;	/* optional boost volume NID */
63 	int index;		/* corresponding to autocfg.input */
64 };
65 
66 struct conexant_spec {
67 
68 	const struct snd_kcontrol_new *mixers[5];
69 	int num_mixers;
70 	hda_nid_t vmaster_nid;
71 
72 	const struct hda_verb *init_verbs[5];	/* initialization verbs
73 						 * don't forget NULL
74 						 * termination!
75 						 */
76 	unsigned int num_init_verbs;
77 
78 	/* playback */
79 	struct hda_multi_out multiout;	/* playback set-up
80 					 * max_channels, dacs must be set
81 					 * dig_out_nid and hp_nid are optional
82 					 */
83 	unsigned int cur_eapd;
84 	unsigned int hp_present;
85 	unsigned int line_present;
86 	unsigned int auto_mic;
87 	int auto_mic_ext;		/* imux_pins[] index for ext mic */
88 	int auto_mic_dock;		/* imux_pins[] index for dock mic */
89 	int auto_mic_int;		/* imux_pins[] index for int mic */
90 	unsigned int need_dac_fix;
91 	hda_nid_t slave_dig_outs[2];
92 
93 	/* capture */
94 	unsigned int num_adc_nids;
95 	const hda_nid_t *adc_nids;
96 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
97 
98 	unsigned int cur_adc_idx;
99 	hda_nid_t cur_adc;
100 	unsigned int cur_adc_stream_tag;
101 	unsigned int cur_adc_format;
102 
103 	const struct hda_pcm_stream *capture_stream;
104 
105 	/* capture source */
106 	const struct hda_input_mux *input_mux;
107 	const hda_nid_t *capsrc_nids;
108 	unsigned int cur_mux[3];
109 
110 	/* channel model */
111 	const struct hda_channel_mode *channel_mode;
112 	int num_channel_mode;
113 
114 	/* PCM information */
115 	struct hda_pcm pcm_rec[2];	/* used in build_pcms() */
116 
117 	unsigned int spdif_route;
118 
119 	/* dynamic controls, init_verbs and input_mux */
120 	struct auto_pin_cfg autocfg;
121 	struct hda_input_mux private_imux;
122 	struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
123 	hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
124 	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
125 	struct pin_dac_pair dac_info[8];
126 	int dac_info_filled;
127 
128 	unsigned int port_d_mode;
129 	unsigned int auto_mute:1;	/* used in auto-parser */
130 	unsigned int detect_line:1;	/* Line-out detection enabled */
131 	unsigned int automute_lines:1;	/* automute line-out as well */
132 	unsigned int automute_hp_lo:1;	/* both HP and LO available */
133 	unsigned int dell_automute:1;
134 	unsigned int dell_vostro:1;
135 	unsigned int ideapad:1;
136 	unsigned int thinkpad:1;
137 	unsigned int hp_laptop:1;
138 	unsigned int asus:1;
139 
140 	unsigned int adc_switching:1;
141 
142 	unsigned int ext_mic_present;
143 	unsigned int recording;
144 	void (*capture_prepare)(struct hda_codec *codec);
145 	void (*capture_cleanup)(struct hda_codec *codec);
146 
147 	/* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
148 	 * through the microphone jack.
149 	 * When the user enables this through a mixer switch, both internal and
150 	 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
151 	 * we also allow the bias to be configured through a separate mixer
152 	 * control. */
153 	unsigned int dc_enable;
154 	unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
155 	unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
156 
157 	unsigned int beep_amp;
158 
159 	/* extra EAPD pins */
160 	unsigned int num_eapds;
161 	hda_nid_t eapds[4];
162 };
163 
164 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
165 				      struct hda_codec *codec,
166 				      struct snd_pcm_substream *substream)
167 {
168 	struct conexant_spec *spec = codec->spec;
169 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
170 					     hinfo);
171 }
172 
173 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
174 					 struct hda_codec *codec,
175 					 unsigned int stream_tag,
176 					 unsigned int format,
177 					 struct snd_pcm_substream *substream)
178 {
179 	struct conexant_spec *spec = codec->spec;
180 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
181 						stream_tag,
182 						format, substream);
183 }
184 
185 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
186 					 struct hda_codec *codec,
187 					 struct snd_pcm_substream *substream)
188 {
189 	struct conexant_spec *spec = codec->spec;
190 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
191 }
192 
193 /*
194  * Digital out
195  */
196 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
197 					  struct hda_codec *codec,
198 					  struct snd_pcm_substream *substream)
199 {
200 	struct conexant_spec *spec = codec->spec;
201 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
202 }
203 
204 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
205 					 struct hda_codec *codec,
206 					 struct snd_pcm_substream *substream)
207 {
208 	struct conexant_spec *spec = codec->spec;
209 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
210 }
211 
212 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
213 					 struct hda_codec *codec,
214 					 unsigned int stream_tag,
215 					 unsigned int format,
216 					 struct snd_pcm_substream *substream)
217 {
218 	struct conexant_spec *spec = codec->spec;
219 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
220 					     stream_tag,
221 					     format, substream);
222 }
223 
224 /*
225  * Analog capture
226  */
227 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
228 				      struct hda_codec *codec,
229 				      unsigned int stream_tag,
230 				      unsigned int format,
231 				      struct snd_pcm_substream *substream)
232 {
233 	struct conexant_spec *spec = codec->spec;
234 	if (spec->capture_prepare)
235 		spec->capture_prepare(codec);
236 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
237 				   stream_tag, 0, format);
238 	return 0;
239 }
240 
241 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
242 				      struct hda_codec *codec,
243 				      struct snd_pcm_substream *substream)
244 {
245 	struct conexant_spec *spec = codec->spec;
246 	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
247 	if (spec->capture_cleanup)
248 		spec->capture_cleanup(codec);
249 	return 0;
250 }
251 
252 
253 
254 static const struct hda_pcm_stream conexant_pcm_analog_playback = {
255 	.substreams = 1,
256 	.channels_min = 2,
257 	.channels_max = 2,
258 	.nid = 0, /* fill later */
259 	.ops = {
260 		.open = conexant_playback_pcm_open,
261 		.prepare = conexant_playback_pcm_prepare,
262 		.cleanup = conexant_playback_pcm_cleanup
263 	},
264 };
265 
266 static const struct hda_pcm_stream conexant_pcm_analog_capture = {
267 	.substreams = 1,
268 	.channels_min = 2,
269 	.channels_max = 2,
270 	.nid = 0, /* fill later */
271 	.ops = {
272 		.prepare = conexant_capture_pcm_prepare,
273 		.cleanup = conexant_capture_pcm_cleanup
274 	},
275 };
276 
277 
278 static const struct hda_pcm_stream conexant_pcm_digital_playback = {
279 	.substreams = 1,
280 	.channels_min = 2,
281 	.channels_max = 2,
282 	.nid = 0, /* fill later */
283 	.ops = {
284 		.open = conexant_dig_playback_pcm_open,
285 		.close = conexant_dig_playback_pcm_close,
286 		.prepare = conexant_dig_playback_pcm_prepare
287 	},
288 };
289 
290 static const struct hda_pcm_stream conexant_pcm_digital_capture = {
291 	.substreams = 1,
292 	.channels_min = 2,
293 	.channels_max = 2,
294 	/* NID is set in alc_build_pcms */
295 };
296 
297 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
298 				      struct hda_codec *codec,
299 				      unsigned int stream_tag,
300 				      unsigned int format,
301 				      struct snd_pcm_substream *substream)
302 {
303 	struct conexant_spec *spec = codec->spec;
304 	spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
305 	spec->cur_adc_stream_tag = stream_tag;
306 	spec->cur_adc_format = format;
307 	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
308 	return 0;
309 }
310 
311 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
312 				      struct hda_codec *codec,
313 				      struct snd_pcm_substream *substream)
314 {
315 	struct conexant_spec *spec = codec->spec;
316 	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
317 	spec->cur_adc = 0;
318 	return 0;
319 }
320 
321 static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
322 	.substreams = 1,
323 	.channels_min = 2,
324 	.channels_max = 2,
325 	.nid = 0, /* fill later */
326 	.ops = {
327 		.prepare = cx5051_capture_pcm_prepare,
328 		.cleanup = cx5051_capture_pcm_cleanup
329 	},
330 };
331 
332 static int conexant_build_pcms(struct hda_codec *codec)
333 {
334 	struct conexant_spec *spec = codec->spec;
335 	struct hda_pcm *info = spec->pcm_rec;
336 
337 	codec->num_pcms = 1;
338 	codec->pcm_info = info;
339 
340 	info->name = "CONEXANT Analog";
341 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
342 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
343 		spec->multiout.max_channels;
344 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
345 		spec->multiout.dac_nids[0];
346 	if (spec->capture_stream)
347 		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
348 	else {
349 		if (codec->vendor_id == 0x14f15051)
350 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
351 				cx5051_pcm_analog_capture;
352 		else {
353 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
354 				conexant_pcm_analog_capture;
355 			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
356 				spec->num_adc_nids;
357 		}
358 	}
359 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
360 
361 	if (spec->multiout.dig_out_nid) {
362 		info++;
363 		codec->num_pcms++;
364 		info->name = "Conexant Digital";
365 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
366 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
367 			conexant_pcm_digital_playback;
368 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
369 			spec->multiout.dig_out_nid;
370 		if (spec->dig_in_nid) {
371 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
372 				conexant_pcm_digital_capture;
373 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
374 				spec->dig_in_nid;
375 		}
376 		if (spec->slave_dig_outs[0])
377 			codec->slave_dig_outs = spec->slave_dig_outs;
378 	}
379 
380 	return 0;
381 }
382 
383 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
384 	       			  struct snd_ctl_elem_info *uinfo)
385 {
386 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387 	struct conexant_spec *spec = codec->spec;
388 
389 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
390 }
391 
392 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
393 				 struct snd_ctl_elem_value *ucontrol)
394 {
395 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
396 	struct conexant_spec *spec = codec->spec;
397 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
398 
399 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
400 	return 0;
401 }
402 
403 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
404 				 struct snd_ctl_elem_value *ucontrol)
405 {
406 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
407 	struct conexant_spec *spec = codec->spec;
408 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
409 
410 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
411 				     spec->capsrc_nids[adc_idx],
412 				     &spec->cur_mux[adc_idx]);
413 }
414 
415 static int conexant_init_jacks(struct hda_codec *codec)
416 {
417 #ifdef CONFIG_SND_HDA_INPUT_JACK
418 	struct conexant_spec *spec = codec->spec;
419 	int i;
420 
421 	for (i = 0; i < spec->num_init_verbs; i++) {
422 		const struct hda_verb *hv;
423 
424 		hv = spec->init_verbs[i];
425 		while (hv->nid) {
426 			int err = 0;
427 			switch (hv->param ^ AC_USRSP_EN) {
428 			case CONEXANT_HP_EVENT:
429 				err = snd_hda_input_jack_add(codec, hv->nid,
430 						SND_JACK_HEADPHONE, NULL);
431 				snd_hda_input_jack_report(codec, hv->nid);
432 				break;
433 			case CXT5051_PORTC_EVENT:
434 			case CONEXANT_MIC_EVENT:
435 				err = snd_hda_input_jack_add(codec, hv->nid,
436 						SND_JACK_MICROPHONE, NULL);
437 				snd_hda_input_jack_report(codec, hv->nid);
438 				break;
439 			}
440 			if (err < 0)
441 				return err;
442 			++hv;
443 		}
444 	}
445 #endif /* CONFIG_SND_HDA_INPUT_JACK */
446 	return 0;
447 }
448 
449 static int conexant_init(struct hda_codec *codec)
450 {
451 	struct conexant_spec *spec = codec->spec;
452 	int i;
453 
454 	for (i = 0; i < spec->num_init_verbs; i++)
455 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
456 	return 0;
457 }
458 
459 static void conexant_free(struct hda_codec *codec)
460 {
461 	snd_hda_input_jack_free(codec);
462 	snd_hda_detach_beep_device(codec);
463 	kfree(codec->spec);
464 }
465 
466 static const struct snd_kcontrol_new cxt_capture_mixers[] = {
467 	{
468 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
469 		.name = "Capture Source",
470 		.info = conexant_mux_enum_info,
471 		.get = conexant_mux_enum_get,
472 		.put = conexant_mux_enum_put
473 	},
474 	{}
475 };
476 
477 #ifdef CONFIG_SND_HDA_INPUT_BEEP
478 /* additional beep mixers; the actual parameters are overwritten at build */
479 static const struct snd_kcontrol_new cxt_beep_mixer[] = {
480 	HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
481 	HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
482 	{ } /* end */
483 };
484 #endif
485 
486 static const char * const slave_vols[] = {
487 	"Headphone Playback Volume",
488 	"Speaker Playback Volume",
489 	"Front Playback Volume",
490 	"Surround Playback Volume",
491 	"CLFE Playback Volume",
492 	NULL
493 };
494 
495 static const char * const slave_sws[] = {
496 	"Headphone Playback Switch",
497 	"Speaker Playback Switch",
498 	"Front Playback Switch",
499 	"Surround Playback Switch",
500 	"CLFE Playback Switch",
501 	NULL
502 };
503 
504 static int conexant_build_controls(struct hda_codec *codec)
505 {
506 	struct conexant_spec *spec = codec->spec;
507 	unsigned int i;
508 	int err;
509 
510 	for (i = 0; i < spec->num_mixers; i++) {
511 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
512 		if (err < 0)
513 			return err;
514 	}
515 	if (spec->multiout.dig_out_nid) {
516 		err = snd_hda_create_spdif_out_ctls(codec,
517 						    spec->multiout.dig_out_nid,
518 						    spec->multiout.dig_out_nid);
519 		if (err < 0)
520 			return err;
521 		err = snd_hda_create_spdif_share_sw(codec,
522 						    &spec->multiout);
523 		if (err < 0)
524 			return err;
525 		spec->multiout.share_spdif = 1;
526 	}
527 	if (spec->dig_in_nid) {
528 		err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
529 		if (err < 0)
530 			return err;
531 	}
532 
533 	/* if we have no master control, let's create it */
534 	if (spec->vmaster_nid &&
535 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
536 		unsigned int vmaster_tlv[4];
537 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
538 					HDA_OUTPUT, vmaster_tlv);
539 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
540 					  vmaster_tlv, slave_vols);
541 		if (err < 0)
542 			return err;
543 	}
544 	if (spec->vmaster_nid &&
545 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
546 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
547 					  NULL, slave_sws);
548 		if (err < 0)
549 			return err;
550 	}
551 
552 	if (spec->input_mux) {
553 		err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
554 		if (err < 0)
555 			return err;
556 	}
557 
558 #ifdef CONFIG_SND_HDA_INPUT_BEEP
559 	/* create beep controls if needed */
560 	if (spec->beep_amp) {
561 		const struct snd_kcontrol_new *knew;
562 		for (knew = cxt_beep_mixer; knew->name; knew++) {
563 			struct snd_kcontrol *kctl;
564 			kctl = snd_ctl_new1(knew, codec);
565 			if (!kctl)
566 				return -ENOMEM;
567 			kctl->private_value = spec->beep_amp;
568 			err = snd_hda_ctl_add(codec, 0, kctl);
569 			if (err < 0)
570 				return err;
571 		}
572 	}
573 #endif
574 
575 	return 0;
576 }
577 
578 #ifdef CONFIG_SND_HDA_POWER_SAVE
579 static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
580 {
581 	snd_hda_shutup_pins(codec);
582 	return 0;
583 }
584 #endif
585 
586 static const struct hda_codec_ops conexant_patch_ops = {
587 	.build_controls = conexant_build_controls,
588 	.build_pcms = conexant_build_pcms,
589 	.init = conexant_init,
590 	.free = conexant_free,
591 #ifdef CONFIG_SND_HDA_POWER_SAVE
592 	.suspend = conexant_suspend,
593 #endif
594 	.reboot_notify = snd_hda_shutup_pins,
595 };
596 
597 #ifdef CONFIG_SND_HDA_INPUT_BEEP
598 #define set_beep_amp(spec, nid, idx, dir) \
599 	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
600 #else
601 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
602 #endif
603 
604 static int patch_conexant_auto(struct hda_codec *codec);
605 /*
606  * EAPD control
607  * the private value = nid | (invert << 8)
608  */
609 
610 #define cxt_eapd_info		snd_ctl_boolean_mono_info
611 
612 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
613 			     struct snd_ctl_elem_value *ucontrol)
614 {
615 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
616 	struct conexant_spec *spec = codec->spec;
617 	int invert = (kcontrol->private_value >> 8) & 1;
618 	if (invert)
619 		ucontrol->value.integer.value[0] = !spec->cur_eapd;
620 	else
621 		ucontrol->value.integer.value[0] = spec->cur_eapd;
622 	return 0;
623 
624 }
625 
626 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
627 			     struct snd_ctl_elem_value *ucontrol)
628 {
629 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630 	struct conexant_spec *spec = codec->spec;
631 	int invert = (kcontrol->private_value >> 8) & 1;
632 	hda_nid_t nid = kcontrol->private_value & 0xff;
633 	unsigned int eapd;
634 
635 	eapd = !!ucontrol->value.integer.value[0];
636 	if (invert)
637 		eapd = !eapd;
638 	if (eapd == spec->cur_eapd)
639 		return 0;
640 
641 	spec->cur_eapd = eapd;
642 	snd_hda_codec_write_cache(codec, nid,
643 				  0, AC_VERB_SET_EAPD_BTLENABLE,
644 				  eapd ? 0x02 : 0x00);
645 	return 1;
646 }
647 
648 /* controls for test mode */
649 #ifdef CONFIG_SND_DEBUG
650 
651 #define CXT_EAPD_SWITCH(xname, nid, mask) \
652 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
653 	  .info = cxt_eapd_info, \
654 	  .get = cxt_eapd_get, \
655 	  .put = cxt_eapd_put, \
656 	  .private_value = nid | (mask<<16) }
657 
658 
659 
660 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
661 				 struct snd_ctl_elem_info *uinfo)
662 {
663 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
664 	struct conexant_spec *spec = codec->spec;
665 	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
666 				    spec->num_channel_mode);
667 }
668 
669 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
670 				struct snd_ctl_elem_value *ucontrol)
671 {
672 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
673 	struct conexant_spec *spec = codec->spec;
674 	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
675 				   spec->num_channel_mode,
676 				   spec->multiout.max_channels);
677 }
678 
679 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
680 				struct snd_ctl_elem_value *ucontrol)
681 {
682 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
683 	struct conexant_spec *spec = codec->spec;
684 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
685 				      spec->num_channel_mode,
686 				      &spec->multiout.max_channels);
687 	if (err >= 0 && spec->need_dac_fix)
688 		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
689 	return err;
690 }
691 
692 #define CXT_PIN_MODE(xname, nid, dir) \
693 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
694 	  .info = conexant_ch_mode_info, \
695 	  .get = conexant_ch_mode_get, \
696 	  .put = conexant_ch_mode_put, \
697 	  .private_value = nid | (dir<<16) }
698 
699 #endif /* CONFIG_SND_DEBUG */
700 
701 /* Conexant 5045 specific */
702 
703 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
704 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
705 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
706 #define CXT5045_SPDIF_OUT	0x18
707 
708 static const struct hda_channel_mode cxt5045_modes[1] = {
709 	{ 2, NULL },
710 };
711 
712 static const struct hda_input_mux cxt5045_capture_source = {
713 	.num_items = 2,
714 	.items = {
715 		{ "IntMic", 0x1 },
716 		{ "ExtMic", 0x2 },
717 	}
718 };
719 
720 static const struct hda_input_mux cxt5045_capture_source_benq = {
721 	.num_items = 5,
722 	.items = {
723 		{ "IntMic", 0x1 },
724 		{ "ExtMic", 0x2 },
725 		{ "LineIn", 0x3 },
726 		{ "CD",     0x4 },
727 		{ "Mixer",  0x0 },
728 	}
729 };
730 
731 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
732 	.num_items = 2,
733 	.items = {
734 		{ "ExtMic", 0x1 },
735 		{ "IntMic", 0x2 },
736 	}
737 };
738 
739 /* turn on/off EAPD (+ mute HP) as a master switch */
740 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
741 				    struct snd_ctl_elem_value *ucontrol)
742 {
743 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 	struct conexant_spec *spec = codec->spec;
745 	unsigned int bits;
746 
747 	if (!cxt_eapd_put(kcontrol, ucontrol))
748 		return 0;
749 
750 	/* toggle internal speakers mute depending of presence of
751 	 * the headphone jack
752 	 */
753 	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
754 	snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
755 				 HDA_AMP_MUTE, bits);
756 
757 	bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
758 	snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
759 				 HDA_AMP_MUTE, bits);
760 	return 1;
761 }
762 
763 /* bind volumes of both NID 0x10 and 0x11 */
764 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
765 	.ops = &snd_hda_bind_vol,
766 	.values = {
767 		HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
768 		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
769 		0
770 	},
771 };
772 
773 /* toggle input of built-in and mic jack appropriately */
774 static void cxt5045_hp_automic(struct hda_codec *codec)
775 {
776 	static const struct hda_verb mic_jack_on[] = {
777 		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
778 		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
779 		{}
780 	};
781 	static const struct hda_verb mic_jack_off[] = {
782 		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
783 		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
784 		{}
785 	};
786 	unsigned int present;
787 
788 	present = snd_hda_jack_detect(codec, 0x12);
789 	if (present)
790 		snd_hda_sequence_write(codec, mic_jack_on);
791 	else
792 		snd_hda_sequence_write(codec, mic_jack_off);
793 }
794 
795 
796 /* mute internal speaker if HP is plugged */
797 static void cxt5045_hp_automute(struct hda_codec *codec)
798 {
799 	struct conexant_spec *spec = codec->spec;
800 	unsigned int bits;
801 
802 	spec->hp_present = snd_hda_jack_detect(codec, 0x11);
803 
804 	bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
805 	snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
806 				 HDA_AMP_MUTE, bits);
807 }
808 
809 /* unsolicited event for HP jack sensing */
810 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
811 				   unsigned int res)
812 {
813 	res >>= 26;
814 	switch (res) {
815 	case CONEXANT_HP_EVENT:
816 		cxt5045_hp_automute(codec);
817 		break;
818 	case CONEXANT_MIC_EVENT:
819 		cxt5045_hp_automic(codec);
820 		break;
821 
822 	}
823 }
824 
825 static const struct snd_kcontrol_new cxt5045_mixers[] = {
826 	HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
827 	HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
828 	HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
829 	HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
830 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
831 	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
832 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
833 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
834 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
835 	HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
836 	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
837 	{
838 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
839 		.name = "Master Playback Switch",
840 		.info = cxt_eapd_info,
841 		.get = cxt_eapd_get,
842 		.put = cxt5045_hp_master_sw_put,
843 		.private_value = 0x10,
844 	},
845 
846 	{}
847 };
848 
849 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
850 	HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
851 	HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
852 	HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
853 	HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
854 
855 	HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
856 	HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
857 	HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
858 	HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
859 
860 	HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
861 	HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
862 
863 	{}
864 };
865 
866 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
867 	HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
868 	HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
869 	HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
870 	HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
871 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
872 	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
873 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
874 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
875 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
876 	HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
877 	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
878 	{
879 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
880 		.name = "Master Playback Switch",
881 		.info = cxt_eapd_info,
882 		.get = cxt_eapd_get,
883 		.put = cxt5045_hp_master_sw_put,
884 		.private_value = 0x10,
885 	},
886 
887 	{}
888 };
889 
890 static const struct hda_verb cxt5045_init_verbs[] = {
891 	/* Line in, Mic */
892 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
893 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
894 	/* HP, Amp  */
895 	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
896 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
897 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
898 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
899 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
900 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
901 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
902 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
903 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
904 	/* Record selector: Internal mic */
905 	{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
906 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
907 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
908 	/* SPDIF route: PCM */
909 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
910 	{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
911 	/* EAPD */
912 	{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
913 	{ } /* end */
914 };
915 
916 static const struct hda_verb cxt5045_benq_init_verbs[] = {
917 	/* Internal Mic, Mic */
918 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
919 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
920 	/* Line In,HP, Amp  */
921 	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
922 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
923 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
924 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
925 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
926 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
927 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
928 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
929 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
930 	/* Record selector: Internal mic */
931 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
932 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
933 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
934 	/* SPDIF route: PCM */
935 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
936 	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
937 	/* EAPD */
938 	{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
939 	{ } /* end */
940 };
941 
942 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
943 	/* pin sensing on HP jack */
944 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
945 	{ } /* end */
946 };
947 
948 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
949 	/* pin sensing on HP jack */
950 	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
951 	{ } /* end */
952 };
953 
954 #ifdef CONFIG_SND_DEBUG
955 /* Test configuration for debugging, modelled after the ALC260 test
956  * configuration.
957  */
958 static const struct hda_input_mux cxt5045_test_capture_source = {
959 	.num_items = 5,
960 	.items = {
961 		{ "MIXER", 0x0 },
962 		{ "MIC1 pin", 0x1 },
963 		{ "LINE1 pin", 0x2 },
964 		{ "HP-OUT pin", 0x3 },
965 		{ "CD pin", 0x4 },
966         },
967 };
968 
969 static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
970 
971 	/* Output controls */
972 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
973 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
974 	HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
975 	HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
976 	HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
977 	HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
978 
979 	/* Modes for retasking pin widgets */
980 	CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
981 	CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
982 
983 	/* EAPD Switch Control */
984 	CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
985 
986 	/* Loopback mixer controls */
987 
988 	HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
989 	HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
990 	HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
991 	HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
992 	HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
993 	HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
994 	HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
995 	HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
996 	HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
997 	HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
998 	{
999 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1000 		.name = "Input Source",
1001 		.info = conexant_mux_enum_info,
1002 		.get = conexant_mux_enum_get,
1003 		.put = conexant_mux_enum_put,
1004 	},
1005 	/* Audio input controls */
1006 	HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
1007 	HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
1008 	HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
1009 	HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
1010 	HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
1011 	HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
1012 	HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
1013 	HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
1014 	HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
1015 	HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
1016 	{ } /* end */
1017 };
1018 
1019 static const struct hda_verb cxt5045_test_init_verbs[] = {
1020 	/* Set connections */
1021 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1022 	{ 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
1023 	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
1024 	/* Enable retasking pins as output, initially without power amp */
1025 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1026 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1027 
1028 	/* Disable digital (SPDIF) pins initially, but users can enable
1029 	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
1030 	 * payload also sets the generation to 0, output to be in "consumer"
1031 	 * PCM format, copyright asserted, no pre-emphasis and no validity
1032 	 * control.
1033 	 */
1034 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1035 	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1036 
1037 	/* Start with output sum widgets muted and their output gains at min */
1038 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1039 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1040 
1041 	/* Unmute retasking pin widget output buffers since the default
1042 	 * state appears to be output.  As the pin mode is changed by the
1043 	 * user the pin mode control will take care of enabling the pin's
1044 	 * input/output buffers as needed.
1045 	 */
1046 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1047 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1048 
1049 	/* Mute capture amp left and right */
1050 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1051 
1052 	/* Set ADC connection select to match default mixer setting (mic1
1053 	 * pin)
1054 	 */
1055 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1056 	{0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1057 
1058 	/* Mute all inputs to mixer widget (even unconnected ones) */
1059 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1060 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1061 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1062 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1063 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1064 
1065 	{ }
1066 };
1067 #endif
1068 
1069 
1070 /* initialize jack-sensing, too */
1071 static int cxt5045_init(struct hda_codec *codec)
1072 {
1073 	conexant_init(codec);
1074 	cxt5045_hp_automute(codec);
1075 	return 0;
1076 }
1077 
1078 
1079 enum {
1080 	CXT5045_LAPTOP_HPSENSE,
1081 	CXT5045_LAPTOP_MICSENSE,
1082 	CXT5045_LAPTOP_HPMICSENSE,
1083 	CXT5045_BENQ,
1084 	CXT5045_LAPTOP_HP530,
1085 #ifdef CONFIG_SND_DEBUG
1086 	CXT5045_TEST,
1087 #endif
1088 	CXT5045_AUTO,
1089 	CXT5045_MODELS
1090 };
1091 
1092 static const char * const cxt5045_models[CXT5045_MODELS] = {
1093 	[CXT5045_LAPTOP_HPSENSE]	= "laptop-hpsense",
1094 	[CXT5045_LAPTOP_MICSENSE]	= "laptop-micsense",
1095 	[CXT5045_LAPTOP_HPMICSENSE]	= "laptop-hpmicsense",
1096 	[CXT5045_BENQ]			= "benq",
1097 	[CXT5045_LAPTOP_HP530]		= "laptop-hp530",
1098 #ifdef CONFIG_SND_DEBUG
1099 	[CXT5045_TEST]		= "test",
1100 #endif
1101 	[CXT5045_AUTO]			= "auto",
1102 };
1103 
1104 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1105 	SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1106 	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1107 			   CXT5045_LAPTOP_HPSENSE),
1108 	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1109 	SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1110 	SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1111 	SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1112 	SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1113 		      CXT5045_LAPTOP_HPMICSENSE),
1114 	SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1115 	SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1116 	SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1117 	SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1118 			   CXT5045_LAPTOP_HPMICSENSE),
1119 	SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1120 	{}
1121 };
1122 
1123 static int patch_cxt5045(struct hda_codec *codec)
1124 {
1125 	struct conexant_spec *spec;
1126 	int board_config;
1127 
1128 	board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1129 						  cxt5045_models,
1130 						  cxt5045_cfg_tbl);
1131 	if (board_config < 0)
1132 		board_config = CXT5045_AUTO; /* model=auto as default */
1133 	if (board_config == CXT5045_AUTO)
1134 		return patch_conexant_auto(codec);
1135 
1136 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1137 	if (!spec)
1138 		return -ENOMEM;
1139 	codec->spec = spec;
1140 	codec->pin_amp_workaround = 1;
1141 
1142 	spec->multiout.max_channels = 2;
1143 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1144 	spec->multiout.dac_nids = cxt5045_dac_nids;
1145 	spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1146 	spec->num_adc_nids = 1;
1147 	spec->adc_nids = cxt5045_adc_nids;
1148 	spec->capsrc_nids = cxt5045_capsrc_nids;
1149 	spec->input_mux = &cxt5045_capture_source;
1150 	spec->num_mixers = 1;
1151 	spec->mixers[0] = cxt5045_mixers;
1152 	spec->num_init_verbs = 1;
1153 	spec->init_verbs[0] = cxt5045_init_verbs;
1154 	spec->spdif_route = 0;
1155 	spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1156 	spec->channel_mode = cxt5045_modes;
1157 
1158 	set_beep_amp(spec, 0x16, 0, 1);
1159 
1160 	codec->patch_ops = conexant_patch_ops;
1161 
1162 	switch (board_config) {
1163 	case CXT5045_LAPTOP_HPSENSE:
1164 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1165 		spec->input_mux = &cxt5045_capture_source;
1166 		spec->num_init_verbs = 2;
1167 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1168 		spec->mixers[0] = cxt5045_mixers;
1169 		codec->patch_ops.init = cxt5045_init;
1170 		break;
1171 	case CXT5045_LAPTOP_MICSENSE:
1172 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1173 		spec->input_mux = &cxt5045_capture_source;
1174 		spec->num_init_verbs = 2;
1175 		spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1176 		spec->mixers[0] = cxt5045_mixers;
1177 		codec->patch_ops.init = cxt5045_init;
1178 		break;
1179 	default:
1180 	case CXT5045_LAPTOP_HPMICSENSE:
1181 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1182 		spec->input_mux = &cxt5045_capture_source;
1183 		spec->num_init_verbs = 3;
1184 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1185 		spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1186 		spec->mixers[0] = cxt5045_mixers;
1187 		codec->patch_ops.init = cxt5045_init;
1188 		break;
1189 	case CXT5045_BENQ:
1190 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1191 		spec->input_mux = &cxt5045_capture_source_benq;
1192 		spec->num_init_verbs = 1;
1193 		spec->init_verbs[0] = cxt5045_benq_init_verbs;
1194 		spec->mixers[0] = cxt5045_mixers;
1195 		spec->mixers[1] = cxt5045_benq_mixers;
1196 		spec->num_mixers = 2;
1197 		codec->patch_ops.init = cxt5045_init;
1198 		break;
1199 	case CXT5045_LAPTOP_HP530:
1200 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1201 		spec->input_mux = &cxt5045_capture_source_hp530;
1202 		spec->num_init_verbs = 2;
1203 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1204 		spec->mixers[0] = cxt5045_mixers_hp530;
1205 		codec->patch_ops.init = cxt5045_init;
1206 		break;
1207 #ifdef CONFIG_SND_DEBUG
1208 	case CXT5045_TEST:
1209 		spec->input_mux = &cxt5045_test_capture_source;
1210 		spec->mixers[0] = cxt5045_test_mixer;
1211 		spec->init_verbs[0] = cxt5045_test_init_verbs;
1212 		break;
1213 
1214 #endif
1215 	}
1216 
1217 	switch (codec->subsystem_id >> 16) {
1218 	case 0x103c:
1219 	case 0x1631:
1220 	case 0x1734:
1221 	case 0x17aa:
1222 		/* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1223 		 * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1224 		 * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1225 		 */
1226 		snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1227 					  (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1228 					  (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1229 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1230 					  (1 << AC_AMPCAP_MUTE_SHIFT));
1231 		break;
1232 	}
1233 
1234 	if (spec->beep_amp)
1235 		snd_hda_attach_beep_device(codec, spec->beep_amp);
1236 
1237 	return 0;
1238 }
1239 
1240 
1241 /* Conexant 5047 specific */
1242 #define CXT5047_SPDIF_OUT	0x11
1243 
1244 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1245 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1246 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1247 
1248 static const struct hda_channel_mode cxt5047_modes[1] = {
1249 	{ 2, NULL },
1250 };
1251 
1252 static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1253 	.num_items = 2,
1254 	.items = {
1255 		{ "ExtMic", 0x2 },
1256 		{ "Line-In", 0x1 },
1257 	}
1258 };
1259 
1260 /* turn on/off EAPD (+ mute HP) as a master switch */
1261 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1262 				    struct snd_ctl_elem_value *ucontrol)
1263 {
1264 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1265 	struct conexant_spec *spec = codec->spec;
1266 	unsigned int bits;
1267 
1268 	if (!cxt_eapd_put(kcontrol, ucontrol))
1269 		return 0;
1270 
1271 	/* toggle internal speakers mute depending of presence of
1272 	 * the headphone jack
1273 	 */
1274 	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1275 	/* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1276 	 * pin widgets unlike other codecs.  In this case, we need to
1277 	 * set index 0x01 for the volume from the mixer amp 0x19.
1278 	 */
1279 	snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1280 				 HDA_AMP_MUTE, bits);
1281 	bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1282 	snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1283 				 HDA_AMP_MUTE, bits);
1284 	return 1;
1285 }
1286 
1287 /* mute internal speaker if HP is plugged */
1288 static void cxt5047_hp_automute(struct hda_codec *codec)
1289 {
1290 	struct conexant_spec *spec = codec->spec;
1291 	unsigned int bits;
1292 
1293 	spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1294 
1295 	bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1296 	/* See the note in cxt5047_hp_master_sw_put */
1297 	snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1298 				 HDA_AMP_MUTE, bits);
1299 }
1300 
1301 /* toggle input of built-in and mic jack appropriately */
1302 static void cxt5047_hp_automic(struct hda_codec *codec)
1303 {
1304 	static const struct hda_verb mic_jack_on[] = {
1305 		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1306 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1307 		{}
1308 	};
1309 	static const struct hda_verb mic_jack_off[] = {
1310 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1311 		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1312 		{}
1313 	};
1314 	unsigned int present;
1315 
1316 	present = snd_hda_jack_detect(codec, 0x15);
1317 	if (present)
1318 		snd_hda_sequence_write(codec, mic_jack_on);
1319 	else
1320 		snd_hda_sequence_write(codec, mic_jack_off);
1321 }
1322 
1323 /* unsolicited event for HP jack sensing */
1324 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1325 				  unsigned int res)
1326 {
1327 	switch (res >> 26) {
1328 	case CONEXANT_HP_EVENT:
1329 		cxt5047_hp_automute(codec);
1330 		break;
1331 	case CONEXANT_MIC_EVENT:
1332 		cxt5047_hp_automic(codec);
1333 		break;
1334 	}
1335 }
1336 
1337 static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1338 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1339 	HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1340 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1341 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1342 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1343 	HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1344 	HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1345 	{
1346 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1347 		.name = "Master Playback Switch",
1348 		.info = cxt_eapd_info,
1349 		.get = cxt_eapd_get,
1350 		.put = cxt5047_hp_master_sw_put,
1351 		.private_value = 0x13,
1352 	},
1353 
1354 	{}
1355 };
1356 
1357 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1358 	/* See the note in cxt5047_hp_master_sw_put */
1359 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1360 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1361 	{}
1362 };
1363 
1364 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1365 	HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1366 	{ } /* end */
1367 };
1368 
1369 static const struct hda_verb cxt5047_init_verbs[] = {
1370 	/* Line in, Mic, Built-in Mic */
1371 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1372 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1373 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1374 	/* HP, Speaker  */
1375 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1376 	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1377 	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1378 	/* Record selector: Mic */
1379 	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1380 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1381 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1382 	{0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1383 	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1384 	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1385 	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1386 	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1387 	/* SPDIF route: PCM */
1388 	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1389 	/* Enable unsolicited events */
1390 	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1391 	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1392 	{ } /* end */
1393 };
1394 
1395 /* configuration for Toshiba Laptops */
1396 static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1397 	{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1398 	{}
1399 };
1400 
1401 /* Test configuration for debugging, modelled after the ALC260 test
1402  * configuration.
1403  */
1404 #ifdef CONFIG_SND_DEBUG
1405 static const struct hda_input_mux cxt5047_test_capture_source = {
1406 	.num_items = 4,
1407 	.items = {
1408 		{ "LINE1 pin", 0x0 },
1409 		{ "MIC1 pin", 0x1 },
1410 		{ "MIC2 pin", 0x2 },
1411 		{ "CD pin", 0x3 },
1412         },
1413 };
1414 
1415 static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1416 
1417 	/* Output only controls */
1418 	HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1419 	HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1420 	HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1421 	HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1422 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1423 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1424 	HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1425 	HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1426 	HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1427 	HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1428 	HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1429 	HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1430 
1431 	/* Modes for retasking pin widgets */
1432 	CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1433 	CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1434 
1435 	/* EAPD Switch Control */
1436 	CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1437 
1438 	/* Loopback mixer controls */
1439 	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1440 	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1441 	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1442 	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1443 	HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1444 	HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1445 	HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1446 	HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1447 
1448 	HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1449 	HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1450 	HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1451 	HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1452 	HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1453 	HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1454 	HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1455 	HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1456 	{
1457 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1458 		.name = "Input Source",
1459 		.info = conexant_mux_enum_info,
1460 		.get = conexant_mux_enum_get,
1461 		.put = conexant_mux_enum_put,
1462 	},
1463 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1464 
1465 	{ } /* end */
1466 };
1467 
1468 static const struct hda_verb cxt5047_test_init_verbs[] = {
1469 	/* Enable retasking pins as output, initially without power amp */
1470 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1471 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1472 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1473 
1474 	/* Disable digital (SPDIF) pins initially, but users can enable
1475 	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
1476 	 * payload also sets the generation to 0, output to be in "consumer"
1477 	 * PCM format, copyright asserted, no pre-emphasis and no validity
1478 	 * control.
1479 	 */
1480 	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1481 
1482 	/* Ensure mic1, mic2, line1 pin widgets take input from the
1483 	 * OUT1 sum bus when acting as an output.
1484 	 */
1485 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1486 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1487 
1488 	/* Start with output sum widgets muted and their output gains at min */
1489 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1490 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1491 
1492 	/* Unmute retasking pin widget output buffers since the default
1493 	 * state appears to be output.  As the pin mode is changed by the
1494 	 * user the pin mode control will take care of enabling the pin's
1495 	 * input/output buffers as needed.
1496 	 */
1497 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500 
1501 	/* Mute capture amp left and right */
1502 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1503 
1504 	/* Set ADC connection select to match default mixer setting (mic1
1505 	 * pin)
1506 	 */
1507 	{0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1508 
1509 	/* Mute all inputs to mixer widget (even unconnected ones) */
1510 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1511 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1512 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1513 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1514 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1515 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1516 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1517 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1518 
1519 	{ }
1520 };
1521 #endif
1522 
1523 
1524 /* initialize jack-sensing, too */
1525 static int cxt5047_hp_init(struct hda_codec *codec)
1526 {
1527 	conexant_init(codec);
1528 	cxt5047_hp_automute(codec);
1529 	return 0;
1530 }
1531 
1532 
1533 enum {
1534 	CXT5047_LAPTOP,		/* Laptops w/o EAPD support */
1535 	CXT5047_LAPTOP_HP,	/* Some HP laptops */
1536 	CXT5047_LAPTOP_EAPD,	/* Laptops with EAPD support */
1537 #ifdef CONFIG_SND_DEBUG
1538 	CXT5047_TEST,
1539 #endif
1540 	CXT5047_AUTO,
1541 	CXT5047_MODELS
1542 };
1543 
1544 static const char * const cxt5047_models[CXT5047_MODELS] = {
1545 	[CXT5047_LAPTOP]	= "laptop",
1546 	[CXT5047_LAPTOP_HP]	= "laptop-hp",
1547 	[CXT5047_LAPTOP_EAPD]	= "laptop-eapd",
1548 #ifdef CONFIG_SND_DEBUG
1549 	[CXT5047_TEST]		= "test",
1550 #endif
1551 	[CXT5047_AUTO]		= "auto",
1552 };
1553 
1554 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1555 	SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1556 	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1557 			   CXT5047_LAPTOP),
1558 	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1559 	{}
1560 };
1561 
1562 static int patch_cxt5047(struct hda_codec *codec)
1563 {
1564 	struct conexant_spec *spec;
1565 	int board_config;
1566 
1567 	board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1568 						  cxt5047_models,
1569 						  cxt5047_cfg_tbl);
1570 	if (board_config < 0)
1571 		board_config = CXT5047_AUTO; /* model=auto as default */
1572 	if (board_config == CXT5047_AUTO)
1573 		return patch_conexant_auto(codec);
1574 
1575 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1576 	if (!spec)
1577 		return -ENOMEM;
1578 	codec->spec = spec;
1579 	codec->pin_amp_workaround = 1;
1580 
1581 	spec->multiout.max_channels = 2;
1582 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1583 	spec->multiout.dac_nids = cxt5047_dac_nids;
1584 	spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1585 	spec->num_adc_nids = 1;
1586 	spec->adc_nids = cxt5047_adc_nids;
1587 	spec->capsrc_nids = cxt5047_capsrc_nids;
1588 	spec->num_mixers = 1;
1589 	spec->mixers[0] = cxt5047_base_mixers;
1590 	spec->num_init_verbs = 1;
1591 	spec->init_verbs[0] = cxt5047_init_verbs;
1592 	spec->spdif_route = 0;
1593 	spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1594 	spec->channel_mode = cxt5047_modes,
1595 
1596 	codec->patch_ops = conexant_patch_ops;
1597 
1598 	switch (board_config) {
1599 	case CXT5047_LAPTOP:
1600 		spec->num_mixers = 2;
1601 		spec->mixers[1] = cxt5047_hp_spk_mixers;
1602 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1603 		break;
1604 	case CXT5047_LAPTOP_HP:
1605 		spec->num_mixers = 2;
1606 		spec->mixers[1] = cxt5047_hp_only_mixers;
1607 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1608 		codec->patch_ops.init = cxt5047_hp_init;
1609 		break;
1610 	case CXT5047_LAPTOP_EAPD:
1611 		spec->input_mux = &cxt5047_toshiba_capture_source;
1612 		spec->num_mixers = 2;
1613 		spec->mixers[1] = cxt5047_hp_spk_mixers;
1614 		spec->num_init_verbs = 2;
1615 		spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1616 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1617 		break;
1618 #ifdef CONFIG_SND_DEBUG
1619 	case CXT5047_TEST:
1620 		spec->input_mux = &cxt5047_test_capture_source;
1621 		spec->mixers[0] = cxt5047_test_mixer;
1622 		spec->init_verbs[0] = cxt5047_test_init_verbs;
1623 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1624 #endif
1625 	}
1626 	spec->vmaster_nid = 0x13;
1627 
1628 	switch (codec->subsystem_id >> 16) {
1629 	case 0x103c:
1630 		/* HP laptops have really bad sound over 0 dB on NID 0x10.
1631 		 * Fix max PCM level to 0 dB (originally it has 0x1e steps
1632 		 * with 0 dB offset 0x17)
1633 		 */
1634 		snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1635 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1636 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1637 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1638 					  (1 << AC_AMPCAP_MUTE_SHIFT));
1639 		break;
1640 	}
1641 
1642 	return 0;
1643 }
1644 
1645 /* Conexant 5051 specific */
1646 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1647 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1648 
1649 static const struct hda_channel_mode cxt5051_modes[1] = {
1650 	{ 2, NULL },
1651 };
1652 
1653 static void cxt5051_update_speaker(struct hda_codec *codec)
1654 {
1655 	struct conexant_spec *spec = codec->spec;
1656 	unsigned int pinctl;
1657 	/* headphone pin */
1658 	pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1659 	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1660 			    pinctl);
1661 	/* speaker pin */
1662 	pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1663 	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1664 			    pinctl);
1665 	/* on ideapad there is an aditional speaker (subwoofer) to mute */
1666 	if (spec->ideapad)
1667 		snd_hda_codec_write(codec, 0x1b, 0,
1668 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
1669 				    pinctl);
1670 }
1671 
1672 /* turn on/off EAPD (+ mute HP) as a master switch */
1673 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1674 				    struct snd_ctl_elem_value *ucontrol)
1675 {
1676 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1677 
1678 	if (!cxt_eapd_put(kcontrol, ucontrol))
1679 		return 0;
1680 	cxt5051_update_speaker(codec);
1681 	return 1;
1682 }
1683 
1684 /* toggle input of built-in and mic jack appropriately */
1685 static void cxt5051_portb_automic(struct hda_codec *codec)
1686 {
1687 	struct conexant_spec *spec = codec->spec;
1688 	unsigned int present;
1689 
1690 	if (!(spec->auto_mic & AUTO_MIC_PORTB))
1691 		return;
1692 	present = snd_hda_jack_detect(codec, 0x17);
1693 	snd_hda_codec_write(codec, 0x14, 0,
1694 			    AC_VERB_SET_CONNECT_SEL,
1695 			    present ? 0x01 : 0x00);
1696 }
1697 
1698 /* switch the current ADC according to the jack state */
1699 static void cxt5051_portc_automic(struct hda_codec *codec)
1700 {
1701 	struct conexant_spec *spec = codec->spec;
1702 	unsigned int present;
1703 	hda_nid_t new_adc;
1704 
1705 	if (!(spec->auto_mic & AUTO_MIC_PORTC))
1706 		return;
1707 	present = snd_hda_jack_detect(codec, 0x18);
1708 	if (present)
1709 		spec->cur_adc_idx = 1;
1710 	else
1711 		spec->cur_adc_idx = 0;
1712 	new_adc = spec->adc_nids[spec->cur_adc_idx];
1713 	if (spec->cur_adc && spec->cur_adc != new_adc) {
1714 		/* stream is running, let's swap the current ADC */
1715 		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1716 		spec->cur_adc = new_adc;
1717 		snd_hda_codec_setup_stream(codec, new_adc,
1718 					   spec->cur_adc_stream_tag, 0,
1719 					   spec->cur_adc_format);
1720 	}
1721 }
1722 
1723 /* mute internal speaker if HP is plugged */
1724 static void cxt5051_hp_automute(struct hda_codec *codec)
1725 {
1726 	struct conexant_spec *spec = codec->spec;
1727 
1728 	spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1729 	cxt5051_update_speaker(codec);
1730 }
1731 
1732 /* unsolicited event for HP jack sensing */
1733 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1734 				   unsigned int res)
1735 {
1736 	int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1737 	switch (res >> 26) {
1738 	case CONEXANT_HP_EVENT:
1739 		cxt5051_hp_automute(codec);
1740 		break;
1741 	case CXT5051_PORTB_EVENT:
1742 		cxt5051_portb_automic(codec);
1743 		break;
1744 	case CXT5051_PORTC_EVENT:
1745 		cxt5051_portc_automic(codec);
1746 		break;
1747 	}
1748 	snd_hda_input_jack_report(codec, nid);
1749 }
1750 
1751 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1752 	HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1753 	{
1754 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1755 		.name = "Master Playback Switch",
1756 		.info = cxt_eapd_info,
1757 		.get = cxt_eapd_get,
1758 		.put = cxt5051_hp_master_sw_put,
1759 		.private_value = 0x1a,
1760 	},
1761 	{}
1762 };
1763 
1764 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1765 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1766 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1767 	HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1768 	HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1769 	HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1770 	HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1771 	{}
1772 };
1773 
1774 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1775 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1776 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1777 	HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1778 	HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1779 	{}
1780 };
1781 
1782 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1783 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1784 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1785 	{}
1786 };
1787 
1788 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1789 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1790 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1791 	{}
1792 };
1793 
1794 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1795 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1796 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1797 	HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1798 	HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1799 	{}
1800 };
1801 
1802 static const struct hda_verb cxt5051_init_verbs[] = {
1803 	/* Line in, Mic */
1804 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1805 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1806 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1807 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1808 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1809 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1810 	/* SPK  */
1811 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1812 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1813 	/* HP, Amp  */
1814 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1815 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1816 	/* DAC1 */
1817 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818 	/* Record selector: Internal mic */
1819 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1820 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1821 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1822 	/* SPDIF route: PCM */
1823 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1824 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1825 	/* EAPD */
1826 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1827 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1828 	{ } /* end */
1829 };
1830 
1831 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1832 	/* Line in, Mic */
1833 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1834 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1835 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1836 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1837 	/* SPK  */
1838 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1839 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1840 	/* HP, Amp  */
1841 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1842 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1843 	/* DAC1 */
1844 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1845 	/* Record selector: Internal mic */
1846 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1847 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1848 	/* SPDIF route: PCM */
1849 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1850 	/* EAPD */
1851 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1852 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1853 	{ } /* end */
1854 };
1855 
1856 static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1857 	/* Line in, Mic */
1858 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1859 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1860 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1861 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1863 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1864 	/* SPK  */
1865 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1866 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1867 	/* HP, Amp  */
1868 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1869 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1870 	/* Docking HP */
1871 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1872 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1873 	/* DAC1 */
1874 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1875 	/* Record selector: Internal mic */
1876 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1877 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1878 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1879 	/* SPDIF route: PCM */
1880 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1881 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1882 	/* EAPD */
1883 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1884 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1885 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1886 	{ } /* end */
1887 };
1888 
1889 static const struct hda_verb cxt5051_f700_init_verbs[] = {
1890 	/* Line in, Mic */
1891 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1892 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1893 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1894 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1895 	/* SPK  */
1896 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1897 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1898 	/* HP, Amp  */
1899 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1900 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1901 	/* DAC1 */
1902 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1903 	/* Record selector: Internal mic */
1904 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1905 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1906 	/* SPDIF route: PCM */
1907 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1908 	/* EAPD */
1909 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1910 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1911 	{ } /* end */
1912 };
1913 
1914 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1915 				 unsigned int event)
1916 {
1917 	snd_hda_codec_write(codec, nid, 0,
1918 			    AC_VERB_SET_UNSOLICITED_ENABLE,
1919 			    AC_USRSP_EN | event);
1920 	snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
1921 	snd_hda_input_jack_report(codec, nid);
1922 }
1923 
1924 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1925 	/* Subwoofer */
1926 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1927 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1928 	{ } /* end */
1929 };
1930 
1931 /* initialize jack-sensing, too */
1932 static int cxt5051_init(struct hda_codec *codec)
1933 {
1934 	struct conexant_spec *spec = codec->spec;
1935 
1936 	conexant_init(codec);
1937 	conexant_init_jacks(codec);
1938 
1939 	if (spec->auto_mic & AUTO_MIC_PORTB)
1940 		cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1941 	if (spec->auto_mic & AUTO_MIC_PORTC)
1942 		cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1943 
1944 	if (codec->patch_ops.unsol_event) {
1945 		cxt5051_hp_automute(codec);
1946 		cxt5051_portb_automic(codec);
1947 		cxt5051_portc_automic(codec);
1948 	}
1949 	return 0;
1950 }
1951 
1952 
1953 enum {
1954 	CXT5051_LAPTOP,	 /* Laptops w/ EAPD support */
1955 	CXT5051_HP,	/* no docking */
1956 	CXT5051_HP_DV6736,	/* HP without mic switch */
1957 	CXT5051_LENOVO_X200,	/* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1958 	CXT5051_F700,       /* HP Compaq Presario F700 */
1959 	CXT5051_TOSHIBA,	/* Toshiba M300 & co */
1960 	CXT5051_IDEAPAD,	/* Lenovo IdeaPad Y430 */
1961 	CXT5051_AUTO,		/* auto-parser */
1962 	CXT5051_MODELS
1963 };
1964 
1965 static const char *const cxt5051_models[CXT5051_MODELS] = {
1966 	[CXT5051_LAPTOP]	= "laptop",
1967 	[CXT5051_HP]		= "hp",
1968 	[CXT5051_HP_DV6736]	= "hp-dv6736",
1969 	[CXT5051_LENOVO_X200]	= "lenovo-x200",
1970 	[CXT5051_F700]          = "hp-700",
1971 	[CXT5051_TOSHIBA]	= "toshiba",
1972 	[CXT5051_IDEAPAD]	= "ideapad",
1973 	[CXT5051_AUTO]		= "auto",
1974 };
1975 
1976 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1977 	SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1978 	SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1979 	SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1980 	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1981 	SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1982 		      CXT5051_LAPTOP),
1983 	SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1984 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1985 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1986 	{}
1987 };
1988 
1989 static int patch_cxt5051(struct hda_codec *codec)
1990 {
1991 	struct conexant_spec *spec;
1992 	int board_config;
1993 
1994 	board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1995 						  cxt5051_models,
1996 						  cxt5051_cfg_tbl);
1997 	if (board_config < 0)
1998 		board_config = CXT5051_AUTO; /* model=auto as default */
1999 	if (board_config == CXT5051_AUTO)
2000 		return patch_conexant_auto(codec);
2001 
2002 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2003 	if (!spec)
2004 		return -ENOMEM;
2005 	codec->spec = spec;
2006 	codec->pin_amp_workaround = 1;
2007 
2008 	codec->patch_ops = conexant_patch_ops;
2009 	codec->patch_ops.init = cxt5051_init;
2010 
2011 	spec->multiout.max_channels = 2;
2012 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
2013 	spec->multiout.dac_nids = cxt5051_dac_nids;
2014 	spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
2015 	spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
2016 	spec->adc_nids = cxt5051_adc_nids;
2017 	spec->num_mixers = 2;
2018 	spec->mixers[0] = cxt5051_capture_mixers;
2019 	spec->mixers[1] = cxt5051_playback_mixers;
2020 	spec->num_init_verbs = 1;
2021 	spec->init_verbs[0] = cxt5051_init_verbs;
2022 	spec->spdif_route = 0;
2023 	spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
2024 	spec->channel_mode = cxt5051_modes;
2025 	spec->cur_adc = 0;
2026 	spec->cur_adc_idx = 0;
2027 
2028 	set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
2029 
2030 	codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
2031 
2032 	spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
2033 	switch (board_config) {
2034 	case CXT5051_HP:
2035 		spec->mixers[0] = cxt5051_hp_mixers;
2036 		break;
2037 	case CXT5051_HP_DV6736:
2038 		spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
2039 		spec->mixers[0] = cxt5051_hp_dv6736_mixers;
2040 		spec->auto_mic = 0;
2041 		break;
2042 	case CXT5051_LENOVO_X200:
2043 		spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
2044 		/* Thinkpad X301 does not have S/PDIF wired and no ability
2045 		   to use a docking station. */
2046 		if (codec->subsystem_id == 0x17aa211f)
2047 			spec->multiout.dig_out_nid = 0;
2048 		break;
2049 	case CXT5051_F700:
2050 		spec->init_verbs[0] = cxt5051_f700_init_verbs;
2051 		spec->mixers[0] = cxt5051_f700_mixers;
2052 		spec->auto_mic = 0;
2053 		break;
2054 	case CXT5051_TOSHIBA:
2055 		spec->mixers[0] = cxt5051_toshiba_mixers;
2056 		spec->auto_mic = AUTO_MIC_PORTB;
2057 		break;
2058 	case CXT5051_IDEAPAD:
2059 		spec->init_verbs[spec->num_init_verbs++] =
2060 			cxt5051_ideapad_init_verbs;
2061 		spec->ideapad = 1;
2062 		break;
2063 	}
2064 
2065 	if (spec->beep_amp)
2066 		snd_hda_attach_beep_device(codec, spec->beep_amp);
2067 
2068 	return 0;
2069 }
2070 
2071 /* Conexant 5066 specific */
2072 
2073 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2074 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2075 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2076 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2077 
2078 /* OLPC's microphone port is DC coupled for use with external sensors,
2079  * therefore we use a 50% mic bias in order to center the input signal with
2080  * the DC input range of the codec. */
2081 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2082 
2083 static const struct hda_channel_mode cxt5066_modes[1] = {
2084 	{ 2, NULL },
2085 };
2086 
2087 #define HP_PRESENT_PORT_A	(1 << 0)
2088 #define HP_PRESENT_PORT_D	(1 << 1)
2089 #define hp_port_a_present(spec)	((spec)->hp_present & HP_PRESENT_PORT_A)
2090 #define hp_port_d_present(spec)	((spec)->hp_present & HP_PRESENT_PORT_D)
2091 
2092 static void cxt5066_update_speaker(struct hda_codec *codec)
2093 {
2094 	struct conexant_spec *spec = codec->spec;
2095 	unsigned int pinctl;
2096 
2097 	snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2098 		    spec->hp_present, spec->cur_eapd);
2099 
2100 	/* Port A (HP) */
2101 	pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2102 	snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2103 			pinctl);
2104 
2105 	/* Port D (HP/LO) */
2106 	pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2107 	if (spec->dell_automute || spec->thinkpad) {
2108 		/* Mute if Port A is connected */
2109 		if (hp_port_a_present(spec))
2110 			pinctl = 0;
2111 	} else {
2112 		/* Thinkpad/Dell doesn't give pin-D status */
2113 		if (!hp_port_d_present(spec))
2114 			pinctl = 0;
2115 	}
2116 	snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2117 			pinctl);
2118 
2119 	/* CLASS_D AMP */
2120 	pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2121 	snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2122 			pinctl);
2123 }
2124 
2125 /* turn on/off EAPD (+ mute HP) as a master switch */
2126 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
2127 				    struct snd_ctl_elem_value *ucontrol)
2128 {
2129 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2130 
2131 	if (!cxt_eapd_put(kcontrol, ucontrol))
2132 		return 0;
2133 
2134 	cxt5066_update_speaker(codec);
2135 	return 1;
2136 }
2137 
2138 static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2139 	.num_items = 3,
2140 	.items = {
2141 		{ "Off", PIN_IN },
2142 		{ "50%", PIN_VREF50 },
2143 		{ "80%", PIN_VREF80 },
2144 	},
2145 };
2146 
2147 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2148 {
2149 	struct conexant_spec *spec = codec->spec;
2150 	/* Even though port F is the DC input, the bias is controlled on port B.
2151 	 * we also leave that port as an active input (but unselected) in DC mode
2152 	 * just in case that is necessary to make the bias setting take effect. */
2153 	return snd_hda_codec_write_cache(codec, 0x1a, 0,
2154 		AC_VERB_SET_PIN_WIDGET_CONTROL,
2155 		cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2156 }
2157 
2158 /* OLPC defers mic widget control until when capture is started because the
2159  * microphone LED comes on as soon as these settings are put in place. if we
2160  * did this before recording, it would give the false indication that recording
2161  * is happening when it is not. */
2162 static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2163 {
2164 	struct conexant_spec *spec = codec->spec;
2165 	if (!spec->recording)
2166 		return;
2167 
2168 	if (spec->dc_enable) {
2169 		/* in DC mode we ignore presence detection and just use the jack
2170 		 * through our special DC port */
2171 		const struct hda_verb enable_dc_mode[] = {
2172 			/* disble internal mic, port C */
2173 			{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2174 
2175 			/* enable DC capture, port F */
2176 			{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2177 			{},
2178 		};
2179 
2180 		snd_hda_sequence_write(codec, enable_dc_mode);
2181 		/* port B input disabled (and bias set) through the following call */
2182 		cxt5066_set_olpc_dc_bias(codec);
2183 		return;
2184 	}
2185 
2186 	/* disable DC (port F) */
2187 	snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2188 
2189 	/* external mic, port B */
2190 	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2191 		spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2192 
2193 	/* internal mic, port C */
2194 	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2195 		spec->ext_mic_present ? 0 : PIN_VREF80);
2196 }
2197 
2198 /* toggle input of built-in and mic jack appropriately */
2199 static void cxt5066_olpc_automic(struct hda_codec *codec)
2200 {
2201 	struct conexant_spec *spec = codec->spec;
2202 	unsigned int present;
2203 
2204 	if (spec->dc_enable) /* don't do presence detection in DC mode */
2205 		return;
2206 
2207 	present = snd_hda_codec_read(codec, 0x1a, 0,
2208 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2209 	if (present)
2210 		snd_printdd("CXT5066: external microphone detected\n");
2211 	else
2212 		snd_printdd("CXT5066: external microphone absent\n");
2213 
2214 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2215 		present ? 0 : 1);
2216 	spec->ext_mic_present = !!present;
2217 
2218 	cxt5066_olpc_select_mic(codec);
2219 }
2220 
2221 /* toggle input of built-in digital mic and mic jack appropriately */
2222 static void cxt5066_vostro_automic(struct hda_codec *codec)
2223 {
2224 	unsigned int present;
2225 
2226 	struct hda_verb ext_mic_present[] = {
2227 		/* enable external mic, port B */
2228 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229 
2230 		/* switch to external mic input */
2231 		{0x17, AC_VERB_SET_CONNECT_SEL, 0},
2232 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2233 
2234 		/* disable internal digital mic */
2235 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2236 		{}
2237 	};
2238 	static const struct hda_verb ext_mic_absent[] = {
2239 		/* enable internal mic, port C */
2240 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2241 
2242 		/* switch to internal mic input */
2243 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2244 
2245 		/* disable external mic, port B */
2246 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2247 		{}
2248 	};
2249 
2250 	present = snd_hda_jack_detect(codec, 0x1a);
2251 	if (present) {
2252 		snd_printdd("CXT5066: external microphone detected\n");
2253 		snd_hda_sequence_write(codec, ext_mic_present);
2254 	} else {
2255 		snd_printdd("CXT5066: external microphone absent\n");
2256 		snd_hda_sequence_write(codec, ext_mic_absent);
2257 	}
2258 }
2259 
2260 /* toggle input of built-in digital mic and mic jack appropriately */
2261 static void cxt5066_ideapad_automic(struct hda_codec *codec)
2262 {
2263 	unsigned int present;
2264 
2265 	struct hda_verb ext_mic_present[] = {
2266 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2267 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2268 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2269 		{}
2270 	};
2271 	static const struct hda_verb ext_mic_absent[] = {
2272 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2273 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2274 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2275 		{}
2276 	};
2277 
2278 	present = snd_hda_jack_detect(codec, 0x1b);
2279 	if (present) {
2280 		snd_printdd("CXT5066: external microphone detected\n");
2281 		snd_hda_sequence_write(codec, ext_mic_present);
2282 	} else {
2283 		snd_printdd("CXT5066: external microphone absent\n");
2284 		snd_hda_sequence_write(codec, ext_mic_absent);
2285 	}
2286 }
2287 
2288 
2289 /* toggle input of built-in digital mic and mic jack appropriately */
2290 static void cxt5066_asus_automic(struct hda_codec *codec)
2291 {
2292 	unsigned int present;
2293 
2294 	present = snd_hda_jack_detect(codec, 0x1b);
2295 	snd_printdd("CXT5066: external microphone present=%d\n", present);
2296 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2297 			    present ? 1 : 0);
2298 }
2299 
2300 
2301 /* toggle input of built-in digital mic and mic jack appropriately */
2302 static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2303 {
2304 	unsigned int present;
2305 
2306 	present = snd_hda_jack_detect(codec, 0x1b);
2307 	snd_printdd("CXT5066: external microphone present=%d\n", present);
2308 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2309 			    present ? 1 : 3);
2310 }
2311 
2312 
2313 /* toggle input of built-in digital mic and mic jack appropriately
2314    order is: external mic -> dock mic -> interal mic */
2315 static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2316 {
2317 	unsigned int ext_present, dock_present;
2318 
2319 	static const struct hda_verb ext_mic_present[] = {
2320 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2321 		{0x17, AC_VERB_SET_CONNECT_SEL, 1},
2322 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2323 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2324 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2325 		{}
2326 	};
2327 	static const struct hda_verb dock_mic_present[] = {
2328 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2329 		{0x17, AC_VERB_SET_CONNECT_SEL, 0},
2330 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2331 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2332 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2333 		{}
2334 	};
2335 	static const struct hda_verb ext_mic_absent[] = {
2336 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2337 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2338 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2339 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2340 		{}
2341 	};
2342 
2343 	ext_present = snd_hda_jack_detect(codec, 0x1b);
2344 	dock_present = snd_hda_jack_detect(codec, 0x1a);
2345 	if (ext_present) {
2346 		snd_printdd("CXT5066: external microphone detected\n");
2347 		snd_hda_sequence_write(codec, ext_mic_present);
2348 	} else if (dock_present) {
2349 		snd_printdd("CXT5066: dock microphone detected\n");
2350 		snd_hda_sequence_write(codec, dock_mic_present);
2351 	} else {
2352 		snd_printdd("CXT5066: external microphone absent\n");
2353 		snd_hda_sequence_write(codec, ext_mic_absent);
2354 	}
2355 }
2356 
2357 /* mute internal speaker if HP is plugged */
2358 static void cxt5066_hp_automute(struct hda_codec *codec)
2359 {
2360 	struct conexant_spec *spec = codec->spec;
2361 	unsigned int portA, portD;
2362 
2363 	/* Port A */
2364 	portA = snd_hda_jack_detect(codec, 0x19);
2365 
2366 	/* Port D */
2367 	portD = snd_hda_jack_detect(codec, 0x1c);
2368 
2369 	spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2370 	spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2371 	snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2372 		portA, portD, spec->hp_present);
2373 	cxt5066_update_speaker(codec);
2374 }
2375 
2376 /* Dispatch the right mic autoswitch function */
2377 static void cxt5066_automic(struct hda_codec *codec)
2378 {
2379 	struct conexant_spec *spec = codec->spec;
2380 
2381 	if (spec->dell_vostro)
2382 		cxt5066_vostro_automic(codec);
2383 	else if (spec->ideapad)
2384 		cxt5066_ideapad_automic(codec);
2385 	else if (spec->thinkpad)
2386 		cxt5066_thinkpad_automic(codec);
2387 	else if (spec->hp_laptop)
2388 		cxt5066_hp_laptop_automic(codec);
2389 	else if (spec->asus)
2390 		cxt5066_asus_automic(codec);
2391 }
2392 
2393 /* unsolicited event for jack sensing */
2394 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2395 {
2396 	struct conexant_spec *spec = codec->spec;
2397 	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2398 	switch (res >> 26) {
2399 	case CONEXANT_HP_EVENT:
2400 		cxt5066_hp_automute(codec);
2401 		break;
2402 	case CONEXANT_MIC_EVENT:
2403 		/* ignore mic events in DC mode; we're always using the jack */
2404 		if (!spec->dc_enable)
2405 			cxt5066_olpc_automic(codec);
2406 		break;
2407 	}
2408 }
2409 
2410 /* unsolicited event for jack sensing */
2411 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2412 {
2413 	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2414 	switch (res >> 26) {
2415 	case CONEXANT_HP_EVENT:
2416 		cxt5066_hp_automute(codec);
2417 		break;
2418 	case CONEXANT_MIC_EVENT:
2419 		cxt5066_automic(codec);
2420 		break;
2421 	}
2422 }
2423 
2424 
2425 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2426 	.num_items = 5,
2427 	.items = {
2428 		{ "0dB",  0 },
2429 		{ "10dB", 1 },
2430 		{ "20dB", 2 },
2431 		{ "30dB", 3 },
2432 		{ "40dB", 4 },
2433 	},
2434 };
2435 
2436 static void cxt5066_set_mic_boost(struct hda_codec *codec)
2437 {
2438 	struct conexant_spec *spec = codec->spec;
2439 	snd_hda_codec_write_cache(codec, 0x17, 0,
2440 		AC_VERB_SET_AMP_GAIN_MUTE,
2441 		AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2442 			cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2443 	if (spec->ideapad || spec->thinkpad) {
2444 		/* adjust the internal mic as well...it is not through 0x17 */
2445 		snd_hda_codec_write_cache(codec, 0x23, 0,
2446 			AC_VERB_SET_AMP_GAIN_MUTE,
2447 			AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2448 				cxt5066_analog_mic_boost.
2449 					items[spec->mic_boost].index);
2450 	}
2451 }
2452 
2453 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2454 					   struct snd_ctl_elem_info *uinfo)
2455 {
2456 	return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2457 }
2458 
2459 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2460 					  struct snd_ctl_elem_value *ucontrol)
2461 {
2462 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2463 	struct conexant_spec *spec = codec->spec;
2464 	ucontrol->value.enumerated.item[0] = spec->mic_boost;
2465 	return 0;
2466 }
2467 
2468 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2469 					  struct snd_ctl_elem_value *ucontrol)
2470 {
2471 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2472 	struct conexant_spec *spec = codec->spec;
2473 	const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2474 	unsigned int idx;
2475 	idx = ucontrol->value.enumerated.item[0];
2476 	if (idx >= imux->num_items)
2477 		idx = imux->num_items - 1;
2478 
2479 	spec->mic_boost = idx;
2480 	if (!spec->dc_enable)
2481 		cxt5066_set_mic_boost(codec);
2482 	return 1;
2483 }
2484 
2485 static void cxt5066_enable_dc(struct hda_codec *codec)
2486 {
2487 	const struct hda_verb enable_dc_mode[] = {
2488 		/* disable gain */
2489 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490 
2491 		/* switch to DC input */
2492 		{0x17, AC_VERB_SET_CONNECT_SEL, 3},
2493 		{}
2494 	};
2495 
2496 	/* configure as input source */
2497 	snd_hda_sequence_write(codec, enable_dc_mode);
2498 	cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2499 }
2500 
2501 static void cxt5066_disable_dc(struct hda_codec *codec)
2502 {
2503 	/* reconfigure input source */
2504 	cxt5066_set_mic_boost(codec);
2505 	/* automic also selects the right mic if we're recording */
2506 	cxt5066_olpc_automic(codec);
2507 }
2508 
2509 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2510 			     struct snd_ctl_elem_value *ucontrol)
2511 {
2512 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2513 	struct conexant_spec *spec = codec->spec;
2514 	ucontrol->value.integer.value[0] = spec->dc_enable;
2515 	return 0;
2516 }
2517 
2518 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2519 			     struct snd_ctl_elem_value *ucontrol)
2520 {
2521 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2522 	struct conexant_spec *spec = codec->spec;
2523 	int dc_enable = !!ucontrol->value.integer.value[0];
2524 
2525 	if (dc_enable == spec->dc_enable)
2526 		return 0;
2527 
2528 	spec->dc_enable = dc_enable;
2529 	if (dc_enable)
2530 		cxt5066_enable_dc(codec);
2531 	else
2532 		cxt5066_disable_dc(codec);
2533 
2534 	return 1;
2535 }
2536 
2537 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2538 					   struct snd_ctl_elem_info *uinfo)
2539 {
2540 	return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2541 }
2542 
2543 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2544 					  struct snd_ctl_elem_value *ucontrol)
2545 {
2546 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2547 	struct conexant_spec *spec = codec->spec;
2548 	ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2549 	return 0;
2550 }
2551 
2552 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2553 					  struct snd_ctl_elem_value *ucontrol)
2554 {
2555 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2556 	struct conexant_spec *spec = codec->spec;
2557 	const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2558 	unsigned int idx;
2559 
2560 	idx = ucontrol->value.enumerated.item[0];
2561 	if (idx >= imux->num_items)
2562 		idx = imux->num_items - 1;
2563 
2564 	spec->dc_input_bias = idx;
2565 	if (spec->dc_enable)
2566 		cxt5066_set_olpc_dc_bias(codec);
2567 	return 1;
2568 }
2569 
2570 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2571 {
2572 	struct conexant_spec *spec = codec->spec;
2573 	/* mark as recording and configure the microphone widget so that the
2574 	 * recording LED comes on. */
2575 	spec->recording = 1;
2576 	cxt5066_olpc_select_mic(codec);
2577 }
2578 
2579 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2580 {
2581 	struct conexant_spec *spec = codec->spec;
2582 	const struct hda_verb disable_mics[] = {
2583 		/* disable external mic, port B */
2584 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2585 
2586 		/* disble internal mic, port C */
2587 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2588 
2589 		/* disable DC capture, port F */
2590 		{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2591 		{},
2592 	};
2593 
2594 	snd_hda_sequence_write(codec, disable_mics);
2595 	spec->recording = 0;
2596 }
2597 
2598 static void conexant_check_dig_outs(struct hda_codec *codec,
2599 				    const hda_nid_t *dig_pins,
2600 				    int num_pins)
2601 {
2602 	struct conexant_spec *spec = codec->spec;
2603 	hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2604 	int i;
2605 
2606 	for (i = 0; i < num_pins; i++, dig_pins++) {
2607 		unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2608 		if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2609 			continue;
2610 		if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2611 			continue;
2612 		if (spec->slave_dig_outs[0])
2613 			nid_loc++;
2614 		else
2615 			nid_loc = spec->slave_dig_outs;
2616 	}
2617 }
2618 
2619 static const struct hda_input_mux cxt5066_capture_source = {
2620 	.num_items = 4,
2621 	.items = {
2622 		{ "Mic B", 0 },
2623 		{ "Mic C", 1 },
2624 		{ "Mic E", 2 },
2625 		{ "Mic F", 3 },
2626 	},
2627 };
2628 
2629 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2630 	.ops = &snd_hda_bind_vol,
2631 	.values = {
2632 		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2633 		HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2634 		0
2635 	},
2636 };
2637 
2638 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2639 	.ops = &snd_hda_bind_sw,
2640 	.values = {
2641 		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2642 		HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2643 		0
2644 	},
2645 };
2646 
2647 static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2648 	HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2649 	{}
2650 };
2651 
2652 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2653 	{
2654 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2655 		.name = "Master Playback Volume",
2656 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2657 				  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2658 				  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2659 		.subdevice = HDA_SUBDEV_AMP_FLAG,
2660 		.info = snd_hda_mixer_amp_volume_info,
2661 		.get = snd_hda_mixer_amp_volume_get,
2662 		.put = snd_hda_mixer_amp_volume_put,
2663 		.tlv = { .c = snd_hda_mixer_amp_tlv },
2664 		/* offset by 28 volume steps to limit minimum gain to -46dB */
2665 		.private_value =
2666 			HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2667 	},
2668 	{}
2669 };
2670 
2671 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2672 	{
2673 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674 		.name = "DC Mode Enable Switch",
2675 		.info = snd_ctl_boolean_mono_info,
2676 		.get = cxt5066_olpc_dc_get,
2677 		.put = cxt5066_olpc_dc_put,
2678 	},
2679 	{
2680 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2681 		.name = "DC Input Bias Enum",
2682 		.info = cxt5066_olpc_dc_bias_enum_info,
2683 		.get = cxt5066_olpc_dc_bias_enum_get,
2684 		.put = cxt5066_olpc_dc_bias_enum_put,
2685 	},
2686 	{}
2687 };
2688 
2689 static const struct snd_kcontrol_new cxt5066_mixers[] = {
2690 	{
2691 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2692 		.name = "Master Playback Switch",
2693 		.info = cxt_eapd_info,
2694 		.get = cxt_eapd_get,
2695 		.put = cxt5066_hp_master_sw_put,
2696 		.private_value = 0x1d,
2697 	},
2698 
2699 	{
2700 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2701 		.name = "Analog Mic Boost Capture Enum",
2702 		.info = cxt5066_mic_boost_mux_enum_info,
2703 		.get = cxt5066_mic_boost_mux_enum_get,
2704 		.put = cxt5066_mic_boost_mux_enum_put,
2705 	},
2706 
2707 	HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2708 	HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2709 	{}
2710 };
2711 
2712 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2713 	{
2714 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2715 		.name = "Internal Mic Boost Capture Enum",
2716 		.info = cxt5066_mic_boost_mux_enum_info,
2717 		.get = cxt5066_mic_boost_mux_enum_get,
2718 		.put = cxt5066_mic_boost_mux_enum_put,
2719 		.private_value = 0x23 | 0x100,
2720 	},
2721 	{}
2722 };
2723 
2724 static const struct hda_verb cxt5066_init_verbs[] = {
2725 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2726 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2727 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2728 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2729 
2730 	/* Speakers  */
2731 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2732 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2733 
2734 	/* HP, Amp  */
2735 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2736 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2737 
2738 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2739 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2740 
2741 	/* DAC1 */
2742 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2743 
2744 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2745 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2746 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2747 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2748 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2749 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2750 
2751 	/* no digital microphone support yet */
2752 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2753 
2754 	/* Audio input selector */
2755 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2756 
2757 	/* SPDIF route: PCM */
2758 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2759 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2760 
2761 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2762 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2763 
2764 	/* EAPD */
2765 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2766 
2767 	/* not handling these yet */
2768 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2769 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2770 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2771 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2772 	{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2773 	{0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2774 	{0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2775 	{0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2776 	{ } /* end */
2777 };
2778 
2779 static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2780 	/* Port A: headphones */
2781 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2782 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2783 
2784 	/* Port B: external microphone */
2785 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2786 
2787 	/* Port C: internal microphone */
2788 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2789 
2790 	/* Port D: unused */
2791 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2792 
2793 	/* Port E: unused, but has primary EAPD */
2794 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2795 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2796 
2797 	/* Port F: external DC input through microphone port */
2798 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2799 
2800 	/* Port G: internal speakers */
2801 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2802 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2803 
2804 	/* DAC1 */
2805 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2806 
2807 	/* DAC2: unused */
2808 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2809 
2810 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2811 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2812 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2813 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2814 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2815 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2816 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2817 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2818 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2819 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2820 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2821 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2822 
2823 	/* Disable digital microphone port */
2824 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2825 
2826 	/* Audio input selectors */
2827 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2828 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2829 
2830 	/* Disable SPDIF */
2831 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2832 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2833 
2834 	/* enable unsolicited events for Port A and B */
2835 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2836 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2837 	{ } /* end */
2838 };
2839 
2840 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2841 	/* Port A: headphones */
2842 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2843 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2844 
2845 	/* Port B: external microphone */
2846 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2847 
2848 	/* Port C: unused */
2849 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2850 
2851 	/* Port D: unused */
2852 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2853 
2854 	/* Port E: unused, but has primary EAPD */
2855 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2856 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2857 
2858 	/* Port F: unused */
2859 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2860 
2861 	/* Port G: internal speakers */
2862 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2863 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2864 
2865 	/* DAC1 */
2866 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2867 
2868 	/* DAC2: unused */
2869 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2870 
2871 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2872 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2873 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2874 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2875 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2876 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2877 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2878 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2879 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2880 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2881 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2882 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2883 
2884 	/* Digital microphone port */
2885 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2886 
2887 	/* Audio input selectors */
2888 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2889 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2890 
2891 	/* Disable SPDIF */
2892 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2893 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2894 
2895 	/* enable unsolicited events for Port A and B */
2896 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2897 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2898 	{ } /* end */
2899 };
2900 
2901 static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2902 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2903 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2904 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2905 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2906 
2907 	/* Speakers  */
2908 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2909 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2910 
2911 	/* HP, Amp  */
2912 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2913 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2914 
2915 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2916 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2917 
2918 	/* DAC1 */
2919 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920 
2921 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2922 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2923 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2924 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2925 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2926 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2927 	{0x14, AC_VERB_SET_CONNECT_SEL, 2},	/* default to internal mic */
2928 
2929 	/* Audio input selector */
2930 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2931 	{0x17, AC_VERB_SET_CONNECT_SEL, 1},	/* route ext mic */
2932 
2933 	/* SPDIF route: PCM */
2934 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2935 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2936 
2937 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2938 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2939 
2940 	/* internal microphone */
2941 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2942 
2943 	/* EAPD */
2944 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2945 
2946 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2947 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2948 	{ } /* end */
2949 };
2950 
2951 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2952 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2953 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2954 
2955 	/* Port G: internal speakers  */
2956 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2957 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2958 
2959 	/* Port A: HP, Amp  */
2960 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2961 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2962 
2963 	/* Port B: Mic Dock */
2964 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2965 
2966 	/* Port C: Mic */
2967 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2968 
2969 	/* Port D: HP Dock, Amp */
2970 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2971 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2972 
2973 	/* DAC1 */
2974 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2975 
2976 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2977 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2978 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2979 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2980 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2981 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2982 	{0x14, AC_VERB_SET_CONNECT_SEL, 2},	/* default to internal mic */
2983 
2984 	/* Audio input selector */
2985 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2986 	{0x17, AC_VERB_SET_CONNECT_SEL, 1},	/* route ext mic */
2987 
2988 	/* SPDIF route: PCM */
2989 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2990 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2991 
2992 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2993 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2994 
2995 	/* internal microphone */
2996 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2997 
2998 	/* EAPD */
2999 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
3000 
3001 	/* enable unsolicited events for Port A, B, C and D */
3002 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
3003 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
3004 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
3005 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
3006 	{ } /* end */
3007 };
3008 
3009 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
3010 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3011 	{ } /* end */
3012 };
3013 
3014 
3015 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
3016 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
3017 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
3018 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
3019 	{ } /* end */
3020 };
3021 
3022 /* initialize jack-sensing, too */
3023 static int cxt5066_init(struct hda_codec *codec)
3024 {
3025 	snd_printdd("CXT5066: init\n");
3026 	conexant_init(codec);
3027 	if (codec->patch_ops.unsol_event) {
3028 		cxt5066_hp_automute(codec);
3029 		cxt5066_automic(codec);
3030 	}
3031 	cxt5066_set_mic_boost(codec);
3032 	return 0;
3033 }
3034 
3035 static int cxt5066_olpc_init(struct hda_codec *codec)
3036 {
3037 	struct conexant_spec *spec = codec->spec;
3038 	snd_printdd("CXT5066: init\n");
3039 	conexant_init(codec);
3040 	cxt5066_hp_automute(codec);
3041 	if (!spec->dc_enable) {
3042 		cxt5066_set_mic_boost(codec);
3043 		cxt5066_olpc_automic(codec);
3044 	} else {
3045 		cxt5066_enable_dc(codec);
3046 	}
3047 	return 0;
3048 }
3049 
3050 enum {
3051 	CXT5066_LAPTOP,		/* Laptops w/ EAPD support */
3052 	CXT5066_DELL_LAPTOP,	/* Dell Laptop */
3053 	CXT5066_OLPC_XO_1_5,	/* OLPC XO 1.5 */
3054 	CXT5066_DELL_VOSTRO,	/* Dell Vostro 1015i */
3055 	CXT5066_IDEAPAD,	/* Lenovo IdeaPad U150 */
3056 	CXT5066_THINKPAD,	/* Lenovo ThinkPad T410s, others? */
3057 	CXT5066_ASUS,		/* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
3058 	CXT5066_HP_LAPTOP,      /* HP Laptop */
3059 	CXT5066_AUTO,		/* BIOS auto-parser */
3060 	CXT5066_MODELS
3061 };
3062 
3063 static const char * const cxt5066_models[CXT5066_MODELS] = {
3064 	[CXT5066_LAPTOP]	= "laptop",
3065 	[CXT5066_DELL_LAPTOP]	= "dell-laptop",
3066 	[CXT5066_OLPC_XO_1_5]	= "olpc-xo-1_5",
3067 	[CXT5066_DELL_VOSTRO]	= "dell-vostro",
3068 	[CXT5066_IDEAPAD]	= "ideapad",
3069 	[CXT5066_THINKPAD]	= "thinkpad",
3070 	[CXT5066_ASUS]		= "asus",
3071 	[CXT5066_HP_LAPTOP]	= "hp-laptop",
3072 	[CXT5066_AUTO]		= "auto",
3073 };
3074 
3075 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3076 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
3077 	SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3078 	SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3079 	SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3080 	SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3081 	SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3082 	SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3083 	SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3084 	SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3085 	SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3086 	SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3087 	SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
3088 	SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
3089 	SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
3090 	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
3091 	SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
3092 	SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
3093 		      CXT5066_LAPTOP),
3094 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3095 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3096 	SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3097 	SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3098  	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3099 	SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3100 	SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3101 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3102 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3103 	SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3104 	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3105 	SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3106 	{}
3107 };
3108 
3109 static int patch_cxt5066(struct hda_codec *codec)
3110 {
3111 	struct conexant_spec *spec;
3112 	int board_config;
3113 
3114 	board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3115 						  cxt5066_models, cxt5066_cfg_tbl);
3116 	if (board_config < 0)
3117 		board_config = CXT5066_AUTO; /* model=auto as default */
3118 	if (board_config == CXT5066_AUTO)
3119 		return patch_conexant_auto(codec);
3120 
3121 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3122 	if (!spec)
3123 		return -ENOMEM;
3124 	codec->spec = spec;
3125 
3126 	codec->patch_ops = conexant_patch_ops;
3127 	codec->patch_ops.init = conexant_init;
3128 
3129 	spec->dell_automute = 0;
3130 	spec->multiout.max_channels = 2;
3131 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
3132 	spec->multiout.dac_nids = cxt5066_dac_nids;
3133 	conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
3134 	    ARRAY_SIZE(cxt5066_digout_pin_nids));
3135 	spec->num_adc_nids = 1;
3136 	spec->adc_nids = cxt5066_adc_nids;
3137 	spec->capsrc_nids = cxt5066_capsrc_nids;
3138 	spec->input_mux = &cxt5066_capture_source;
3139 
3140 	spec->port_d_mode = PIN_HP;
3141 
3142 	spec->num_init_verbs = 1;
3143 	spec->init_verbs[0] = cxt5066_init_verbs;
3144 	spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
3145 	spec->channel_mode = cxt5066_modes;
3146 	spec->cur_adc = 0;
3147 	spec->cur_adc_idx = 0;
3148 
3149 	set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3150 
3151 	switch (board_config) {
3152 	default:
3153 	case CXT5066_LAPTOP:
3154 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3155 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3156 		break;
3157 	case CXT5066_DELL_LAPTOP:
3158 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3159 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3160 
3161 		spec->port_d_mode = PIN_OUT;
3162 		spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
3163 		spec->num_init_verbs++;
3164 		spec->dell_automute = 1;
3165 		break;
3166 	case CXT5066_ASUS:
3167 	case CXT5066_HP_LAPTOP:
3168 		codec->patch_ops.init = cxt5066_init;
3169 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3170 		spec->init_verbs[spec->num_init_verbs] =
3171 			cxt5066_init_verbs_hp_laptop;
3172 		spec->num_init_verbs++;
3173 		spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3174 		spec->asus = board_config == CXT5066_ASUS;
3175 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3176 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3177 		/* no S/PDIF out */
3178 		if (board_config == CXT5066_HP_LAPTOP)
3179 			spec->multiout.dig_out_nid = 0;
3180 		/* input source automatically selected */
3181 		spec->input_mux = NULL;
3182 		spec->port_d_mode = 0;
3183 		spec->mic_boost = 3; /* default 30dB gain */
3184 		break;
3185 
3186 	case CXT5066_OLPC_XO_1_5:
3187 		codec->patch_ops.init = cxt5066_olpc_init;
3188 		codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
3189 		spec->init_verbs[0] = cxt5066_init_verbs_olpc;
3190 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3191 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
3192 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3193 		spec->port_d_mode = 0;
3194 		spec->mic_boost = 3; /* default 30dB gain */
3195 
3196 		/* no S/PDIF out */
3197 		spec->multiout.dig_out_nid = 0;
3198 
3199 		/* input source automatically selected */
3200 		spec->input_mux = NULL;
3201 
3202 		/* our capture hooks which allow us to turn on the microphone LED
3203 		 * at the right time */
3204 		spec->capture_prepare = cxt5066_olpc_capture_prepare;
3205 		spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3206 		break;
3207 	case CXT5066_DELL_VOSTRO:
3208 		codec->patch_ops.init = cxt5066_init;
3209 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3210 		spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3211 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3212 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3213 		spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
3214 		spec->port_d_mode = 0;
3215 		spec->dell_vostro = 1;
3216 		spec->mic_boost = 3; /* default 30dB gain */
3217 
3218 		/* no S/PDIF out */
3219 		spec->multiout.dig_out_nid = 0;
3220 
3221 		/* input source automatically selected */
3222 		spec->input_mux = NULL;
3223 		break;
3224 	case CXT5066_IDEAPAD:
3225 		codec->patch_ops.init = cxt5066_init;
3226 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3227 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3228 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3229 		spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
3230 		spec->port_d_mode = 0;
3231 		spec->ideapad = 1;
3232 		spec->mic_boost = 2;	/* default 20dB gain */
3233 
3234 		/* no S/PDIF out */
3235 		spec->multiout.dig_out_nid = 0;
3236 
3237 		/* input source automatically selected */
3238 		spec->input_mux = NULL;
3239 		break;
3240 	case CXT5066_THINKPAD:
3241 		codec->patch_ops.init = cxt5066_init;
3242 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3243 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3244 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3245 		spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3246 		spec->thinkpad = 1;
3247 		spec->port_d_mode = PIN_OUT;
3248 		spec->mic_boost = 2;	/* default 20dB gain */
3249 
3250 		/* no S/PDIF out */
3251 		spec->multiout.dig_out_nid = 0;
3252 
3253 		/* input source automatically selected */
3254 		spec->input_mux = NULL;
3255 		break;
3256 	}
3257 
3258 	if (spec->beep_amp)
3259 		snd_hda_attach_beep_device(codec, spec->beep_amp);
3260 
3261 	return 0;
3262 }
3263 
3264 /*
3265  * Automatic parser for CX20641 & co
3266  */
3267 
3268 static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3269 				       struct hda_codec *codec,
3270 				       unsigned int stream_tag,
3271 				       unsigned int format,
3272 				       struct snd_pcm_substream *substream)
3273 {
3274 	struct conexant_spec *spec = codec->spec;
3275 	hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3276 	if (spec->adc_switching) {
3277 		spec->cur_adc = adc;
3278 		spec->cur_adc_stream_tag = stream_tag;
3279 		spec->cur_adc_format = format;
3280 	}
3281 	snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3282 	return 0;
3283 }
3284 
3285 static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3286 				       struct hda_codec *codec,
3287 				       struct snd_pcm_substream *substream)
3288 {
3289 	struct conexant_spec *spec = codec->spec;
3290 	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3291 	spec->cur_adc = 0;
3292 	return 0;
3293 }
3294 
3295 static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3296 	.substreams = 1,
3297 	.channels_min = 2,
3298 	.channels_max = 2,
3299 	.nid = 0, /* fill later */
3300 	.ops = {
3301 		.prepare = cx_auto_capture_pcm_prepare,
3302 		.cleanup = cx_auto_capture_pcm_cleanup
3303 	},
3304 };
3305 
3306 static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3307 
3308 #define get_connection_index(codec, mux, nid)\
3309 	snd_hda_get_conn_index(codec, mux, nid, 0)
3310 
3311 /* get an unassigned DAC from the given list.
3312  * Return the nid if found and reduce the DAC list, or return zero if
3313  * not found
3314  */
3315 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3316 				    hda_nid_t *dacs, int *num_dacs)
3317 {
3318 	int i, nums = *num_dacs;
3319 	hda_nid_t ret = 0;
3320 
3321 	for (i = 0; i < nums; i++) {
3322 		if (get_connection_index(codec, pin, dacs[i]) >= 0) {
3323 			ret = dacs[i];
3324 			break;
3325 		}
3326 	}
3327 	if (!ret)
3328 		return 0;
3329 	if (--nums > 0)
3330 		memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t));
3331 	*num_dacs = nums;
3332 	return ret;
3333 }
3334 
3335 #define MAX_AUTO_DACS	5
3336 
3337 /* fill analog DAC list from the widget tree */
3338 static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3339 {
3340 	hda_nid_t nid, end_nid;
3341 	int nums = 0;
3342 
3343 	end_nid = codec->start_nid + codec->num_nodes;
3344 	for (nid = codec->start_nid; nid < end_nid; nid++) {
3345 		unsigned int wcaps = get_wcaps(codec, nid);
3346 		unsigned int type = get_wcaps_type(wcaps);
3347 		if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) {
3348 			dacs[nums++] = nid;
3349 			if (nums >= MAX_AUTO_DACS)
3350 				break;
3351 		}
3352 	}
3353 	return nums;
3354 }
3355 
3356 /* fill pin_dac_pair list from the pin and dac list */
3357 static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3358 			      int num_pins, hda_nid_t *dacs, int *rest,
3359 			      struct pin_dac_pair *filled, int type)
3360 {
3361 	int i, nums;
3362 
3363 	nums = 0;
3364 	for (i = 0; i < num_pins; i++) {
3365 		filled[nums].pin = pins[i];
3366 		filled[nums].type = type;
3367 		filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3368 		nums++;
3369 	}
3370 	return nums;
3371 }
3372 
3373 /* parse analog output paths */
3374 static void cx_auto_parse_output(struct hda_codec *codec)
3375 {
3376 	struct conexant_spec *spec = codec->spec;
3377 	struct auto_pin_cfg *cfg = &spec->autocfg;
3378 	hda_nid_t dacs[MAX_AUTO_DACS];
3379 	int i, j, nums, rest;
3380 
3381 	rest = fill_cx_auto_dacs(codec, dacs);
3382 	/* parse all analog output pins */
3383 	nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3384 				  dacs, &rest, spec->dac_info,
3385 				  AUTO_PIN_LINE_OUT);
3386 	nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3387 				  dacs, &rest, spec->dac_info + nums,
3388 				  AUTO_PIN_HP_OUT);
3389 	nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3390 				  dacs, &rest, spec->dac_info + nums,
3391 				  AUTO_PIN_SPEAKER_OUT);
3392 	spec->dac_info_filled = nums;
3393 	/* fill multiout struct */
3394 	for (i = 0; i < nums; i++) {
3395 		hda_nid_t dac = spec->dac_info[i].dac;
3396 		if (!dac)
3397 			continue;
3398 		switch (spec->dac_info[i].type) {
3399 		case AUTO_PIN_LINE_OUT:
3400 			spec->private_dac_nids[spec->multiout.num_dacs] = dac;
3401 			spec->multiout.num_dacs++;
3402 			break;
3403 		case AUTO_PIN_HP_OUT:
3404 		case AUTO_PIN_SPEAKER_OUT:
3405 			if (!spec->multiout.hp_nid) {
3406 				spec->multiout.hp_nid = dac;
3407 				break;
3408 			}
3409 			for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++)
3410 				if (!spec->multiout.extra_out_nid[j]) {
3411 					spec->multiout.extra_out_nid[j] = dac;
3412 					break;
3413 				}
3414 			break;
3415 		}
3416 	}
3417 	spec->multiout.dac_nids = spec->private_dac_nids;
3418 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3419 
3420 	for (i = 0; i < cfg->hp_outs; i++) {
3421 		if (is_jack_detectable(codec, cfg->hp_pins[i])) {
3422 			spec->auto_mute = 1;
3423 			break;
3424 		}
3425 	}
3426 	if (spec->auto_mute &&
3427 	    cfg->line_out_pins[0] &&
3428 	    cfg->line_out_type != AUTO_PIN_SPEAKER_OUT &&
3429 	    cfg->line_out_pins[0] != cfg->hp_pins[0] &&
3430 	    cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
3431 		for (i = 0; i < cfg->line_outs; i++) {
3432 			if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
3433 				spec->detect_line = 1;
3434 				break;
3435 			}
3436 		}
3437 		spec->automute_lines = spec->detect_line;
3438 	}
3439 
3440 	spec->vmaster_nid = spec->private_dac_nids[0];
3441 }
3442 
3443 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3444 			      hda_nid_t *pins, bool on);
3445 
3446 static void do_automute(struct hda_codec *codec, int num_pins,
3447 			hda_nid_t *pins, bool on)
3448 {
3449 	int i;
3450 	for (i = 0; i < num_pins; i++)
3451 		snd_hda_codec_write(codec, pins[i], 0,
3452 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
3453 				    on ? PIN_OUT : 0);
3454 	cx_auto_turn_eapd(codec, num_pins, pins, on);
3455 }
3456 
3457 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3458 {
3459 	int i, present = 0;
3460 
3461 	for (i = 0; i < num_pins; i++) {
3462 		hda_nid_t nid = pins[i];
3463 		if (!nid || !is_jack_detectable(codec, nid))
3464 			break;
3465 		snd_hda_input_jack_report(codec, nid);
3466 		present |= snd_hda_jack_detect(codec, nid);
3467 	}
3468 	return present;
3469 }
3470 
3471 /* auto-mute/unmute speaker and line outs according to headphone jack */
3472 static void cx_auto_update_speakers(struct hda_codec *codec)
3473 {
3474 	struct conexant_spec *spec = codec->spec;
3475 	struct auto_pin_cfg *cfg = &spec->autocfg;
3476 	int on = 1;
3477 
3478 	/* turn on HP EAPD when HP jacks are present */
3479 	if (spec->auto_mute)
3480 		on = spec->hp_present;
3481 	cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3482 	/* mute speakers in auto-mode if HP or LO jacks are plugged */
3483 	if (spec->auto_mute)
3484 		on = !(spec->hp_present ||
3485 		       (spec->detect_line && spec->line_present));
3486 	do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on);
3487 
3488 	/* toggle line-out mutes if needed, too */
3489 	/* if LO is a copy of either HP or Speaker, don't need to handle it */
3490 	if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
3491 	    cfg->line_out_pins[0] == cfg->speaker_pins[0])
3492 		return;
3493 	if (spec->auto_mute) {
3494 		/* mute LO in auto-mode when HP jack is present */
3495 		if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ||
3496 		    spec->automute_lines)
3497 			on = !spec->hp_present;
3498 		else
3499 			on = 1;
3500 	}
3501 	do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
3502 }
3503 
3504 static void cx_auto_hp_automute(struct hda_codec *codec)
3505 {
3506 	struct conexant_spec *spec = codec->spec;
3507 	struct auto_pin_cfg *cfg = &spec->autocfg;
3508 
3509 	if (!spec->auto_mute)
3510 		return;
3511 	spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
3512 	cx_auto_update_speakers(codec);
3513 }
3514 
3515 static void cx_auto_line_automute(struct hda_codec *codec)
3516 {
3517 	struct conexant_spec *spec = codec->spec;
3518 	struct auto_pin_cfg *cfg = &spec->autocfg;
3519 
3520 	if (!spec->auto_mute || !spec->detect_line)
3521 		return;
3522 	spec->line_present = detect_jacks(codec, cfg->line_outs,
3523 					  cfg->line_out_pins);
3524 	cx_auto_update_speakers(codec);
3525 }
3526 
3527 static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3528 				 struct snd_ctl_elem_info *uinfo)
3529 {
3530 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3531 	struct conexant_spec *spec = codec->spec;
3532 	static const char * const texts2[] = {
3533 		"Disabled", "Enabled"
3534 	};
3535 	static const char * const texts3[] = {
3536 		"Disabled", "Speaker Only", "Line-Out+Speaker"
3537 	};
3538 	const char * const *texts;
3539 
3540 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3541 	uinfo->count = 1;
3542 	if (spec->automute_hp_lo) {
3543 		uinfo->value.enumerated.items = 3;
3544 		texts = texts3;
3545 	} else {
3546 		uinfo->value.enumerated.items = 2;
3547 		texts = texts2;
3548 	}
3549 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3550 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3551 	strcpy(uinfo->value.enumerated.name,
3552 	       texts[uinfo->value.enumerated.item]);
3553 	return 0;
3554 }
3555 
3556 static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
3557 				struct snd_ctl_elem_value *ucontrol)
3558 {
3559 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3560 	struct conexant_spec *spec = codec->spec;
3561 	unsigned int val;
3562 	if (!spec->auto_mute)
3563 		val = 0;
3564 	else if (!spec->automute_lines)
3565 		val = 1;
3566 	else
3567 		val = 2;
3568 	ucontrol->value.enumerated.item[0] = val;
3569 	return 0;
3570 }
3571 
3572 static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
3573 				struct snd_ctl_elem_value *ucontrol)
3574 {
3575 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3576 	struct conexant_spec *spec = codec->spec;
3577 
3578 	switch (ucontrol->value.enumerated.item[0]) {
3579 	case 0:
3580 		if (!spec->auto_mute)
3581 			return 0;
3582 		spec->auto_mute = 0;
3583 		break;
3584 	case 1:
3585 		if (spec->auto_mute && !spec->automute_lines)
3586 			return 0;
3587 		spec->auto_mute = 1;
3588 		spec->automute_lines = 0;
3589 		break;
3590 	case 2:
3591 		if (!spec->automute_hp_lo)
3592 			return -EINVAL;
3593 		if (spec->auto_mute && spec->automute_lines)
3594 			return 0;
3595 		spec->auto_mute = 1;
3596 		spec->automute_lines = 1;
3597 		break;
3598 	default:
3599 		return -EINVAL;
3600 	}
3601 	cx_auto_update_speakers(codec);
3602 	return 1;
3603 }
3604 
3605 static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
3606 	{
3607 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3608 		.name = "Auto-Mute Mode",
3609 		.info = cx_automute_mode_info,
3610 		.get = cx_automute_mode_get,
3611 		.put = cx_automute_mode_put,
3612 	},
3613 	{ }
3614 };
3615 
3616 static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3617 				 struct snd_ctl_elem_info *uinfo)
3618 {
3619 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3620 	struct conexant_spec *spec = codec->spec;
3621 
3622 	return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3623 }
3624 
3625 static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3626 				struct snd_ctl_elem_value *ucontrol)
3627 {
3628 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3629 	struct conexant_spec *spec = codec->spec;
3630 
3631 	ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3632 	return 0;
3633 }
3634 
3635 /* look for the route the given pin from mux and return the index;
3636  * if do_select is set, actually select the route.
3637  */
3638 static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3639 				     hda_nid_t pin, hda_nid_t *srcp,
3640 				     bool do_select, int depth)
3641 {
3642 	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3643 	int i, nums;
3644 
3645 	switch (get_wcaps_type(get_wcaps(codec, mux))) {
3646 	case AC_WID_AUD_IN:
3647 	case AC_WID_AUD_SEL:
3648 	case AC_WID_AUD_MIX:
3649 		break;
3650 	default:
3651 		return -1;
3652 	}
3653 
3654 	nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3655 	for (i = 0; i < nums; i++)
3656 		if (conn[i] == pin) {
3657 			if (do_select)
3658 				snd_hda_codec_write(codec, mux, 0,
3659 						    AC_VERB_SET_CONNECT_SEL, i);
3660 			if (srcp)
3661 				*srcp = mux;
3662 			return i;
3663 		}
3664 	depth++;
3665 	if (depth == 2)
3666 		return -1;
3667 	for (i = 0; i < nums; i++) {
3668 		int ret  = __select_input_connection(codec, conn[i], pin, srcp,
3669 						     do_select, depth);
3670 		if (ret >= 0) {
3671 			if (do_select)
3672 				snd_hda_codec_write(codec, mux, 0,
3673 						    AC_VERB_SET_CONNECT_SEL, i);
3674 			return i;
3675 		}
3676 	}
3677 	return -1;
3678 }
3679 
3680 static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3681 				   hda_nid_t pin)
3682 {
3683 	__select_input_connection(codec, mux, pin, NULL, true, 0);
3684 }
3685 
3686 static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3687 				hda_nid_t pin)
3688 {
3689 	return __select_input_connection(codec, mux, pin, NULL, false, 0);
3690 }
3691 
3692 static int cx_auto_mux_enum_update(struct hda_codec *codec,
3693 				   const struct hda_input_mux *imux,
3694 				   unsigned int idx)
3695 {
3696 	struct conexant_spec *spec = codec->spec;
3697 	hda_nid_t adc;
3698 	int changed = 1;
3699 
3700 	if (!imux->num_items)
3701 		return 0;
3702 	if (idx >= imux->num_items)
3703 		idx = imux->num_items - 1;
3704 	if (spec->cur_mux[0] == idx)
3705 		changed = 0;
3706 	adc = spec->imux_info[idx].adc;
3707 	select_input_connection(codec, spec->imux_info[idx].adc,
3708 				spec->imux_info[idx].pin);
3709 	if (spec->cur_adc && spec->cur_adc != adc) {
3710 		/* stream is running, let's swap the current ADC */
3711 		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3712 		spec->cur_adc = adc;
3713 		snd_hda_codec_setup_stream(codec, adc,
3714 					   spec->cur_adc_stream_tag, 0,
3715 					   spec->cur_adc_format);
3716 	}
3717 	spec->cur_mux[0] = idx;
3718 	return changed;
3719 }
3720 
3721 static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3722 				struct snd_ctl_elem_value *ucontrol)
3723 {
3724 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3725 	struct conexant_spec *spec = codec->spec;
3726 
3727 	return cx_auto_mux_enum_update(codec, &spec->private_imux,
3728 				       ucontrol->value.enumerated.item[0]);
3729 }
3730 
3731 static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3732 	{
3733 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3734 		.name = "Capture Source",
3735 		.info = cx_auto_mux_enum_info,
3736 		.get = cx_auto_mux_enum_get,
3737 		.put = cx_auto_mux_enum_put
3738 	},
3739 	{}
3740 };
3741 
3742 static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3743 {
3744 	struct conexant_spec *spec = codec->spec;
3745 	if (idx < 0)
3746 		return false;
3747 	if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
3748 		return false;
3749 	cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
3750 	return true;
3751 }
3752 
3753 /* automatic switch internal and external mic */
3754 static void cx_auto_automic(struct hda_codec *codec)
3755 {
3756 	struct conexant_spec *spec = codec->spec;
3757 
3758 	if (!spec->auto_mic)
3759 		return;
3760 	if (!select_automic(codec, spec->auto_mic_ext, true))
3761 		if (!select_automic(codec, spec->auto_mic_dock, true))
3762 			select_automic(codec, spec->auto_mic_int, false);
3763 }
3764 
3765 static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3766 {
3767 	int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
3768 	switch (res >> 26) {
3769 	case CONEXANT_HP_EVENT:
3770 		cx_auto_hp_automute(codec);
3771 		break;
3772 	case CONEXANT_LINE_EVENT:
3773 		cx_auto_line_automute(codec);
3774 		break;
3775 	case CONEXANT_MIC_EVENT:
3776 		cx_auto_automic(codec);
3777 		snd_hda_input_jack_report(codec, nid);
3778 		break;
3779 	}
3780 }
3781 
3782 /* check whether the pin config is suitable for auto-mic switching;
3783  * auto-mic is enabled only when one int-mic and one ext- and/or
3784  * one dock-mic exist
3785  */
3786 static void cx_auto_check_auto_mic(struct hda_codec *codec)
3787 {
3788 	struct conexant_spec *spec = codec->spec;
3789 	int pset[INPUT_PIN_ATTR_NORMAL + 1];
3790 	int i;
3791 
3792 	for (i = 0; i < ARRAY_SIZE(pset); i++)
3793 		pset[i] = -1;
3794 	for (i = 0; i < spec->private_imux.num_items; i++) {
3795 		hda_nid_t pin = spec->imux_info[i].pin;
3796 		unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3797 		int type, attr;
3798 		attr = snd_hda_get_input_pin_attr(def_conf);
3799 		if (attr == INPUT_PIN_ATTR_UNUSED)
3800 			return; /* invalid entry */
3801 		if (attr > INPUT_PIN_ATTR_NORMAL)
3802 			attr = INPUT_PIN_ATTR_NORMAL;
3803 		if (attr != INPUT_PIN_ATTR_INT &&
3804 		    !is_jack_detectable(codec, pin))
3805 			return; /* non-detectable pin */
3806 		type = get_defcfg_device(def_conf);
3807 		if (type != AC_JACK_MIC_IN &&
3808 		    (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
3809 			return; /* no valid input type */
3810 		if (pset[attr] >= 0)
3811 			return; /* already occupied */
3812 		pset[attr] = i;
3813 	}
3814 	if (pset[INPUT_PIN_ATTR_INT] < 0 ||
3815 	    (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
3816 		return; /* no input to switch*/
3817 	spec->auto_mic = 1;
3818 	spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
3819 	spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
3820 	spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
3821 }
3822 
3823 static void cx_auto_parse_input(struct hda_codec *codec)
3824 {
3825 	struct conexant_spec *spec = codec->spec;
3826 	struct auto_pin_cfg *cfg = &spec->autocfg;
3827 	struct hda_input_mux *imux;
3828 	int i, j;
3829 
3830 	imux = &spec->private_imux;
3831 	for (i = 0; i < cfg->num_inputs; i++) {
3832 		for (j = 0; j < spec->num_adc_nids; j++) {
3833 			hda_nid_t adc = spec->adc_nids[j];
3834 			int idx = get_input_connection(codec, adc,
3835 						       cfg->inputs[i].pin);
3836 			if (idx >= 0) {
3837 				const char *label;
3838 				label = hda_get_autocfg_input_label(codec, cfg, i);
3839 				spec->imux_info[imux->num_items].index = i;
3840 				spec->imux_info[imux->num_items].boost = 0;
3841 				spec->imux_info[imux->num_items].adc = adc;
3842 				spec->imux_info[imux->num_items].pin =
3843 					cfg->inputs[i].pin;
3844 				snd_hda_add_imux_item(imux, label, idx, NULL);
3845 				break;
3846 			}
3847 		}
3848 	}
3849 	if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3850 		cx_auto_check_auto_mic(codec);
3851 	if (imux->num_items > 1 && !spec->auto_mic) {
3852 		for (i = 1; i < imux->num_items; i++) {
3853 			if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3854 				spec->adc_switching = 1;
3855 				break;
3856 			}
3857 		}
3858 	}
3859 }
3860 
3861 /* get digital-input audio widget corresponding to the given pin */
3862 static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin)
3863 {
3864 	hda_nid_t nid, end_nid;
3865 
3866 	end_nid = codec->start_nid + codec->num_nodes;
3867 	for (nid = codec->start_nid; nid < end_nid; nid++) {
3868 		unsigned int wcaps = get_wcaps(codec, nid);
3869 		unsigned int type = get_wcaps_type(wcaps);
3870 		if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) {
3871 			if (get_connection_index(codec, nid, pin) >= 0)
3872 				return nid;
3873 		}
3874 	}
3875 	return 0;
3876 }
3877 
3878 static void cx_auto_parse_digital(struct hda_codec *codec)
3879 {
3880 	struct conexant_spec *spec = codec->spec;
3881 	struct auto_pin_cfg *cfg = &spec->autocfg;
3882 	hda_nid_t nid;
3883 
3884 	if (cfg->dig_outs &&
3885 	    snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1)
3886 		spec->multiout.dig_out_nid = nid;
3887 	if (cfg->dig_in_pin)
3888 		spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin);
3889 }
3890 
3891 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3892 static void cx_auto_parse_beep(struct hda_codec *codec)
3893 {
3894 	struct conexant_spec *spec = codec->spec;
3895 	hda_nid_t nid, end_nid;
3896 
3897 	end_nid = codec->start_nid + codec->num_nodes;
3898 	for (nid = codec->start_nid; nid < end_nid; nid++)
3899 		if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
3900 			set_beep_amp(spec, nid, 0, HDA_OUTPUT);
3901 			break;
3902 		}
3903 }
3904 #else
3905 #define cx_auto_parse_beep(codec)
3906 #endif
3907 
3908 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3909 {
3910 	int i;
3911 	for (i = 0; i < nums; i++)
3912 		if (list[i] == nid)
3913 			return true;
3914 	return false;
3915 }
3916 
3917 /* parse extra-EAPD that aren't assigned to any pins */
3918 static void cx_auto_parse_eapd(struct hda_codec *codec)
3919 {
3920 	struct conexant_spec *spec = codec->spec;
3921 	struct auto_pin_cfg *cfg = &spec->autocfg;
3922 	hda_nid_t nid, end_nid;
3923 
3924 	end_nid = codec->start_nid + codec->num_nodes;
3925 	for (nid = codec->start_nid; nid < end_nid; nid++) {
3926 		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3927 			continue;
3928 		if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3929 			continue;
3930 		if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3931 		    found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3932 		    found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3933 			continue;
3934 		spec->eapds[spec->num_eapds++] = nid;
3935 		if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3936 			break;
3937 	}
3938 }
3939 
3940 static int cx_auto_parse_auto_config(struct hda_codec *codec)
3941 {
3942 	struct conexant_spec *spec = codec->spec;
3943 	int err;
3944 
3945 	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3946 	if (err < 0)
3947 		return err;
3948 
3949 	cx_auto_parse_output(codec);
3950 	cx_auto_parse_input(codec);
3951 	cx_auto_parse_digital(codec);
3952 	cx_auto_parse_beep(codec);
3953 	cx_auto_parse_eapd(codec);
3954 	return 0;
3955 }
3956 
3957 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3958 			      hda_nid_t *pins, bool on)
3959 {
3960 	int i;
3961 	for (i = 0; i < num_pins; i++) {
3962 		if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3963 			snd_hda_codec_write(codec, pins[i], 0,
3964 					    AC_VERB_SET_EAPD_BTLENABLE,
3965 					    on ? 0x02 : 0);
3966 	}
3967 }
3968 
3969 static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3970 			      hda_nid_t src)
3971 {
3972 	int idx = get_connection_index(codec, pin, src);
3973 	if (idx >= 0)
3974 		snd_hda_codec_write(codec, pin, 0,
3975 				    AC_VERB_SET_CONNECT_SEL, idx);
3976 }
3977 
3978 static void mute_outputs(struct hda_codec *codec, int num_nids,
3979 			 const hda_nid_t *nids)
3980 {
3981 	int i, val;
3982 
3983 	for (i = 0; i < num_nids; i++) {
3984 		hda_nid_t nid = nids[i];
3985 		if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3986 			continue;
3987 		if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3988 			val = AMP_OUT_MUTE;
3989 		else
3990 			val = AMP_OUT_ZERO;
3991 		snd_hda_codec_write(codec, nid, 0,
3992 				    AC_VERB_SET_AMP_GAIN_MUTE, val);
3993 	}
3994 }
3995 
3996 static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3997 			      hda_nid_t *pins, unsigned int tag)
3998 {
3999 	int i;
4000 	for (i = 0; i < num_pins; i++)
4001 		snd_hda_codec_write(codec, pins[i], 0,
4002 				    AC_VERB_SET_UNSOLICITED_ENABLE,
4003 				    AC_USRSP_EN | tag);
4004 }
4005 
4006 static void cx_auto_init_output(struct hda_codec *codec)
4007 {
4008 	struct conexant_spec *spec = codec->spec;
4009 	struct auto_pin_cfg *cfg = &spec->autocfg;
4010 	hda_nid_t nid;
4011 	int i;
4012 
4013 	mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
4014 	for (i = 0; i < cfg->hp_outs; i++)
4015 		snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
4016 				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4017 	mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
4018 	mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
4019 	mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
4020 	for (i = 0; i < spec->dac_info_filled; i++) {
4021 		nid = spec->dac_info[i].dac;
4022 		if (!nid)
4023 			nid = spec->multiout.dac_nids[0];
4024 		select_connection(codec, spec->dac_info[i].pin, nid);
4025 	}
4026 	if (spec->auto_mute) {
4027 		enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
4028 				  CONEXANT_HP_EVENT);
4029 		spec->hp_present = detect_jacks(codec, cfg->hp_outs,
4030 						cfg->hp_pins);
4031 		if (spec->detect_line) {
4032 			enable_unsol_pins(codec, cfg->line_outs,
4033 					  cfg->line_out_pins,
4034 					  CONEXANT_LINE_EVENT);
4035 			spec->line_present =
4036 				detect_jacks(codec, cfg->line_outs,
4037 					     cfg->line_out_pins);
4038 		}
4039 	}
4040 	cx_auto_update_speakers(codec);
4041 	/* turn on/off extra EAPDs, too */
4042 	cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4043 }
4044 
4045 static void cx_auto_init_input(struct hda_codec *codec)
4046 {
4047 	struct conexant_spec *spec = codec->spec;
4048 	struct auto_pin_cfg *cfg = &spec->autocfg;
4049 	int i, val;
4050 
4051 	for (i = 0; i < spec->num_adc_nids; i++) {
4052 		hda_nid_t nid = spec->adc_nids[i];
4053 		if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
4054 			continue;
4055 		if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
4056 			val = AMP_IN_MUTE(0);
4057 		else
4058 			val = AMP_IN_UNMUTE(0);
4059 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4060 				    val);
4061 	}
4062 
4063 	for (i = 0; i < cfg->num_inputs; i++) {
4064 		unsigned int type;
4065 		if (cfg->inputs[i].type == AUTO_PIN_MIC)
4066 			type = PIN_VREF80;
4067 		else
4068 			type = PIN_IN;
4069 		snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
4070 				    AC_VERB_SET_PIN_WIDGET_CONTROL, type);
4071 	}
4072 
4073 	if (spec->auto_mic) {
4074 		if (spec->auto_mic_ext >= 0) {
4075 			snd_hda_codec_write(codec,
4076 				cfg->inputs[spec->auto_mic_ext].pin, 0,
4077 				AC_VERB_SET_UNSOLICITED_ENABLE,
4078 				AC_USRSP_EN | CONEXANT_MIC_EVENT);
4079 		}
4080 		if (spec->auto_mic_dock >= 0) {
4081 			snd_hda_codec_write(codec,
4082 				cfg->inputs[spec->auto_mic_dock].pin, 0,
4083 				AC_VERB_SET_UNSOLICITED_ENABLE,
4084 				AC_USRSP_EN | CONEXANT_MIC_EVENT);
4085 		}
4086 		cx_auto_automic(codec);
4087 	} else {
4088 		select_input_connection(codec, spec->imux_info[0].adc,
4089 					spec->imux_info[0].pin);
4090 	}
4091 }
4092 
4093 static void cx_auto_init_digital(struct hda_codec *codec)
4094 {
4095 	struct conexant_spec *spec = codec->spec;
4096 	struct auto_pin_cfg *cfg = &spec->autocfg;
4097 
4098 	if (spec->multiout.dig_out_nid)
4099 		snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
4100 				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4101 	if (spec->dig_in_nid)
4102 		snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
4103 				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
4104 }
4105 
4106 static int cx_auto_init(struct hda_codec *codec)
4107 {
4108 	/*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4109 	cx_auto_init_output(codec);
4110 	cx_auto_init_input(codec);
4111 	cx_auto_init_digital(codec);
4112 	return 0;
4113 }
4114 
4115 static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4116 			      const char *dir, int cidx,
4117 			      hda_nid_t nid, int hda_dir, int amp_idx)
4118 {
4119 	static char name[32];
4120 	static struct snd_kcontrol_new knew[] = {
4121 		HDA_CODEC_VOLUME(name, 0, 0, 0),
4122 		HDA_CODEC_MUTE(name, 0, 0, 0),
4123 	};
4124 	static const char * const sfx[2] = { "Volume", "Switch" };
4125 	int i, err;
4126 
4127 	for (i = 0; i < 2; i++) {
4128 		struct snd_kcontrol *kctl;
4129 		knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
4130 							    hda_dir);
4131 		knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
4132 		knew[i].index = cidx;
4133 		snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
4134 		kctl = snd_ctl_new1(&knew[i], codec);
4135 		if (!kctl)
4136 			return -ENOMEM;
4137 		err = snd_hda_ctl_add(codec, nid, kctl);
4138 		if (err < 0)
4139 			return err;
4140 		if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
4141 			break;
4142 	}
4143 	return 0;
4144 }
4145 
4146 #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir)		\
4147 	cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
4148 
4149 #define cx_auto_add_pb_volume(codec, nid, str, idx)			\
4150 	cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
4151 
4152 static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4153 			     hda_nid_t pin, const char *name, int idx)
4154 {
4155 	unsigned int caps;
4156 	caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4157 	if (caps & AC_AMPCAP_NUM_STEPS)
4158 		return cx_auto_add_pb_volume(codec, dac, name, idx);
4159 	caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4160 	if (caps & AC_AMPCAP_NUM_STEPS)
4161 		return cx_auto_add_pb_volume(codec, pin, name, idx);
4162 	return 0;
4163 }
4164 
4165 static int cx_auto_build_output_controls(struct hda_codec *codec)
4166 {
4167 	struct conexant_spec *spec = codec->spec;
4168 	int i, err;
4169 	int num_line = 0, num_hp = 0, num_spk = 0;
4170 	static const char * const texts[3] = { "Front", "Surround", "CLFE" };
4171 
4172 	if (spec->dac_info_filled == 1)
4173 		return try_add_pb_volume(codec, spec->dac_info[0].dac,
4174 					 spec->dac_info[0].pin,
4175 					 "Master", 0);
4176 
4177 	for (i = 0; i < spec->dac_info_filled; i++) {
4178 		const char *label;
4179 		int idx, type;
4180 		if (!spec->dac_info[i].dac)
4181 			continue;
4182 		type = spec->dac_info[i].type;
4183 		if (type == AUTO_PIN_LINE_OUT)
4184 			type = spec->autocfg.line_out_type;
4185 		switch (type) {
4186 		case AUTO_PIN_LINE_OUT:
4187 		default:
4188 			label = texts[num_line++];
4189 			idx = 0;
4190 			break;
4191 		case AUTO_PIN_HP_OUT:
4192 			label = "Headphone";
4193 			idx = num_hp++;
4194 			break;
4195 		case AUTO_PIN_SPEAKER_OUT:
4196 			label = "Speaker";
4197 			idx = num_spk++;
4198 			break;
4199 		}
4200 		err = try_add_pb_volume(codec, spec->dac_info[i].dac,
4201 					spec->dac_info[i].pin,
4202 					label, idx);
4203 		if (err < 0)
4204 			return err;
4205 	}
4206 
4207 	if (spec->auto_mute) {
4208 		err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
4209 		if (err < 0)
4210 			return err;
4211 	}
4212 
4213 	return 0;
4214 }
4215 
4216 static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4217 				      const char *label, const char *pfx,
4218 				      int cidx)
4219 {
4220 	struct conexant_spec *spec = codec->spec;
4221 	int i;
4222 
4223 	for (i = 0; i < spec->num_adc_nids; i++) {
4224 		hda_nid_t adc_nid = spec->adc_nids[i];
4225 		int idx = get_input_connection(codec, adc_nid, nid);
4226 		if (idx < 0)
4227 			continue;
4228 		return cx_auto_add_volume_idx(codec, label, pfx,
4229 					      cidx, adc_nid, HDA_INPUT, idx);
4230 	}
4231 	return 0;
4232 }
4233 
4234 static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4235 				    const char *label, int cidx)
4236 {
4237 	struct conexant_spec *spec = codec->spec;
4238 	hda_nid_t mux, nid;
4239 	int i, con;
4240 
4241 	nid = spec->imux_info[idx].pin;
4242 	if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
4243 		return cx_auto_add_volume(codec, label, " Boost", cidx,
4244 					  nid, HDA_INPUT);
4245 	con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4246 					&mux, false, 0);
4247 	if (con < 0)
4248 		return 0;
4249 	for (i = 0; i < idx; i++) {
4250 		if (spec->imux_info[i].boost == mux)
4251 			return 0; /* already present */
4252 	}
4253 
4254 	if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
4255 		spec->imux_info[idx].boost = mux;
4256 		return cx_auto_add_volume(codec, label, " Boost", 0,
4257 					  mux, HDA_OUTPUT);
4258 	}
4259 	return 0;
4260 }
4261 
4262 static int cx_auto_build_input_controls(struct hda_codec *codec)
4263 {
4264 	struct conexant_spec *spec = codec->spec;
4265 	struct hda_input_mux *imux = &spec->private_imux;
4266 	const char *prev_label;
4267 	int input_conn[HDA_MAX_NUM_INPUTS];
4268 	int i, err, cidx;
4269 	int multi_connection;
4270 
4271 	multi_connection = 0;
4272 	for (i = 0; i < imux->num_items; i++) {
4273 		cidx = get_input_connection(codec, spec->imux_info[i].adc,
4274 					    spec->imux_info[i].pin);
4275 		input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
4276 		if (i > 0 && input_conn[i] != input_conn[0])
4277 			multi_connection = 1;
4278 	}
4279 
4280 	prev_label = NULL;
4281 	cidx = 0;
4282 	for (i = 0; i < imux->num_items; i++) {
4283 		hda_nid_t nid = spec->imux_info[i].pin;
4284 		const char *label;
4285 
4286 		label = hda_get_autocfg_input_label(codec, &spec->autocfg,
4287 						    spec->imux_info[i].index);
4288 		if (label == prev_label)
4289 			cidx++;
4290 		else
4291 			cidx = 0;
4292 		prev_label = label;
4293 
4294 		err = cx_auto_add_boost_volume(codec, i, label, cidx);
4295 		if (err < 0)
4296 			return err;
4297 
4298 		if (!multi_connection) {
4299 			if (i > 0)
4300 				continue;
4301 			err = cx_auto_add_capture_volume(codec, nid,
4302 							 "Capture", "", cidx);
4303 		} else {
4304 			err = cx_auto_add_capture_volume(codec, nid,
4305 							 label, " Capture", cidx);
4306 		}
4307 		if (err < 0)
4308 			return err;
4309 	}
4310 
4311 	if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
4312 		err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
4313 		if (err < 0)
4314 			return err;
4315 	}
4316 
4317 	return 0;
4318 }
4319 
4320 static int cx_auto_build_controls(struct hda_codec *codec)
4321 {
4322 	int err;
4323 
4324 	err = cx_auto_build_output_controls(codec);
4325 	if (err < 0)
4326 		return err;
4327 	err = cx_auto_build_input_controls(codec);
4328 	if (err < 0)
4329 		return err;
4330 	return conexant_build_controls(codec);
4331 }
4332 
4333 static int cx_auto_search_adcs(struct hda_codec *codec)
4334 {
4335 	struct conexant_spec *spec = codec->spec;
4336 	hda_nid_t nid, end_nid;
4337 
4338 	end_nid = codec->start_nid + codec->num_nodes;
4339 	for (nid = codec->start_nid; nid < end_nid; nid++) {
4340 		unsigned int caps = get_wcaps(codec, nid);
4341 		if (get_wcaps_type(caps) != AC_WID_AUD_IN)
4342 			continue;
4343 		if (caps & AC_WCAP_DIGITAL)
4344 			continue;
4345 		if (snd_BUG_ON(spec->num_adc_nids >=
4346 			       ARRAY_SIZE(spec->private_adc_nids)))
4347 			break;
4348 		spec->private_adc_nids[spec->num_adc_nids++] = nid;
4349 	}
4350 	spec->adc_nids = spec->private_adc_nids;
4351 	return 0;
4352 }
4353 
4354 
4355 static const struct hda_codec_ops cx_auto_patch_ops = {
4356 	.build_controls = cx_auto_build_controls,
4357 	.build_pcms = conexant_build_pcms,
4358 	.init = cx_auto_init,
4359 	.free = conexant_free,
4360 	.unsol_event = cx_auto_unsol_event,
4361 #ifdef CONFIG_SND_HDA_POWER_SAVE
4362 	.suspend = conexant_suspend,
4363 #endif
4364 	.reboot_notify = snd_hda_shutup_pins,
4365 };
4366 
4367 static int patch_conexant_auto(struct hda_codec *codec)
4368 {
4369 	struct conexant_spec *spec;
4370 	int err;
4371 
4372 	printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4373 	       codec->chip_name);
4374 
4375 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4376 	if (!spec)
4377 		return -ENOMEM;
4378 	codec->spec = spec;
4379 	codec->pin_amp_workaround = 1;
4380 	err = cx_auto_search_adcs(codec);
4381 	if (err < 0)
4382 		return err;
4383 	err = cx_auto_parse_auto_config(codec);
4384 	if (err < 0) {
4385 		kfree(codec->spec);
4386 		codec->spec = NULL;
4387 		return err;
4388 	}
4389 	spec->capture_stream = &cx_auto_pcm_analog_capture;
4390 	codec->patch_ops = cx_auto_patch_ops;
4391 	if (spec->beep_amp)
4392 		snd_hda_attach_beep_device(codec, spec->beep_amp);
4393 	return 0;
4394 }
4395 
4396 /*
4397  */
4398 
4399 static const struct hda_codec_preset snd_hda_preset_conexant[] = {
4400 	{ .id = 0x14f15045, .name = "CX20549 (Venice)",
4401 	  .patch = patch_cxt5045 },
4402 	{ .id = 0x14f15047, .name = "CX20551 (Waikiki)",
4403 	  .patch = patch_cxt5047 },
4404 	{ .id = 0x14f15051, .name = "CX20561 (Hermosa)",
4405 	  .patch = patch_cxt5051 },
4406 	{ .id = 0x14f15066, .name = "CX20582 (Pebble)",
4407 	  .patch = patch_cxt5066 },
4408 	{ .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
4409 	  .patch = patch_cxt5066 },
4410 	{ .id = 0x14f15068, .name = "CX20584",
4411 	  .patch = patch_cxt5066 },
4412 	{ .id = 0x14f15069, .name = "CX20585",
4413 	  .patch = patch_cxt5066 },
4414 	{ .id = 0x14f1506c, .name = "CX20588",
4415 	  .patch = patch_cxt5066 },
4416 	{ .id = 0x14f1506e, .name = "CX20590",
4417 	  .patch = patch_cxt5066 },
4418 	{ .id = 0x14f15097, .name = "CX20631",
4419 	  .patch = patch_conexant_auto },
4420 	{ .id = 0x14f15098, .name = "CX20632",
4421 	  .patch = patch_conexant_auto },
4422 	{ .id = 0x14f150a1, .name = "CX20641",
4423 	  .patch = patch_conexant_auto },
4424 	{ .id = 0x14f150a2, .name = "CX20642",
4425 	  .patch = patch_conexant_auto },
4426 	{ .id = 0x14f150ab, .name = "CX20651",
4427 	  .patch = patch_conexant_auto },
4428 	{ .id = 0x14f150ac, .name = "CX20652",
4429 	  .patch = patch_conexant_auto },
4430 	{ .id = 0x14f150b8, .name = "CX20664",
4431 	  .patch = patch_conexant_auto },
4432 	{ .id = 0x14f150b9, .name = "CX20665",
4433 	  .patch = patch_conexant_auto },
4434 	{} /* terminator */
4435 };
4436 
4437 MODULE_ALIAS("snd-hda-codec-id:14f15045");
4438 MODULE_ALIAS("snd-hda-codec-id:14f15047");
4439 MODULE_ALIAS("snd-hda-codec-id:14f15051");
4440 MODULE_ALIAS("snd-hda-codec-id:14f15066");
4441 MODULE_ALIAS("snd-hda-codec-id:14f15067");
4442 MODULE_ALIAS("snd-hda-codec-id:14f15068");
4443 MODULE_ALIAS("snd-hda-codec-id:14f15069");
4444 MODULE_ALIAS("snd-hda-codec-id:14f1506c");
4445 MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4446 MODULE_ALIAS("snd-hda-codec-id:14f15097");
4447 MODULE_ALIAS("snd-hda-codec-id:14f15098");
4448 MODULE_ALIAS("snd-hda-codec-id:14f150a1");
4449 MODULE_ALIAS("snd-hda-codec-id:14f150a2");
4450 MODULE_ALIAS("snd-hda-codec-id:14f150ab");
4451 MODULE_ALIAS("snd-hda-codec-id:14f150ac");
4452 MODULE_ALIAS("snd-hda-codec-id:14f150b8");
4453 MODULE_ALIAS("snd-hda-codec-id:14f150b9");
4454 
4455 MODULE_LICENSE("GPL");
4456 MODULE_DESCRIPTION("Conexant HD-audio codec");
4457 
4458 static struct hda_codec_preset_list conexant_list = {
4459 	.preset = snd_hda_preset_conexant,
4460 	.owner = THIS_MODULE,
4461 };
4462 
4463 static int __init patch_conexant_init(void)
4464 {
4465 	return snd_hda_add_codec_preset(&conexant_list);
4466 }
4467 
4468 static void __exit patch_conexant_exit(void)
4469 {
4470 	snd_hda_delete_codec_preset(&conexant_list);
4471 }
4472 
4473 module_init(patch_conexant_init)
4474 module_exit(patch_conexant_exit)
4475