xref: /openbmc/linux/sound/pci/hda/patch_conexant.c (revision 2792d42f)
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 <linux/module.h>
28 #include <sound/core.h>
29 #include <sound/jack.h>
30 
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_auto_parser.h"
34 #include "hda_beep.h"
35 #include "hda_jack.h"
36 #include "hda_generic.h"
37 
38 #define ENABLE_CXT_STATIC_QUIRKS
39 
40 #define CXT_PIN_DIR_IN              0x00
41 #define CXT_PIN_DIR_OUT             0x01
42 #define CXT_PIN_DIR_INOUT           0x02
43 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
44 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
45 
46 #define CONEXANT_HP_EVENT	0x37
47 #define CONEXANT_MIC_EVENT	0x38
48 #define CONEXANT_LINE_EVENT	0x39
49 
50 /* Conexant 5051 specific */
51 
52 #define CXT5051_SPDIF_OUT	0x12
53 #define CXT5051_PORTB_EVENT	0x38
54 #define CXT5051_PORTC_EVENT	0x39
55 
56 #define AUTO_MIC_PORTB		(1 << 1)
57 #define AUTO_MIC_PORTC		(1 << 2)
58 
59 struct conexant_spec {
60 	struct hda_gen_spec gen;
61 
62 	unsigned int beep_amp;
63 
64 	/* extra EAPD pins */
65 	unsigned int num_eapds;
66 	hda_nid_t eapds[4];
67 	bool dynamic_eapd;
68 
69 #ifdef ENABLE_CXT_STATIC_QUIRKS
70 	const struct snd_kcontrol_new *mixers[5];
71 	int num_mixers;
72 	hda_nid_t vmaster_nid;
73 
74 	const struct hda_verb *init_verbs[5];	/* initialization verbs
75 						 * don't forget NULL
76 						 * termination!
77 						 */
78 	unsigned int num_init_verbs;
79 
80 	/* playback */
81 	struct hda_multi_out multiout;	/* playback set-up
82 					 * max_channels, dacs must be set
83 					 * dig_out_nid and hp_nid are optional
84 					 */
85 	unsigned int cur_eapd;
86 	unsigned int hp_present;
87 	unsigned int line_present;
88 	unsigned int auto_mic;
89 
90 	/* capture */
91 	unsigned int num_adc_nids;
92 	const hda_nid_t *adc_nids;
93 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
94 
95 	unsigned int cur_adc_idx;
96 	hda_nid_t cur_adc;
97 	unsigned int cur_adc_stream_tag;
98 	unsigned int cur_adc_format;
99 
100 	const struct hda_pcm_stream *capture_stream;
101 
102 	/* capture source */
103 	const struct hda_input_mux *input_mux;
104 	const hda_nid_t *capsrc_nids;
105 	unsigned int cur_mux[3];
106 
107 	/* channel model */
108 	const struct hda_channel_mode *channel_mode;
109 	int num_channel_mode;
110 
111 	/* PCM information */
112 	struct hda_pcm pcm_rec[2];	/* used in build_pcms() */
113 
114 	unsigned int spdif_route;
115 
116 	unsigned int port_d_mode;
117 	unsigned int dell_automute:1;
118 	unsigned int dell_vostro:1;
119 	unsigned int ideapad:1;
120 	unsigned int thinkpad:1;
121 	unsigned int hp_laptop:1;
122 	unsigned int asus:1;
123 
124 	unsigned int ext_mic_present;
125 	unsigned int recording;
126 	void (*capture_prepare)(struct hda_codec *codec);
127 	void (*capture_cleanup)(struct hda_codec *codec);
128 
129 	/* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
130 	 * through the microphone jack.
131 	 * When the user enables this through a mixer switch, both internal and
132 	 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
133 	 * we also allow the bias to be configured through a separate mixer
134 	 * control. */
135 	unsigned int dc_enable;
136 	unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
137 	unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
138 #endif /* ENABLE_CXT_STATIC_QUIRKS */
139 };
140 
141 
142 #ifdef CONFIG_SND_HDA_INPUT_BEEP
143 static inline void set_beep_amp(struct conexant_spec *spec, hda_nid_t nid,
144 				int idx, int dir)
145 {
146 	spec->gen.beep_nid = nid;
147 	spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
148 }
149 /* additional beep mixers; the actual parameters are overwritten at build */
150 static const struct snd_kcontrol_new cxt_beep_mixer[] = {
151 	HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
152 	HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
153 	{ } /* end */
154 };
155 
156 /* create beep controls if needed */
157 static int add_beep_ctls(struct hda_codec *codec)
158 {
159 	struct conexant_spec *spec = codec->spec;
160 	int err;
161 
162 	if (spec->beep_amp) {
163 		const struct snd_kcontrol_new *knew;
164 		for (knew = cxt_beep_mixer; knew->name; knew++) {
165 			struct snd_kcontrol *kctl;
166 			kctl = snd_ctl_new1(knew, codec);
167 			if (!kctl)
168 				return -ENOMEM;
169 			kctl->private_value = spec->beep_amp;
170 			err = snd_hda_ctl_add(codec, 0, kctl);
171 			if (err < 0)
172 				return err;
173 		}
174 	}
175 	return 0;
176 }
177 #else
178 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
179 #define add_beep_ctls(codec)	0
180 #endif
181 
182 
183 #ifdef ENABLE_CXT_STATIC_QUIRKS
184 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
185 				      struct hda_codec *codec,
186 				      struct snd_pcm_substream *substream)
187 {
188 	struct conexant_spec *spec = codec->spec;
189 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
190 					     hinfo);
191 }
192 
193 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
194 					 struct hda_codec *codec,
195 					 unsigned int stream_tag,
196 					 unsigned int format,
197 					 struct snd_pcm_substream *substream)
198 {
199 	struct conexant_spec *spec = codec->spec;
200 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
201 						stream_tag,
202 						format, substream);
203 }
204 
205 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
206 					 struct hda_codec *codec,
207 					 struct snd_pcm_substream *substream)
208 {
209 	struct conexant_spec *spec = codec->spec;
210 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
211 }
212 
213 /*
214  * Digital out
215  */
216 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
217 					  struct hda_codec *codec,
218 					  struct snd_pcm_substream *substream)
219 {
220 	struct conexant_spec *spec = codec->spec;
221 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
222 }
223 
224 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
225 					 struct hda_codec *codec,
226 					 struct snd_pcm_substream *substream)
227 {
228 	struct conexant_spec *spec = codec->spec;
229 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
230 }
231 
232 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
233 					 struct hda_codec *codec,
234 					 unsigned int stream_tag,
235 					 unsigned int format,
236 					 struct snd_pcm_substream *substream)
237 {
238 	struct conexant_spec *spec = codec->spec;
239 	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
240 					     stream_tag,
241 					     format, substream);
242 }
243 
244 /*
245  * Analog capture
246  */
247 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
248 				      struct hda_codec *codec,
249 				      unsigned int stream_tag,
250 				      unsigned int format,
251 				      struct snd_pcm_substream *substream)
252 {
253 	struct conexant_spec *spec = codec->spec;
254 	if (spec->capture_prepare)
255 		spec->capture_prepare(codec);
256 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
257 				   stream_tag, 0, format);
258 	return 0;
259 }
260 
261 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
262 				      struct hda_codec *codec,
263 				      struct snd_pcm_substream *substream)
264 {
265 	struct conexant_spec *spec = codec->spec;
266 	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
267 	if (spec->capture_cleanup)
268 		spec->capture_cleanup(codec);
269 	return 0;
270 }
271 
272 
273 
274 static const struct hda_pcm_stream conexant_pcm_analog_playback = {
275 	.substreams = 1,
276 	.channels_min = 2,
277 	.channels_max = 2,
278 	.nid = 0, /* fill later */
279 	.ops = {
280 		.open = conexant_playback_pcm_open,
281 		.prepare = conexant_playback_pcm_prepare,
282 		.cleanup = conexant_playback_pcm_cleanup
283 	},
284 };
285 
286 static const struct hda_pcm_stream conexant_pcm_analog_capture = {
287 	.substreams = 1,
288 	.channels_min = 2,
289 	.channels_max = 2,
290 	.nid = 0, /* fill later */
291 	.ops = {
292 		.prepare = conexant_capture_pcm_prepare,
293 		.cleanup = conexant_capture_pcm_cleanup
294 	},
295 };
296 
297 
298 static const struct hda_pcm_stream conexant_pcm_digital_playback = {
299 	.substreams = 1,
300 	.channels_min = 2,
301 	.channels_max = 2,
302 	.nid = 0, /* fill later */
303 	.ops = {
304 		.open = conexant_dig_playback_pcm_open,
305 		.close = conexant_dig_playback_pcm_close,
306 		.prepare = conexant_dig_playback_pcm_prepare
307 	},
308 };
309 
310 static const struct hda_pcm_stream conexant_pcm_digital_capture = {
311 	.substreams = 1,
312 	.channels_min = 2,
313 	.channels_max = 2,
314 	/* NID is set in alc_build_pcms */
315 };
316 
317 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
318 				      struct hda_codec *codec,
319 				      unsigned int stream_tag,
320 				      unsigned int format,
321 				      struct snd_pcm_substream *substream)
322 {
323 	struct conexant_spec *spec = codec->spec;
324 	spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
325 	spec->cur_adc_stream_tag = stream_tag;
326 	spec->cur_adc_format = format;
327 	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
328 	return 0;
329 }
330 
331 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
332 				      struct hda_codec *codec,
333 				      struct snd_pcm_substream *substream)
334 {
335 	struct conexant_spec *spec = codec->spec;
336 	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
337 	spec->cur_adc = 0;
338 	return 0;
339 }
340 
341 static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
342 	.substreams = 1,
343 	.channels_min = 2,
344 	.channels_max = 2,
345 	.nid = 0, /* fill later */
346 	.ops = {
347 		.prepare = cx5051_capture_pcm_prepare,
348 		.cleanup = cx5051_capture_pcm_cleanup
349 	},
350 };
351 
352 static int conexant_build_pcms(struct hda_codec *codec)
353 {
354 	struct conexant_spec *spec = codec->spec;
355 	struct hda_pcm *info = spec->pcm_rec;
356 
357 	codec->num_pcms = 1;
358 	codec->pcm_info = info;
359 
360 	info->name = "CONEXANT Analog";
361 	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
362 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
363 		spec->multiout.max_channels;
364 	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
365 		spec->multiout.dac_nids[0];
366 	if (spec->capture_stream)
367 		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
368 	else {
369 		if (codec->vendor_id == 0x14f15051)
370 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
371 				cx5051_pcm_analog_capture;
372 		else {
373 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
374 				conexant_pcm_analog_capture;
375 			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
376 				spec->num_adc_nids;
377 		}
378 	}
379 	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
380 
381 	if (spec->multiout.dig_out_nid) {
382 		info++;
383 		codec->num_pcms++;
384 		info->name = "Conexant Digital";
385 		info->pcm_type = HDA_PCM_TYPE_SPDIF;
386 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
387 			conexant_pcm_digital_playback;
388 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
389 			spec->multiout.dig_out_nid;
390 		if (spec->dig_in_nid) {
391 			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
392 				conexant_pcm_digital_capture;
393 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
394 				spec->dig_in_nid;
395 		}
396 	}
397 
398 	return 0;
399 }
400 
401 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
402 	       			  struct snd_ctl_elem_info *uinfo)
403 {
404 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 	struct conexant_spec *spec = codec->spec;
406 
407 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
408 }
409 
410 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
411 				 struct snd_ctl_elem_value *ucontrol)
412 {
413 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
414 	struct conexant_spec *spec = codec->spec;
415 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
416 
417 	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
418 	return 0;
419 }
420 
421 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
422 				 struct snd_ctl_elem_value *ucontrol)
423 {
424 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
425 	struct conexant_spec *spec = codec->spec;
426 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
427 
428 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
429 				     spec->capsrc_nids[adc_idx],
430 				     &spec->cur_mux[adc_idx]);
431 }
432 
433 static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
434 			       unsigned int power_state)
435 {
436 	if (power_state == AC_PWRST_D3)
437 		msleep(100);
438 	snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
439 			    power_state);
440 	/* partial workaround for "azx_get_response timeout" */
441 	if (power_state == AC_PWRST_D0)
442 		msleep(10);
443 	snd_hda_codec_set_power_to_all(codec, fg, power_state);
444 }
445 
446 static int conexant_init(struct hda_codec *codec)
447 {
448 	struct conexant_spec *spec = codec->spec;
449 	int i;
450 
451 	for (i = 0; i < spec->num_init_verbs; i++)
452 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
453 	return 0;
454 }
455 
456 static void conexant_free(struct hda_codec *codec)
457 {
458 	struct conexant_spec *spec = codec->spec;
459 	snd_hda_detach_beep_device(codec);
460 	kfree(spec);
461 }
462 
463 static const struct snd_kcontrol_new cxt_capture_mixers[] = {
464 	{
465 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
466 		.name = "Capture Source",
467 		.info = conexant_mux_enum_info,
468 		.get = conexant_mux_enum_get,
469 		.put = conexant_mux_enum_put
470 	},
471 	{}
472 };
473 
474 static const char * const slave_pfxs[] = {
475 	"Headphone", "Speaker", "Bass Speaker", "Front", "Surround", "CLFE",
476 	NULL
477 };
478 
479 static int conexant_build_controls(struct hda_codec *codec)
480 {
481 	struct conexant_spec *spec = codec->spec;
482 	unsigned int i;
483 	int err;
484 
485 	for (i = 0; i < spec->num_mixers; i++) {
486 		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
487 		if (err < 0)
488 			return err;
489 	}
490 	if (spec->multiout.dig_out_nid) {
491 		err = snd_hda_create_spdif_out_ctls(codec,
492 						    spec->multiout.dig_out_nid,
493 						    spec->multiout.dig_out_nid);
494 		if (err < 0)
495 			return err;
496 		err = snd_hda_create_spdif_share_sw(codec,
497 						    &spec->multiout);
498 		if (err < 0)
499 			return err;
500 		spec->multiout.share_spdif = 1;
501 	}
502 	if (spec->dig_in_nid) {
503 		err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
504 		if (err < 0)
505 			return err;
506 	}
507 
508 	/* if we have no master control, let's create it */
509 	if (spec->vmaster_nid &&
510 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
511 		unsigned int vmaster_tlv[4];
512 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
513 					HDA_OUTPUT, vmaster_tlv);
514 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
515 					  vmaster_tlv, slave_pfxs,
516 					  "Playback Volume");
517 		if (err < 0)
518 			return err;
519 	}
520 	if (spec->vmaster_nid &&
521 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
522 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
523 					  NULL, slave_pfxs,
524 					  "Playback Switch");
525 		if (err < 0)
526 			return err;
527 	}
528 
529 	if (spec->input_mux) {
530 		err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
531 		if (err < 0)
532 			return err;
533 	}
534 
535 	err = add_beep_ctls(codec);
536 	if (err < 0)
537 		return err;
538 
539 	return 0;
540 }
541 
542 static const struct hda_codec_ops conexant_patch_ops = {
543 	.build_controls = conexant_build_controls,
544 	.build_pcms = conexant_build_pcms,
545 	.init = conexant_init,
546 	.free = conexant_free,
547 	.set_power_state = conexant_set_power,
548 };
549 
550 static int patch_conexant_auto(struct hda_codec *codec);
551 /*
552  * EAPD control
553  * the private value = nid | (invert << 8)
554  */
555 
556 #define cxt_eapd_info		snd_ctl_boolean_mono_info
557 
558 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
559 			     struct snd_ctl_elem_value *ucontrol)
560 {
561 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
562 	struct conexant_spec *spec = codec->spec;
563 	int invert = (kcontrol->private_value >> 8) & 1;
564 	if (invert)
565 		ucontrol->value.integer.value[0] = !spec->cur_eapd;
566 	else
567 		ucontrol->value.integer.value[0] = spec->cur_eapd;
568 	return 0;
569 
570 }
571 
572 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
573 			     struct snd_ctl_elem_value *ucontrol)
574 {
575 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
576 	struct conexant_spec *spec = codec->spec;
577 	int invert = (kcontrol->private_value >> 8) & 1;
578 	hda_nid_t nid = kcontrol->private_value & 0xff;
579 	unsigned int eapd;
580 
581 	eapd = !!ucontrol->value.integer.value[0];
582 	if (invert)
583 		eapd = !eapd;
584 	if (eapd == spec->cur_eapd)
585 		return 0;
586 
587 	spec->cur_eapd = eapd;
588 	snd_hda_codec_write_cache(codec, nid,
589 				  0, AC_VERB_SET_EAPD_BTLENABLE,
590 				  eapd ? 0x02 : 0x00);
591 	return 1;
592 }
593 
594 /* controls for test mode */
595 #ifdef CONFIG_SND_DEBUG
596 
597 #define CXT_EAPD_SWITCH(xname, nid, mask) \
598 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
599 	  .info = cxt_eapd_info, \
600 	  .get = cxt_eapd_get, \
601 	  .put = cxt_eapd_put, \
602 	  .private_value = nid | (mask<<16) }
603 
604 
605 
606 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
607 				 struct snd_ctl_elem_info *uinfo)
608 {
609 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
610 	struct conexant_spec *spec = codec->spec;
611 	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
612 				    spec->num_channel_mode);
613 }
614 
615 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
616 				struct snd_ctl_elem_value *ucontrol)
617 {
618 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
619 	struct conexant_spec *spec = codec->spec;
620 	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
621 				   spec->num_channel_mode,
622 				   spec->multiout.max_channels);
623 }
624 
625 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
626 				struct snd_ctl_elem_value *ucontrol)
627 {
628 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629 	struct conexant_spec *spec = codec->spec;
630 	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
631 				      spec->num_channel_mode,
632 				      &spec->multiout.max_channels);
633 	return err;
634 }
635 
636 #define CXT_PIN_MODE(xname, nid, dir) \
637 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
638 	  .info = conexant_ch_mode_info, \
639 	  .get = conexant_ch_mode_get, \
640 	  .put = conexant_ch_mode_put, \
641 	  .private_value = nid | (dir<<16) }
642 
643 #endif /* CONFIG_SND_DEBUG */
644 
645 /* Conexant 5045 specific */
646 
647 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
648 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
649 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
650 #define CXT5045_SPDIF_OUT	0x18
651 
652 static const struct hda_channel_mode cxt5045_modes[1] = {
653 	{ 2, NULL },
654 };
655 
656 static const struct hda_input_mux cxt5045_capture_source = {
657 	.num_items = 2,
658 	.items = {
659 		{ "Internal Mic", 0x1 },
660 		{ "Mic",          0x2 },
661 	}
662 };
663 
664 static const struct hda_input_mux cxt5045_capture_source_benq = {
665 	.num_items = 4,
666 	.items = {
667 		{ "Internal Mic", 0x1 },
668 		{ "Mic",          0x2 },
669 		{ "Line",         0x3 },
670 		{ "Mixer",        0x0 },
671 	}
672 };
673 
674 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
675 	.num_items = 2,
676 	.items = {
677 		{ "Mic",          0x1 },
678 		{ "Internal Mic", 0x2 },
679 	}
680 };
681 
682 /* turn on/off EAPD (+ mute HP) as a master switch */
683 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
684 				    struct snd_ctl_elem_value *ucontrol)
685 {
686 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
687 	struct conexant_spec *spec = codec->spec;
688 	unsigned int bits;
689 
690 	if (!cxt_eapd_put(kcontrol, ucontrol))
691 		return 0;
692 
693 	/* toggle internal speakers mute depending of presence of
694 	 * the headphone jack
695 	 */
696 	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
697 	snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
698 				 HDA_AMP_MUTE, bits);
699 
700 	bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
701 	snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
702 				 HDA_AMP_MUTE, bits);
703 	return 1;
704 }
705 
706 /* bind volumes of both NID 0x10 and 0x11 */
707 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
708 	.ops = &snd_hda_bind_vol,
709 	.values = {
710 		HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
711 		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
712 		0
713 	},
714 };
715 
716 /* toggle input of built-in and mic jack appropriately */
717 static void cxt5045_hp_automic(struct hda_codec *codec)
718 {
719 	static const struct hda_verb mic_jack_on[] = {
720 		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
721 		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
722 		{}
723 	};
724 	static const struct hda_verb mic_jack_off[] = {
725 		{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
726 		{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
727 		{}
728 	};
729 	unsigned int present;
730 
731 	present = snd_hda_jack_detect(codec, 0x12);
732 	if (present)
733 		snd_hda_sequence_write(codec, mic_jack_on);
734 	else
735 		snd_hda_sequence_write(codec, mic_jack_off);
736 }
737 
738 
739 /* mute internal speaker if HP is plugged */
740 static void cxt5045_hp_automute(struct hda_codec *codec)
741 {
742 	struct conexant_spec *spec = codec->spec;
743 	unsigned int bits;
744 
745 	spec->hp_present = snd_hda_jack_detect(codec, 0x11);
746 
747 	bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
748 	snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
749 				 HDA_AMP_MUTE, bits);
750 }
751 
752 /* unsolicited event for HP jack sensing */
753 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
754 				   unsigned int res)
755 {
756 	res >>= 26;
757 	switch (res) {
758 	case CONEXANT_HP_EVENT:
759 		cxt5045_hp_automute(codec);
760 		break;
761 	case CONEXANT_MIC_EVENT:
762 		cxt5045_hp_automic(codec);
763 		break;
764 
765 	}
766 }
767 
768 static const struct snd_kcontrol_new cxt5045_mixers[] = {
769 	HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
770 	HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
771 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
772 	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
773 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
774 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
775 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
776 	HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
777 	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
778 	{
779 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
780 		.name = "Master Playback Switch",
781 		.info = cxt_eapd_info,
782 		.get = cxt_eapd_get,
783 		.put = cxt5045_hp_master_sw_put,
784 		.private_value = 0x10,
785 	},
786 
787 	{}
788 };
789 
790 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
791 	HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x3, HDA_INPUT),
792 	HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x3, HDA_INPUT),
793 
794 	{}
795 };
796 
797 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
798 	HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
799 	HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
800 	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
801 	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
802 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
803 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
804 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
805 	HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
806 	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
807 	{
808 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
809 		.name = "Master Playback Switch",
810 		.info = cxt_eapd_info,
811 		.get = cxt_eapd_get,
812 		.put = cxt5045_hp_master_sw_put,
813 		.private_value = 0x10,
814 	},
815 
816 	{}
817 };
818 
819 static const struct hda_verb cxt5045_init_verbs[] = {
820 	/* Line in, Mic */
821 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
822 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
823 	/* HP, Amp  */
824 	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
825 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
826 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
827 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
828 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
829 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
830 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
831 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
832 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
833 	/* Record selector: Internal mic */
834 	{0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
835 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
836 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
837 	/* SPDIF route: PCM */
838 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
839 	{ 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
840 	/* EAPD */
841 	{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */
842 	{ } /* end */
843 };
844 
845 static const struct hda_verb cxt5045_benq_init_verbs[] = {
846 	/* Internal Mic, Mic */
847 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
848 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
849 	/* Line In,HP, Amp  */
850 	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
851 	{0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
852 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
853 	{0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
854 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
855 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
856 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
857 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
858 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
859 	/* Record selector: Internal mic */
860 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
861 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
862 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
863 	/* SPDIF route: PCM */
864 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
865 	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
866 	/* EAPD */
867 	{0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
868 	{ } /* end */
869 };
870 
871 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
872 	/* pin sensing on HP jack */
873 	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
874 	{ } /* end */
875 };
876 
877 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
878 	/* pin sensing on HP jack */
879 	{0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
880 	{ } /* end */
881 };
882 
883 #ifdef CONFIG_SND_DEBUG
884 /* Test configuration for debugging, modelled after the ALC260 test
885  * configuration.
886  */
887 static const struct hda_input_mux cxt5045_test_capture_source = {
888 	.num_items = 5,
889 	.items = {
890 		{ "MIXER", 0x0 },
891 		{ "MIC1 pin", 0x1 },
892 		{ "LINE1 pin", 0x2 },
893 		{ "HP-OUT pin", 0x3 },
894 		{ "CD pin", 0x4 },
895         },
896 };
897 
898 static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
899 
900 	/* Output controls */
901 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
902 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
903 	HDA_CODEC_VOLUME("HP-OUT Playback Volume", 0x11, 0x0, HDA_OUTPUT),
904 	HDA_CODEC_MUTE("HP-OUT Playback Switch", 0x11, 0x0, HDA_OUTPUT),
905 	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
906 	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
907 
908 	/* Modes for retasking pin widgets */
909 	CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
910 	CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
911 
912 	/* EAPD Switch Control */
913 	CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
914 
915 	/* Loopback mixer controls */
916 
917 	HDA_CODEC_VOLUME("PCM Volume", 0x17, 0x0, HDA_INPUT),
918 	HDA_CODEC_MUTE("PCM Switch", 0x17, 0x0, HDA_INPUT),
919 	HDA_CODEC_VOLUME("MIC1 pin Volume", 0x17, 0x1, HDA_INPUT),
920 	HDA_CODEC_MUTE("MIC1 pin Switch", 0x17, 0x1, HDA_INPUT),
921 	HDA_CODEC_VOLUME("LINE1 pin Volume", 0x17, 0x2, HDA_INPUT),
922 	HDA_CODEC_MUTE("LINE1 pin Switch", 0x17, 0x2, HDA_INPUT),
923 	HDA_CODEC_VOLUME("HP-OUT pin Volume", 0x17, 0x3, HDA_INPUT),
924 	HDA_CODEC_MUTE("HP-OUT pin Switch", 0x17, 0x3, HDA_INPUT),
925 	HDA_CODEC_VOLUME("CD pin Volume", 0x17, 0x4, HDA_INPUT),
926 	HDA_CODEC_MUTE("CD pin Switch", 0x17, 0x4, HDA_INPUT),
927 	{
928 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
929 		.name = "Input Source",
930 		.info = conexant_mux_enum_info,
931 		.get = conexant_mux_enum_get,
932 		.put = conexant_mux_enum_put,
933 	},
934 	/* Audio input controls */
935 	HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT),
936 	HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
937 	{ } /* end */
938 };
939 
940 static const struct hda_verb cxt5045_test_init_verbs[] = {
941 	/* Set connections */
942 	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
943 	{ 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
944 	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
945 	/* Enable retasking pins as output, initially without power amp */
946 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
947 	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
948 
949 	/* Disable digital (SPDIF) pins initially, but users can enable
950 	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
951 	 * payload also sets the generation to 0, output to be in "consumer"
952 	 * PCM format, copyright asserted, no pre-emphasis and no validity
953 	 * control.
954 	 */
955 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
956 	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
957 
958 	/* Unmute retasking pin widget output buffers since the default
959 	 * state appears to be output.  As the pin mode is changed by the
960 	 * user the pin mode control will take care of enabling the pin's
961 	 * input/output buffers as needed.
962 	 */
963 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
964 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
965 
966 	/* Mute capture amp left and right */
967 	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
968 
969 	/* Set ADC connection select to match default mixer setting (mic1
970 	 * pin)
971 	 */
972 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
973 	{0x17, AC_VERB_SET_CONNECT_SEL, 0x01},
974 
975 	/* Mute all inputs to mixer widget (even unconnected ones) */
976 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer */
977 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
978 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
979 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
980 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
981 
982 	{ }
983 };
984 #endif
985 
986 
987 /* initialize jack-sensing, too */
988 static int cxt5045_init(struct hda_codec *codec)
989 {
990 	conexant_init(codec);
991 	cxt5045_hp_automute(codec);
992 	return 0;
993 }
994 
995 
996 enum {
997 	CXT5045_LAPTOP_HPSENSE,
998 	CXT5045_LAPTOP_MICSENSE,
999 	CXT5045_LAPTOP_HPMICSENSE,
1000 	CXT5045_BENQ,
1001 	CXT5045_LAPTOP_HP530,
1002 #ifdef CONFIG_SND_DEBUG
1003 	CXT5045_TEST,
1004 #endif
1005 	CXT5045_AUTO,
1006 	CXT5045_MODELS
1007 };
1008 
1009 static const char * const cxt5045_models[CXT5045_MODELS] = {
1010 	[CXT5045_LAPTOP_HPSENSE]	= "laptop-hpsense",
1011 	[CXT5045_LAPTOP_MICSENSE]	= "laptop-micsense",
1012 	[CXT5045_LAPTOP_HPMICSENSE]	= "laptop-hpmicsense",
1013 	[CXT5045_BENQ]			= "benq",
1014 	[CXT5045_LAPTOP_HP530]		= "laptop-hp530",
1015 #ifdef CONFIG_SND_DEBUG
1016 	[CXT5045_TEST]		= "test",
1017 #endif
1018 	[CXT5045_AUTO]			= "auto",
1019 };
1020 
1021 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1022 	SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1023 	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1024 	SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1025 	SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1026 	SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1027 	SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1028 		      CXT5045_LAPTOP_HPMICSENSE),
1029 	SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1030 	SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1031 	SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1032 	SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1033 			   CXT5045_LAPTOP_HPMICSENSE),
1034 	SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1035 	{}
1036 };
1037 
1038 static int patch_cxt5045(struct hda_codec *codec)
1039 {
1040 	struct conexant_spec *spec;
1041 	int board_config;
1042 
1043 	board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1044 						  cxt5045_models,
1045 						  cxt5045_cfg_tbl);
1046 	if (board_config < 0)
1047 		board_config = CXT5045_AUTO; /* model=auto as default */
1048 	if (board_config == CXT5045_AUTO)
1049 		return patch_conexant_auto(codec);
1050 
1051 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1052 	if (!spec)
1053 		return -ENOMEM;
1054 	codec->spec = spec;
1055 	codec->single_adc_amp = 1;
1056 
1057 	spec->multiout.max_channels = 2;
1058 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1059 	spec->multiout.dac_nids = cxt5045_dac_nids;
1060 	spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1061 	spec->num_adc_nids = 1;
1062 	spec->adc_nids = cxt5045_adc_nids;
1063 	spec->capsrc_nids = cxt5045_capsrc_nids;
1064 	spec->input_mux = &cxt5045_capture_source;
1065 	spec->num_mixers = 1;
1066 	spec->mixers[0] = cxt5045_mixers;
1067 	spec->num_init_verbs = 1;
1068 	spec->init_verbs[0] = cxt5045_init_verbs;
1069 	spec->spdif_route = 0;
1070 	spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1071 	spec->channel_mode = cxt5045_modes;
1072 
1073 	set_beep_amp(spec, 0x16, 0, 1);
1074 
1075 	codec->patch_ops = conexant_patch_ops;
1076 
1077 	switch (board_config) {
1078 	case CXT5045_LAPTOP_HPSENSE:
1079 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1080 		spec->input_mux = &cxt5045_capture_source;
1081 		spec->num_init_verbs = 2;
1082 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1083 		spec->mixers[0] = cxt5045_mixers;
1084 		codec->patch_ops.init = cxt5045_init;
1085 		break;
1086 	case CXT5045_LAPTOP_MICSENSE:
1087 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1088 		spec->input_mux = &cxt5045_capture_source;
1089 		spec->num_init_verbs = 2;
1090 		spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1091 		spec->mixers[0] = cxt5045_mixers;
1092 		codec->patch_ops.init = cxt5045_init;
1093 		break;
1094 	default:
1095 	case CXT5045_LAPTOP_HPMICSENSE:
1096 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1097 		spec->input_mux = &cxt5045_capture_source;
1098 		spec->num_init_verbs = 3;
1099 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1100 		spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1101 		spec->mixers[0] = cxt5045_mixers;
1102 		codec->patch_ops.init = cxt5045_init;
1103 		break;
1104 	case CXT5045_BENQ:
1105 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1106 		spec->input_mux = &cxt5045_capture_source_benq;
1107 		spec->num_init_verbs = 1;
1108 		spec->init_verbs[0] = cxt5045_benq_init_verbs;
1109 		spec->mixers[0] = cxt5045_mixers;
1110 		spec->mixers[1] = cxt5045_benq_mixers;
1111 		spec->num_mixers = 2;
1112 		codec->patch_ops.init = cxt5045_init;
1113 		break;
1114 	case CXT5045_LAPTOP_HP530:
1115 		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1116 		spec->input_mux = &cxt5045_capture_source_hp530;
1117 		spec->num_init_verbs = 2;
1118 		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1119 		spec->mixers[0] = cxt5045_mixers_hp530;
1120 		codec->patch_ops.init = cxt5045_init;
1121 		break;
1122 #ifdef CONFIG_SND_DEBUG
1123 	case CXT5045_TEST:
1124 		spec->input_mux = &cxt5045_test_capture_source;
1125 		spec->mixers[0] = cxt5045_test_mixer;
1126 		spec->init_verbs[0] = cxt5045_test_init_verbs;
1127 		break;
1128 
1129 #endif
1130 	}
1131 
1132 	switch (codec->subsystem_id >> 16) {
1133 	case 0x103c:
1134 	case 0x1631:
1135 	case 0x1734:
1136 	case 0x17aa:
1137 		/* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1138 		 * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1139 		 * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1140 		 */
1141 		snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1142 					  (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1143 					  (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1144 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1145 					  (1 << AC_AMPCAP_MUTE_SHIFT));
1146 		break;
1147 	}
1148 
1149 	if (spec->beep_amp)
1150 		snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
1151 
1152 	return 0;
1153 }
1154 
1155 
1156 /* Conexant 5047 specific */
1157 #define CXT5047_SPDIF_OUT	0x11
1158 
1159 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1160 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1161 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1162 
1163 static const struct hda_channel_mode cxt5047_modes[1] = {
1164 	{ 2, NULL },
1165 };
1166 
1167 static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1168 	.num_items = 2,
1169 	.items = {
1170 		{ "ExtMic", 0x2 },
1171 		{ "Line-In", 0x1 },
1172 	}
1173 };
1174 
1175 /* turn on/off EAPD (+ mute HP) as a master switch */
1176 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1177 				    struct snd_ctl_elem_value *ucontrol)
1178 {
1179 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1180 	struct conexant_spec *spec = codec->spec;
1181 	unsigned int bits;
1182 
1183 	if (!cxt_eapd_put(kcontrol, ucontrol))
1184 		return 0;
1185 
1186 	/* toggle internal speakers mute depending of presence of
1187 	 * the headphone jack
1188 	 */
1189 	bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1190 	/* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1191 	 * pin widgets unlike other codecs.  In this case, we need to
1192 	 * set index 0x01 for the volume from the mixer amp 0x19.
1193 	 */
1194 	snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1195 				 HDA_AMP_MUTE, bits);
1196 	bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1197 	snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1198 				 HDA_AMP_MUTE, bits);
1199 	return 1;
1200 }
1201 
1202 /* mute internal speaker if HP is plugged */
1203 static void cxt5047_hp_automute(struct hda_codec *codec)
1204 {
1205 	struct conexant_spec *spec = codec->spec;
1206 	unsigned int bits;
1207 
1208 	spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1209 
1210 	bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1211 	/* See the note in cxt5047_hp_master_sw_put */
1212 	snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1213 				 HDA_AMP_MUTE, bits);
1214 }
1215 
1216 /* toggle input of built-in and mic jack appropriately */
1217 static void cxt5047_hp_automic(struct hda_codec *codec)
1218 {
1219 	static const struct hda_verb mic_jack_on[] = {
1220 		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1221 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1222 		{}
1223 	};
1224 	static const struct hda_verb mic_jack_off[] = {
1225 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1226 		{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1227 		{}
1228 	};
1229 	unsigned int present;
1230 
1231 	present = snd_hda_jack_detect(codec, 0x15);
1232 	if (present)
1233 		snd_hda_sequence_write(codec, mic_jack_on);
1234 	else
1235 		snd_hda_sequence_write(codec, mic_jack_off);
1236 }
1237 
1238 /* unsolicited event for HP jack sensing */
1239 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1240 				  unsigned int res)
1241 {
1242 	switch (res >> 26) {
1243 	case CONEXANT_HP_EVENT:
1244 		cxt5047_hp_automute(codec);
1245 		break;
1246 	case CONEXANT_MIC_EVENT:
1247 		cxt5047_hp_automic(codec);
1248 		break;
1249 	}
1250 }
1251 
1252 static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1253 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1254 	HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1255 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1256 	HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1257 	HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1258 	HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1259 	HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1260 	{
1261 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1262 		.name = "Master Playback Switch",
1263 		.info = cxt_eapd_info,
1264 		.get = cxt_eapd_get,
1265 		.put = cxt5047_hp_master_sw_put,
1266 		.private_value = 0x13,
1267 	},
1268 
1269 	{}
1270 };
1271 
1272 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1273 	/* See the note in cxt5047_hp_master_sw_put */
1274 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1275 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1276 	{}
1277 };
1278 
1279 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1280 	HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1281 	{ } /* end */
1282 };
1283 
1284 static const struct hda_verb cxt5047_init_verbs[] = {
1285 	/* Line in, Mic, Built-in Mic */
1286 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1287 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1288 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1289 	/* HP, Speaker  */
1290 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1291 	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1292 	{0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1293 	/* Record selector: Mic */
1294 	{0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1295 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1296 	 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1297 	{0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1298 	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1299 	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1300 	{0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1301 	 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1302 	/* SPDIF route: PCM */
1303 	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1304 	/* Enable unsolicited events */
1305 	{0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1306 	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1307 	{ } /* end */
1308 };
1309 
1310 /* configuration for Toshiba Laptops */
1311 static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1312 	{0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1313 	{}
1314 };
1315 
1316 /* Test configuration for debugging, modelled after the ALC260 test
1317  * configuration.
1318  */
1319 #ifdef CONFIG_SND_DEBUG
1320 static const struct hda_input_mux cxt5047_test_capture_source = {
1321 	.num_items = 4,
1322 	.items = {
1323 		{ "LINE1 pin", 0x0 },
1324 		{ "MIC1 pin", 0x1 },
1325 		{ "MIC2 pin", 0x2 },
1326 		{ "CD pin", 0x3 },
1327         },
1328 };
1329 
1330 static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1331 
1332 	/* Output only controls */
1333 	HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1334 	HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1335 	HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1336 	HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1337 	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1338 	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1339 	HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1340 	HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1341 	HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1342 	HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1343 	HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1344 	HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1345 
1346 	/* Modes for retasking pin widgets */
1347 	CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1348 	CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1349 
1350 	/* EAPD Switch Control */
1351 	CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1352 
1353 	/* Loopback mixer controls */
1354 	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1355 	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1356 	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1357 	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1358 	HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1359 	HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1360 	HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1361 	HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1362 
1363 	HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1364 	HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1365 	HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1366 	HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1367 	HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1368 	HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1369 	HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1370 	HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1371 	{
1372 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1373 		.name = "Input Source",
1374 		.info = conexant_mux_enum_info,
1375 		.get = conexant_mux_enum_get,
1376 		.put = conexant_mux_enum_put,
1377 	},
1378 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1379 
1380 	{ } /* end */
1381 };
1382 
1383 static const struct hda_verb cxt5047_test_init_verbs[] = {
1384 	/* Enable retasking pins as output, initially without power amp */
1385 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1386 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1387 	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1388 
1389 	/* Disable digital (SPDIF) pins initially, but users can enable
1390 	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
1391 	 * payload also sets the generation to 0, output to be in "consumer"
1392 	 * PCM format, copyright asserted, no pre-emphasis and no validity
1393 	 * control.
1394 	 */
1395 	{0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1396 
1397 	/* Ensure mic1, mic2, line1 pin widgets take input from the
1398 	 * OUT1 sum bus when acting as an output.
1399 	 */
1400 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1401 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1402 
1403 	/* Start with output sum widgets muted and their output gains at min */
1404 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1405 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1406 
1407 	/* Unmute retasking pin widget output buffers since the default
1408 	 * state appears to be output.  As the pin mode is changed by the
1409 	 * user the pin mode control will take care of enabling the pin's
1410 	 * input/output buffers as needed.
1411 	 */
1412 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1413 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1414 	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1415 
1416 	/* Mute capture amp left and right */
1417 	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1418 
1419 	/* Set ADC connection select to match default mixer setting (mic1
1420 	 * pin)
1421 	 */
1422 	{0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1423 
1424 	/* Mute all inputs to mixer widget (even unconnected ones) */
1425 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1426 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1427 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1428 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1429 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1430 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1431 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1432 	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1433 
1434 	{ }
1435 };
1436 #endif
1437 
1438 
1439 /* initialize jack-sensing, too */
1440 static int cxt5047_hp_init(struct hda_codec *codec)
1441 {
1442 	conexant_init(codec);
1443 	cxt5047_hp_automute(codec);
1444 	return 0;
1445 }
1446 
1447 
1448 enum {
1449 	CXT5047_LAPTOP,		/* Laptops w/o EAPD support */
1450 	CXT5047_LAPTOP_HP,	/* Some HP laptops */
1451 	CXT5047_LAPTOP_EAPD,	/* Laptops with EAPD support */
1452 #ifdef CONFIG_SND_DEBUG
1453 	CXT5047_TEST,
1454 #endif
1455 	CXT5047_AUTO,
1456 	CXT5047_MODELS
1457 };
1458 
1459 static const char * const cxt5047_models[CXT5047_MODELS] = {
1460 	[CXT5047_LAPTOP]	= "laptop",
1461 	[CXT5047_LAPTOP_HP]	= "laptop-hp",
1462 	[CXT5047_LAPTOP_EAPD]	= "laptop-eapd",
1463 #ifdef CONFIG_SND_DEBUG
1464 	[CXT5047_TEST]		= "test",
1465 #endif
1466 	[CXT5047_AUTO]		= "auto",
1467 };
1468 
1469 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1470 	SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1471 	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1472 			   CXT5047_LAPTOP),
1473 	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1474 	{}
1475 };
1476 
1477 static int patch_cxt5047(struct hda_codec *codec)
1478 {
1479 	struct conexant_spec *spec;
1480 	int board_config;
1481 
1482 	board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1483 						  cxt5047_models,
1484 						  cxt5047_cfg_tbl);
1485 	if (board_config < 0)
1486 		board_config = CXT5047_AUTO; /* model=auto as default */
1487 	if (board_config == CXT5047_AUTO)
1488 		return patch_conexant_auto(codec);
1489 
1490 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1491 	if (!spec)
1492 		return -ENOMEM;
1493 	codec->spec = spec;
1494 	codec->pin_amp_workaround = 1;
1495 
1496 	spec->multiout.max_channels = 2;
1497 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1498 	spec->multiout.dac_nids = cxt5047_dac_nids;
1499 	spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1500 	spec->num_adc_nids = 1;
1501 	spec->adc_nids = cxt5047_adc_nids;
1502 	spec->capsrc_nids = cxt5047_capsrc_nids;
1503 	spec->num_mixers = 1;
1504 	spec->mixers[0] = cxt5047_base_mixers;
1505 	spec->num_init_verbs = 1;
1506 	spec->init_verbs[0] = cxt5047_init_verbs;
1507 	spec->spdif_route = 0;
1508 	spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1509 	spec->channel_mode = cxt5047_modes,
1510 
1511 	codec->patch_ops = conexant_patch_ops;
1512 
1513 	switch (board_config) {
1514 	case CXT5047_LAPTOP:
1515 		spec->num_mixers = 2;
1516 		spec->mixers[1] = cxt5047_hp_spk_mixers;
1517 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1518 		break;
1519 	case CXT5047_LAPTOP_HP:
1520 		spec->num_mixers = 2;
1521 		spec->mixers[1] = cxt5047_hp_only_mixers;
1522 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1523 		codec->patch_ops.init = cxt5047_hp_init;
1524 		break;
1525 	case CXT5047_LAPTOP_EAPD:
1526 		spec->input_mux = &cxt5047_toshiba_capture_source;
1527 		spec->num_mixers = 2;
1528 		spec->mixers[1] = cxt5047_hp_spk_mixers;
1529 		spec->num_init_verbs = 2;
1530 		spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1531 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1532 		break;
1533 #ifdef CONFIG_SND_DEBUG
1534 	case CXT5047_TEST:
1535 		spec->input_mux = &cxt5047_test_capture_source;
1536 		spec->mixers[0] = cxt5047_test_mixer;
1537 		spec->init_verbs[0] = cxt5047_test_init_verbs;
1538 		codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1539 #endif
1540 	}
1541 	spec->vmaster_nid = 0x13;
1542 
1543 	switch (codec->subsystem_id >> 16) {
1544 	case 0x103c:
1545 		/* HP laptops have really bad sound over 0 dB on NID 0x10.
1546 		 * Fix max PCM level to 0 dB (originally it has 0x1e steps
1547 		 * with 0 dB offset 0x17)
1548 		 */
1549 		snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1550 					  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1551 					  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1552 					  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1553 					  (1 << AC_AMPCAP_MUTE_SHIFT));
1554 		break;
1555 	}
1556 
1557 	return 0;
1558 }
1559 
1560 /* Conexant 5051 specific */
1561 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1562 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1563 
1564 static const struct hda_channel_mode cxt5051_modes[1] = {
1565 	{ 2, NULL },
1566 };
1567 
1568 static void cxt5051_update_speaker(struct hda_codec *codec)
1569 {
1570 	struct conexant_spec *spec = codec->spec;
1571 	unsigned int pinctl;
1572 	/* headphone pin */
1573 	pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1574 	snd_hda_set_pin_ctl(codec, 0x16, pinctl);
1575 	/* speaker pin */
1576 	pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1577 	snd_hda_set_pin_ctl(codec, 0x1a, pinctl);
1578 	/* on ideapad there is an additional speaker (subwoofer) to mute */
1579 	if (spec->ideapad)
1580 		snd_hda_set_pin_ctl(codec, 0x1b, pinctl);
1581 }
1582 
1583 /* turn on/off EAPD (+ mute HP) as a master switch */
1584 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1585 				    struct snd_ctl_elem_value *ucontrol)
1586 {
1587 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1588 
1589 	if (!cxt_eapd_put(kcontrol, ucontrol))
1590 		return 0;
1591 	cxt5051_update_speaker(codec);
1592 	return 1;
1593 }
1594 
1595 /* toggle input of built-in and mic jack appropriately */
1596 static void cxt5051_portb_automic(struct hda_codec *codec)
1597 {
1598 	struct conexant_spec *spec = codec->spec;
1599 	unsigned int present;
1600 
1601 	if (!(spec->auto_mic & AUTO_MIC_PORTB))
1602 		return;
1603 	present = snd_hda_jack_detect(codec, 0x17);
1604 	snd_hda_codec_write(codec, 0x14, 0,
1605 			    AC_VERB_SET_CONNECT_SEL,
1606 			    present ? 0x01 : 0x00);
1607 }
1608 
1609 /* switch the current ADC according to the jack state */
1610 static void cxt5051_portc_automic(struct hda_codec *codec)
1611 {
1612 	struct conexant_spec *spec = codec->spec;
1613 	unsigned int present;
1614 	hda_nid_t new_adc;
1615 
1616 	if (!(spec->auto_mic & AUTO_MIC_PORTC))
1617 		return;
1618 	present = snd_hda_jack_detect(codec, 0x18);
1619 	if (present)
1620 		spec->cur_adc_idx = 1;
1621 	else
1622 		spec->cur_adc_idx = 0;
1623 	new_adc = spec->adc_nids[spec->cur_adc_idx];
1624 	if (spec->cur_adc && spec->cur_adc != new_adc) {
1625 		/* stream is running, let's swap the current ADC */
1626 		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1627 		spec->cur_adc = new_adc;
1628 		snd_hda_codec_setup_stream(codec, new_adc,
1629 					   spec->cur_adc_stream_tag, 0,
1630 					   spec->cur_adc_format);
1631 	}
1632 }
1633 
1634 /* mute internal speaker if HP is plugged */
1635 static void cxt5051_hp_automute(struct hda_codec *codec)
1636 {
1637 	struct conexant_spec *spec = codec->spec;
1638 
1639 	spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1640 	cxt5051_update_speaker(codec);
1641 }
1642 
1643 /* unsolicited event for HP jack sensing */
1644 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1645 				   unsigned int res)
1646 {
1647 	switch (res >> 26) {
1648 	case CONEXANT_HP_EVENT:
1649 		cxt5051_hp_automute(codec);
1650 		break;
1651 	case CXT5051_PORTB_EVENT:
1652 		cxt5051_portb_automic(codec);
1653 		break;
1654 	case CXT5051_PORTC_EVENT:
1655 		cxt5051_portc_automic(codec);
1656 		break;
1657 	}
1658 }
1659 
1660 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1661 	HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1662 	{
1663 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1664 		.name = "Master Playback Switch",
1665 		.info = cxt_eapd_info,
1666 		.get = cxt_eapd_get,
1667 		.put = cxt5051_hp_master_sw_put,
1668 		.private_value = 0x1a,
1669 	},
1670 	{}
1671 };
1672 
1673 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1674 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1675 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1676 	HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1677 	HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1678 	HDA_CODEC_VOLUME("Dock Mic Volume", 0x15, 0x00, HDA_INPUT),
1679 	HDA_CODEC_MUTE("Dock Mic Switch", 0x15, 0x00, HDA_INPUT),
1680 	{}
1681 };
1682 
1683 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1684 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1685 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1686 	HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1687 	HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1688 	{}
1689 };
1690 
1691 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1692 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1693 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1694 	{}
1695 };
1696 
1697 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1698 	HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1699 	HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1700 	{}
1701 };
1702 
1703 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1704 	HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1705 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1706 	HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1707 	HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1708 	{}
1709 };
1710 
1711 static const struct hda_verb cxt5051_init_verbs[] = {
1712 	/* Line in, Mic */
1713 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1714 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1716 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1718 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1719 	/* SPK  */
1720 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1721 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1722 	/* HP, Amp  */
1723 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1724 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1725 	/* DAC1 */
1726 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1727 	/* Record selector: Internal mic */
1728 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1729 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1730 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1731 	/* SPDIF route: PCM */
1732 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1733 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1734 	/* EAPD */
1735 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1736 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1737 	{ } /* end */
1738 };
1739 
1740 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1741 	/* Line in, Mic */
1742 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1743 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1744 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1745 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1746 	/* SPK  */
1747 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1748 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1749 	/* HP, Amp  */
1750 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1751 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1752 	/* DAC1 */
1753 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1754 	/* Record selector: Internal mic */
1755 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1756 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1757 	/* SPDIF route: PCM */
1758 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1759 	/* EAPD */
1760 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1761 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1762 	{ } /* end */
1763 };
1764 
1765 static const struct hda_verb cxt5051_f700_init_verbs[] = {
1766 	/* Line in, Mic */
1767 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1768 	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1769 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1770 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1771 	/* SPK  */
1772 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1773 	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1774 	/* HP, Amp  */
1775 	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1776 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1777 	/* DAC1 */
1778 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1779 	/* Record selector: Internal mic */
1780 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1781 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1782 	/* SPDIF route: PCM */
1783 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1784 	/* EAPD */
1785 	{0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1786 	{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1787 	{ } /* end */
1788 };
1789 
1790 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1791 				 unsigned int event)
1792 {
1793 	snd_hda_codec_write(codec, nid, 0,
1794 			    AC_VERB_SET_UNSOLICITED_ENABLE,
1795 			    AC_USRSP_EN | event);
1796 }
1797 
1798 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1799 	/* Subwoofer */
1800 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1801 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1802 	{ } /* end */
1803 };
1804 
1805 /* initialize jack-sensing, too */
1806 static int cxt5051_init(struct hda_codec *codec)
1807 {
1808 	struct conexant_spec *spec = codec->spec;
1809 
1810 	conexant_init(codec);
1811 
1812 	if (spec->auto_mic & AUTO_MIC_PORTB)
1813 		cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1814 	if (spec->auto_mic & AUTO_MIC_PORTC)
1815 		cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1816 
1817 	if (codec->patch_ops.unsol_event) {
1818 		cxt5051_hp_automute(codec);
1819 		cxt5051_portb_automic(codec);
1820 		cxt5051_portc_automic(codec);
1821 	}
1822 	return 0;
1823 }
1824 
1825 
1826 enum {
1827 	CXT5051_LAPTOP,	 /* Laptops w/ EAPD support */
1828 	CXT5051_HP,	/* no docking */
1829 	CXT5051_HP_DV6736,	/* HP without mic switch */
1830 	CXT5051_F700,       /* HP Compaq Presario F700 */
1831 	CXT5051_TOSHIBA,	/* Toshiba M300 & co */
1832 	CXT5051_IDEAPAD,	/* Lenovo IdeaPad Y430 */
1833 	CXT5051_AUTO,		/* auto-parser */
1834 	CXT5051_MODELS
1835 };
1836 
1837 static const char *const cxt5051_models[CXT5051_MODELS] = {
1838 	[CXT5051_LAPTOP]	= "laptop",
1839 	[CXT5051_HP]		= "hp",
1840 	[CXT5051_HP_DV6736]	= "hp-dv6736",
1841 	[CXT5051_F700]          = "hp-700",
1842 	[CXT5051_TOSHIBA]	= "toshiba",
1843 	[CXT5051_IDEAPAD]	= "ideapad",
1844 	[CXT5051_AUTO]		= "auto",
1845 };
1846 
1847 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1848 	SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1849 	SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1850 	SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1851 	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1852 	SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1853 		      CXT5051_LAPTOP),
1854 	SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1855 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1856 	{}
1857 };
1858 
1859 static int patch_cxt5051(struct hda_codec *codec)
1860 {
1861 	struct conexant_spec *spec;
1862 	int board_config;
1863 
1864 	board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1865 						  cxt5051_models,
1866 						  cxt5051_cfg_tbl);
1867 	if (board_config < 0)
1868 		board_config = CXT5051_AUTO; /* model=auto as default */
1869 	if (board_config == CXT5051_AUTO)
1870 		return patch_conexant_auto(codec);
1871 
1872 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1873 	if (!spec)
1874 		return -ENOMEM;
1875 	codec->spec = spec;
1876 	codec->pin_amp_workaround = 1;
1877 
1878 	codec->patch_ops = conexant_patch_ops;
1879 	codec->patch_ops.init = cxt5051_init;
1880 
1881 	spec->multiout.max_channels = 2;
1882 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1883 	spec->multiout.dac_nids = cxt5051_dac_nids;
1884 	spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1885 	spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1886 	spec->adc_nids = cxt5051_adc_nids;
1887 	spec->num_mixers = 2;
1888 	spec->mixers[0] = cxt5051_capture_mixers;
1889 	spec->mixers[1] = cxt5051_playback_mixers;
1890 	spec->num_init_verbs = 1;
1891 	spec->init_verbs[0] = cxt5051_init_verbs;
1892 	spec->spdif_route = 0;
1893 	spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1894 	spec->channel_mode = cxt5051_modes;
1895 	spec->cur_adc = 0;
1896 	spec->cur_adc_idx = 0;
1897 
1898 	set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
1899 
1900 	codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1901 
1902 	spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1903 	switch (board_config) {
1904 	case CXT5051_HP:
1905 		spec->mixers[0] = cxt5051_hp_mixers;
1906 		break;
1907 	case CXT5051_HP_DV6736:
1908 		spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1909 		spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1910 		spec->auto_mic = 0;
1911 		break;
1912 	case CXT5051_F700:
1913 		spec->init_verbs[0] = cxt5051_f700_init_verbs;
1914 		spec->mixers[0] = cxt5051_f700_mixers;
1915 		spec->auto_mic = 0;
1916 		break;
1917 	case CXT5051_TOSHIBA:
1918 		spec->mixers[0] = cxt5051_toshiba_mixers;
1919 		spec->auto_mic = AUTO_MIC_PORTB;
1920 		break;
1921 	case CXT5051_IDEAPAD:
1922 		spec->init_verbs[spec->num_init_verbs++] =
1923 			cxt5051_ideapad_init_verbs;
1924 		spec->ideapad = 1;
1925 		break;
1926 	}
1927 
1928 	if (spec->beep_amp)
1929 		snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
1930 
1931 	return 0;
1932 }
1933 
1934 /* Conexant 5066 specific */
1935 
1936 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1937 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1938 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1939 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
1940 
1941 /* OLPC's microphone port is DC coupled for use with external sensors,
1942  * therefore we use a 50% mic bias in order to center the input signal with
1943  * the DC input range of the codec. */
1944 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
1945 
1946 static const struct hda_channel_mode cxt5066_modes[1] = {
1947 	{ 2, NULL },
1948 };
1949 
1950 #define HP_PRESENT_PORT_A	(1 << 0)
1951 #define HP_PRESENT_PORT_D	(1 << 1)
1952 #define hp_port_a_present(spec)	((spec)->hp_present & HP_PRESENT_PORT_A)
1953 #define hp_port_d_present(spec)	((spec)->hp_present & HP_PRESENT_PORT_D)
1954 
1955 static void cxt5066_update_speaker(struct hda_codec *codec)
1956 {
1957 	struct conexant_spec *spec = codec->spec;
1958 	unsigned int pinctl;
1959 
1960 	snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
1961 		    spec->hp_present, spec->cur_eapd);
1962 
1963 	/* Port A (HP) */
1964 	pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
1965 	snd_hda_set_pin_ctl(codec, 0x19, pinctl);
1966 
1967 	/* Port D (HP/LO) */
1968 	pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
1969 	if (spec->dell_automute || spec->thinkpad) {
1970 		/* Mute if Port A is connected */
1971 		if (hp_port_a_present(spec))
1972 			pinctl = 0;
1973 	} else {
1974 		/* Thinkpad/Dell doesn't give pin-D status */
1975 		if (!hp_port_d_present(spec))
1976 			pinctl = 0;
1977 	}
1978 	snd_hda_set_pin_ctl(codec, 0x1c, pinctl);
1979 
1980 	/* CLASS_D AMP */
1981 	pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1982 	snd_hda_set_pin_ctl(codec, 0x1f, pinctl);
1983 }
1984 
1985 /* turn on/off EAPD (+ mute HP) as a master switch */
1986 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1987 				    struct snd_ctl_elem_value *ucontrol)
1988 {
1989 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1990 
1991 	if (!cxt_eapd_put(kcontrol, ucontrol))
1992 		return 0;
1993 
1994 	cxt5066_update_speaker(codec);
1995 	return 1;
1996 }
1997 
1998 static const struct hda_input_mux cxt5066_olpc_dc_bias = {
1999 	.num_items = 3,
2000 	.items = {
2001 		{ "Off", PIN_IN },
2002 		{ "50%", PIN_VREF50 },
2003 		{ "80%", PIN_VREF80 },
2004 	},
2005 };
2006 
2007 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2008 {
2009 	struct conexant_spec *spec = codec->spec;
2010 	/* Even though port F is the DC input, the bias is controlled on port B.
2011 	 * we also leave that port as an active input (but unselected) in DC mode
2012 	 * just in case that is necessary to make the bias setting take effect. */
2013 	return snd_hda_set_pin_ctl_cache(codec, 0x1a,
2014 		cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2015 }
2016 
2017 /* OLPC defers mic widget control until when capture is started because the
2018  * microphone LED comes on as soon as these settings are put in place. if we
2019  * did this before recording, it would give the false indication that recording
2020  * is happening when it is not. */
2021 static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2022 {
2023 	struct conexant_spec *spec = codec->spec;
2024 	if (!spec->recording)
2025 		return;
2026 
2027 	if (spec->dc_enable) {
2028 		/* in DC mode we ignore presence detection and just use the jack
2029 		 * through our special DC port */
2030 		const struct hda_verb enable_dc_mode[] = {
2031 			/* disble internal mic, port C */
2032 			{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2033 
2034 			/* enable DC capture, port F */
2035 			{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2036 			{},
2037 		};
2038 
2039 		snd_hda_sequence_write(codec, enable_dc_mode);
2040 		/* port B input disabled (and bias set) through the following call */
2041 		cxt5066_set_olpc_dc_bias(codec);
2042 		return;
2043 	}
2044 
2045 	/* disable DC (port F) */
2046 	snd_hda_set_pin_ctl(codec, 0x1e, 0);
2047 
2048 	/* external mic, port B */
2049 	snd_hda_set_pin_ctl(codec, 0x1a,
2050 		spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2051 
2052 	/* internal mic, port C */
2053 	snd_hda_set_pin_ctl(codec, 0x1b,
2054 		spec->ext_mic_present ? 0 : PIN_VREF80);
2055 }
2056 
2057 /* toggle input of built-in and mic jack appropriately */
2058 static void cxt5066_olpc_automic(struct hda_codec *codec)
2059 {
2060 	struct conexant_spec *spec = codec->spec;
2061 	unsigned int present;
2062 
2063 	if (spec->dc_enable) /* don't do presence detection in DC mode */
2064 		return;
2065 
2066 	present = snd_hda_codec_read(codec, 0x1a, 0,
2067 				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2068 	if (present)
2069 		snd_printdd("CXT5066: external microphone detected\n");
2070 	else
2071 		snd_printdd("CXT5066: external microphone absent\n");
2072 
2073 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2074 		present ? 0 : 1);
2075 	spec->ext_mic_present = !!present;
2076 
2077 	cxt5066_olpc_select_mic(codec);
2078 }
2079 
2080 /* toggle input of built-in digital mic and mic jack appropriately */
2081 static void cxt5066_vostro_automic(struct hda_codec *codec)
2082 {
2083 	unsigned int present;
2084 
2085 	struct hda_verb ext_mic_present[] = {
2086 		/* enable external mic, port B */
2087 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2088 
2089 		/* switch to external mic input */
2090 		{0x17, AC_VERB_SET_CONNECT_SEL, 0},
2091 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2092 
2093 		/* disable internal digital mic */
2094 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2095 		{}
2096 	};
2097 	static const struct hda_verb ext_mic_absent[] = {
2098 		/* enable internal mic, port C */
2099 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2100 
2101 		/* switch to internal mic input */
2102 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2103 
2104 		/* disable external mic, port B */
2105 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2106 		{}
2107 	};
2108 
2109 	present = snd_hda_jack_detect(codec, 0x1a);
2110 	if (present) {
2111 		snd_printdd("CXT5066: external microphone detected\n");
2112 		snd_hda_sequence_write(codec, ext_mic_present);
2113 	} else {
2114 		snd_printdd("CXT5066: external microphone absent\n");
2115 		snd_hda_sequence_write(codec, ext_mic_absent);
2116 	}
2117 }
2118 
2119 /* toggle input of built-in digital mic and mic jack appropriately */
2120 static void cxt5066_ideapad_automic(struct hda_codec *codec)
2121 {
2122 	unsigned int present;
2123 
2124 	struct hda_verb ext_mic_present[] = {
2125 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2126 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2127 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2128 		{}
2129 	};
2130 	static const struct hda_verb ext_mic_absent[] = {
2131 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2132 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2133 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2134 		{}
2135 	};
2136 
2137 	present = snd_hda_jack_detect(codec, 0x1b);
2138 	if (present) {
2139 		snd_printdd("CXT5066: external microphone detected\n");
2140 		snd_hda_sequence_write(codec, ext_mic_present);
2141 	} else {
2142 		snd_printdd("CXT5066: external microphone absent\n");
2143 		snd_hda_sequence_write(codec, ext_mic_absent);
2144 	}
2145 }
2146 
2147 
2148 /* toggle input of built-in digital mic and mic jack appropriately */
2149 static void cxt5066_asus_automic(struct hda_codec *codec)
2150 {
2151 	unsigned int present;
2152 
2153 	present = snd_hda_jack_detect(codec, 0x1b);
2154 	snd_printdd("CXT5066: external microphone present=%d\n", present);
2155 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2156 			    present ? 1 : 0);
2157 }
2158 
2159 
2160 /* toggle input of built-in digital mic and mic jack appropriately */
2161 static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2162 {
2163 	unsigned int present;
2164 
2165 	present = snd_hda_jack_detect(codec, 0x1b);
2166 	snd_printdd("CXT5066: external microphone present=%d\n", present);
2167 	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2168 			    present ? 1 : 3);
2169 }
2170 
2171 
2172 /* toggle input of built-in digital mic and mic jack appropriately
2173    order is: external mic -> dock mic -> interal mic */
2174 static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2175 {
2176 	unsigned int ext_present, dock_present;
2177 
2178 	static const struct hda_verb ext_mic_present[] = {
2179 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2180 		{0x17, AC_VERB_SET_CONNECT_SEL, 1},
2181 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2182 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2183 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2184 		{}
2185 	};
2186 	static const struct hda_verb dock_mic_present[] = {
2187 		{0x14, AC_VERB_SET_CONNECT_SEL, 0},
2188 		{0x17, AC_VERB_SET_CONNECT_SEL, 0},
2189 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2190 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2191 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2192 		{}
2193 	};
2194 	static const struct hda_verb ext_mic_absent[] = {
2195 		{0x14, AC_VERB_SET_CONNECT_SEL, 2},
2196 		{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2198 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2199 		{}
2200 	};
2201 
2202 	ext_present = snd_hda_jack_detect(codec, 0x1b);
2203 	dock_present = snd_hda_jack_detect(codec, 0x1a);
2204 	if (ext_present) {
2205 		snd_printdd("CXT5066: external microphone detected\n");
2206 		snd_hda_sequence_write(codec, ext_mic_present);
2207 	} else if (dock_present) {
2208 		snd_printdd("CXT5066: dock microphone detected\n");
2209 		snd_hda_sequence_write(codec, dock_mic_present);
2210 	} else {
2211 		snd_printdd("CXT5066: external microphone absent\n");
2212 		snd_hda_sequence_write(codec, ext_mic_absent);
2213 	}
2214 }
2215 
2216 /* mute internal speaker if HP is plugged */
2217 static void cxt5066_hp_automute(struct hda_codec *codec)
2218 {
2219 	struct conexant_spec *spec = codec->spec;
2220 	unsigned int portA, portD;
2221 
2222 	/* Port A */
2223 	portA = snd_hda_jack_detect(codec, 0x19);
2224 
2225 	/* Port D */
2226 	portD = snd_hda_jack_detect(codec, 0x1c);
2227 
2228 	spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2229 	spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2230 	snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2231 		portA, portD, spec->hp_present);
2232 	cxt5066_update_speaker(codec);
2233 }
2234 
2235 /* Dispatch the right mic autoswitch function */
2236 static void cxt5066_automic(struct hda_codec *codec)
2237 {
2238 	struct conexant_spec *spec = codec->spec;
2239 
2240 	if (spec->dell_vostro)
2241 		cxt5066_vostro_automic(codec);
2242 	else if (spec->ideapad)
2243 		cxt5066_ideapad_automic(codec);
2244 	else if (spec->thinkpad)
2245 		cxt5066_thinkpad_automic(codec);
2246 	else if (spec->hp_laptop)
2247 		cxt5066_hp_laptop_automic(codec);
2248 	else if (spec->asus)
2249 		cxt5066_asus_automic(codec);
2250 }
2251 
2252 /* unsolicited event for jack sensing */
2253 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2254 {
2255 	struct conexant_spec *spec = codec->spec;
2256 	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2257 	switch (res >> 26) {
2258 	case CONEXANT_HP_EVENT:
2259 		cxt5066_hp_automute(codec);
2260 		break;
2261 	case CONEXANT_MIC_EVENT:
2262 		/* ignore mic events in DC mode; we're always using the jack */
2263 		if (!spec->dc_enable)
2264 			cxt5066_olpc_automic(codec);
2265 		break;
2266 	}
2267 }
2268 
2269 /* unsolicited event for jack sensing */
2270 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2271 {
2272 	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2273 	switch (res >> 26) {
2274 	case CONEXANT_HP_EVENT:
2275 		cxt5066_hp_automute(codec);
2276 		break;
2277 	case CONEXANT_MIC_EVENT:
2278 		cxt5066_automic(codec);
2279 		break;
2280 	}
2281 }
2282 
2283 
2284 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2285 	.num_items = 5,
2286 	.items = {
2287 		{ "0dB",  0 },
2288 		{ "10dB", 1 },
2289 		{ "20dB", 2 },
2290 		{ "30dB", 3 },
2291 		{ "40dB", 4 },
2292 	},
2293 };
2294 
2295 static void cxt5066_set_mic_boost(struct hda_codec *codec)
2296 {
2297 	struct conexant_spec *spec = codec->spec;
2298 	snd_hda_codec_write_cache(codec, 0x17, 0,
2299 		AC_VERB_SET_AMP_GAIN_MUTE,
2300 		AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2301 			cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2302 	if (spec->ideapad || spec->thinkpad) {
2303 		/* adjust the internal mic as well...it is not through 0x17 */
2304 		snd_hda_codec_write_cache(codec, 0x23, 0,
2305 			AC_VERB_SET_AMP_GAIN_MUTE,
2306 			AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2307 				cxt5066_analog_mic_boost.
2308 					items[spec->mic_boost].index);
2309 	}
2310 }
2311 
2312 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2313 					   struct snd_ctl_elem_info *uinfo)
2314 {
2315 	return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2316 }
2317 
2318 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2319 					  struct snd_ctl_elem_value *ucontrol)
2320 {
2321 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2322 	struct conexant_spec *spec = codec->spec;
2323 	ucontrol->value.enumerated.item[0] = spec->mic_boost;
2324 	return 0;
2325 }
2326 
2327 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2328 					  struct snd_ctl_elem_value *ucontrol)
2329 {
2330 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2331 	struct conexant_spec *spec = codec->spec;
2332 	const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2333 	unsigned int idx;
2334 	idx = ucontrol->value.enumerated.item[0];
2335 	if (idx >= imux->num_items)
2336 		idx = imux->num_items - 1;
2337 
2338 	spec->mic_boost = idx;
2339 	if (!spec->dc_enable)
2340 		cxt5066_set_mic_boost(codec);
2341 	return 1;
2342 }
2343 
2344 static void cxt5066_enable_dc(struct hda_codec *codec)
2345 {
2346 	const struct hda_verb enable_dc_mode[] = {
2347 		/* disable gain */
2348 		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2349 
2350 		/* switch to DC input */
2351 		{0x17, AC_VERB_SET_CONNECT_SEL, 3},
2352 		{}
2353 	};
2354 
2355 	/* configure as input source */
2356 	snd_hda_sequence_write(codec, enable_dc_mode);
2357 	cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2358 }
2359 
2360 static void cxt5066_disable_dc(struct hda_codec *codec)
2361 {
2362 	/* reconfigure input source */
2363 	cxt5066_set_mic_boost(codec);
2364 	/* automic also selects the right mic if we're recording */
2365 	cxt5066_olpc_automic(codec);
2366 }
2367 
2368 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2369 			     struct snd_ctl_elem_value *ucontrol)
2370 {
2371 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2372 	struct conexant_spec *spec = codec->spec;
2373 	ucontrol->value.integer.value[0] = spec->dc_enable;
2374 	return 0;
2375 }
2376 
2377 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2378 			     struct snd_ctl_elem_value *ucontrol)
2379 {
2380 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2381 	struct conexant_spec *spec = codec->spec;
2382 	int dc_enable = !!ucontrol->value.integer.value[0];
2383 
2384 	if (dc_enable == spec->dc_enable)
2385 		return 0;
2386 
2387 	spec->dc_enable = dc_enable;
2388 	if (dc_enable)
2389 		cxt5066_enable_dc(codec);
2390 	else
2391 		cxt5066_disable_dc(codec);
2392 
2393 	return 1;
2394 }
2395 
2396 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2397 					   struct snd_ctl_elem_info *uinfo)
2398 {
2399 	return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2400 }
2401 
2402 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2403 					  struct snd_ctl_elem_value *ucontrol)
2404 {
2405 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2406 	struct conexant_spec *spec = codec->spec;
2407 	ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2408 	return 0;
2409 }
2410 
2411 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2412 					  struct snd_ctl_elem_value *ucontrol)
2413 {
2414 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2415 	struct conexant_spec *spec = codec->spec;
2416 	const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2417 	unsigned int idx;
2418 
2419 	idx = ucontrol->value.enumerated.item[0];
2420 	if (idx >= imux->num_items)
2421 		idx = imux->num_items - 1;
2422 
2423 	spec->dc_input_bias = idx;
2424 	if (spec->dc_enable)
2425 		cxt5066_set_olpc_dc_bias(codec);
2426 	return 1;
2427 }
2428 
2429 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2430 {
2431 	struct conexant_spec *spec = codec->spec;
2432 	/* mark as recording and configure the microphone widget so that the
2433 	 * recording LED comes on. */
2434 	spec->recording = 1;
2435 	cxt5066_olpc_select_mic(codec);
2436 }
2437 
2438 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2439 {
2440 	struct conexant_spec *spec = codec->spec;
2441 	const struct hda_verb disable_mics[] = {
2442 		/* disable external mic, port B */
2443 		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2444 
2445 		/* disble internal mic, port C */
2446 		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2447 
2448 		/* disable DC capture, port F */
2449 		{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2450 		{},
2451 	};
2452 
2453 	snd_hda_sequence_write(codec, disable_mics);
2454 	spec->recording = 0;
2455 }
2456 
2457 static void conexant_check_dig_outs(struct hda_codec *codec,
2458 				    const hda_nid_t *dig_pins,
2459 				    int num_pins)
2460 {
2461 	struct conexant_spec *spec = codec->spec;
2462 	hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2463 	int i;
2464 
2465 	for (i = 0; i < num_pins; i++, dig_pins++) {
2466 		unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2467 		if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2468 			continue;
2469 		if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2470 			continue;
2471 	}
2472 }
2473 
2474 static const struct hda_input_mux cxt5066_capture_source = {
2475 	.num_items = 4,
2476 	.items = {
2477 		{ "Mic B", 0 },
2478 		{ "Mic C", 1 },
2479 		{ "Mic E", 2 },
2480 		{ "Mic F", 3 },
2481 	},
2482 };
2483 
2484 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2485 	.ops = &snd_hda_bind_vol,
2486 	.values = {
2487 		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2488 		HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2489 		0
2490 	},
2491 };
2492 
2493 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2494 	.ops = &snd_hda_bind_sw,
2495 	.values = {
2496 		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2497 		HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2498 		0
2499 	},
2500 };
2501 
2502 static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2503 	HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2504 	{}
2505 };
2506 
2507 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2508 	{
2509 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2510 		.name = "Master Playback Volume",
2511 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2512 				  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2513 				  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2514 		.subdevice = HDA_SUBDEV_AMP_FLAG,
2515 		.info = snd_hda_mixer_amp_volume_info,
2516 		.get = snd_hda_mixer_amp_volume_get,
2517 		.put = snd_hda_mixer_amp_volume_put,
2518 		.tlv = { .c = snd_hda_mixer_amp_tlv },
2519 		/* offset by 28 volume steps to limit minimum gain to -46dB */
2520 		.private_value =
2521 			HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2522 	},
2523 	{}
2524 };
2525 
2526 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2527 	{
2528 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2529 		.name = "DC Mode Enable Switch",
2530 		.info = snd_ctl_boolean_mono_info,
2531 		.get = cxt5066_olpc_dc_get,
2532 		.put = cxt5066_olpc_dc_put,
2533 	},
2534 	{
2535 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2536 		.name = "DC Input Bias Enum",
2537 		.info = cxt5066_olpc_dc_bias_enum_info,
2538 		.get = cxt5066_olpc_dc_bias_enum_get,
2539 		.put = cxt5066_olpc_dc_bias_enum_put,
2540 	},
2541 	{}
2542 };
2543 
2544 static const struct snd_kcontrol_new cxt5066_mixers[] = {
2545 	{
2546 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2547 		.name = "Master Playback Switch",
2548 		.info = cxt_eapd_info,
2549 		.get = cxt_eapd_get,
2550 		.put = cxt5066_hp_master_sw_put,
2551 		.private_value = 0x1d,
2552 	},
2553 
2554 	{
2555 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2556 		.name = "Analog Mic Boost Capture Enum",
2557 		.info = cxt5066_mic_boost_mux_enum_info,
2558 		.get = cxt5066_mic_boost_mux_enum_get,
2559 		.put = cxt5066_mic_boost_mux_enum_put,
2560 	},
2561 
2562 	HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2563 	HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2564 	{}
2565 };
2566 
2567 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2568 	{
2569 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2570 		.name = "Internal Mic Boost Capture Enum",
2571 		.info = cxt5066_mic_boost_mux_enum_info,
2572 		.get = cxt5066_mic_boost_mux_enum_get,
2573 		.put = cxt5066_mic_boost_mux_enum_put,
2574 		.private_value = 0x23 | 0x100,
2575 	},
2576 	{}
2577 };
2578 
2579 static const struct hda_verb cxt5066_init_verbs[] = {
2580 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2581 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2582 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2583 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2584 
2585 	/* Speakers  */
2586 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2587 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2588 
2589 	/* HP, Amp  */
2590 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2591 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2592 
2593 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2594 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2595 
2596 	/* DAC1 */
2597 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2598 
2599 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2600 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2601 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2602 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2603 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2604 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2605 
2606 	/* no digital microphone support yet */
2607 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2608 
2609 	/* Audio input selector */
2610 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2611 
2612 	/* SPDIF route: PCM */
2613 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2614 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2615 
2616 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2617 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2618 
2619 	/* EAPD */
2620 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2621 
2622 	/* not handling these yet */
2623 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2624 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2625 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2626 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2627 	{0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2628 	{0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2629 	{0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2630 	{0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2631 	{ } /* end */
2632 };
2633 
2634 static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2635 	/* Port A: headphones */
2636 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2637 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2638 
2639 	/* Port B: external microphone */
2640 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2641 
2642 	/* Port C: internal microphone */
2643 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2644 
2645 	/* Port D: unused */
2646 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2647 
2648 	/* Port E: unused, but has primary EAPD */
2649 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2650 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2651 
2652 	/* Port F: external DC input through microphone port */
2653 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2654 
2655 	/* Port G: internal speakers */
2656 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2657 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2658 
2659 	/* DAC1 */
2660 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2661 
2662 	/* DAC2: unused */
2663 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2664 
2665 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2666 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2667 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2668 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2669 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2670 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2671 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2672 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2673 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2674 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2675 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2676 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2677 
2678 	/* Disable digital microphone port */
2679 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2680 
2681 	/* Audio input selectors */
2682 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2683 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2684 
2685 	/* Disable SPDIF */
2686 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2687 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2688 
2689 	/* enable unsolicited events for Port A and B */
2690 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2691 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2692 	{ } /* end */
2693 };
2694 
2695 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2696 	/* Port A: headphones */
2697 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2698 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2699 
2700 	/* Port B: external microphone */
2701 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2702 
2703 	/* Port C: unused */
2704 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2705 
2706 	/* Port D: unused */
2707 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2708 
2709 	/* Port E: unused, but has primary EAPD */
2710 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2711 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2712 
2713 	/* Port F: unused */
2714 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2715 
2716 	/* Port G: internal speakers */
2717 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2718 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2719 
2720 	/* DAC1 */
2721 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2722 
2723 	/* DAC2: unused */
2724 	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2725 
2726 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2727 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2728 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2729 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2730 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2731 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2732 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2733 	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2734 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2735 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2736 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2737 	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2738 
2739 	/* Digital microphone port */
2740 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2741 
2742 	/* Audio input selectors */
2743 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2744 	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2745 
2746 	/* Disable SPDIF */
2747 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2748 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2749 
2750 	/* enable unsolicited events for Port A and B */
2751 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2752 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2753 	{ } /* end */
2754 };
2755 
2756 static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2757 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2758 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2759 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2760 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2761 
2762 	/* Speakers  */
2763 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2764 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2765 
2766 	/* HP, Amp  */
2767 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2768 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2769 
2770 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2771 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2772 
2773 	/* DAC1 */
2774 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2775 
2776 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2777 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2778 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2779 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2780 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2781 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2782 	{0x14, AC_VERB_SET_CONNECT_SEL, 2},	/* default to internal mic */
2783 
2784 	/* Audio input selector */
2785 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2786 	{0x17, AC_VERB_SET_CONNECT_SEL, 1},	/* route ext mic */
2787 
2788 	/* SPDIF route: PCM */
2789 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2790 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2791 
2792 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2793 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2794 
2795 	/* internal microphone */
2796 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2797 
2798 	/* EAPD */
2799 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2800 
2801 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2802 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2803 	{ } /* end */
2804 };
2805 
2806 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2807 	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2808 	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2809 
2810 	/* Port G: internal speakers  */
2811 	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812 	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2813 
2814 	/* Port A: HP, Amp  */
2815 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2816 	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2817 
2818 	/* Port B: Mic Dock */
2819 	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2820 
2821 	/* Port C: Mic */
2822 	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2823 
2824 	/* Port D: HP Dock, Amp */
2825 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2826 	{0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2827 
2828 	/* DAC1 */
2829 	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2830 
2831 	/* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2832 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2833 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2834 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2835 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2836 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2837 	{0x14, AC_VERB_SET_CONNECT_SEL, 2},	/* default to internal mic */
2838 
2839 	/* Audio input selector */
2840 	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2841 	{0x17, AC_VERB_SET_CONNECT_SEL, 1},	/* route ext mic */
2842 
2843 	/* SPDIF route: PCM */
2844 	{0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2845 	{0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2846 
2847 	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2848 	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2849 
2850 	/* internal microphone */
2851 	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2852 
2853 	/* EAPD */
2854 	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2855 
2856 	/* enable unsolicited events for Port A, B, C and D */
2857 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2858 	{0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2859 	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2860 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2861 	{ } /* end */
2862 };
2863 
2864 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2865 	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2866 	{ } /* end */
2867 };
2868 
2869 
2870 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2871 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2872 	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2873 	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2874 	{ } /* end */
2875 };
2876 
2877 /* initialize jack-sensing, too */
2878 static int cxt5066_init(struct hda_codec *codec)
2879 {
2880 	snd_printdd("CXT5066: init\n");
2881 	conexant_init(codec);
2882 	if (codec->patch_ops.unsol_event) {
2883 		cxt5066_hp_automute(codec);
2884 		cxt5066_automic(codec);
2885 	}
2886 	cxt5066_set_mic_boost(codec);
2887 	return 0;
2888 }
2889 
2890 static int cxt5066_olpc_init(struct hda_codec *codec)
2891 {
2892 	struct conexant_spec *spec = codec->spec;
2893 	snd_printdd("CXT5066: init\n");
2894 	conexant_init(codec);
2895 	cxt5066_hp_automute(codec);
2896 	if (!spec->dc_enable) {
2897 		cxt5066_set_mic_boost(codec);
2898 		cxt5066_olpc_automic(codec);
2899 	} else {
2900 		cxt5066_enable_dc(codec);
2901 	}
2902 	return 0;
2903 }
2904 
2905 enum {
2906 	CXT5066_LAPTOP,		/* Laptops w/ EAPD support */
2907 	CXT5066_DELL_LAPTOP,	/* Dell Laptop */
2908 	CXT5066_OLPC_XO_1_5,	/* OLPC XO 1.5 */
2909 	CXT5066_DELL_VOSTRO,	/* Dell Vostro 1015i */
2910 	CXT5066_IDEAPAD,	/* Lenovo IdeaPad U150 */
2911 	CXT5066_THINKPAD,	/* Lenovo ThinkPad T410s, others? */
2912 	CXT5066_ASUS,		/* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
2913 	CXT5066_HP_LAPTOP,      /* HP Laptop */
2914 	CXT5066_AUTO,		/* BIOS auto-parser */
2915 	CXT5066_MODELS
2916 };
2917 
2918 static const char * const cxt5066_models[CXT5066_MODELS] = {
2919 	[CXT5066_LAPTOP]	= "laptop",
2920 	[CXT5066_DELL_LAPTOP]	= "dell-laptop",
2921 	[CXT5066_OLPC_XO_1_5]	= "olpc-xo-1_5",
2922 	[CXT5066_DELL_VOSTRO]	= "dell-vostro",
2923 	[CXT5066_IDEAPAD]	= "ideapad",
2924 	[CXT5066_THINKPAD]	= "thinkpad",
2925 	[CXT5066_ASUS]		= "asus",
2926 	[CXT5066_HP_LAPTOP]	= "hp-laptop",
2927 	[CXT5066_AUTO]		= "auto",
2928 };
2929 
2930 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2931 	SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
2932 	SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
2933 	SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
2934 	SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
2935 	SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
2936 	SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
2937 	SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
2938 	SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
2939 	SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
2940 	SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
2941 	SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
2942 	SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
2943 	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
2944 	SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2945 		      CXT5066_LAPTOP),
2946 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2947 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
2948 	SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
2949 	SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
2950 	SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
2951 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
2952 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
2953 	{}
2954 };
2955 
2956 static int patch_cxt5066(struct hda_codec *codec)
2957 {
2958 	struct conexant_spec *spec;
2959 	int board_config;
2960 
2961 	board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2962 						  cxt5066_models, cxt5066_cfg_tbl);
2963 	if (board_config < 0)
2964 		board_config = CXT5066_AUTO; /* model=auto as default */
2965 	if (board_config == CXT5066_AUTO)
2966 		return patch_conexant_auto(codec);
2967 
2968 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2969 	if (!spec)
2970 		return -ENOMEM;
2971 	codec->spec = spec;
2972 
2973 	codec->patch_ops = conexant_patch_ops;
2974 	codec->patch_ops.init = conexant_init;
2975 
2976 	spec->dell_automute = 0;
2977 	spec->multiout.max_channels = 2;
2978 	spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2979 	spec->multiout.dac_nids = cxt5066_dac_nids;
2980 	conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
2981 	    ARRAY_SIZE(cxt5066_digout_pin_nids));
2982 	spec->num_adc_nids = 1;
2983 	spec->adc_nids = cxt5066_adc_nids;
2984 	spec->capsrc_nids = cxt5066_capsrc_nids;
2985 	spec->input_mux = &cxt5066_capture_source;
2986 
2987 	spec->port_d_mode = PIN_HP;
2988 
2989 	spec->num_init_verbs = 1;
2990 	spec->init_verbs[0] = cxt5066_init_verbs;
2991 	spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2992 	spec->channel_mode = cxt5066_modes;
2993 	spec->cur_adc = 0;
2994 	spec->cur_adc_idx = 0;
2995 
2996 	set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
2997 
2998 	switch (board_config) {
2999 	default:
3000 	case CXT5066_LAPTOP:
3001 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3002 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3003 		break;
3004 	case CXT5066_DELL_LAPTOP:
3005 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3006 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3007 
3008 		spec->port_d_mode = PIN_OUT;
3009 		spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
3010 		spec->num_init_verbs++;
3011 		spec->dell_automute = 1;
3012 		break;
3013 	case CXT5066_ASUS:
3014 	case CXT5066_HP_LAPTOP:
3015 		codec->patch_ops.init = cxt5066_init;
3016 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3017 		spec->init_verbs[spec->num_init_verbs] =
3018 			cxt5066_init_verbs_hp_laptop;
3019 		spec->num_init_verbs++;
3020 		spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3021 		spec->asus = board_config == CXT5066_ASUS;
3022 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3023 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3024 		/* no S/PDIF out */
3025 		if (board_config == CXT5066_HP_LAPTOP)
3026 			spec->multiout.dig_out_nid = 0;
3027 		/* input source automatically selected */
3028 		spec->input_mux = NULL;
3029 		spec->port_d_mode = 0;
3030 		spec->mic_boost = 3; /* default 30dB gain */
3031 		break;
3032 
3033 	case CXT5066_OLPC_XO_1_5:
3034 		codec->patch_ops.init = cxt5066_olpc_init;
3035 		codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
3036 		spec->init_verbs[0] = cxt5066_init_verbs_olpc;
3037 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3038 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
3039 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3040 		spec->port_d_mode = 0;
3041 		spec->mic_boost = 3; /* default 30dB gain */
3042 
3043 		/* no S/PDIF out */
3044 		spec->multiout.dig_out_nid = 0;
3045 
3046 		/* input source automatically selected */
3047 		spec->input_mux = NULL;
3048 
3049 		/* our capture hooks which allow us to turn on the microphone LED
3050 		 * at the right time */
3051 		spec->capture_prepare = cxt5066_olpc_capture_prepare;
3052 		spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3053 		break;
3054 	case CXT5066_DELL_VOSTRO:
3055 		codec->patch_ops.init = cxt5066_init;
3056 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3057 		spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3058 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3059 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3060 		spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
3061 		spec->port_d_mode = 0;
3062 		spec->dell_vostro = 1;
3063 		spec->mic_boost = 3; /* default 30dB gain */
3064 
3065 		/* no S/PDIF out */
3066 		spec->multiout.dig_out_nid = 0;
3067 
3068 		/* input source automatically selected */
3069 		spec->input_mux = NULL;
3070 		break;
3071 	case CXT5066_IDEAPAD:
3072 		codec->patch_ops.init = cxt5066_init;
3073 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3074 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3075 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3076 		spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
3077 		spec->port_d_mode = 0;
3078 		spec->ideapad = 1;
3079 		spec->mic_boost = 2;	/* default 20dB gain */
3080 
3081 		/* no S/PDIF out */
3082 		spec->multiout.dig_out_nid = 0;
3083 
3084 		/* input source automatically selected */
3085 		spec->input_mux = NULL;
3086 		break;
3087 	case CXT5066_THINKPAD:
3088 		codec->patch_ops.init = cxt5066_init;
3089 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
3090 		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3091 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3092 		spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3093 		spec->thinkpad = 1;
3094 		spec->port_d_mode = PIN_OUT;
3095 		spec->mic_boost = 2;	/* default 20dB gain */
3096 
3097 		/* no S/PDIF out */
3098 		spec->multiout.dig_out_nid = 0;
3099 
3100 		/* input source automatically selected */
3101 		spec->input_mux = NULL;
3102 		break;
3103 	}
3104 
3105 	if (spec->beep_amp)
3106 		snd_hda_attach_beep_device(codec, get_amp_nid_(spec->beep_amp));
3107 
3108 	return 0;
3109 }
3110 
3111 #endif /* ENABLE_CXT_STATIC_QUIRKS */
3112 
3113 
3114 /*
3115  * Automatic parser for CX20641 & co
3116  */
3117 
3118 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3119 static void cx_auto_parse_beep(struct hda_codec *codec)
3120 {
3121 	struct conexant_spec *spec = codec->spec;
3122 	hda_nid_t nid, end_nid;
3123 
3124 	end_nid = codec->start_nid + codec->num_nodes;
3125 	for (nid = codec->start_nid; nid < end_nid; nid++)
3126 		if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
3127 			set_beep_amp(spec, nid, 0, HDA_OUTPUT);
3128 			break;
3129 		}
3130 }
3131 #else
3132 #define cx_auto_parse_beep(codec)
3133 #endif
3134 
3135 /* parse EAPDs */
3136 static void cx_auto_parse_eapd(struct hda_codec *codec)
3137 {
3138 	struct conexant_spec *spec = codec->spec;
3139 	hda_nid_t nid, end_nid;
3140 
3141 	end_nid = codec->start_nid + codec->num_nodes;
3142 	for (nid = codec->start_nid; nid < end_nid; nid++) {
3143 		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3144 			continue;
3145 		if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3146 			continue;
3147 		spec->eapds[spec->num_eapds++] = nid;
3148 		if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3149 			break;
3150 	}
3151 
3152 	/* NOTE: below is a wild guess; if we have more than two EAPDs,
3153 	 * it's a new chip, where EAPDs are supposed to be associated to
3154 	 * pins, and we can control EAPD per pin.
3155 	 * OTOH, if only one or two EAPDs are found, it's an old chip,
3156 	 * thus it might control over all pins.
3157 	 */
3158 	if (spec->num_eapds > 2)
3159 		spec->dynamic_eapd = 1;
3160 }
3161 
3162 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3163 			      hda_nid_t *pins, bool on)
3164 {
3165 	int i;
3166 	for (i = 0; i < num_pins; i++) {
3167 		if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3168 			snd_hda_codec_write(codec, pins[i], 0,
3169 					    AC_VERB_SET_EAPD_BTLENABLE,
3170 					    on ? 0x02 : 0);
3171 	}
3172 }
3173 
3174 /* turn on/off EAPD according to Master switch */
3175 static void cx_auto_vmaster_hook(void *private_data, int enabled)
3176 {
3177 	struct hda_codec *codec = private_data;
3178 	struct conexant_spec *spec = codec->spec;
3179 
3180 	cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
3181 }
3182 
3183 static int cx_auto_build_controls(struct hda_codec *codec)
3184 {
3185 	int err;
3186 
3187 	err = snd_hda_gen_build_controls(codec);
3188 	if (err < 0)
3189 		return err;
3190 
3191 	err = add_beep_ctls(codec);
3192 	if (err < 0)
3193 		return err;
3194 
3195 	return 0;
3196 }
3197 
3198 static int cx_auto_init(struct hda_codec *codec)
3199 {
3200 	struct conexant_spec *spec = codec->spec;
3201 	snd_hda_gen_init(codec);
3202 	if (!spec->dynamic_eapd)
3203 		cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
3204 	return 0;
3205 }
3206 
3207 static const struct hda_codec_ops cx_auto_patch_ops = {
3208 	.build_controls = cx_auto_build_controls,
3209 	.build_pcms = snd_hda_gen_build_pcms,
3210 	.init = cx_auto_init,
3211 	.free = snd_hda_gen_free,
3212 	.unsol_event = snd_hda_jack_unsol_event,
3213 #ifdef CONFIG_PM
3214 	.check_power_status = snd_hda_gen_check_power_status,
3215 #endif
3216 };
3217 
3218 /*
3219  * pin fix-up
3220  */
3221 enum {
3222 	CXT_PINCFG_LENOVO_X200,
3223 	CXT_PINCFG_LENOVO_TP410,
3224 	CXT_PINCFG_LEMOTE_A1004,
3225 	CXT_PINCFG_LEMOTE_A1205,
3226 	CXT_FIXUP_STEREO_DMIC,
3227 	CXT_FIXUP_INC_MIC_BOOST,
3228 };
3229 
3230 static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
3231 				  const struct hda_fixup *fix, int action)
3232 {
3233 	struct conexant_spec *spec = codec->spec;
3234 	spec->gen.inv_dmic_split = 1;
3235 }
3236 
3237 static void cxt5066_increase_mic_boost(struct hda_codec *codec,
3238 				   const struct hda_fixup *fix, int action)
3239 {
3240 	if (action != HDA_FIXUP_ACT_PRE_PROBE)
3241 		return;
3242 
3243 	snd_hda_override_amp_caps(codec, 0x17, HDA_OUTPUT,
3244 				  (0x3 << AC_AMPCAP_OFFSET_SHIFT) |
3245 				  (0x4 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3246 				  (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3247 				  (0 << AC_AMPCAP_MUTE_SHIFT));
3248 }
3249 
3250 /* ThinkPad X200 & co with cxt5051 */
3251 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
3252 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
3253 	{ 0x17, 0x21a11000 }, /* dock-mic */
3254 	{ 0x19, 0x2121103f }, /* dock-HP */
3255 	{ 0x1c, 0x21440100 }, /* dock SPDIF out */
3256 	{}
3257 };
3258 
3259 /* ThinkPad 410/420/510/520, X201 & co with cxt5066 */
3260 static const struct hda_pintbl cxt_pincfg_lenovo_tp410[] = {
3261 	{ 0x19, 0x042110ff }, /* HP (seq# overridden) */
3262 	{ 0x1a, 0x21a190f0 }, /* dock-mic */
3263 	{ 0x1c, 0x212140ff }, /* dock-HP */
3264 	{}
3265 };
3266 
3267 /* Lemote A1004/A1205 with cxt5066 */
3268 static const struct hda_pintbl cxt_pincfg_lemote[] = {
3269 	{ 0x1a, 0x90a10020 }, /* Internal mic */
3270 	{ 0x1b, 0x03a11020 }, /* External mic */
3271 	{ 0x1d, 0x400101f0 }, /* Not used */
3272 	{ 0x1e, 0x40a701f0 }, /* Not used */
3273 	{ 0x20, 0x404501f0 }, /* Not used */
3274 	{ 0x22, 0x404401f0 }, /* Not used */
3275 	{ 0x23, 0x40a701f0 }, /* Not used */
3276 	{}
3277 };
3278 
3279 static const struct hda_fixup cxt_fixups[] = {
3280 	[CXT_PINCFG_LENOVO_X200] = {
3281 		.type = HDA_FIXUP_PINS,
3282 		.v.pins = cxt_pincfg_lenovo_x200,
3283 	},
3284 	[CXT_PINCFG_LENOVO_TP410] = {
3285 		.type = HDA_FIXUP_PINS,
3286 		.v.pins = cxt_pincfg_lenovo_tp410,
3287 	},
3288 	[CXT_PINCFG_LEMOTE_A1004] = {
3289 		.type = HDA_FIXUP_PINS,
3290 		.chained = true,
3291 		.chain_id = CXT_FIXUP_INC_MIC_BOOST,
3292 		.v.pins = cxt_pincfg_lemote,
3293 	},
3294 	[CXT_PINCFG_LEMOTE_A1205] = {
3295 		.type = HDA_FIXUP_PINS,
3296 		.v.pins = cxt_pincfg_lemote,
3297 	},
3298 	[CXT_FIXUP_STEREO_DMIC] = {
3299 		.type = HDA_FIXUP_FUNC,
3300 		.v.func = cxt_fixup_stereo_dmic,
3301 	},
3302 	[CXT_FIXUP_INC_MIC_BOOST] = {
3303 		.type = HDA_FIXUP_FUNC,
3304 		.v.func = cxt5066_increase_mic_boost,
3305 	},
3306 };
3307 
3308 static const struct snd_pci_quirk cxt5051_fixups[] = {
3309 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
3310 	{}
3311 };
3312 
3313 static const struct snd_pci_quirk cxt5066_fixups[] = {
3314 	SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
3315 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
3316 	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
3317 	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
3318 	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
3319 	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
3320 	SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
3321 	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
3322 	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
3323 	SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
3324 	SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
3325 	SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
3326 	{}
3327 };
3328 
3329 /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
3330  * can be created (bko#42825)
3331  */
3332 static void add_cx5051_fake_mutes(struct hda_codec *codec)
3333 {
3334 	static hda_nid_t out_nids[] = {
3335 		0x10, 0x11, 0
3336 	};
3337 	hda_nid_t *p;
3338 
3339 	for (p = out_nids; *p; p++)
3340 		snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
3341 					  AC_AMPCAP_MIN_MUTE |
3342 					  query_amp_caps(codec, *p, HDA_OUTPUT));
3343 }
3344 
3345 static int patch_conexant_auto(struct hda_codec *codec)
3346 {
3347 	struct conexant_spec *spec;
3348 	int err;
3349 
3350 	printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3351 	       codec->chip_name);
3352 
3353 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3354 	if (!spec)
3355 		return -ENOMEM;
3356 	snd_hda_gen_spec_init(&spec->gen);
3357 	codec->spec = spec;
3358 
3359 	cx_auto_parse_beep(codec);
3360 	cx_auto_parse_eapd(codec);
3361 	spec->gen.own_eapd_ctl = 1;
3362 	if (spec->dynamic_eapd)
3363 		spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook;
3364 
3365 	switch (codec->vendor_id) {
3366 	case 0x14f15045:
3367 		codec->single_adc_amp = 1;
3368 		break;
3369 	case 0x14f15047:
3370 		codec->pin_amp_workaround = 1;
3371 		spec->gen.mixer_nid = 0x19;
3372 		break;
3373 	case 0x14f15051:
3374 		add_cx5051_fake_mutes(codec);
3375 		codec->pin_amp_workaround = 1;
3376 		snd_hda_pick_fixup(codec, NULL, cxt5051_fixups, cxt_fixups);
3377 		break;
3378 	default:
3379 		codec->pin_amp_workaround = 1;
3380 		snd_hda_pick_fixup(codec, NULL, cxt5066_fixups, cxt_fixups);
3381 		break;
3382 	}
3383 
3384 	/* Show mute-led control only on HP laptops
3385 	 * This is a sort of white-list: on HP laptops, EAPD corresponds
3386 	 * only to the mute-LED without actualy amp function.  Meanwhile,
3387 	 * others may use EAPD really as an amp switch, so it might be
3388 	 * not good to expose it blindly.
3389 	 */
3390 	switch (codec->subsystem_id >> 16) {
3391 	case 0x103c:
3392 		spec->gen.vmaster_mute_enum = 1;
3393 		break;
3394 	}
3395 
3396 	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3397 
3398 	err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
3399 	if (err < 0)
3400 		goto error;
3401 
3402 	err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
3403 	if (err < 0)
3404 		goto error;
3405 
3406 	codec->patch_ops = cx_auto_patch_ops;
3407 
3408 	/* Some laptops with Conexant chips show stalls in S3 resume,
3409 	 * which falls into the single-cmd mode.
3410 	 * Better to make reset, then.
3411 	 */
3412 	if (!codec->bus->sync_write) {
3413 		snd_printd("hda_codec: "
3414 			   "Enable sync_write for stable communication\n");
3415 		codec->bus->sync_write = 1;
3416 		codec->bus->allow_bus_reset = 1;
3417 	}
3418 
3419 	return 0;
3420 
3421  error:
3422 	snd_hda_gen_free(codec);
3423 	return err;
3424 }
3425 
3426 #ifndef ENABLE_CXT_STATIC_QUIRKS
3427 #define patch_cxt5045	patch_conexant_auto
3428 #define patch_cxt5047	patch_conexant_auto
3429 #define patch_cxt5051	patch_conexant_auto
3430 #define patch_cxt5066	patch_conexant_auto
3431 #endif
3432 
3433 /*
3434  */
3435 
3436 static const struct hda_codec_preset snd_hda_preset_conexant[] = {
3437 	{ .id = 0x14f15045, .name = "CX20549 (Venice)",
3438 	  .patch = patch_cxt5045 },
3439 	{ .id = 0x14f15047, .name = "CX20551 (Waikiki)",
3440 	  .patch = patch_cxt5047 },
3441 	{ .id = 0x14f15051, .name = "CX20561 (Hermosa)",
3442 	  .patch = patch_cxt5051 },
3443 	{ .id = 0x14f15066, .name = "CX20582 (Pebble)",
3444 	  .patch = patch_cxt5066 },
3445 	{ .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
3446 	  .patch = patch_cxt5066 },
3447 	{ .id = 0x14f15068, .name = "CX20584",
3448 	  .patch = patch_cxt5066 },
3449 	{ .id = 0x14f15069, .name = "CX20585",
3450 	  .patch = patch_cxt5066 },
3451 	{ .id = 0x14f1506c, .name = "CX20588",
3452 	  .patch = patch_cxt5066 },
3453 	{ .id = 0x14f1506e, .name = "CX20590",
3454 	  .patch = patch_cxt5066 },
3455 	{ .id = 0x14f15097, .name = "CX20631",
3456 	  .patch = patch_conexant_auto },
3457 	{ .id = 0x14f15098, .name = "CX20632",
3458 	  .patch = patch_conexant_auto },
3459 	{ .id = 0x14f150a1, .name = "CX20641",
3460 	  .patch = patch_conexant_auto },
3461 	{ .id = 0x14f150a2, .name = "CX20642",
3462 	  .patch = patch_conexant_auto },
3463 	{ .id = 0x14f150ab, .name = "CX20651",
3464 	  .patch = patch_conexant_auto },
3465 	{ .id = 0x14f150ac, .name = "CX20652",
3466 	  .patch = patch_conexant_auto },
3467 	{ .id = 0x14f150b8, .name = "CX20664",
3468 	  .patch = patch_conexant_auto },
3469 	{ .id = 0x14f150b9, .name = "CX20665",
3470 	  .patch = patch_conexant_auto },
3471 	{ .id = 0x14f1510f, .name = "CX20751/2",
3472 	  .patch = patch_conexant_auto },
3473 	{ .id = 0x14f15110, .name = "CX20751/2",
3474 	  .patch = patch_conexant_auto },
3475 	{ .id = 0x14f15111, .name = "CX20753/4",
3476 	  .patch = patch_conexant_auto },
3477 	{ .id = 0x14f15113, .name = "CX20755",
3478 	  .patch = patch_conexant_auto },
3479 	{ .id = 0x14f15114, .name = "CX20756",
3480 	  .patch = patch_conexant_auto },
3481 	{ .id = 0x14f15115, .name = "CX20757",
3482 	  .patch = patch_conexant_auto },
3483 	{} /* terminator */
3484 };
3485 
3486 MODULE_ALIAS("snd-hda-codec-id:14f15045");
3487 MODULE_ALIAS("snd-hda-codec-id:14f15047");
3488 MODULE_ALIAS("snd-hda-codec-id:14f15051");
3489 MODULE_ALIAS("snd-hda-codec-id:14f15066");
3490 MODULE_ALIAS("snd-hda-codec-id:14f15067");
3491 MODULE_ALIAS("snd-hda-codec-id:14f15068");
3492 MODULE_ALIAS("snd-hda-codec-id:14f15069");
3493 MODULE_ALIAS("snd-hda-codec-id:14f1506c");
3494 MODULE_ALIAS("snd-hda-codec-id:14f1506e");
3495 MODULE_ALIAS("snd-hda-codec-id:14f15097");
3496 MODULE_ALIAS("snd-hda-codec-id:14f15098");
3497 MODULE_ALIAS("snd-hda-codec-id:14f150a1");
3498 MODULE_ALIAS("snd-hda-codec-id:14f150a2");
3499 MODULE_ALIAS("snd-hda-codec-id:14f150ab");
3500 MODULE_ALIAS("snd-hda-codec-id:14f150ac");
3501 MODULE_ALIAS("snd-hda-codec-id:14f150b8");
3502 MODULE_ALIAS("snd-hda-codec-id:14f150b9");
3503 MODULE_ALIAS("snd-hda-codec-id:14f1510f");
3504 MODULE_ALIAS("snd-hda-codec-id:14f15110");
3505 MODULE_ALIAS("snd-hda-codec-id:14f15111");
3506 MODULE_ALIAS("snd-hda-codec-id:14f15113");
3507 MODULE_ALIAS("snd-hda-codec-id:14f15114");
3508 MODULE_ALIAS("snd-hda-codec-id:14f15115");
3509 
3510 MODULE_LICENSE("GPL");
3511 MODULE_DESCRIPTION("Conexant HD-audio codec");
3512 
3513 static struct hda_codec_preset_list conexant_list = {
3514 	.preset = snd_hda_preset_conexant,
3515 	.owner = THIS_MODULE,
3516 };
3517 
3518 static int __init patch_conexant_init(void)
3519 {
3520 	return snd_hda_add_codec_preset(&conexant_list);
3521 }
3522 
3523 static void __exit patch_conexant_exit(void)
3524 {
3525 	snd_hda_delete_codec_preset(&conexant_list);
3526 }
3527 
3528 module_init(patch_conexant_init)
3529 module_exit(patch_conexant_exit)
3530