1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
33#include "hda_beep.h"
34
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
39
40
41enum {
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
47 ALC880_Z71V,
48 ALC880_6ST,
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
54 ALC880_ASUS_DIG2,
55 ALC880_FUJITSU,
56 ALC880_UNIWILL_DIG,
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
61 ALC880_LG,
62 ALC880_LG_LW,
63 ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
67 ALC880_AUTO,
68 ALC880_MODEL_LAST
69};
70
71
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
75 ALC260_HP_DC7600,
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
78 ALC260_ACER,
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
81 ALC260_FAVORIT100,
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
85 ALC260_AUTO,
86 ALC260_MODEL_LAST
87};
88
89
90enum {
91 ALC262_BASIC,
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
94 ALC262_FUJITSU,
95 ALC262_HP_BPC,
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
98 ALC262_HP_TC_T5735,
99 ALC262_HP_RP5700,
100 ALC262_BENQ_ED8,
101 ALC262_SONY_ASSAMD,
102 ALC262_BENQ_T31,
103 ALC262_ULTRA,
104 ALC262_LENOVO_3000,
105 ALC262_NEC,
106 ALC262_TOSHIBA_S06,
107 ALC262_TOSHIBA_RX1,
108 ALC262_TYAN,
109 ALC262_AUTO,
110 ALC262_MODEL_LAST
111};
112
113
114enum {
115 ALC267_QUANTA_IL1,
116 ALC268_3ST,
117 ALC268_TOSHIBA,
118 ALC268_ACER,
119 ALC268_ACER_DMIC,
120 ALC268_ACER_ASPIRE_ONE,
121 ALC268_DELL,
122 ALC268_ZEPTO,
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
126 ALC268_AUTO,
127 ALC268_MODEL_LAST
128};
129
130
131enum {
132 ALC269_BASIC,
133 ALC269_QUANTA_FL1,
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
138 ALC269_FUJITSU,
139 ALC269_LIFEBOOK,
140 ALC269_AUTO,
141 ALC269_MODEL_LAST
142};
143
144
145enum {
146 ALC861_3ST,
147 ALC660_3ST,
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
150 ALC861_UNIWILL_M31,
151 ALC861_TOSHIBA,
152 ALC861_ASUS,
153 ALC861_ASUS_LAPTOP,
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156};
157
158
159enum {
160 ALC660VD_3ST,
161 ALC660VD_3ST_DIG,
162 ALC660VD_ASUS_V1S,
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
166 ALC861VD_LENOVO,
167 ALC861VD_DALLAS,
168 ALC861VD_HP,
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171};
172
173
174enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
180 ALC662_ASUS_EEEPC_P701,
181 ALC662_ASUS_EEEPC_EP20,
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
197 ALC272_SAMSUNG_NC10,
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200};
201
202
203enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
206 ALC882_ARIMA,
207 ALC882_W2JC,
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
210 ALC882_ASUS_A7M,
211 ALC885_MACPRO,
212 ALC885_MBA21,
213 ALC885_MBP3,
214 ALC885_MB5,
215 ALC885_MACMINI3,
216 ALC885_IMAC24,
217 ALC885_IMAC91,
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
224 ALC883_TARGA_8ch_DIG,
225 ALC883_ACER,
226 ALC883_ACER_ASPIRE,
227 ALC888_ACER_ASPIRE_4930G,
228 ALC888_ACER_ASPIRE_6530G,
229 ALC888_ACER_ASPIRE_8930G,
230 ALC888_ACER_ASPIRE_7730G,
231 ALC883_MEDION,
232 ALC883_MEDION_MD2,
233 ALC883_MEDION_WIM2160,
234 ALC883_LAPTOP_EAPD,
235 ALC883_LENOVO_101E_2ch,
236 ALC883_LENOVO_NB0763,
237 ALC888_LENOVO_MS7195_DIG,
238 ALC888_LENOVO_SKY,
239 ALC883_HAIER_W66,
240 ALC888_3ST_HP,
241 ALC888_6ST_DELL,
242 ALC883_MITAC,
243 ALC883_CLEVO_M540R,
244 ALC883_CLEVO_M720,
245 ALC883_FUJITSU_PI2515,
246 ALC888_FUJITSU_XA3530,
247 ALC883_3ST_6ch_INTEL,
248 ALC889A_INTEL,
249 ALC889_INTEL,
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
252 ALC889A_MB31,
253 ALC1200_ASUS_P5Q,
254 ALC883_SONY_VAIO_TT,
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
257};
258
259
260#define GPIO_MASK 0x03
261
262
263enum {
264 ALC_INIT_NONE,
265 ALC_INIT_DEFAULT,
266 ALC_INIT_GPIO1,
267 ALC_INIT_GPIO2,
268 ALC_INIT_GPIO3,
269};
270
271struct alc_mic_route {
272 hda_nid_t pin;
273 unsigned char mux_idx;
274 unsigned char amix_idx;
275};
276
277#define MUX_IDX_UNDEF ((unsigned char)-1)
278
279struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
289};
290
291struct alc_spec {
292
293 struct snd_kcontrol_new *mixers[5];
294 unsigned int num_mixers;
295 struct snd_kcontrol_new *cap_mixer;
296 unsigned int beep_amp;
297
298 const struct hda_verb *init_verbs[10];
299
300
301
302 unsigned int num_init_verbs;
303
304 char stream_name_analog[32];
305 struct hda_pcm_stream *stream_analog_playback;
306 struct hda_pcm_stream *stream_analog_capture;
307 struct hda_pcm_stream *stream_analog_alt_playback;
308 struct hda_pcm_stream *stream_analog_alt_capture;
309
310 char stream_name_digital[32];
311 struct hda_pcm_stream *stream_digital_playback;
312 struct hda_pcm_stream *stream_digital_capture;
313
314
315 struct hda_multi_out multiout;
316
317
318
319 hda_nid_t alt_dac_nid;
320 hda_nid_t slave_dig_outs[3];
321 int dig_out_type;
322
323
324 unsigned int num_adc_nids;
325 hda_nid_t *adc_nids;
326 hda_nid_t *capsrc_nids;
327 hda_nid_t dig_in_nid;
328
329
330 unsigned int num_mux_defs;
331 const struct hda_input_mux *input_mux;
332 unsigned int cur_mux[3];
333 struct alc_mic_route ext_mic;
334 struct alc_mic_route int_mic;
335
336
337 const struct hda_channel_mode *channel_mode;
338 int num_channel_mode;
339 int need_dac_fix;
340 int const_channel_count;
341 int ext_channel_count;
342
343
344 struct hda_pcm pcm_rec[3];
345
346
347 struct auto_pin_cfg autocfg;
348 struct alc_customize_define cdefine;
349 struct snd_array kctls;
350 struct hda_input_mux private_imux[3];
351 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
352 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
353 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
354
355
356 void (*init_hook)(struct hda_codec *codec);
357 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
358#ifdef CONFIG_SND_HDA_POWER_SAVE
359 void (*power_hook)(struct hda_codec *codec);
360#endif
361
362
363 unsigned int sense_updated: 1;
364 unsigned int jack_present: 1;
365 unsigned int master_sw: 1;
366 unsigned int auto_mic:1;
367
368
369 unsigned int no_analog :1;
370 int init_amp;
371
372
373 hda_nid_t vmaster_nid;
374#ifdef CONFIG_SND_HDA_POWER_SAVE
375 struct hda_loopback_check loopback;
376#endif
377
378
379 hda_nid_t pll_nid;
380 unsigned int pll_coef_idx, pll_coef_bit;
381};
382
383
384
385
386struct alc_config_preset {
387 struct snd_kcontrol_new *mixers[5];
388
389
390 struct snd_kcontrol_new *cap_mixer;
391 const struct hda_verb *init_verbs[5];
392 unsigned int num_dacs;
393 hda_nid_t *dac_nids;
394 hda_nid_t dig_out_nid;
395 hda_nid_t hp_nid;
396 hda_nid_t *slave_dig_outs;
397 unsigned int num_adc_nids;
398 hda_nid_t *adc_nids;
399 hda_nid_t *capsrc_nids;
400 hda_nid_t dig_in_nid;
401 unsigned int num_channel_mode;
402 const struct hda_channel_mode *channel_mode;
403 int need_dac_fix;
404 int const_channel_count;
405 unsigned int num_mux_defs;
406 const struct hda_input_mux *input_mux;
407 void (*unsol_event)(struct hda_codec *, unsigned int);
408 void (*setup)(struct hda_codec *);
409 void (*init_hook)(struct hda_codec *);
410#ifdef CONFIG_SND_HDA_POWER_SAVE
411 struct hda_amp_list *loopbacks;
412 void (*power_hook)(struct hda_codec *codec);
413#endif
414};
415
416
417
418
419
420static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
421 struct snd_ctl_elem_info *uinfo)
422{
423 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
424 struct alc_spec *spec = codec->spec;
425 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
426 if (mux_idx >= spec->num_mux_defs)
427 mux_idx = 0;
428 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
429 mux_idx = 0;
430 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
431}
432
433static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
434 struct snd_ctl_elem_value *ucontrol)
435{
436 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
437 struct alc_spec *spec = codec->spec;
438 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
439
440 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
441 return 0;
442}
443
444static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
445 struct snd_ctl_elem_value *ucontrol)
446{
447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
448 struct alc_spec *spec = codec->spec;
449 const struct hda_input_mux *imux;
450 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
451 unsigned int mux_idx;
452 hda_nid_t nid = spec->capsrc_nids ?
453 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
454 unsigned int type;
455
456 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
457 imux = &spec->input_mux[mux_idx];
458 if (!imux->num_items && mux_idx > 0)
459 imux = &spec->input_mux[0];
460
461 type = get_wcaps_type(get_wcaps(codec, nid));
462 if (type == AC_WID_AUD_MIX) {
463
464 unsigned int *cur_val = &spec->cur_mux[adc_idx];
465 unsigned int i, idx;
466
467 idx = ucontrol->value.enumerated.item[0];
468 if (idx >= imux->num_items)
469 idx = imux->num_items - 1;
470 if (*cur_val == idx)
471 return 0;
472 for (i = 0; i < imux->num_items; i++) {
473 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
474 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
475 imux->items[i].index,
476 HDA_AMP_MUTE, v);
477 }
478 *cur_val = idx;
479 return 1;
480 } else {
481
482 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
483 &spec->cur_mux[adc_idx]);
484 }
485}
486
487
488
489
490static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_info *uinfo)
492{
493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
494 struct alc_spec *spec = codec->spec;
495 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
496 spec->num_channel_mode);
497}
498
499static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
500 struct snd_ctl_elem_value *ucontrol)
501{
502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503 struct alc_spec *spec = codec->spec;
504 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
505 spec->num_channel_mode,
506 spec->ext_channel_count);
507}
508
509static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
511{
512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct alc_spec *spec = codec->spec;
514 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
515 spec->num_channel_mode,
516 &spec->ext_channel_count);
517 if (err >= 0 && !spec->const_channel_count) {
518 spec->multiout.max_channels = spec->ext_channel_count;
519 if (spec->need_dac_fix)
520 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
521 }
522 return err;
523}
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538static char *alc_pin_mode_names[] = {
539 "Mic 50pc bias", "Mic 80pc bias",
540 "Line in", "Line out", "Headphone out",
541};
542static unsigned char alc_pin_mode_values[] = {
543 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
544};
545
546
547
548
549
550
551
552#define ALC_PIN_DIR_IN 0x00
553#define ALC_PIN_DIR_OUT 0x01
554#define ALC_PIN_DIR_INOUT 0x02
555#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
556#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
557
558
559
560
561static signed char alc_pin_mode_dir_info[5][2] = {
562 { 0, 2 },
563 { 3, 4 },
564 { 0, 4 },
565 { 2, 2 },
566 { 2, 4 },
567};
568#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
569#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
570#define alc_pin_mode_n_items(_dir) \
571 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
572
573static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_info *uinfo)
575{
576 unsigned int item_num = uinfo->value.enumerated.item;
577 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
578
579 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
580 uinfo->count = 1;
581 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
582
583 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
584 item_num = alc_pin_mode_min(dir);
585 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
586 return 0;
587}
588
589static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
591{
592 unsigned int i;
593 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594 hda_nid_t nid = kcontrol->private_value & 0xffff;
595 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
596 long *valp = ucontrol->value.integer.value;
597 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
598 AC_VERB_GET_PIN_WIDGET_CONTROL,
599 0x00);
600
601
602 i = alc_pin_mode_min(dir);
603 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
604 i++;
605 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
606 return 0;
607}
608
609static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_value *ucontrol)
611{
612 signed int change;
613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
614 hda_nid_t nid = kcontrol->private_value & 0xffff;
615 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
616 long val = *ucontrol->value.integer.value;
617 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
618 AC_VERB_GET_PIN_WIDGET_CONTROL,
619 0x00);
620
621 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
622 val = alc_pin_mode_min(dir);
623
624 change = pinctl != alc_pin_mode_values[val];
625 if (change) {
626
627 snd_hda_codec_write_cache(codec, nid, 0,
628 AC_VERB_SET_PIN_WIDGET_CONTROL,
629 alc_pin_mode_values[val]);
630
631
632
633
634
635
636
637
638
639
640
641 if (val <= 2) {
642 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
643 HDA_AMP_MUTE, HDA_AMP_MUTE);
644 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
645 HDA_AMP_MUTE, 0);
646 } else {
647 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
648 HDA_AMP_MUTE, HDA_AMP_MUTE);
649 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
650 HDA_AMP_MUTE, 0);
651 }
652 }
653 return change;
654}
655
656#define ALC_PIN_MODE(xname, nid, dir) \
657 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
658 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
659 .info = alc_pin_mode_info, \
660 .get = alc_pin_mode_get, \
661 .put = alc_pin_mode_put, \
662 .private_value = nid | (dir<<16) }
663
664
665
666
667
668
669#ifdef CONFIG_SND_DEBUG
670#define alc_gpio_data_info snd_ctl_boolean_mono_info
671
672static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 hda_nid_t nid = kcontrol->private_value & 0xffff;
677 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
678 long *valp = ucontrol->value.integer.value;
679 unsigned int val = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_GPIO_DATA, 0x00);
681
682 *valp = (val & mask) != 0;
683 return 0;
684}
685static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
686 struct snd_ctl_elem_value *ucontrol)
687{
688 signed int change;
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long val = *ucontrol->value.integer.value;
693 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA,
695 0x00);
696
697
698 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
699 if (val == 0)
700 gpio_data &= ~mask;
701 else
702 gpio_data |= mask;
703 snd_hda_codec_write_cache(codec, nid, 0,
704 AC_VERB_SET_GPIO_DATA, gpio_data);
705
706 return change;
707}
708#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711 .info = alc_gpio_data_info, \
712 .get = alc_gpio_data_get, \
713 .put = alc_gpio_data_put, \
714 .private_value = nid | (mask<<16) }
715#endif
716
717
718
719
720
721
722
723
724#ifdef CONFIG_SND_DEBUG
725#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
726
727static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
729{
730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
731 hda_nid_t nid = kcontrol->private_value & 0xffff;
732 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
733 long *valp = ucontrol->value.integer.value;
734 unsigned int val = snd_hda_codec_read(codec, nid, 0,
735 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
736
737 *valp = (val & mask) != 0;
738 return 0;
739}
740static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_value *ucontrol)
742{
743 signed int change;
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long val = *ucontrol->value.integer.value;
748 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
749 AC_VERB_GET_DIGI_CONVERT_1,
750 0x00);
751
752
753 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
754 if (val==0)
755 ctrl_data &= ~mask;
756 else
757 ctrl_data |= mask;
758 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
759 ctrl_data);
760
761 return change;
762}
763#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
764 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
765 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
766 .info = alc_spdif_ctrl_info, \
767 .get = alc_spdif_ctrl_get, \
768 .put = alc_spdif_ctrl_put, \
769 .private_value = nid | (mask<<16) }
770#endif
771
772
773
774
775
776#ifdef CONFIG_SND_DEBUG
777#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
778
779static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
781{
782 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783 hda_nid_t nid = kcontrol->private_value & 0xffff;
784 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785 long *valp = ucontrol->value.integer.value;
786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
787 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
788
789 *valp = (val & mask) != 0;
790 return 0;
791}
792
793static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
796 int change;
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
802 AC_VERB_GET_EAPD_BTLENABLE,
803 0x00);
804
805
806 change = (!val ? 0 : mask) != (ctrl_data & mask);
807 if (!val)
808 ctrl_data &= ~mask;
809 else
810 ctrl_data |= mask;
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
812 ctrl_data);
813
814 return change;
815}
816
817#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
820 .info = alc_eapd_ctrl_info, \
821 .get = alc_eapd_ctrl_get, \
822 .put = alc_eapd_ctrl_put, \
823 .private_value = nid | (mask<<16) }
824#endif
825
826
827
828
829static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
830 int auto_pin_type)
831{
832 unsigned int val = PIN_IN;
833
834 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
835 unsigned int pincap;
836 pincap = snd_hda_query_pin_caps(codec, nid);
837 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
838 if (pincap & AC_PINCAP_VREF_80)
839 val = PIN_VREF80;
840 else if (pincap & AC_PINCAP_VREF_50)
841 val = PIN_VREF50;
842 else if (pincap & AC_PINCAP_VREF_100)
843 val = PIN_VREF100;
844 else if (pincap & AC_PINCAP_VREF_GRD)
845 val = PIN_VREFGRD;
846 }
847 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
848}
849
850
851
852static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
853{
854 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
855 return;
856 spec->mixers[spec->num_mixers++] = mix;
857}
858
859static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
860{
861 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
862 return;
863 spec->init_verbs[spec->num_init_verbs++] = verb;
864}
865
866
867
868
869static void setup_preset(struct hda_codec *codec,
870 const struct alc_config_preset *preset)
871{
872 struct alc_spec *spec = codec->spec;
873 int i;
874
875 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
876 add_mixer(spec, preset->mixers[i]);
877 spec->cap_mixer = preset->cap_mixer;
878 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
879 i++)
880 add_verb(spec, preset->init_verbs[i]);
881
882 spec->channel_mode = preset->channel_mode;
883 spec->num_channel_mode = preset->num_channel_mode;
884 spec->need_dac_fix = preset->need_dac_fix;
885 spec->const_channel_count = preset->const_channel_count;
886
887 if (preset->const_channel_count)
888 spec->multiout.max_channels = preset->const_channel_count;
889 else
890 spec->multiout.max_channels = spec->channel_mode[0].channels;
891 spec->ext_channel_count = spec->channel_mode[0].channels;
892
893 spec->multiout.num_dacs = preset->num_dacs;
894 spec->multiout.dac_nids = preset->dac_nids;
895 spec->multiout.dig_out_nid = preset->dig_out_nid;
896 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
897 spec->multiout.hp_nid = preset->hp_nid;
898
899 spec->num_mux_defs = preset->num_mux_defs;
900 if (!spec->num_mux_defs)
901 spec->num_mux_defs = 1;
902 spec->input_mux = preset->input_mux;
903
904 spec->num_adc_nids = preset->num_adc_nids;
905 spec->adc_nids = preset->adc_nids;
906 spec->capsrc_nids = preset->capsrc_nids;
907 spec->dig_in_nid = preset->dig_in_nid;
908
909 spec->unsol_event = preset->unsol_event;
910 spec->init_hook = preset->init_hook;
911#ifdef CONFIG_SND_HDA_POWER_SAVE
912 spec->power_hook = preset->power_hook;
913 spec->loopback.amplist = preset->loopbacks;
914#endif
915
916 if (preset->setup)
917 preset->setup(codec);
918}
919
920
921static struct hda_verb alc_gpio1_init_verbs[] = {
922 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
923 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
924 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
925 { }
926};
927
928static struct hda_verb alc_gpio2_init_verbs[] = {
929 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
930 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
931 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
932 { }
933};
934
935static struct hda_verb alc_gpio3_init_verbs[] = {
936 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
937 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
938 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
939 { }
940};
941
942
943
944
945
946
947static void alc_fix_pll(struct hda_codec *codec)
948{
949 struct alc_spec *spec = codec->spec;
950 unsigned int val;
951
952 if (!spec->pll_nid)
953 return;
954 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
955 spec->pll_coef_idx);
956 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
957 AC_VERB_GET_PROC_COEF, 0);
958 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
959 spec->pll_coef_idx);
960 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
961 val & ~(1 << spec->pll_coef_bit));
962}
963
964static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
965 unsigned int coef_idx, unsigned int coef_bit)
966{
967 struct alc_spec *spec = codec->spec;
968 spec->pll_nid = nid;
969 spec->pll_coef_idx = coef_idx;
970 spec->pll_coef_bit = coef_bit;
971 alc_fix_pll(codec);
972}
973
974static void alc_automute_pin(struct hda_codec *codec)
975{
976 struct alc_spec *spec = codec->spec;
977 unsigned int nid = spec->autocfg.hp_pins[0];
978 int i;
979
980 if (!nid)
981 return;
982 spec->jack_present = snd_hda_jack_detect(codec, nid);
983 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
984 nid = spec->autocfg.speaker_pins[i];
985 if (!nid)
986 break;
987 snd_hda_codec_write(codec, nid, 0,
988 AC_VERB_SET_PIN_WIDGET_CONTROL,
989 spec->jack_present ? 0 : PIN_OUT);
990 }
991}
992
993static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
994 hda_nid_t nid)
995{
996 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
997 int i, nums;
998
999 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1000 for (i = 0; i < nums; i++)
1001 if (conn[i] == nid)
1002 return i;
1003 return -1;
1004}
1005
1006static void alc_mic_automute(struct hda_codec *codec)
1007{
1008 struct alc_spec *spec = codec->spec;
1009 struct alc_mic_route *dead, *alive;
1010 unsigned int present, type;
1011 hda_nid_t cap_nid;
1012
1013 if (!spec->auto_mic)
1014 return;
1015 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1016 return;
1017 if (snd_BUG_ON(!spec->adc_nids))
1018 return;
1019
1020 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1021
1022 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1023 if (present) {
1024 alive = &spec->ext_mic;
1025 dead = &spec->int_mic;
1026 } else {
1027 alive = &spec->int_mic;
1028 dead = &spec->ext_mic;
1029 }
1030
1031 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1032 if (type == AC_WID_AUD_MIX) {
1033
1034 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1035 alive->mux_idx,
1036 HDA_AMP_MUTE, 0);
1037 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1038 dead->mux_idx,
1039 HDA_AMP_MUTE, HDA_AMP_MUTE);
1040 } else {
1041
1042 snd_hda_codec_write_cache(codec, cap_nid, 0,
1043 AC_VERB_SET_CONNECT_SEL,
1044 alive->mux_idx);
1045 }
1046
1047
1048}
1049
1050
1051static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1052{
1053 if (codec->vendor_id == 0x10ec0880)
1054 res >>= 28;
1055 else
1056 res >>= 26;
1057 switch (res) {
1058 case ALC880_HP_EVENT:
1059 alc_automute_pin(codec);
1060 break;
1061 case ALC880_MIC_EVENT:
1062 alc_mic_automute(codec);
1063 break;
1064 }
1065}
1066
1067static void alc_inithook(struct hda_codec *codec)
1068{
1069 alc_automute_pin(codec);
1070 alc_mic_automute(codec);
1071}
1072
1073
1074static void alc888_coef_init(struct hda_codec *codec)
1075{
1076 unsigned int tmp;
1077
1078 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1079 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1080 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1081 if ((tmp & 0xf0) == 0x20)
1082
1083 snd_hda_codec_read(codec, 0x20, 0,
1084 AC_VERB_SET_PROC_COEF, 0x830);
1085 else
1086
1087 snd_hda_codec_read(codec, 0x20, 0,
1088 AC_VERB_SET_PROC_COEF, 0x3030);
1089}
1090
1091static void alc889_coef_init(struct hda_codec *codec)
1092{
1093 unsigned int tmp;
1094
1095 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1096 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1097 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1098 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1099}
1100
1101
1102static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1103{
1104 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1105 return;
1106 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1107 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1108 on ? 2 : 0);
1109}
1110
1111static void alc_auto_init_amp(struct hda_codec *codec, int type)
1112{
1113 unsigned int tmp;
1114
1115 switch (type) {
1116 case ALC_INIT_GPIO1:
1117 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1118 break;
1119 case ALC_INIT_GPIO2:
1120 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1121 break;
1122 case ALC_INIT_GPIO3:
1123 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1124 break;
1125 case ALC_INIT_DEFAULT:
1126 switch (codec->vendor_id) {
1127 case 0x10ec0260:
1128 set_eapd(codec, 0x0f, 1);
1129 set_eapd(codec, 0x10, 1);
1130 break;
1131 case 0x10ec0262:
1132 case 0x10ec0267:
1133 case 0x10ec0268:
1134 case 0x10ec0269:
1135 case 0x10ec0270:
1136 case 0x10ec0272:
1137 case 0x10ec0660:
1138 case 0x10ec0662:
1139 case 0x10ec0663:
1140 case 0x10ec0862:
1141 case 0x10ec0889:
1142 set_eapd(codec, 0x14, 1);
1143 set_eapd(codec, 0x15, 1);
1144 break;
1145 }
1146 switch (codec->vendor_id) {
1147 case 0x10ec0260:
1148 snd_hda_codec_write(codec, 0x1a, 0,
1149 AC_VERB_SET_COEF_INDEX, 7);
1150 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1151 AC_VERB_GET_PROC_COEF, 0);
1152 snd_hda_codec_write(codec, 0x1a, 0,
1153 AC_VERB_SET_COEF_INDEX, 7);
1154 snd_hda_codec_write(codec, 0x1a, 0,
1155 AC_VERB_SET_PROC_COEF,
1156 tmp | 0x2010);
1157 break;
1158 case 0x10ec0262:
1159 case 0x10ec0880:
1160 case 0x10ec0882:
1161 case 0x10ec0883:
1162 case 0x10ec0885:
1163 case 0x10ec0887:
1164 case 0x10ec0889:
1165 alc889_coef_init(codec);
1166 break;
1167 case 0x10ec0888:
1168 alc888_coef_init(codec);
1169 break;
1170#if 0
1171 case 0x10ec0267:
1172 case 0x10ec0268:
1173 snd_hda_codec_write(codec, 0x20, 0,
1174 AC_VERB_SET_COEF_INDEX, 7);
1175 tmp = snd_hda_codec_read(codec, 0x20, 0,
1176 AC_VERB_GET_PROC_COEF, 0);
1177 snd_hda_codec_write(codec, 0x20, 0,
1178 AC_VERB_SET_COEF_INDEX, 7);
1179 snd_hda_codec_write(codec, 0x20, 0,
1180 AC_VERB_SET_PROC_COEF,
1181 tmp | 0x3000);
1182 break;
1183#endif
1184 }
1185 break;
1186 }
1187}
1188
1189static void alc_init_auto_hp(struct hda_codec *codec)
1190{
1191 struct alc_spec *spec = codec->spec;
1192
1193 if (!spec->autocfg.hp_pins[0])
1194 return;
1195
1196 if (!spec->autocfg.speaker_pins[0]) {
1197 if (spec->autocfg.line_out_pins[0] &&
1198 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1199 spec->autocfg.speaker_pins[0] =
1200 spec->autocfg.line_out_pins[0];
1201 else
1202 return;
1203 }
1204
1205 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1206 spec->autocfg.hp_pins[0]);
1207 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1208 AC_VERB_SET_UNSOLICITED_ENABLE,
1209 AC_USRSP_EN | ALC880_HP_EVENT);
1210 spec->unsol_event = alc_sku_unsol_event;
1211}
1212
1213static void alc_init_auto_mic(struct hda_codec *codec)
1214{
1215 struct alc_spec *spec = codec->spec;
1216 struct auto_pin_cfg *cfg = &spec->autocfg;
1217 hda_nid_t fixed, ext;
1218 int i;
1219
1220
1221 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1222 if (cfg->input_pins[i])
1223 return;
1224
1225 fixed = ext = 0;
1226 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1227 hda_nid_t nid = cfg->input_pins[i];
1228 unsigned int defcfg;
1229 if (!nid)
1230 return;
1231 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1232 switch (get_defcfg_connect(defcfg)) {
1233 case AC_JACK_PORT_FIXED:
1234 if (fixed)
1235 return;
1236 fixed = nid;
1237 break;
1238 case AC_JACK_PORT_COMPLEX:
1239 if (ext)
1240 return;
1241 ext = nid;
1242 break;
1243 default:
1244 return;
1245 }
1246 }
1247 if (!ext || !fixed)
1248 return;
1249 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1250 return;
1251 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1252 ext, fixed);
1253 spec->ext_mic.pin = ext;
1254 spec->int_mic.pin = fixed;
1255 spec->ext_mic.mux_idx = MUX_IDX_UNDEF;
1256 spec->int_mic.mux_idx = MUX_IDX_UNDEF;
1257 spec->auto_mic = 1;
1258 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1259 AC_VERB_SET_UNSOLICITED_ENABLE,
1260 AC_USRSP_EN | ALC880_MIC_EVENT);
1261 spec->unsol_event = alc_sku_unsol_event;
1262}
1263
1264static int alc_auto_parse_customize_define(struct hda_codec *codec)
1265{
1266 unsigned int ass, tmp, i;
1267 unsigned nid = 0;
1268 struct alc_spec *spec = codec->spec;
1269
1270 spec->cdefine.enable_pcbeep = 1;
1271
1272 ass = codec->subsystem_id & 0xffff;
1273 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1274 goto do_sku;
1275
1276 nid = 0x1d;
1277 if (codec->vendor_id == 0x10ec0260)
1278 nid = 0x17;
1279 ass = snd_hda_codec_get_pincfg(codec, nid);
1280
1281 if (!(ass & 1)) {
1282 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1283 codec->chip_name, ass);
1284 return -1;
1285 }
1286
1287
1288 tmp = 0;
1289 for (i = 1; i < 16; i++) {
1290 if ((ass >> i) & 1)
1291 tmp++;
1292 }
1293 if (((ass >> 16) & 0xf) != tmp)
1294 return -1;
1295
1296 spec->cdefine.port_connectivity = ass >> 30;
1297 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1298 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1299 spec->cdefine.customization = ass >> 8;
1300do_sku:
1301 spec->cdefine.sku_cfg = ass;
1302 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1303 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1304 spec->cdefine.swap = (ass & 0x2) >> 1;
1305 spec->cdefine.override = ass & 0x1;
1306
1307 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1308 nid, spec->cdefine.sku_cfg);
1309 snd_printd("SKU: port_connectivity=0x%x\n",
1310 spec->cdefine.port_connectivity);
1311 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1312 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1313 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1314 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1315 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1316 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1317 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1318
1319 return 0;
1320}
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331static int alc_subsystem_id(struct hda_codec *codec,
1332 hda_nid_t porta, hda_nid_t porte,
1333 hda_nid_t portd, hda_nid_t porti)
1334{
1335 unsigned int ass, tmp, i;
1336 unsigned nid;
1337 struct alc_spec *spec = codec->spec;
1338
1339 ass = codec->subsystem_id & 0xffff;
1340 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1341 goto do_sku;
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 nid = 0x1d;
1353 if (codec->vendor_id == 0x10ec0260)
1354 nid = 0x17;
1355 ass = snd_hda_codec_get_pincfg(codec, nid);
1356 snd_printd("realtek: No valid SSID, "
1357 "checking pincfg 0x%08x for NID 0x%x\n",
1358 ass, nid);
1359 if (!(ass & 1))
1360 return 0;
1361 if ((ass >> 30) != 1)
1362 return 0;
1363
1364
1365 tmp = 0;
1366 for (i = 1; i < 16; i++) {
1367 if ((ass >> i) & 1)
1368 tmp++;
1369 }
1370 if (((ass >> 16) & 0xf) != tmp)
1371 return 0;
1372do_sku:
1373 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1374 ass & 0xffff, codec->vendor_id);
1375
1376
1377
1378
1379
1380
1381
1382 tmp = (ass & 0x38) >> 3;
1383 switch (tmp) {
1384 case 1:
1385 spec->init_amp = ALC_INIT_GPIO1;
1386 break;
1387 case 3:
1388 spec->init_amp = ALC_INIT_GPIO2;
1389 break;
1390 case 7:
1391 spec->init_amp = ALC_INIT_GPIO3;
1392 break;
1393 case 5:
1394 spec->init_amp = ALC_INIT_DEFAULT;
1395 break;
1396 }
1397
1398
1399
1400
1401 if (!(ass & 0x8000))
1402 return 1;
1403
1404
1405
1406
1407
1408
1409
1410 if (!spec->autocfg.hp_pins[0]) {
1411 hda_nid_t nid;
1412 tmp = (ass >> 11) & 0x3;
1413 if (tmp == 0)
1414 nid = porta;
1415 else if (tmp == 1)
1416 nid = porte;
1417 else if (tmp == 2)
1418 nid = portd;
1419 else if (tmp == 3)
1420 nid = porti;
1421 else
1422 return 1;
1423 for (i = 0; i < spec->autocfg.line_outs; i++)
1424 if (spec->autocfg.line_out_pins[i] == nid)
1425 return 1;
1426 spec->autocfg.hp_pins[0] = nid;
1427 }
1428
1429 alc_init_auto_hp(codec);
1430 alc_init_auto_mic(codec);
1431 return 1;
1432}
1433
1434static void alc_ssid_check(struct hda_codec *codec,
1435 hda_nid_t porta, hda_nid_t porte,
1436 hda_nid_t portd, hda_nid_t porti)
1437{
1438 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1439 struct alc_spec *spec = codec->spec;
1440 snd_printd("realtek: "
1441 "Enable default setup for auto mode as fallback\n");
1442 spec->init_amp = ALC_INIT_DEFAULT;
1443 alc_init_auto_hp(codec);
1444 alc_init_auto_mic(codec);
1445 }
1446}
1447
1448
1449
1450
1451
1452struct alc_pincfg {
1453 hda_nid_t nid;
1454 u32 val;
1455};
1456
1457struct alc_fixup {
1458 const struct alc_pincfg *pins;
1459 const struct hda_verb *verbs;
1460};
1461
1462static void alc_pick_fixup(struct hda_codec *codec,
1463 const struct snd_pci_quirk *quirk,
1464 const struct alc_fixup *fix,
1465 int pre_init)
1466{
1467 const struct alc_pincfg *cfg;
1468
1469 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1470 if (!quirk)
1471 return;
1472 fix += quirk->value;
1473 cfg = fix->pins;
1474 if (pre_init && cfg) {
1475#ifdef CONFIG_SND_DEBUG_VERBOSE
1476 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1477 codec->chip_name, quirk->name);
1478#endif
1479 for (; cfg->nid; cfg++)
1480 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1481 }
1482 if (!pre_init && fix->verbs) {
1483#ifdef CONFIG_SND_DEBUG_VERBOSE
1484 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1485 codec->chip_name, quirk->name);
1486#endif
1487 add_verb(codec->spec, fix->verbs);
1488 }
1489}
1490
1491static int alc_read_coef_idx(struct hda_codec *codec,
1492 unsigned int coef_idx)
1493{
1494 unsigned int val;
1495 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1496 coef_idx);
1497 val = snd_hda_codec_read(codec, 0x20, 0,
1498 AC_VERB_GET_PROC_COEF, 0);
1499 return val;
1500}
1501
1502
1503
1504
1505
1506
1507
1508
1509static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1510
1511 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1512 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1513
1514 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1515 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1516
1517 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1518 { }
1519};
1520
1521
1522
1523
1524static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1525
1526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1528
1529 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1530 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1531
1532 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1533 { }
1534};
1535
1536
1537
1538
1539static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1540
1541 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1542 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1543
1544 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1545 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1546
1547 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1548 { }
1549};
1550
1551
1552
1553
1554static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1555
1556 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1557 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1558
1559 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1560 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1561
1562 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1563 { }
1564};
1565
1566static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1567 { 2, alc888_4ST_ch2_intel_init },
1568 { 4, alc888_4ST_ch4_intel_init },
1569 { 6, alc888_4ST_ch6_intel_init },
1570 { 8, alc888_4ST_ch8_intel_init },
1571};
1572
1573
1574
1575
1576
1577static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1578
1579 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1580
1581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1584
1585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1588
1589 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1592
1593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1594 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1595 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1596
1597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1599 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1600
1601 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1602 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1603 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1604
1605 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1606 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1607 {}
1608};
1609
1610static void alc_automute_amp(struct hda_codec *codec)
1611{
1612 struct alc_spec *spec = codec->spec;
1613 unsigned int mute;
1614 hda_nid_t nid;
1615 int i;
1616
1617 spec->jack_present = 0;
1618 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1619 nid = spec->autocfg.hp_pins[i];
1620 if (!nid)
1621 break;
1622 if (snd_hda_jack_detect(codec, nid)) {
1623 spec->jack_present = 1;
1624 break;
1625 }
1626 }
1627
1628 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1629
1630 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1631 nid = spec->autocfg.speaker_pins[i];
1632 if (!nid)
1633 break;
1634 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1635 HDA_AMP_MUTE, mute);
1636 }
1637}
1638
1639static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1640 unsigned int res)
1641{
1642 if (codec->vendor_id == 0x10ec0880)
1643 res >>= 28;
1644 else
1645 res >>= 26;
1646 if (res == ALC880_HP_EVENT)
1647 alc_automute_amp(codec);
1648}
1649
1650static void alc889_automute_setup(struct hda_codec *codec)
1651{
1652 struct alc_spec *spec = codec->spec;
1653
1654 spec->autocfg.hp_pins[0] = 0x15;
1655 spec->autocfg.speaker_pins[0] = 0x14;
1656 spec->autocfg.speaker_pins[1] = 0x16;
1657 spec->autocfg.speaker_pins[2] = 0x17;
1658 spec->autocfg.speaker_pins[3] = 0x19;
1659 spec->autocfg.speaker_pins[4] = 0x1a;
1660}
1661
1662static void alc889_intel_init_hook(struct hda_codec *codec)
1663{
1664 alc889_coef_init(codec);
1665 alc_automute_amp(codec);
1666}
1667
1668static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1669{
1670 struct alc_spec *spec = codec->spec;
1671
1672 spec->autocfg.hp_pins[0] = 0x17;
1673 spec->autocfg.hp_pins[1] = 0x1b;
1674 spec->autocfg.speaker_pins[0] = 0x14;
1675 spec->autocfg.speaker_pins[1] = 0x15;
1676}
1677
1678
1679
1680
1681
1682static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1683
1684 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1685
1686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1687
1688 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1689
1690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1692 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1693
1694 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1696 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1697 { }
1698};
1699
1700
1701
1702
1703
1704static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1705
1706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1708 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1709 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1710
1711 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1712
1713 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1714
1715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1716
1717 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1718
1719 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1721 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1722
1723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1726 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1727 { }
1728};
1729
1730
1731
1732
1733
1734static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1735
1736 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1737
1738 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1739
1740 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1741
1742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1745
1746 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1747 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1749
1750 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1753
1754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1757
1758
1759
1760 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1761 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1762
1763
1764 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1765 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1776 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1777 { }
1778};
1779
1780static struct hda_input_mux alc888_2_capture_sources[2] = {
1781
1782 {
1783 .num_items = 4,
1784 .items = {
1785 { "Mic", 0x0 },
1786 { "Line", 0x2 },
1787 { "CD", 0x4 },
1788 { "Front Mic", 0xb },
1789 },
1790 },
1791 {
1792 .num_items = 3,
1793 .items = {
1794 { "Mic", 0x0 },
1795 { "Line", 0x2 },
1796 { "CD", 0x4 },
1797 },
1798 }
1799};
1800
1801static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1802
1803 {
1804 .num_items = 5,
1805 .items = {
1806 { "Ext Mic", 0x0 },
1807 { "Line In", 0x2 },
1808 { "CD", 0x4 },
1809 { "Input Mix", 0xa },
1810 { "Int Mic", 0xb },
1811 },
1812 },
1813 {
1814 .num_items = 4,
1815 .items = {
1816 { "Ext Mic", 0x0 },
1817 { "Line In", 0x2 },
1818 { "CD", 0x4 },
1819 { "Input Mix", 0xa },
1820 },
1821 }
1822};
1823
1824static struct hda_input_mux alc889_capture_sources[3] = {
1825
1826 {
1827 .num_items = 5,
1828 .items = {
1829 { "Mic", 0x0 },
1830 { "Line", 0x2 },
1831 { "CD", 0x4 },
1832 { "Front Mic", 0xb },
1833 { "Input Mix", 0xa },
1834 },
1835 },
1836 {
1837 .num_items = 4,
1838 .items = {
1839 { "Mic", 0x0 },
1840 { "Line", 0x2 },
1841 { "CD", 0x4 },
1842 { "Input Mix", 0xa },
1843 },
1844 },
1845 {
1846 .num_items = 4,
1847 .items = {
1848 { "Mic", 0x0 },
1849 { "Line", 0x2 },
1850 { "CD", 0x4 },
1851 { "Input Mix", 0xa },
1852 },
1853 }
1854};
1855
1856static struct snd_kcontrol_new alc888_base_mixer[] = {
1857 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1858 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1859 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1860 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1861 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1862 HDA_OUTPUT),
1863 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1864 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1865 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1866 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1867 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1870 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1871 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1873 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1874 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1875 { }
1876};
1877
1878static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1881 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1882 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1883 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1884 HDA_OUTPUT),
1885 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1886 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1887 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1888 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1889 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1891 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1892 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1893 { }
1894};
1895
1896
1897static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1898{
1899 struct alc_spec *spec = codec->spec;
1900
1901 spec->autocfg.hp_pins[0] = 0x15;
1902 spec->autocfg.speaker_pins[0] = 0x14;
1903 spec->autocfg.speaker_pins[1] = 0x16;
1904 spec->autocfg.speaker_pins[2] = 0x17;
1905}
1906
1907static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1908{
1909 struct alc_spec *spec = codec->spec;
1910
1911 spec->autocfg.hp_pins[0] = 0x15;
1912 spec->autocfg.speaker_pins[0] = 0x14;
1913 spec->autocfg.speaker_pins[1] = 0x16;
1914 spec->autocfg.speaker_pins[2] = 0x17;
1915}
1916
1917static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1918{
1919 struct alc_spec *spec = codec->spec;
1920
1921 spec->autocfg.hp_pins[0] = 0x15;
1922 spec->autocfg.speaker_pins[0] = 0x14;
1923 spec->autocfg.speaker_pins[1] = 0x16;
1924 spec->autocfg.speaker_pins[2] = 0x1b;
1925}
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935static hda_nid_t alc880_dac_nids[4] = {
1936
1937 0x02, 0x05, 0x04, 0x03
1938};
1939
1940static hda_nid_t alc880_adc_nids[3] = {
1941
1942 0x07, 0x08, 0x09,
1943};
1944
1945
1946
1947
1948
1949static hda_nid_t alc880_adc_nids_alt[2] = {
1950
1951 0x08, 0x09,
1952};
1953
1954#define ALC880_DIGOUT_NID 0x06
1955#define ALC880_DIGIN_NID 0x0a
1956
1957static struct hda_input_mux alc880_capture_source = {
1958 .num_items = 4,
1959 .items = {
1960 { "Mic", 0x0 },
1961 { "Front Mic", 0x3 },
1962 { "Line", 0x2 },
1963 { "CD", 0x4 },
1964 },
1965};
1966
1967
1968
1969static struct hda_verb alc880_threestack_ch2_init[] = {
1970
1971 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1972 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1973
1974 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1975 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1976 { }
1977};
1978
1979
1980static struct hda_verb alc880_threestack_ch6_init[] = {
1981
1982 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1983 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1984
1985 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1986 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1987 { }
1988};
1989
1990static struct hda_channel_mode alc880_threestack_modes[2] = {
1991 { 2, alc880_threestack_ch2_init },
1992 { 6, alc880_threestack_ch6_init },
1993};
1994
1995static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1996 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1997 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1998 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1999 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2000 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2001 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2002 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2003 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2005 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2007 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2010 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2011 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2013 {
2014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2015 .name = "Channel Mode",
2016 .info = alc_ch_mode_info,
2017 .get = alc_ch_mode_get,
2018 .put = alc_ch_mode_put,
2019 },
2020 { }
2021};
2022
2023
2024static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2025 struct snd_ctl_elem_info *uinfo)
2026{
2027 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2028 struct alc_spec *spec = codec->spec;
2029 int err;
2030
2031 mutex_lock(&codec->control_mutex);
2032 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2033 HDA_INPUT);
2034 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2035 mutex_unlock(&codec->control_mutex);
2036 return err;
2037}
2038
2039static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2040 unsigned int size, unsigned int __user *tlv)
2041{
2042 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2043 struct alc_spec *spec = codec->spec;
2044 int err;
2045
2046 mutex_lock(&codec->control_mutex);
2047 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2048 HDA_INPUT);
2049 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2050 mutex_unlock(&codec->control_mutex);
2051 return err;
2052}
2053
2054typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2055 struct snd_ctl_elem_value *ucontrol);
2056
2057static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2058 struct snd_ctl_elem_value *ucontrol,
2059 getput_call_t func)
2060{
2061 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2062 struct alc_spec *spec = codec->spec;
2063 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2064 int err;
2065
2066 mutex_lock(&codec->control_mutex);
2067 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2068 3, 0, HDA_INPUT);
2069 err = func(kcontrol, ucontrol);
2070 mutex_unlock(&codec->control_mutex);
2071 return err;
2072}
2073
2074static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2075 struct snd_ctl_elem_value *ucontrol)
2076{
2077 return alc_cap_getput_caller(kcontrol, ucontrol,
2078 snd_hda_mixer_amp_volume_get);
2079}
2080
2081static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2082 struct snd_ctl_elem_value *ucontrol)
2083{
2084 return alc_cap_getput_caller(kcontrol, ucontrol,
2085 snd_hda_mixer_amp_volume_put);
2086}
2087
2088
2089#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2090
2091static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2092 struct snd_ctl_elem_value *ucontrol)
2093{
2094 return alc_cap_getput_caller(kcontrol, ucontrol,
2095 snd_hda_mixer_amp_switch_get);
2096}
2097
2098static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2099 struct snd_ctl_elem_value *ucontrol)
2100{
2101 return alc_cap_getput_caller(kcontrol, ucontrol,
2102 snd_hda_mixer_amp_switch_put);
2103}
2104
2105#define _DEFINE_CAPMIX(num) \
2106 { \
2107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2108 .name = "Capture Switch", \
2109 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2110 .count = num, \
2111 .info = alc_cap_sw_info, \
2112 .get = alc_cap_sw_get, \
2113 .put = alc_cap_sw_put, \
2114 }, \
2115 { \
2116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2117 .name = "Capture Volume", \
2118 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2119 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2120 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2121 .count = num, \
2122 .info = alc_cap_vol_info, \
2123 .get = alc_cap_vol_get, \
2124 .put = alc_cap_vol_put, \
2125 .tlv = { .c = alc_cap_vol_tlv }, \
2126 }
2127
2128#define _DEFINE_CAPSRC(num) \
2129 { \
2130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2131 \
2132 .name = "Input Source", \
2133 .count = num, \
2134 .info = alc_mux_enum_info, \
2135 .get = alc_mux_enum_get, \
2136 .put = alc_mux_enum_put, \
2137 }
2138
2139#define DEFINE_CAPMIX(num) \
2140static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2141 _DEFINE_CAPMIX(num), \
2142 _DEFINE_CAPSRC(num), \
2143 { } \
2144}
2145
2146#define DEFINE_CAPMIX_NOSRC(num) \
2147static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2148 _DEFINE_CAPMIX(num), \
2149 { } \
2150}
2151
2152
2153DEFINE_CAPMIX(1);
2154DEFINE_CAPMIX(2);
2155DEFINE_CAPMIX(3);
2156DEFINE_CAPMIX_NOSRC(1);
2157DEFINE_CAPMIX_NOSRC(2);
2158DEFINE_CAPMIX_NOSRC(3);
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2171 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2172 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2173 { }
2174};
2175
2176
2177
2178static struct hda_verb alc880_fivestack_ch6_init[] = {
2179
2180 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2181 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2182 { }
2183};
2184
2185
2186static struct hda_verb alc880_fivestack_ch8_init[] = {
2187
2188 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2189 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2190 { }
2191};
2192
2193static struct hda_channel_mode alc880_fivestack_modes[2] = {
2194 { 6, alc880_fivestack_ch6_init },
2195 { 8, alc880_fivestack_ch8_init },
2196};
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208static hda_nid_t alc880_6st_dac_nids[4] = {
2209
2210 0x02, 0x03, 0x04, 0x05
2211};
2212
2213static struct hda_input_mux alc880_6stack_capture_source = {
2214 .num_items = 4,
2215 .items = {
2216 { "Mic", 0x0 },
2217 { "Front Mic", 0x1 },
2218 { "Line", 0x2 },
2219 { "CD", 0x4 },
2220 },
2221};
2222
2223
2224static struct hda_channel_mode alc880_sixstack_modes[1] = {
2225 { 8, NULL },
2226};
2227
2228static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2229 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2232 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2233 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2235 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2236 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2237 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2238 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2241 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2242 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2245 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2246 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2247 {
2248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2249 .name = "Channel Mode",
2250 .info = alc_ch_mode_info,
2251 .get = alc_ch_mode_get,
2252 .put = alc_ch_mode_put,
2253 },
2254 { }
2255};
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283static hda_nid_t alc880_w810_dac_nids[3] = {
2284
2285 0x02, 0x03, 0x04
2286};
2287
2288
2289static struct hda_channel_mode alc880_w810_modes[1] = {
2290 { 6, NULL }
2291};
2292
2293
2294static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2296 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2297 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2298 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2299 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2300 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2301 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2302 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2303 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2304 { }
2305};
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316static hda_nid_t alc880_z71v_dac_nids[1] = {
2317 0x02
2318};
2319#define ALC880_Z71V_HP_DAC 0x03
2320
2321
2322static struct hda_channel_mode alc880_2_jack_modes[1] = {
2323 { 2, NULL }
2324};
2325
2326static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2328 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2329 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2330 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2333 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2334 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2335 { }
2336};
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346static hda_nid_t alc880_f1734_dac_nids[1] = {
2347 0x03
2348};
2349#define ALC880_F1734_HP_DAC 0x02
2350
2351static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2352 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2353 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2354 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2357 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2360 { }
2361};
2362
2363static struct hda_input_mux alc880_f1734_capture_source = {
2364 .num_items = 2,
2365 .items = {
2366 { "Mic", 0x1 },
2367 { "CD", 0x4 },
2368 },
2369};
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380#define alc880_asus_dac_nids alc880_w810_dac_nids
2381#define alc880_asus_modes alc880_threestack_modes
2382
2383static struct snd_kcontrol_new alc880_asus_mixer[] = {
2384 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2385 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2386 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2387 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2388 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2389 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2390 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2391 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2392 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2393 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2394 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2395 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2397 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2398 {
2399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2400 .name = "Channel Mode",
2401 .info = alc_ch_mode_info,
2402 .get = alc_ch_mode_get,
2403 .put = alc_ch_mode_put,
2404 },
2405 { }
2406};
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2418 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2419 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2420 { }
2421};
2422
2423
2424static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2426 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2428 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2429 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2433 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2434 { }
2435};
2436
2437
2438static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2439 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2440 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2441 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2442 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2443 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2444 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2445 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2446 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2453 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2454 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2455 {
2456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2457 .name = "Channel Mode",
2458 .info = alc_ch_mode_info,
2459 .get = alc_ch_mode_get,
2460 .put = alc_ch_mode_put,
2461 },
2462 { }
2463};
2464
2465static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2466 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2467 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2468 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2469 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2471 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2472 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2473 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2474 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2475 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2476 { }
2477};
2478
2479static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2480 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2483 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2486 { }
2487};
2488
2489
2490
2491
2492
2493
2494
2495
2496static const char *alc_slave_vols[] = {
2497 "Front Playback Volume",
2498 "Surround Playback Volume",
2499 "Center Playback Volume",
2500 "LFE Playback Volume",
2501 "Side Playback Volume",
2502 "Headphone Playback Volume",
2503 "Speaker Playback Volume",
2504 "Mono Playback Volume",
2505 "Line-Out Playback Volume",
2506 "PCM Playback Volume",
2507 NULL,
2508};
2509
2510static const char *alc_slave_sws[] = {
2511 "Front Playback Switch",
2512 "Surround Playback Switch",
2513 "Center Playback Switch",
2514 "LFE Playback Switch",
2515 "Side Playback Switch",
2516 "Headphone Playback Switch",
2517 "Speaker Playback Switch",
2518 "Mono Playback Switch",
2519 "IEC958 Playback Switch",
2520 "Line-Out Playback Switch",
2521 "PCM Playback Switch",
2522 NULL,
2523};
2524
2525
2526
2527
2528
2529#define NID_MAPPING (-1)
2530
2531#define SUBDEV_SPEAKER_ (0 << 6)
2532#define SUBDEV_HP_ (1 << 6)
2533#define SUBDEV_LINE_ (2 << 6)
2534#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2535#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2536#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2537
2538static void alc_free_kctls(struct hda_codec *codec);
2539
2540#ifdef CONFIG_SND_HDA_INPUT_BEEP
2541
2542static struct snd_kcontrol_new alc_beep_mixer[] = {
2543 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2544 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2545 { }
2546};
2547#endif
2548
2549static int alc_build_controls(struct hda_codec *codec)
2550{
2551 struct alc_spec *spec = codec->spec;
2552 struct snd_kcontrol *kctl = NULL;
2553 struct snd_kcontrol_new *knew;
2554 int i, j, err;
2555 unsigned int u;
2556 hda_nid_t nid;
2557
2558 for (i = 0; i < spec->num_mixers; i++) {
2559 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2560 if (err < 0)
2561 return err;
2562 }
2563 if (spec->cap_mixer) {
2564 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2565 if (err < 0)
2566 return err;
2567 }
2568 if (spec->multiout.dig_out_nid) {
2569 err = snd_hda_create_spdif_out_ctls(codec,
2570 spec->multiout.dig_out_nid);
2571 if (err < 0)
2572 return err;
2573 if (!spec->no_analog) {
2574 err = snd_hda_create_spdif_share_sw(codec,
2575 &spec->multiout);
2576 if (err < 0)
2577 return err;
2578 spec->multiout.share_spdif = 1;
2579 }
2580 }
2581 if (spec->dig_in_nid) {
2582 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2583 if (err < 0)
2584 return err;
2585 }
2586
2587#ifdef CONFIG_SND_HDA_INPUT_BEEP
2588
2589 if (spec->beep_amp) {
2590 struct snd_kcontrol_new *knew;
2591 for (knew = alc_beep_mixer; knew->name; knew++) {
2592 struct snd_kcontrol *kctl;
2593 kctl = snd_ctl_new1(knew, codec);
2594 if (!kctl)
2595 return -ENOMEM;
2596 kctl->private_value = spec->beep_amp;
2597 err = snd_hda_ctl_add(codec, 0, kctl);
2598 if (err < 0)
2599 return err;
2600 }
2601 }
2602#endif
2603
2604
2605 if (!spec->no_analog &&
2606 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2607 unsigned int vmaster_tlv[4];
2608 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2609 HDA_OUTPUT, vmaster_tlv);
2610 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2611 vmaster_tlv, alc_slave_vols);
2612 if (err < 0)
2613 return err;
2614 }
2615 if (!spec->no_analog &&
2616 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2617 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2618 NULL, alc_slave_sws);
2619 if (err < 0)
2620 return err;
2621 }
2622
2623
2624 if (spec->capsrc_nids || spec->adc_nids) {
2625 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2626 if (!kctl)
2627 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2628 for (i = 0; kctl && i < kctl->count; i++) {
2629 hda_nid_t *nids = spec->capsrc_nids;
2630 if (!nids)
2631 nids = spec->adc_nids;
2632 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2633 if (err < 0)
2634 return err;
2635 }
2636 }
2637 if (spec->cap_mixer) {
2638 const char *kname = kctl ? kctl->id.name : NULL;
2639 for (knew = spec->cap_mixer; knew->name; knew++) {
2640 if (kname && strcmp(knew->name, kname) == 0)
2641 continue;
2642 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2643 for (i = 0; kctl && i < kctl->count; i++) {
2644 err = snd_hda_add_nid(codec, kctl, i,
2645 spec->adc_nids[i]);
2646 if (err < 0)
2647 return err;
2648 }
2649 }
2650 }
2651
2652
2653 for (i = 0; i < spec->num_mixers; i++) {
2654 for (knew = spec->mixers[i]; knew->name; knew++) {
2655 if (knew->iface != NID_MAPPING)
2656 continue;
2657 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2658 if (kctl == NULL)
2659 continue;
2660 u = knew->subdevice;
2661 for (j = 0; j < 4; j++, u >>= 8) {
2662 nid = u & 0x3f;
2663 if (nid == 0)
2664 continue;
2665 switch (u & 0xc0) {
2666 case SUBDEV_SPEAKER_:
2667 nid = spec->autocfg.speaker_pins[nid];
2668 break;
2669 case SUBDEV_LINE_:
2670 nid = spec->autocfg.line_out_pins[nid];
2671 break;
2672 case SUBDEV_HP_:
2673 nid = spec->autocfg.hp_pins[nid];
2674 break;
2675 default:
2676 continue;
2677 }
2678 err = snd_hda_add_nid(codec, kctl, 0, nid);
2679 if (err < 0)
2680 return err;
2681 }
2682 u = knew->private_value;
2683 for (j = 0; j < 4; j++, u >>= 8) {
2684 nid = u & 0xff;
2685 if (nid == 0)
2686 continue;
2687 err = snd_hda_add_nid(codec, kctl, 0, nid);
2688 if (err < 0)
2689 return err;
2690 }
2691 }
2692 }
2693
2694 alc_free_kctls(codec);
2695
2696 return 0;
2697}
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707static struct hda_verb alc880_volume_init_verbs[] = {
2708
2709
2710
2711 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2713 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2714 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2715 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2716 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2717
2718
2719
2720
2721
2722
2723
2724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2727 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2728 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2729 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2731
2732
2733
2734
2735
2736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2739 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2740
2741
2742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2750
2751 { }
2752};
2753
2754
2755
2756
2757
2758static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2759
2760
2761
2762
2763 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2764 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2765 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03},
2766
2767
2768
2769
2770
2771 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2773
2774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2776
2777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2779
2780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2782
2783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2785
2786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2787
2788 { }
2789};
2790
2791
2792
2793
2794
2795
2796static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2797
2798
2799
2800
2801 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2802 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2803
2804
2805
2806
2807
2808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2810 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2811 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812
2813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2816 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2817
2818
2819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2820 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2821
2822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2824
2825 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2827
2828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2830
2831 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2832
2833 { }
2834};
2835
2836
2837
2838
2839
2840static struct hda_verb alc880_pin_w810_init_verbs[] = {
2841
2842 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2843
2844 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2849 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2850
2851 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2852 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2853
2854 { }
2855};
2856
2857
2858
2859
2860
2861static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2866
2867 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2870 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2871
2872 { }
2873};
2874
2875
2876
2877
2878
2879
2880static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2881 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2882
2883 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2884 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2885 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2887 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2888 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2889 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2890 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2891
2892 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2893 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2894 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2895 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2896 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2897 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2898 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2899 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2900 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2901
2902 { }
2903};
2904
2905
2906
2907
2908
2909
2910static struct hda_verb alc880_uniwill_init_verbs[] = {
2911 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2912
2913 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2917 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2920 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2921 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2923 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2924 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2925 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2926 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2927
2928 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2929 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2931 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2932 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2933 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2934
2935
2936 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2937
2938 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2939 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2940
2941 { }
2942};
2943
2944
2945
2946
2947
2948static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2949 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2950
2951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2952 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2955 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2956 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2959 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2963
2964 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2965 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2966 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2967 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2968 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2969 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2970
2971 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2972 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2973
2974 { }
2975};
2976
2977static struct hda_verb alc880_beep_init_verbs[] = {
2978 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2979 { }
2980};
2981
2982
2983static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2984{
2985 unsigned int present;
2986 unsigned char bits;
2987
2988 present = snd_hda_jack_detect(codec, 0x18);
2989 bits = present ? HDA_AMP_MUTE : 0;
2990 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2991}
2992
2993static void alc880_uniwill_setup(struct hda_codec *codec)
2994{
2995 struct alc_spec *spec = codec->spec;
2996
2997 spec->autocfg.hp_pins[0] = 0x14;
2998 spec->autocfg.speaker_pins[0] = 0x15;
2999 spec->autocfg.speaker_pins[0] = 0x16;
3000}
3001
3002static void alc880_uniwill_init_hook(struct hda_codec *codec)
3003{
3004 alc_automute_amp(codec);
3005 alc880_uniwill_mic_automute(codec);
3006}
3007
3008static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3009 unsigned int res)
3010{
3011
3012
3013
3014 switch (res >> 28) {
3015 case ALC880_MIC_EVENT:
3016 alc880_uniwill_mic_automute(codec);
3017 break;
3018 default:
3019 alc_automute_amp_unsol_event(codec, res);
3020 break;
3021 }
3022}
3023
3024static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3025{
3026 struct alc_spec *spec = codec->spec;
3027
3028 spec->autocfg.hp_pins[0] = 0x14;
3029 spec->autocfg.speaker_pins[0] = 0x15;
3030}
3031
3032static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3033{
3034 unsigned int present;
3035
3036 present = snd_hda_codec_read(codec, 0x21, 0,
3037 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3038 present &= HDA_AMP_VOLMASK;
3039 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3040 HDA_AMP_VOLMASK, present);
3041 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3042 HDA_AMP_VOLMASK, present);
3043}
3044
3045static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3046 unsigned int res)
3047{
3048
3049
3050
3051 if ((res >> 28) == ALC880_DCVOL_EVENT)
3052 alc880_uniwill_p53_dcvol_automute(codec);
3053 else
3054 alc_automute_amp_unsol_event(codec, res);
3055}
3056
3057
3058
3059
3060
3061static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3062 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3063 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3064 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3065 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3066 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3067
3068 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3069 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3072
3073 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3074 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3075 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3076 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3077 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3079 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3080 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3081 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3082
3083 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3084 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3085
3086 { }
3087};
3088
3089
3090
3091
3092
3093static struct hda_verb alc880_pin_asus_init_verbs[] = {
3094 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3095 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3096 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3097 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3098
3099 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3100 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3101 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3102 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3103 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3105 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3107
3108 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3110 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3111 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3114 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3115 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3116 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3117
3118 { }
3119};
3120
3121
3122#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3123#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3124#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3125
3126
3127static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3128
3129 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3130
3131 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3132 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3133
3134 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3136
3137 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3138 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3139
3140 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3141 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3142
3143 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3144 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3145
3146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3147 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3148
3149 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3150 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3151
3152 { }
3153};
3154
3155static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3156
3157 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3158 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3159
3160
3161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3162
3163 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3164 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3165
3166
3167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3168
3169 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3170
3171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3172
3173
3174 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3175 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3176
3177 { }
3178};
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193static hda_nid_t alc880_lg_dac_nids[3] = {
3194 0x05, 0x02, 0x03
3195};
3196
3197
3198static struct hda_input_mux alc880_lg_capture_source = {
3199 .num_items = 3,
3200 .items = {
3201 { "Mic", 0x1 },
3202 { "Line", 0x5 },
3203 { "Internal Mic", 0x6 },
3204 },
3205};
3206
3207
3208static struct hda_verb alc880_lg_ch2_init[] = {
3209
3210 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3211 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3212 { }
3213};
3214
3215static struct hda_verb alc880_lg_ch4_init[] = {
3216
3217 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3218 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3219 { }
3220};
3221
3222static struct hda_verb alc880_lg_ch6_init[] = {
3223
3224 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3225 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3226 { }
3227};
3228
3229static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3230 { 2, alc880_lg_ch2_init },
3231 { 4, alc880_lg_ch4_init },
3232 { 6, alc880_lg_ch6_init },
3233};
3234
3235static struct snd_kcontrol_new alc880_lg_mixer[] = {
3236 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3237 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3238 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3239 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3240 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3241 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3242 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3243 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3248 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3249 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3250 {
3251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3252 .name = "Channel Mode",
3253 .info = alc_ch_mode_info,
3254 .get = alc_ch_mode_get,
3255 .put = alc_ch_mode_put,
3256 },
3257 { }
3258};
3259
3260static struct hda_verb alc880_lg_init_verbs[] = {
3261
3262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3264 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3265
3266 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3269
3270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3272
3273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3275
3276 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3277 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3278
3279 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3280 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3281 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3282
3283 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3284 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3285 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3286
3287 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3288 { }
3289};
3290
3291
3292static void alc880_lg_setup(struct hda_codec *codec)
3293{
3294 struct alc_spec *spec = codec->spec;
3295
3296 spec->autocfg.hp_pins[0] = 0x1b;
3297 spec->autocfg.speaker_pins[0] = 0x17;
3298}
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312static struct hda_input_mux alc880_lg_lw_capture_source = {
3313 .num_items = 3,
3314 .items = {
3315 { "Mic", 0x0 },
3316 { "Internal Mic", 0x1 },
3317 { "Line In", 0x2 },
3318 },
3319};
3320
3321#define alc880_lg_lw_modes alc880_threestack_modes
3322
3323static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3324 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3325 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3326 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3327 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3328 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3329 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3330 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3331 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3334 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3335 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3336 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3337 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3338 {
3339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3340 .name = "Channel Mode",
3341 .info = alc_ch_mode_info,
3342 .get = alc_ch_mode_get,
3343 .put = alc_ch_mode_put,
3344 },
3345 { }
3346};
3347
3348static struct hda_verb alc880_lg_lw_init_verbs[] = {
3349 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3350 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3351 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03},
3352
3353
3354 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3355 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3356 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3357 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3358
3359 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3360 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3361
3362 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3363 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3364
3365 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3366 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3367
3368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3370
3371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3372 { }
3373};
3374
3375
3376static void alc880_lg_lw_setup(struct hda_codec *codec)
3377{
3378 struct alc_spec *spec = codec->spec;
3379
3380 spec->autocfg.hp_pins[0] = 0x1b;
3381 spec->autocfg.speaker_pins[0] = 0x14;
3382}
3383
3384static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3385 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3386 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3389 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3390 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3391 { }
3392};
3393
3394static struct hda_input_mux alc880_medion_rim_capture_source = {
3395 .num_items = 2,
3396 .items = {
3397 { "Mic", 0x0 },
3398 { "Internal Mic", 0x1 },
3399 },
3400};
3401
3402static struct hda_verb alc880_medion_rim_init_verbs[] = {
3403 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3404
3405 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3406 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3407
3408
3409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3410 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3411
3412 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3413 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3414
3415 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3416 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3417
3418 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3419 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3420
3421 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3422 { }
3423};
3424
3425
3426static void alc880_medion_rim_automute(struct hda_codec *codec)
3427{
3428 struct alc_spec *spec = codec->spec;
3429 alc_automute_amp(codec);
3430
3431 if (spec->jack_present)
3432 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3433 else
3434 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3435}
3436
3437static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3438 unsigned int res)
3439{
3440
3441
3442
3443 if ((res >> 28) == ALC880_HP_EVENT)
3444 alc880_medion_rim_automute(codec);
3445}
3446
3447static void alc880_medion_rim_setup(struct hda_codec *codec)
3448{
3449 struct alc_spec *spec = codec->spec;
3450
3451 spec->autocfg.hp_pins[0] = 0x14;
3452 spec->autocfg.speaker_pins[0] = 0x1b;
3453}
3454
3455#ifdef CONFIG_SND_HDA_POWER_SAVE
3456static struct hda_amp_list alc880_loopbacks[] = {
3457 { 0x0b, HDA_INPUT, 0 },
3458 { 0x0b, HDA_INPUT, 1 },
3459 { 0x0b, HDA_INPUT, 2 },
3460 { 0x0b, HDA_INPUT, 3 },
3461 { 0x0b, HDA_INPUT, 4 },
3462 { }
3463};
3464
3465static struct hda_amp_list alc880_lg_loopbacks[] = {
3466 { 0x0b, HDA_INPUT, 1 },
3467 { 0x0b, HDA_INPUT, 6 },
3468 { 0x0b, HDA_INPUT, 7 },
3469 { }
3470};
3471#endif
3472
3473
3474
3475
3476
3477static int alc_init(struct hda_codec *codec)
3478{
3479 struct alc_spec *spec = codec->spec;
3480 unsigned int i;
3481
3482 alc_fix_pll(codec);
3483 alc_auto_init_amp(codec, spec->init_amp);
3484
3485 for (i = 0; i < spec->num_init_verbs; i++)
3486 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3487
3488 if (spec->init_hook)
3489 spec->init_hook(codec);
3490
3491#ifdef CONFIG_SND_HDA_POWER_SAVE
3492 if (codec->patch_ops.check_power_status)
3493 codec->patch_ops.check_power_status(codec, 0x01);
3494#endif
3495 return 0;
3496}
3497
3498static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3499{
3500 struct alc_spec *spec = codec->spec;
3501
3502 if (spec->unsol_event)
3503 spec->unsol_event(codec, res);
3504}
3505
3506#ifdef CONFIG_SND_HDA_POWER_SAVE
3507static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3508{
3509 struct alc_spec *spec = codec->spec;
3510 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3511}
3512#endif
3513
3514
3515
3516
3517static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3518 struct hda_codec *codec,
3519 struct snd_pcm_substream *substream)
3520{
3521 struct alc_spec *spec = codec->spec;
3522 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3523 hinfo);
3524}
3525
3526static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3527 struct hda_codec *codec,
3528 unsigned int stream_tag,
3529 unsigned int format,
3530 struct snd_pcm_substream *substream)
3531{
3532 struct alc_spec *spec = codec->spec;
3533 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3534 stream_tag, format, substream);
3535}
3536
3537static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3538 struct hda_codec *codec,
3539 struct snd_pcm_substream *substream)
3540{
3541 struct alc_spec *spec = codec->spec;
3542 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3543}
3544
3545
3546
3547
3548static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3549 struct hda_codec *codec,
3550 struct snd_pcm_substream *substream)
3551{
3552 struct alc_spec *spec = codec->spec;
3553 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3554}
3555
3556static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3557 struct hda_codec *codec,
3558 unsigned int stream_tag,
3559 unsigned int format,
3560 struct snd_pcm_substream *substream)
3561{
3562 struct alc_spec *spec = codec->spec;
3563 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3564 stream_tag, format, substream);
3565}
3566
3567static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3568 struct hda_codec *codec,
3569 struct snd_pcm_substream *substream)
3570{
3571 struct alc_spec *spec = codec->spec;
3572 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3573}
3574
3575static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3576 struct hda_codec *codec,
3577 struct snd_pcm_substream *substream)
3578{
3579 struct alc_spec *spec = codec->spec;
3580 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3581}
3582
3583
3584
3585
3586static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3587 struct hda_codec *codec,
3588 unsigned int stream_tag,
3589 unsigned int format,
3590 struct snd_pcm_substream *substream)
3591{
3592 struct alc_spec *spec = codec->spec;
3593
3594 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3595 stream_tag, 0, format);
3596 return 0;
3597}
3598
3599static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3600 struct hda_codec *codec,
3601 struct snd_pcm_substream *substream)
3602{
3603 struct alc_spec *spec = codec->spec;
3604
3605 snd_hda_codec_cleanup_stream(codec,
3606 spec->adc_nids[substream->number + 1]);
3607 return 0;
3608}
3609
3610
3611
3612
3613static struct hda_pcm_stream alc880_pcm_analog_playback = {
3614 .substreams = 1,
3615 .channels_min = 2,
3616 .channels_max = 8,
3617
3618 .ops = {
3619 .open = alc880_playback_pcm_open,
3620 .prepare = alc880_playback_pcm_prepare,
3621 .cleanup = alc880_playback_pcm_cleanup
3622 },
3623};
3624
3625static struct hda_pcm_stream alc880_pcm_analog_capture = {
3626 .substreams = 1,
3627 .channels_min = 2,
3628 .channels_max = 2,
3629
3630};
3631
3632static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3633 .substreams = 1,
3634 .channels_min = 2,
3635 .channels_max = 2,
3636
3637};
3638
3639static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3640 .substreams = 2,
3641 .channels_min = 2,
3642 .channels_max = 2,
3643
3644 .ops = {
3645 .prepare = alc880_alt_capture_pcm_prepare,
3646 .cleanup = alc880_alt_capture_pcm_cleanup
3647 },
3648};
3649
3650static struct hda_pcm_stream alc880_pcm_digital_playback = {
3651 .substreams = 1,
3652 .channels_min = 2,
3653 .channels_max = 2,
3654
3655 .ops = {
3656 .open = alc880_dig_playback_pcm_open,
3657 .close = alc880_dig_playback_pcm_close,
3658 .prepare = alc880_dig_playback_pcm_prepare,
3659 .cleanup = alc880_dig_playback_pcm_cleanup
3660 },
3661};
3662
3663static struct hda_pcm_stream alc880_pcm_digital_capture = {
3664 .substreams = 1,
3665 .channels_min = 2,
3666 .channels_max = 2,
3667
3668};
3669
3670
3671static struct hda_pcm_stream alc_pcm_null_stream = {
3672 .substreams = 0,
3673 .channels_min = 0,
3674 .channels_max = 0,
3675};
3676
3677static int alc_build_pcms(struct hda_codec *codec)
3678{
3679 struct alc_spec *spec = codec->spec;
3680 struct hda_pcm *info = spec->pcm_rec;
3681 int i;
3682
3683 codec->num_pcms = 1;
3684 codec->pcm_info = info;
3685
3686 if (spec->no_analog)
3687 goto skip_analog;
3688
3689 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3690 "%s Analog", codec->chip_name);
3691 info->name = spec->stream_name_analog;
3692
3693 if (spec->stream_analog_playback) {
3694 if (snd_BUG_ON(!spec->multiout.dac_nids))
3695 return -EINVAL;
3696 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3697 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3698 }
3699 if (spec->stream_analog_capture) {
3700 if (snd_BUG_ON(!spec->adc_nids))
3701 return -EINVAL;
3702 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3703 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3704 }
3705
3706 if (spec->channel_mode) {
3707 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3708 for (i = 0; i < spec->num_channel_mode; i++) {
3709 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3710 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3711 }
3712 }
3713 }
3714
3715 skip_analog:
3716
3717 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3718 snprintf(spec->stream_name_digital,
3719 sizeof(spec->stream_name_digital),
3720 "%s Digital", codec->chip_name);
3721 codec->num_pcms = 2;
3722 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3723 info = spec->pcm_rec + 1;
3724 info->name = spec->stream_name_digital;
3725 if (spec->dig_out_type)
3726 info->pcm_type = spec->dig_out_type;
3727 else
3728 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3729 if (spec->multiout.dig_out_nid &&
3730 spec->stream_digital_playback) {
3731 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3732 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3733 }
3734 if (spec->dig_in_nid &&
3735 spec->stream_digital_capture) {
3736 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3737 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3738 }
3739
3740 codec->spdif_status_reset = 1;
3741 }
3742
3743 if (spec->no_analog)
3744 return 0;
3745
3746
3747
3748
3749
3750 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3751 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3752 codec->num_pcms = 3;
3753 info = spec->pcm_rec + 2;
3754 info->name = spec->stream_name_analog;
3755 if (spec->alt_dac_nid) {
3756 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3757 *spec->stream_analog_alt_playback;
3758 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3759 spec->alt_dac_nid;
3760 } else {
3761 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3762 alc_pcm_null_stream;
3763 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3764 }
3765 if (spec->num_adc_nids > 1) {
3766 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3767 *spec->stream_analog_alt_capture;
3768 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3769 spec->adc_nids[1];
3770 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3771 spec->num_adc_nids - 1;
3772 } else {
3773 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3774 alc_pcm_null_stream;
3775 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3776 }
3777 }
3778
3779 return 0;
3780}
3781
3782static inline void alc_shutup(struct hda_codec *codec)
3783{
3784 snd_hda_shutup_pins(codec);
3785}
3786
3787static void alc_free_kctls(struct hda_codec *codec)
3788{
3789 struct alc_spec *spec = codec->spec;
3790
3791 if (spec->kctls.list) {
3792 struct snd_kcontrol_new *kctl = spec->kctls.list;
3793 int i;
3794 for (i = 0; i < spec->kctls.used; i++)
3795 kfree(kctl[i].name);
3796 }
3797 snd_array_free(&spec->kctls);
3798}
3799
3800static void alc_free(struct hda_codec *codec)
3801{
3802 struct alc_spec *spec = codec->spec;
3803
3804 if (!spec)
3805 return;
3806
3807 alc_shutup(codec);
3808 alc_free_kctls(codec);
3809 kfree(spec);
3810 snd_hda_detach_beep_device(codec);
3811}
3812
3813#ifdef CONFIG_SND_HDA_POWER_SAVE
3814static void alc_power_eapd(struct hda_codec *codec)
3815{
3816
3817 switch (codec->vendor_id) {
3818 case 0x10ec0260:
3819 set_eapd(codec, 0x0f, 0);
3820 set_eapd(codec, 0x10, 0);
3821 break;
3822 case 0x10ec0262:
3823 case 0x10ec0267:
3824 case 0x10ec0268:
3825 case 0x10ec0269:
3826 case 0x10ec0270:
3827 case 0x10ec0272:
3828 case 0x10ec0660:
3829 case 0x10ec0662:
3830 case 0x10ec0663:
3831 case 0x10ec0862:
3832 case 0x10ec0889:
3833 set_eapd(codec, 0x14, 0);
3834 set_eapd(codec, 0x15, 0);
3835 break;
3836 }
3837}
3838
3839static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3840{
3841 struct alc_spec *spec = codec->spec;
3842 alc_shutup(codec);
3843 if (spec && spec->power_hook)
3844 spec->power_hook(codec);
3845 return 0;
3846}
3847#endif
3848
3849#ifdef SND_HDA_NEEDS_RESUME
3850static int alc_resume(struct hda_codec *codec)
3851{
3852 codec->patch_ops.init(codec);
3853 snd_hda_codec_resume_amp(codec);
3854 snd_hda_codec_resume_cache(codec);
3855#ifdef CONFIG_SND_HDA_POWER_SAVE
3856 if (codec->patch_ops.check_power_status)
3857 codec->patch_ops.check_power_status(codec, 0x01);
3858#endif
3859 return 0;
3860}
3861#endif
3862
3863
3864
3865static struct hda_codec_ops alc_patch_ops = {
3866 .build_controls = alc_build_controls,
3867 .build_pcms = alc_build_pcms,
3868 .init = alc_init,
3869 .free = alc_free,
3870 .unsol_event = alc_unsol_event,
3871#ifdef SND_HDA_NEEDS_RESUME
3872 .resume = alc_resume,
3873#endif
3874#ifdef CONFIG_SND_HDA_POWER_SAVE
3875 .suspend = alc_suspend,
3876 .check_power_status = alc_check_power_status,
3877#endif
3878 .reboot_notify = alc_shutup,
3879};
3880
3881
3882static int alc_codec_rename(struct hda_codec *codec, const char *name)
3883{
3884 kfree(codec->chip_name);
3885 codec->chip_name = kstrdup(name, GFP_KERNEL);
3886 if (!codec->chip_name) {
3887 alc_free(codec);
3888 return -ENOMEM;
3889 }
3890 return 0;
3891}
3892
3893
3894
3895
3896
3897
3898
3899#ifdef CONFIG_SND_DEBUG
3900static hda_nid_t alc880_test_dac_nids[4] = {
3901 0x02, 0x03, 0x04, 0x05
3902};
3903
3904static struct hda_input_mux alc880_test_capture_source = {
3905 .num_items = 7,
3906 .items = {
3907 { "In-1", 0x0 },
3908 { "In-2", 0x1 },
3909 { "In-3", 0x2 },
3910 { "In-4", 0x3 },
3911 { "CD", 0x4 },
3912 { "Front", 0x5 },
3913 { "Surround", 0x6 },
3914 },
3915};
3916
3917static struct hda_channel_mode alc880_test_modes[4] = {
3918 { 2, NULL },
3919 { 4, NULL },
3920 { 6, NULL },
3921 { 8, NULL },
3922};
3923
3924static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3925 struct snd_ctl_elem_info *uinfo)
3926{
3927 static char *texts[] = {
3928 "N/A", "Line Out", "HP Out",
3929 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3930 };
3931 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3932 uinfo->count = 1;
3933 uinfo->value.enumerated.items = 8;
3934 if (uinfo->value.enumerated.item >= 8)
3935 uinfo->value.enumerated.item = 7;
3936 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3937 return 0;
3938}
3939
3940static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3941 struct snd_ctl_elem_value *ucontrol)
3942{
3943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3944 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3945 unsigned int pin_ctl, item = 0;
3946
3947 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3948 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3949 if (pin_ctl & AC_PINCTL_OUT_EN) {
3950 if (pin_ctl & AC_PINCTL_HP_EN)
3951 item = 2;
3952 else
3953 item = 1;
3954 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3955 switch (pin_ctl & AC_PINCTL_VREFEN) {
3956 case AC_PINCTL_VREF_HIZ: item = 3; break;
3957 case AC_PINCTL_VREF_50: item = 4; break;
3958 case AC_PINCTL_VREF_GRD: item = 5; break;
3959 case AC_PINCTL_VREF_80: item = 6; break;
3960 case AC_PINCTL_VREF_100: item = 7; break;
3961 }
3962 }
3963 ucontrol->value.enumerated.item[0] = item;
3964 return 0;
3965}
3966
3967static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3968 struct snd_ctl_elem_value *ucontrol)
3969{
3970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3971 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3972 static unsigned int ctls[] = {
3973 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3974 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3975 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3976 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3977 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3978 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3979 };
3980 unsigned int old_ctl, new_ctl;
3981
3982 old_ctl = snd_hda_codec_read(codec, nid, 0,
3983 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3984 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3985 if (old_ctl != new_ctl) {
3986 int val;
3987 snd_hda_codec_write_cache(codec, nid, 0,
3988 AC_VERB_SET_PIN_WIDGET_CONTROL,
3989 new_ctl);
3990 val = ucontrol->value.enumerated.item[0] >= 3 ?
3991 HDA_AMP_MUTE : 0;
3992 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3993 HDA_AMP_MUTE, val);
3994 return 1;
3995 }
3996 return 0;
3997}
3998
3999static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4000 struct snd_ctl_elem_info *uinfo)
4001{
4002 static char *texts[] = {
4003 "Front", "Surround", "CLFE", "Side"
4004 };
4005 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4006 uinfo->count = 1;
4007 uinfo->value.enumerated.items = 4;
4008 if (uinfo->value.enumerated.item >= 4)
4009 uinfo->value.enumerated.item = 3;
4010 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4011 return 0;
4012}
4013
4014static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4015 struct snd_ctl_elem_value *ucontrol)
4016{
4017 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4018 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4019 unsigned int sel;
4020
4021 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4022 ucontrol->value.enumerated.item[0] = sel & 3;
4023 return 0;
4024}
4025
4026static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4027 struct snd_ctl_elem_value *ucontrol)
4028{
4029 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4030 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4031 unsigned int sel;
4032
4033 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4034 if (ucontrol->value.enumerated.item[0] != sel) {
4035 sel = ucontrol->value.enumerated.item[0] & 3;
4036 snd_hda_codec_write_cache(codec, nid, 0,
4037 AC_VERB_SET_CONNECT_SEL, sel);
4038 return 1;
4039 }
4040 return 0;
4041}
4042
4043#define PIN_CTL_TEST(xname,nid) { \
4044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4045 .name = xname, \
4046 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4047 .info = alc_test_pin_ctl_info, \
4048 .get = alc_test_pin_ctl_get, \
4049 .put = alc_test_pin_ctl_put, \
4050 .private_value = nid \
4051 }
4052
4053#define PIN_SRC_TEST(xname,nid) { \
4054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4055 .name = xname, \
4056 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4057 .info = alc_test_pin_src_info, \
4058 .get = alc_test_pin_src_get, \
4059 .put = alc_test_pin_src_put, \
4060 .private_value = nid \
4061 }
4062
4063static struct snd_kcontrol_new alc880_test_mixer[] = {
4064 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4065 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4066 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4067 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4068 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4069 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4070 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4071 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4072 PIN_CTL_TEST("Front Pin Mode", 0x14),
4073 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4074 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4075 PIN_CTL_TEST("Side Pin Mode", 0x17),
4076 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4077 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4078 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4079 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4080 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4081 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4082 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4083 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4084 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4085 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4086 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4087 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4088 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4089 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4090 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4091 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4092 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4093 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4094 {
4095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4096 .name = "Channel Mode",
4097 .info = alc_ch_mode_info,
4098 .get = alc_ch_mode_get,
4099 .put = alc_ch_mode_put,
4100 },
4101 { }
4102};
4103
4104static struct hda_verb alc880_test_init_verbs[] = {
4105
4106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4113 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4114
4115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4116 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4117 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4118 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4119
4120 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4121 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4122 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4124
4125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4127 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4128 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4129
4130 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4131 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4132 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4133 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4134 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4135
4136 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4139 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4140
4141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4142 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4143 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4144 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4145 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4146 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4147
4148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4153 { }
4154};
4155#endif
4156
4157
4158
4159
4160static const char *alc880_models[ALC880_MODEL_LAST] = {
4161 [ALC880_3ST] = "3stack",
4162 [ALC880_TCL_S700] = "tcl",
4163 [ALC880_3ST_DIG] = "3stack-digout",
4164 [ALC880_CLEVO] = "clevo",
4165 [ALC880_5ST] = "5stack",
4166 [ALC880_5ST_DIG] = "5stack-digout",
4167 [ALC880_W810] = "w810",
4168 [ALC880_Z71V] = "z71v",
4169 [ALC880_6ST] = "6stack",
4170 [ALC880_6ST_DIG] = "6stack-digout",
4171 [ALC880_ASUS] = "asus",
4172 [ALC880_ASUS_W1V] = "asus-w1v",
4173 [ALC880_ASUS_DIG] = "asus-dig",
4174 [ALC880_ASUS_DIG2] = "asus-dig2",
4175 [ALC880_UNIWILL_DIG] = "uniwill",
4176 [ALC880_UNIWILL_P53] = "uniwill-p53",
4177 [ALC880_FUJITSU] = "fujitsu",
4178 [ALC880_F1734] = "F1734",
4179 [ALC880_LG] = "lg",
4180 [ALC880_LG_LW] = "lg-lw",
4181 [ALC880_MEDION_RIM] = "medion",
4182#ifdef CONFIG_SND_DEBUG
4183 [ALC880_TEST] = "test",
4184#endif
4185 [ALC880_AUTO] = "auto",
4186};
4187
4188static struct snd_pci_quirk alc880_cfg_tbl[] = {
4189 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4190 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4191 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4192 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4193 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4194 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4195 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4196 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4197 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4198 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4199 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4200 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4201 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4202 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4203 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4204 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4205 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4206 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4207
4208 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4209 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4210 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4211 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4212 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4213 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4214 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS),
4215 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4216 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4217 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4218 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4219 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4220 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4221 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4222 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4223 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4224 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4225 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4226 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4227 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4228 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4229 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4230 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4231 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4232 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4233 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4234 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4235 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4236 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4237 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4238 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4239 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4240 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4241 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4242 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4243 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4244 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4245 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
4246 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4247 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4248 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4249 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4250 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4251 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4252 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4253 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4254 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4255 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4256 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4257
4258 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4259 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4260 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4261 {}
4262};
4263
4264
4265
4266
4267static struct alc_config_preset alc880_presets[] = {
4268 [ALC880_3ST] = {
4269 .mixers = { alc880_three_stack_mixer },
4270 .init_verbs = { alc880_volume_init_verbs,
4271 alc880_pin_3stack_init_verbs },
4272 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4273 .dac_nids = alc880_dac_nids,
4274 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4275 .channel_mode = alc880_threestack_modes,
4276 .need_dac_fix = 1,
4277 .input_mux = &alc880_capture_source,
4278 },
4279 [ALC880_3ST_DIG] = {
4280 .mixers = { alc880_three_stack_mixer },
4281 .init_verbs = { alc880_volume_init_verbs,
4282 alc880_pin_3stack_init_verbs },
4283 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4284 .dac_nids = alc880_dac_nids,
4285 .dig_out_nid = ALC880_DIGOUT_NID,
4286 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4287 .channel_mode = alc880_threestack_modes,
4288 .need_dac_fix = 1,
4289 .input_mux = &alc880_capture_source,
4290 },
4291 [ALC880_TCL_S700] = {
4292 .mixers = { alc880_tcl_s700_mixer },
4293 .init_verbs = { alc880_volume_init_verbs,
4294 alc880_pin_tcl_S700_init_verbs,
4295 alc880_gpio2_init_verbs },
4296 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4297 .dac_nids = alc880_dac_nids,
4298 .adc_nids = alc880_adc_nids_alt,
4299 .num_adc_nids = 1,
4300 .hp_nid = 0x03,
4301 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4302 .channel_mode = alc880_2_jack_modes,
4303 .input_mux = &alc880_capture_source,
4304 },
4305 [ALC880_5ST] = {
4306 .mixers = { alc880_three_stack_mixer,
4307 alc880_five_stack_mixer},
4308 .init_verbs = { alc880_volume_init_verbs,
4309 alc880_pin_5stack_init_verbs },
4310 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4311 .dac_nids = alc880_dac_nids,
4312 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4313 .channel_mode = alc880_fivestack_modes,
4314 .input_mux = &alc880_capture_source,
4315 },
4316 [ALC880_5ST_DIG] = {
4317 .mixers = { alc880_three_stack_mixer,
4318 alc880_five_stack_mixer },
4319 .init_verbs = { alc880_volume_init_verbs,
4320 alc880_pin_5stack_init_verbs },
4321 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4322 .dac_nids = alc880_dac_nids,
4323 .dig_out_nid = ALC880_DIGOUT_NID,
4324 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4325 .channel_mode = alc880_fivestack_modes,
4326 .input_mux = &alc880_capture_source,
4327 },
4328 [ALC880_6ST] = {
4329 .mixers = { alc880_six_stack_mixer },
4330 .init_verbs = { alc880_volume_init_verbs,
4331 alc880_pin_6stack_init_verbs },
4332 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4333 .dac_nids = alc880_6st_dac_nids,
4334 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4335 .channel_mode = alc880_sixstack_modes,
4336 .input_mux = &alc880_6stack_capture_source,
4337 },
4338 [ALC880_6ST_DIG] = {
4339 .mixers = { alc880_six_stack_mixer },
4340 .init_verbs = { alc880_volume_init_verbs,
4341 alc880_pin_6stack_init_verbs },
4342 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4343 .dac_nids = alc880_6st_dac_nids,
4344 .dig_out_nid = ALC880_DIGOUT_NID,
4345 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4346 .channel_mode = alc880_sixstack_modes,
4347 .input_mux = &alc880_6stack_capture_source,
4348 },
4349 [ALC880_W810] = {
4350 .mixers = { alc880_w810_base_mixer },
4351 .init_verbs = { alc880_volume_init_verbs,
4352 alc880_pin_w810_init_verbs,
4353 alc880_gpio2_init_verbs },
4354 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4355 .dac_nids = alc880_w810_dac_nids,
4356 .dig_out_nid = ALC880_DIGOUT_NID,
4357 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4358 .channel_mode = alc880_w810_modes,
4359 .input_mux = &alc880_capture_source,
4360 },
4361 [ALC880_Z71V] = {
4362 .mixers = { alc880_z71v_mixer },
4363 .init_verbs = { alc880_volume_init_verbs,
4364 alc880_pin_z71v_init_verbs },
4365 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4366 .dac_nids = alc880_z71v_dac_nids,
4367 .dig_out_nid = ALC880_DIGOUT_NID,
4368 .hp_nid = 0x03,
4369 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4370 .channel_mode = alc880_2_jack_modes,
4371 .input_mux = &alc880_capture_source,
4372 },
4373 [ALC880_F1734] = {
4374 .mixers = { alc880_f1734_mixer },
4375 .init_verbs = { alc880_volume_init_verbs,
4376 alc880_pin_f1734_init_verbs },
4377 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4378 .dac_nids = alc880_f1734_dac_nids,
4379 .hp_nid = 0x02,
4380 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4381 .channel_mode = alc880_2_jack_modes,
4382 .input_mux = &alc880_f1734_capture_source,
4383 .unsol_event = alc880_uniwill_p53_unsol_event,
4384 .setup = alc880_uniwill_p53_setup,
4385 .init_hook = alc_automute_amp,
4386 },
4387 [ALC880_ASUS] = {
4388 .mixers = { alc880_asus_mixer },
4389 .init_verbs = { alc880_volume_init_verbs,
4390 alc880_pin_asus_init_verbs,
4391 alc880_gpio1_init_verbs },
4392 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4393 .dac_nids = alc880_asus_dac_nids,
4394 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4395 .channel_mode = alc880_asus_modes,
4396 .need_dac_fix = 1,
4397 .input_mux = &alc880_capture_source,
4398 },
4399 [ALC880_ASUS_DIG] = {
4400 .mixers = { alc880_asus_mixer },
4401 .init_verbs = { alc880_volume_init_verbs,
4402 alc880_pin_asus_init_verbs,
4403 alc880_gpio1_init_verbs },
4404 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4405 .dac_nids = alc880_asus_dac_nids,
4406 .dig_out_nid = ALC880_DIGOUT_NID,
4407 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4408 .channel_mode = alc880_asus_modes,
4409 .need_dac_fix = 1,
4410 .input_mux = &alc880_capture_source,
4411 },
4412 [ALC880_ASUS_DIG2] = {
4413 .mixers = { alc880_asus_mixer },
4414 .init_verbs = { alc880_volume_init_verbs,
4415 alc880_pin_asus_init_verbs,
4416 alc880_gpio2_init_verbs },
4417 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4418 .dac_nids = alc880_asus_dac_nids,
4419 .dig_out_nid = ALC880_DIGOUT_NID,
4420 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4421 .channel_mode = alc880_asus_modes,
4422 .need_dac_fix = 1,
4423 .input_mux = &alc880_capture_source,
4424 },
4425 [ALC880_ASUS_W1V] = {
4426 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4427 .init_verbs = { alc880_volume_init_verbs,
4428 alc880_pin_asus_init_verbs,
4429 alc880_gpio1_init_verbs },
4430 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4431 .dac_nids = alc880_asus_dac_nids,
4432 .dig_out_nid = ALC880_DIGOUT_NID,
4433 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4434 .channel_mode = alc880_asus_modes,
4435 .need_dac_fix = 1,
4436 .input_mux = &alc880_capture_source,
4437 },
4438 [ALC880_UNIWILL_DIG] = {
4439 .mixers = { alc880_asus_mixer },
4440 .init_verbs = { alc880_volume_init_verbs,
4441 alc880_pin_asus_init_verbs },
4442 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4443 .dac_nids = alc880_asus_dac_nids,
4444 .dig_out_nid = ALC880_DIGOUT_NID,
4445 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4446 .channel_mode = alc880_asus_modes,
4447 .need_dac_fix = 1,
4448 .input_mux = &alc880_capture_source,
4449 },
4450 [ALC880_UNIWILL] = {
4451 .mixers = { alc880_uniwill_mixer },
4452 .init_verbs = { alc880_volume_init_verbs,
4453 alc880_uniwill_init_verbs },
4454 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4455 .dac_nids = alc880_asus_dac_nids,
4456 .dig_out_nid = ALC880_DIGOUT_NID,
4457 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4458 .channel_mode = alc880_threestack_modes,
4459 .need_dac_fix = 1,
4460 .input_mux = &alc880_capture_source,
4461 .unsol_event = alc880_uniwill_unsol_event,
4462 .setup = alc880_uniwill_setup,
4463 .init_hook = alc880_uniwill_init_hook,
4464 },
4465 [ALC880_UNIWILL_P53] = {
4466 .mixers = { alc880_uniwill_p53_mixer },
4467 .init_verbs = { alc880_volume_init_verbs,
4468 alc880_uniwill_p53_init_verbs },
4469 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4470 .dac_nids = alc880_asus_dac_nids,
4471 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4472 .channel_mode = alc880_threestack_modes,
4473 .input_mux = &alc880_capture_source,
4474 .unsol_event = alc880_uniwill_p53_unsol_event,
4475 .setup = alc880_uniwill_p53_setup,
4476 .init_hook = alc_automute_amp,
4477 },
4478 [ALC880_FUJITSU] = {
4479 .mixers = { alc880_fujitsu_mixer },
4480 .init_verbs = { alc880_volume_init_verbs,
4481 alc880_uniwill_p53_init_verbs,
4482 alc880_beep_init_verbs },
4483 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4484 .dac_nids = alc880_dac_nids,
4485 .dig_out_nid = ALC880_DIGOUT_NID,
4486 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4487 .channel_mode = alc880_2_jack_modes,
4488 .input_mux = &alc880_capture_source,
4489 .unsol_event = alc880_uniwill_p53_unsol_event,
4490 .setup = alc880_uniwill_p53_setup,
4491 .init_hook = alc_automute_amp,
4492 },
4493 [ALC880_CLEVO] = {
4494 .mixers = { alc880_three_stack_mixer },
4495 .init_verbs = { alc880_volume_init_verbs,
4496 alc880_pin_clevo_init_verbs },
4497 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4498 .dac_nids = alc880_dac_nids,
4499 .hp_nid = 0x03,
4500 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4501 .channel_mode = alc880_threestack_modes,
4502 .need_dac_fix = 1,
4503 .input_mux = &alc880_capture_source,
4504 },
4505 [ALC880_LG] = {
4506 .mixers = { alc880_lg_mixer },
4507 .init_verbs = { alc880_volume_init_verbs,
4508 alc880_lg_init_verbs },
4509 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4510 .dac_nids = alc880_lg_dac_nids,
4511 .dig_out_nid = ALC880_DIGOUT_NID,
4512 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4513 .channel_mode = alc880_lg_ch_modes,
4514 .need_dac_fix = 1,
4515 .input_mux = &alc880_lg_capture_source,
4516 .unsol_event = alc_automute_amp_unsol_event,
4517 .setup = alc880_lg_setup,
4518 .init_hook = alc_automute_amp,
4519#ifdef CONFIG_SND_HDA_POWER_SAVE
4520 .loopbacks = alc880_lg_loopbacks,
4521#endif
4522 },
4523 [ALC880_LG_LW] = {
4524 .mixers = { alc880_lg_lw_mixer },
4525 .init_verbs = { alc880_volume_init_verbs,
4526 alc880_lg_lw_init_verbs },
4527 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4528 .dac_nids = alc880_dac_nids,
4529 .dig_out_nid = ALC880_DIGOUT_NID,
4530 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4531 .channel_mode = alc880_lg_lw_modes,
4532 .input_mux = &alc880_lg_lw_capture_source,
4533 .unsol_event = alc_automute_amp_unsol_event,
4534 .setup = alc880_lg_lw_setup,
4535 .init_hook = alc_automute_amp,
4536 },
4537 [ALC880_MEDION_RIM] = {
4538 .mixers = { alc880_medion_rim_mixer },
4539 .init_verbs = { alc880_volume_init_verbs,
4540 alc880_medion_rim_init_verbs,
4541 alc_gpio2_init_verbs },
4542 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4543 .dac_nids = alc880_dac_nids,
4544 .dig_out_nid = ALC880_DIGOUT_NID,
4545 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4546 .channel_mode = alc880_2_jack_modes,
4547 .input_mux = &alc880_medion_rim_capture_source,
4548 .unsol_event = alc880_medion_rim_unsol_event,
4549 .setup = alc880_medion_rim_setup,
4550 .init_hook = alc880_medion_rim_automute,
4551 },
4552#ifdef CONFIG_SND_DEBUG
4553 [ALC880_TEST] = {
4554 .mixers = { alc880_test_mixer },
4555 .init_verbs = { alc880_test_init_verbs },
4556 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4557 .dac_nids = alc880_test_dac_nids,
4558 .dig_out_nid = ALC880_DIGOUT_NID,
4559 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4560 .channel_mode = alc880_test_modes,
4561 .input_mux = &alc880_test_capture_source,
4562 },
4563#endif
4564};
4565
4566
4567
4568
4569
4570enum {
4571 ALC_CTL_WIDGET_VOL,
4572 ALC_CTL_WIDGET_MUTE,
4573 ALC_CTL_BIND_MUTE,
4574};
4575static struct snd_kcontrol_new alc880_control_templates[] = {
4576 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4577 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4578 HDA_BIND_MUTE(NULL, 0, 0, 0),
4579};
4580
4581
4582static int add_control(struct alc_spec *spec, int type, const char *name,
4583 unsigned long val)
4584{
4585 struct snd_kcontrol_new *knew;
4586
4587 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4588 knew = snd_array_new(&spec->kctls);
4589 if (!knew)
4590 return -ENOMEM;
4591 *knew = alc880_control_templates[type];
4592 knew->name = kstrdup(name, GFP_KERNEL);
4593 if (!knew->name)
4594 return -ENOMEM;
4595 if (get_amp_nid_(val))
4596 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4597 knew->private_value = val;
4598 return 0;
4599}
4600
4601static int add_control_with_pfx(struct alc_spec *spec, int type,
4602 const char *pfx, const char *dir,
4603 const char *sfx, unsigned long val)
4604{
4605 char name[32];
4606 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4607 return add_control(spec, type, name, val);
4608}
4609
4610#define add_pb_vol_ctrl(spec, type, pfx, val) \
4611 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4612#define add_pb_sw_ctrl(spec, type, pfx, val) \
4613 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4614
4615#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4616#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4617#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4618#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4619#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4620#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4621#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4622#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4623#define ALC880_PIN_CD_NID 0x1c
4624
4625
4626static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4627 const struct auto_pin_cfg *cfg)
4628{
4629 hda_nid_t nid;
4630 int assigned[4];
4631 int i, j;
4632
4633 memset(assigned, 0, sizeof(assigned));
4634 spec->multiout.dac_nids = spec->private_dac_nids;
4635
4636
4637 for (i = 0; i < cfg->line_outs; i++) {
4638 nid = cfg->line_out_pins[i];
4639 if (alc880_is_fixed_pin(nid)) {
4640 int idx = alc880_fixed_pin_idx(nid);
4641 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4642 assigned[idx] = 1;
4643 }
4644 }
4645
4646 for (i = 0; i < cfg->line_outs; i++) {
4647 nid = cfg->line_out_pins[i];
4648 if (alc880_is_fixed_pin(nid))
4649 continue;
4650
4651 for (j = 0; j < cfg->line_outs; j++) {
4652 if (!assigned[j]) {
4653 spec->multiout.dac_nids[i] =
4654 alc880_idx_to_dac(j);
4655 assigned[j] = 1;
4656 break;
4657 }
4658 }
4659 }
4660 spec->multiout.num_dacs = cfg->line_outs;
4661 return 0;
4662}
4663
4664
4665static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4666 const struct auto_pin_cfg *cfg)
4667{
4668 static const char *chname[4] = {
4669 "Front", "Surround", NULL , "Side"
4670 };
4671 hda_nid_t nid;
4672 int i, err;
4673
4674 for (i = 0; i < cfg->line_outs; i++) {
4675 if (!spec->multiout.dac_nids[i])
4676 continue;
4677 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4678 if (i == 2) {
4679
4680 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4681 "Center",
4682 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4683 HDA_OUTPUT));
4684 if (err < 0)
4685 return err;
4686 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4687 "LFE",
4688 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4689 HDA_OUTPUT));
4690 if (err < 0)
4691 return err;
4692 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4693 "Center",
4694 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4695 HDA_INPUT));
4696 if (err < 0)
4697 return err;
4698 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4699 "LFE",
4700 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4701 HDA_INPUT));
4702 if (err < 0)
4703 return err;
4704 } else {
4705 const char *pfx;
4706 if (cfg->line_outs == 1 &&
4707 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4708 pfx = "Speaker";
4709 else
4710 pfx = chname[i];
4711 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4712 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4713 HDA_OUTPUT));
4714 if (err < 0)
4715 return err;
4716 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4717 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4718 HDA_INPUT));
4719 if (err < 0)
4720 return err;
4721 }
4722 }
4723 return 0;
4724}
4725
4726
4727static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4728 const char *pfx)
4729{
4730 hda_nid_t nid;
4731 int err;
4732
4733 if (!pin)
4734 return 0;
4735
4736 if (alc880_is_fixed_pin(pin)) {
4737 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4738
4739 if (!spec->multiout.hp_nid)
4740 spec->multiout.hp_nid = nid;
4741 else
4742 spec->multiout.extra_out_nid[0] = nid;
4743
4744 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4745 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4746 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4747 if (err < 0)
4748 return err;
4749 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4750 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4751 if (err < 0)
4752 return err;
4753 } else if (alc880_is_multi_pin(pin)) {
4754
4755
4756 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4757 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4758 if (err < 0)
4759 return err;
4760 }
4761 return 0;
4762}
4763
4764
4765static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4766 const char *ctlname,
4767 int idx, hda_nid_t mix_nid)
4768{
4769 int err;
4770
4771 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4772 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4773 if (err < 0)
4774 return err;
4775 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4776 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4777 if (err < 0)
4778 return err;
4779 return 0;
4780}
4781
4782static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4783{
4784 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4785 return (pincap & AC_PINCAP_IN) != 0;
4786}
4787
4788
4789static int alc_auto_create_input_ctls(struct hda_codec *codec,
4790 const struct auto_pin_cfg *cfg,
4791 hda_nid_t mixer,
4792 hda_nid_t cap1, hda_nid_t cap2)
4793{
4794 struct alc_spec *spec = codec->spec;
4795 struct hda_input_mux *imux = &spec->private_imux[0];
4796 int i, err, idx;
4797
4798 for (i = 0; i < AUTO_PIN_LAST; i++) {
4799 hda_nid_t pin;
4800
4801 pin = cfg->input_pins[i];
4802 if (!alc_is_input_pin(codec, pin))
4803 continue;
4804
4805 if (mixer) {
4806 idx = get_connection_index(codec, mixer, pin);
4807 if (idx >= 0) {
4808 err = new_analog_input(spec, pin,
4809 auto_pin_cfg_labels[i],
4810 idx, mixer);
4811 if (err < 0)
4812 return err;
4813 }
4814 }
4815
4816 if (!cap1)
4817 continue;
4818 idx = get_connection_index(codec, cap1, pin);
4819 if (idx < 0 && cap2)
4820 idx = get_connection_index(codec, cap2, pin);
4821 if (idx >= 0) {
4822 imux->items[imux->num_items].label =
4823 auto_pin_cfg_labels[i];
4824 imux->items[imux->num_items].index = idx;
4825 imux->num_items++;
4826 }
4827 }
4828 return 0;
4829}
4830
4831static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4832 const struct auto_pin_cfg *cfg)
4833{
4834 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4835}
4836
4837static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4838 unsigned int pin_type)
4839{
4840 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4841 pin_type);
4842
4843 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4844 AMP_OUT_UNMUTE);
4845}
4846
4847static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4848 hda_nid_t nid, int pin_type,
4849 int dac_idx)
4850{
4851 alc_set_pin_output(codec, nid, pin_type);
4852
4853 if (alc880_is_multi_pin(nid)) {
4854 struct alc_spec *spec = codec->spec;
4855 int idx = alc880_multi_pin_idx(nid);
4856 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4857 AC_VERB_SET_CONNECT_SEL,
4858 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4859 }
4860}
4861
4862static int get_pin_type(int line_out_type)
4863{
4864 if (line_out_type == AUTO_PIN_HP_OUT)
4865 return PIN_HP;
4866 else
4867 return PIN_OUT;
4868}
4869
4870static void alc880_auto_init_multi_out(struct hda_codec *codec)
4871{
4872 struct alc_spec *spec = codec->spec;
4873 int i;
4874
4875 for (i = 0; i < spec->autocfg.line_outs; i++) {
4876 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4877 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4878 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4879 }
4880}
4881
4882static void alc880_auto_init_extra_out(struct hda_codec *codec)
4883{
4884 struct alc_spec *spec = codec->spec;
4885 hda_nid_t pin;
4886
4887 pin = spec->autocfg.speaker_pins[0];
4888 if (pin)
4889 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4890 pin = spec->autocfg.hp_pins[0];
4891 if (pin)
4892 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4893}
4894
4895static void alc880_auto_init_analog_input(struct hda_codec *codec)
4896{
4897 struct alc_spec *spec = codec->spec;
4898 int i;
4899
4900 for (i = 0; i < AUTO_PIN_LAST; i++) {
4901 hda_nid_t nid = spec->autocfg.input_pins[i];
4902 if (alc_is_input_pin(codec, nid)) {
4903 alc_set_input_pin(codec, nid, i);
4904 if (nid != ALC880_PIN_CD_NID &&
4905 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4906 snd_hda_codec_write(codec, nid, 0,
4907 AC_VERB_SET_AMP_GAIN_MUTE,
4908 AMP_OUT_MUTE);
4909 }
4910 }
4911}
4912
4913static void alc880_auto_init_input_src(struct hda_codec *codec)
4914{
4915 struct alc_spec *spec = codec->spec;
4916 int c;
4917
4918 for (c = 0; c < spec->num_adc_nids; c++) {
4919 unsigned int mux_idx;
4920 const struct hda_input_mux *imux;
4921 mux_idx = c >= spec->num_mux_defs ? 0 : c;
4922 imux = &spec->input_mux[mux_idx];
4923 if (!imux->num_items && mux_idx > 0)
4924 imux = &spec->input_mux[0];
4925 if (imux)
4926 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
4927 AC_VERB_SET_CONNECT_SEL,
4928 imux->items[0].index);
4929 }
4930}
4931
4932
4933
4934
4935
4936static int alc880_parse_auto_config(struct hda_codec *codec)
4937{
4938 struct alc_spec *spec = codec->spec;
4939 int i, err;
4940 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4941
4942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4943 alc880_ignore);
4944 if (err < 0)
4945 return err;
4946 if (!spec->autocfg.line_outs)
4947 return 0;
4948
4949 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4950 if (err < 0)
4951 return err;
4952 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4953 if (err < 0)
4954 return err;
4955 err = alc880_auto_create_extra_out(spec,
4956 spec->autocfg.speaker_pins[0],
4957 "Speaker");
4958 if (err < 0)
4959 return err;
4960 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4961 "Headphone");
4962 if (err < 0)
4963 return err;
4964 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4965 if (err < 0)
4966 return err;
4967
4968 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4969
4970
4971 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4972 hda_nid_t dig_nid;
4973 err = snd_hda_get_connections(codec,
4974 spec->autocfg.dig_out_pins[i],
4975 &dig_nid, 1);
4976 if (err < 0)
4977 continue;
4978 if (!i)
4979 spec->multiout.dig_out_nid = dig_nid;
4980 else {
4981 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4982 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4983 break;
4984 spec->slave_dig_outs[i - 1] = dig_nid;
4985 }
4986 }
4987 if (spec->autocfg.dig_in_pin)
4988 spec->dig_in_nid = ALC880_DIGIN_NID;
4989
4990 if (spec->kctls.list)
4991 add_mixer(spec, spec->kctls.list);
4992
4993 add_verb(spec, alc880_volume_init_verbs);
4994
4995 spec->num_mux_defs = 1;
4996 spec->input_mux = &spec->private_imux[0];
4997
4998 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4999
5000 return 1;
5001}
5002
5003
5004static void alc880_auto_init(struct hda_codec *codec)
5005{
5006 struct alc_spec *spec = codec->spec;
5007 alc880_auto_init_multi_out(codec);
5008 alc880_auto_init_extra_out(codec);
5009 alc880_auto_init_analog_input(codec);
5010 alc880_auto_init_input_src(codec);
5011 if (spec->unsol_event)
5012 alc_inithook(codec);
5013}
5014
5015
5016
5017
5018static void fixup_automic_adc(struct hda_codec *codec)
5019{
5020 struct alc_spec *spec = codec->spec;
5021 int i;
5022
5023 for (i = 0; i < spec->num_adc_nids; i++) {