patch_realtek.c revision fc091769a5aa65c045bfbda149c424ba33d0abbb
1/* 2 * Universal Interface for Intel High Definition Audio Codec 3 * 4 * HD audio interface patch for ALC 260/880/882 codecs 5 * 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw> 8 * Takashi Iwai <tiwai@suse.de> 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au> 10 * 11 * This driver is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This driver is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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/* ALC880 board config type */ 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 /* last tag */ 69}; 70 71/* ALC260 models */ 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 /* last tag */ 87}; 88 89/* ALC262 models */ 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 /* last tag */ 111}; 112 113/* ALC268 models */ 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 /* last tag */ 128}; 129 130/* ALC269 models */ 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 /* last tag */ 142}; 143 144/* ALC861 models */ 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/* ALC861-VD models */ 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/* ALC662 models */ 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/* ALC882 models */ 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/* ALC680 models */ 260enum { 261 ALC680_BASE, 262 ALC680_AUTO, 263 ALC680_MODEL_LAST, 264}; 265 266/* for GPIO Poll */ 267#define GPIO_MASK 0x03 268 269/* extra amp-initialization sequence types */ 270enum { 271 ALC_INIT_NONE, 272 ALC_INIT_DEFAULT, 273 ALC_INIT_GPIO1, 274 ALC_INIT_GPIO2, 275 ALC_INIT_GPIO3, 276}; 277 278struct alc_mic_route { 279 hda_nid_t pin; 280 unsigned char mux_idx; 281 unsigned char amix_idx; 282}; 283 284#define MUX_IDX_UNDEF ((unsigned char)-1) 285 286struct alc_customize_define { 287 unsigned int sku_cfg; 288 unsigned char port_connectivity; 289 unsigned char check_sum; 290 unsigned char customization; 291 unsigned char external_amp; 292 unsigned int enable_pcbeep:1; 293 unsigned int platform_type:1; 294 unsigned int swap:1; 295 unsigned int override:1; 296}; 297 298struct alc_spec { 299 /* codec parameterization */ 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 301 unsigned int num_mixers; 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 304 305 const struct hda_verb *init_verbs[10]; /* initialization verbs 306 * don't forget NULL 307 * termination! 308 */ 309 unsigned int num_init_verbs; 310 311 char stream_name_analog[32]; /* analog PCM stream */ 312 struct hda_pcm_stream *stream_analog_playback; 313 struct hda_pcm_stream *stream_analog_capture; 314 struct hda_pcm_stream *stream_analog_alt_playback; 315 struct hda_pcm_stream *stream_analog_alt_capture; 316 317 char stream_name_digital[32]; /* digital PCM stream */ 318 struct hda_pcm_stream *stream_digital_playback; 319 struct hda_pcm_stream *stream_digital_capture; 320 321 /* playback */ 322 struct hda_multi_out multiout; /* playback set-up 323 * max_channels, dacs must be set 324 * dig_out_nid and hp_nid are optional 325 */ 326 hda_nid_t alt_dac_nid; 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 328 int dig_out_type; 329 330 /* capture */ 331 unsigned int num_adc_nids; 332 hda_nid_t *adc_nids; 333 hda_nid_t *capsrc_nids; 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 335 336 /* capture setup for dynamic dual-adc switch */ 337 unsigned int cur_adc_idx; 338 hda_nid_t cur_adc; 339 unsigned int cur_adc_stream_tag; 340 unsigned int cur_adc_format; 341 342 /* capture source */ 343 unsigned int num_mux_defs; 344 const struct hda_input_mux *input_mux; 345 unsigned int cur_mux[3]; 346 struct alc_mic_route ext_mic; 347 struct alc_mic_route int_mic; 348 349 /* channel model */ 350 const struct hda_channel_mode *channel_mode; 351 int num_channel_mode; 352 int need_dac_fix; 353 int const_channel_count; 354 int ext_channel_count; 355 356 /* PCM information */ 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 358 359 /* dynamic controls, init_verbs and input_mux */ 360 struct auto_pin_cfg autocfg; 361 struct alc_customize_define cdefine; 362 struct snd_array kctls; 363 struct hda_input_mux private_imux[3]; 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 367 368 /* hooks */ 369 void (*init_hook)(struct hda_codec *codec); 370 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 371#ifdef CONFIG_SND_HDA_POWER_SAVE 372 void (*power_hook)(struct hda_codec *codec); 373#endif 374 375 /* for pin sensing */ 376 unsigned int sense_updated: 1; 377 unsigned int jack_present: 1; 378 unsigned int master_sw: 1; 379 unsigned int auto_mic:1; 380 381 /* other flags */ 382 unsigned int no_analog :1; /* digital I/O only */ 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 384 int init_amp; 385 386 /* for virtual master */ 387 hda_nid_t vmaster_nid; 388#ifdef CONFIG_SND_HDA_POWER_SAVE 389 struct hda_loopback_check loopback; 390#endif 391 392 /* for PLL fix */ 393 hda_nid_t pll_nid; 394 unsigned int pll_coef_idx, pll_coef_bit; 395}; 396 397/* 398 * configuration template - to be copied to the spec instance 399 */ 400struct alc_config_preset { 401 struct snd_kcontrol_new *mixers[5]; /* should be identical size 402 * with spec 403 */ 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 405 const struct hda_verb *init_verbs[5]; 406 unsigned int num_dacs; 407 hda_nid_t *dac_nids; 408 hda_nid_t dig_out_nid; /* optional */ 409 hda_nid_t hp_nid; /* optional */ 410 hda_nid_t *slave_dig_outs; 411 unsigned int num_adc_nids; 412 hda_nid_t *adc_nids; 413 hda_nid_t *capsrc_nids; 414 hda_nid_t dig_in_nid; 415 unsigned int num_channel_mode; 416 const struct hda_channel_mode *channel_mode; 417 int need_dac_fix; 418 int const_channel_count; 419 unsigned int num_mux_defs; 420 const struct hda_input_mux *input_mux; 421 void (*unsol_event)(struct hda_codec *, unsigned int); 422 void (*setup)(struct hda_codec *); 423 void (*init_hook)(struct hda_codec *); 424#ifdef CONFIG_SND_HDA_POWER_SAVE 425 struct hda_amp_list *loopbacks; 426 void (*power_hook)(struct hda_codec *codec); 427#endif 428}; 429 430 431/* 432 * input MUX handling 433 */ 434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 435 struct snd_ctl_elem_info *uinfo) 436{ 437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 438 struct alc_spec *spec = codec->spec; 439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 440 if (mux_idx >= spec->num_mux_defs) 441 mux_idx = 0; 442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 443 mux_idx = 0; 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 445} 446 447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 448 struct snd_ctl_elem_value *ucontrol) 449{ 450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 451 struct alc_spec *spec = codec->spec; 452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 453 454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 455 return 0; 456} 457 458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 459 struct snd_ctl_elem_value *ucontrol) 460{ 461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 462 struct alc_spec *spec = codec->spec; 463 const struct hda_input_mux *imux; 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 465 unsigned int mux_idx; 466 hda_nid_t nid = spec->capsrc_nids ? 467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 468 unsigned int type; 469 470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 471 imux = &spec->input_mux[mux_idx]; 472 if (!imux->num_items && mux_idx > 0) 473 imux = &spec->input_mux[0]; 474 475 type = get_wcaps_type(get_wcaps(codec, nid)); 476 if (type == AC_WID_AUD_MIX) { 477 /* Matrix-mixer style (e.g. ALC882) */ 478 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 479 unsigned int i, idx; 480 481 idx = ucontrol->value.enumerated.item[0]; 482 if (idx >= imux->num_items) 483 idx = imux->num_items - 1; 484 if (*cur_val == idx) 485 return 0; 486 for (i = 0; i < imux->num_items; i++) { 487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 489 imux->items[i].index, 490 HDA_AMP_MUTE, v); 491 } 492 *cur_val = idx; 493 return 1; 494 } else { 495 /* MUX style (e.g. ALC880) */ 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 497 &spec->cur_mux[adc_idx]); 498 } 499} 500 501/* 502 * channel mode setting 503 */ 504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 505 struct snd_ctl_elem_info *uinfo) 506{ 507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 508 struct alc_spec *spec = codec->spec; 509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 510 spec->num_channel_mode); 511} 512 513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 514 struct snd_ctl_elem_value *ucontrol) 515{ 516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 517 struct alc_spec *spec = codec->spec; 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 519 spec->num_channel_mode, 520 spec->ext_channel_count); 521} 522 523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 524 struct snd_ctl_elem_value *ucontrol) 525{ 526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 527 struct alc_spec *spec = codec->spec; 528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 529 spec->num_channel_mode, 530 &spec->ext_channel_count); 531 if (err >= 0 && !spec->const_channel_count) { 532 spec->multiout.max_channels = spec->ext_channel_count; 533 if (spec->need_dac_fix) 534 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 535 } 536 return err; 537} 538 539/* 540 * Control the mode of pin widget settings via the mixer. "pc" is used 541 * instead of "%" to avoid consequences of accidently treating the % as 542 * being part of a format specifier. Maximum allowed length of a value is 543 * 63 characters plus NULL terminator. 544 * 545 * Note: some retasking pin complexes seem to ignore requests for input 546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 547 * are requested. Therefore order this list so that this behaviour will not 548 * cause problems when mixer clients move through the enum sequentially. 549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 550 * March 2006. 551 */ 552static char *alc_pin_mode_names[] = { 553 "Mic 50pc bias", "Mic 80pc bias", 554 "Line in", "Line out", "Headphone out", 555}; 556static unsigned char alc_pin_mode_values[] = { 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 558}; 559/* The control can present all 5 options, or it can limit the options based 560 * in the pin being assumed to be exclusively an input or an output pin. In 561 * addition, "input" pins may or may not process the mic bias option 562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 563 * accept requests for bias as of chip versions up to March 2006) and/or 564 * wiring in the computer. 565 */ 566#define ALC_PIN_DIR_IN 0x00 567#define ALC_PIN_DIR_OUT 0x01 568#define ALC_PIN_DIR_INOUT 0x02 569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 571 572/* Info about the pin modes supported by the different pin direction modes. 573 * For each direction the minimum and maximum values are given. 574 */ 575static signed char alc_pin_mode_dir_info[5][2] = { 576 { 0, 2 }, /* ALC_PIN_DIR_IN */ 577 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 581}; 582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 584#define alc_pin_mode_n_items(_dir) \ 585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 586 587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 588 struct snd_ctl_elem_info *uinfo) 589{ 590 unsigned int item_num = uinfo->value.enumerated.item; 591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 592 593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 594 uinfo->count = 1; 595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 596 597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 598 item_num = alc_pin_mode_min(dir); 599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 600 return 0; 601} 602 603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 604 struct snd_ctl_elem_value *ucontrol) 605{ 606 unsigned int i; 607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 608 hda_nid_t nid = kcontrol->private_value & 0xffff; 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 610 long *valp = ucontrol->value.integer.value; 611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 612 AC_VERB_GET_PIN_WIDGET_CONTROL, 613 0x00); 614 615 /* Find enumerated value for current pinctl setting */ 616 i = alc_pin_mode_min(dir); 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 618 i++; 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 620 return 0; 621} 622 623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 624 struct snd_ctl_elem_value *ucontrol) 625{ 626 signed int change; 627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 628 hda_nid_t nid = kcontrol->private_value & 0xffff; 629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 630 long val = *ucontrol->value.integer.value; 631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 632 AC_VERB_GET_PIN_WIDGET_CONTROL, 633 0x00); 634 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 636 val = alc_pin_mode_min(dir); 637 638 change = pinctl != alc_pin_mode_values[val]; 639 if (change) { 640 /* Set pin mode to that requested */ 641 snd_hda_codec_write_cache(codec, nid, 0, 642 AC_VERB_SET_PIN_WIDGET_CONTROL, 643 alc_pin_mode_values[val]); 644 645 /* Also enable the retasking pin's input/output as required 646 * for the requested pin mode. Enum values of 2 or less are 647 * input modes. 648 * 649 * Dynamically switching the input/output buffers probably 650 * reduces noise slightly (particularly on input) so we'll 651 * do it. However, having both input and output buffers 652 * enabled simultaneously doesn't seem to be problematic if 653 * this turns out to be necessary in the future. 654 */ 655 if (val <= 2) { 656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 657 HDA_AMP_MUTE, HDA_AMP_MUTE); 658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 659 HDA_AMP_MUTE, 0); 660 } else { 661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 662 HDA_AMP_MUTE, HDA_AMP_MUTE); 663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 664 HDA_AMP_MUTE, 0); 665 } 666 } 667 return change; 668} 669 670#define ALC_PIN_MODE(xname, nid, dir) \ 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 673 .info = alc_pin_mode_info, \ 674 .get = alc_pin_mode_get, \ 675 .put = alc_pin_mode_put, \ 676 .private_value = nid | (dir<<16) } 677 678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 679 * together using a mask with more than one bit set. This control is 680 * currently used only by the ALC260 test model. At this stage they are not 681 * needed for any "production" models. 682 */ 683#ifdef CONFIG_SND_DEBUG 684#define alc_gpio_data_info snd_ctl_boolean_mono_info 685 686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 687 struct snd_ctl_elem_value *ucontrol) 688{ 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 *valp = ucontrol->value.integer.value; 693 unsigned int val = snd_hda_codec_read(codec, nid, 0, 694 AC_VERB_GET_GPIO_DATA, 0x00); 695 696 *valp = (val & mask) != 0; 697 return 0; 698} 699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 700 struct snd_ctl_elem_value *ucontrol) 701{ 702 signed int change; 703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 704 hda_nid_t nid = kcontrol->private_value & 0xffff; 705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 706 long val = *ucontrol->value.integer.value; 707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 708 AC_VERB_GET_GPIO_DATA, 709 0x00); 710 711 /* Set/unset the masked GPIO bit(s) as needed */ 712 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 713 if (val == 0) 714 gpio_data &= ~mask; 715 else 716 gpio_data |= mask; 717 snd_hda_codec_write_cache(codec, nid, 0, 718 AC_VERB_SET_GPIO_DATA, gpio_data); 719 720 return change; 721} 722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 725 .info = alc_gpio_data_info, \ 726 .get = alc_gpio_data_get, \ 727 .put = alc_gpio_data_put, \ 728 .private_value = nid | (mask<<16) } 729#endif /* CONFIG_SND_DEBUG */ 730 731/* A switch control to allow the enabling of the digital IO pins on the 732 * ALC260. This is incredibly simplistic; the intention of this control is 733 * to provide something in the test model allowing digital outputs to be 734 * identified if present. If models are found which can utilise these 735 * outputs a more complete mixer control can be devised for those models if 736 * necessary. 737 */ 738#ifdef CONFIG_SND_DEBUG 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 740 741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 742 struct snd_ctl_elem_value *ucontrol) 743{ 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 *valp = ucontrol->value.integer.value; 748 unsigned int val = snd_hda_codec_read(codec, nid, 0, 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 750 751 *valp = (val & mask) != 0; 752 return 0; 753} 754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 755 struct snd_ctl_elem_value *ucontrol) 756{ 757 signed int change; 758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 759 hda_nid_t nid = kcontrol->private_value & 0xffff; 760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 761 long val = *ucontrol->value.integer.value; 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 763 AC_VERB_GET_DIGI_CONVERT_1, 764 0x00); 765 766 /* Set/unset the masked control bit(s) as needed */ 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 768 if (val==0) 769 ctrl_data &= ~mask; 770 else 771 ctrl_data |= mask; 772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 773 ctrl_data); 774 775 return change; 776} 777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 780 .info = alc_spdif_ctrl_info, \ 781 .get = alc_spdif_ctrl_get, \ 782 .put = alc_spdif_ctrl_put, \ 783 .private_value = nid | (mask<<16) } 784#endif /* CONFIG_SND_DEBUG */ 785 786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 787 * Again, this is only used in the ALC26x test models to help identify when 788 * the EAPD line must be asserted for features to work. 789 */ 790#ifdef CONFIG_SND_DEBUG 791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 792 793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 794 struct snd_ctl_elem_value *ucontrol) 795{ 796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 797 hda_nid_t nid = kcontrol->private_value & 0xffff; 798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 799 long *valp = ucontrol->value.integer.value; 800 unsigned int val = snd_hda_codec_read(codec, nid, 0, 801 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 802 803 *valp = (val & mask) != 0; 804 return 0; 805} 806 807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 808 struct snd_ctl_elem_value *ucontrol) 809{ 810 int change; 811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 812 hda_nid_t nid = kcontrol->private_value & 0xffff; 813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 814 long val = *ucontrol->value.integer.value; 815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 816 AC_VERB_GET_EAPD_BTLENABLE, 817 0x00); 818 819 /* Set/unset the masked control bit(s) as needed */ 820 change = (!val ? 0 : mask) != (ctrl_data & mask); 821 if (!val) 822 ctrl_data &= ~mask; 823 else 824 ctrl_data |= mask; 825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 826 ctrl_data); 827 828 return change; 829} 830 831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 834 .info = alc_eapd_ctrl_info, \ 835 .get = alc_eapd_ctrl_get, \ 836 .put = alc_eapd_ctrl_put, \ 837 .private_value = nid | (mask<<16) } 838#endif /* CONFIG_SND_DEBUG */ 839 840/* 841 * set up the input pin config (depending on the given auto-pin type) 842 */ 843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 844 int auto_pin_type) 845{ 846 unsigned int val = PIN_IN; 847 848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) { 849 unsigned int pincap; 850 unsigned int oldval; 851 oldval = snd_hda_codec_read(codec, nid, 0, 852 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 853 pincap = snd_hda_query_pin_caps(codec, nid); 854 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 855 /* if the default pin setup is vref50, we give it priority */ 856 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 857 val = PIN_VREF80; 858 else if (pincap & AC_PINCAP_VREF_50) 859 val = PIN_VREF50; 860 else if (pincap & AC_PINCAP_VREF_100) 861 val = PIN_VREF100; 862 else if (pincap & AC_PINCAP_VREF_GRD) 863 val = PIN_VREFGRD; 864 } 865 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 866} 867 868/* 869 */ 870static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) 871{ 872 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 873 return; 874 spec->mixers[spec->num_mixers++] = mix; 875} 876 877static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 878{ 879 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 880 return; 881 spec->init_verbs[spec->num_init_verbs++] = verb; 882} 883 884/* 885 * set up from the preset table 886 */ 887static void setup_preset(struct hda_codec *codec, 888 const struct alc_config_preset *preset) 889{ 890 struct alc_spec *spec = codec->spec; 891 int i; 892 893 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 894 add_mixer(spec, preset->mixers[i]); 895 spec->cap_mixer = preset->cap_mixer; 896 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 897 i++) 898 add_verb(spec, preset->init_verbs[i]); 899 900 spec->channel_mode = preset->channel_mode; 901 spec->num_channel_mode = preset->num_channel_mode; 902 spec->need_dac_fix = preset->need_dac_fix; 903 spec->const_channel_count = preset->const_channel_count; 904 905 if (preset->const_channel_count) 906 spec->multiout.max_channels = preset->const_channel_count; 907 else 908 spec->multiout.max_channels = spec->channel_mode[0].channels; 909 spec->ext_channel_count = spec->channel_mode[0].channels; 910 911 spec->multiout.num_dacs = preset->num_dacs; 912 spec->multiout.dac_nids = preset->dac_nids; 913 spec->multiout.dig_out_nid = preset->dig_out_nid; 914 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 915 spec->multiout.hp_nid = preset->hp_nid; 916 917 spec->num_mux_defs = preset->num_mux_defs; 918 if (!spec->num_mux_defs) 919 spec->num_mux_defs = 1; 920 spec->input_mux = preset->input_mux; 921 922 spec->num_adc_nids = preset->num_adc_nids; 923 spec->adc_nids = preset->adc_nids; 924 spec->capsrc_nids = preset->capsrc_nids; 925 spec->dig_in_nid = preset->dig_in_nid; 926 927 spec->unsol_event = preset->unsol_event; 928 spec->init_hook = preset->init_hook; 929#ifdef CONFIG_SND_HDA_POWER_SAVE 930 spec->power_hook = preset->power_hook; 931 spec->loopback.amplist = preset->loopbacks; 932#endif 933 934 if (preset->setup) 935 preset->setup(codec); 936} 937 938/* Enable GPIO mask and set output */ 939static struct hda_verb alc_gpio1_init_verbs[] = { 940 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 941 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 942 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 943 { } 944}; 945 946static struct hda_verb alc_gpio2_init_verbs[] = { 947 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 948 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 949 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 950 { } 951}; 952 953static struct hda_verb alc_gpio3_init_verbs[] = { 954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 956 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 957 { } 958}; 959 960/* 961 * Fix hardware PLL issue 962 * On some codecs, the analog PLL gating control must be off while 963 * the default value is 1. 964 */ 965static void alc_fix_pll(struct hda_codec *codec) 966{ 967 struct alc_spec *spec = codec->spec; 968 unsigned int val; 969 970 if (!spec->pll_nid) 971 return; 972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 973 spec->pll_coef_idx); 974 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 975 AC_VERB_GET_PROC_COEF, 0); 976 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 977 spec->pll_coef_idx); 978 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 979 val & ~(1 << spec->pll_coef_bit)); 980} 981 982static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 983 unsigned int coef_idx, unsigned int coef_bit) 984{ 985 struct alc_spec *spec = codec->spec; 986 spec->pll_nid = nid; 987 spec->pll_coef_idx = coef_idx; 988 spec->pll_coef_bit = coef_bit; 989 alc_fix_pll(codec); 990} 991 992static void alc_automute_pin(struct hda_codec *codec) 993{ 994 struct alc_spec *spec = codec->spec; 995 unsigned int nid = spec->autocfg.hp_pins[0]; 996 int i; 997 998 if (!nid) 999 return; 1000 spec->jack_present = snd_hda_jack_detect(codec, nid); 1001 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1002 nid = spec->autocfg.speaker_pins[i]; 1003 if (!nid) 1004 break; 1005 snd_hda_codec_write(codec, nid, 0, 1006 AC_VERB_SET_PIN_WIDGET_CONTROL, 1007 spec->jack_present ? 0 : PIN_OUT); 1008 } 1009} 1010 1011static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1012 hda_nid_t nid) 1013{ 1014 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1015 int i, nums; 1016 1017 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1018 for (i = 0; i < nums; i++) 1019 if (conn[i] == nid) 1020 return i; 1021 return -1; 1022} 1023 1024/* switch the current ADC according to the jack state */ 1025static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1026{ 1027 struct alc_spec *spec = codec->spec; 1028 unsigned int present; 1029 hda_nid_t new_adc; 1030 1031 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1032 if (present) 1033 spec->cur_adc_idx = 1; 1034 else 1035 spec->cur_adc_idx = 0; 1036 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1037 if (spec->cur_adc && spec->cur_adc != new_adc) { 1038 /* stream is running, let's swap the current ADC */ 1039 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 1040 spec->cur_adc = new_adc; 1041 snd_hda_codec_setup_stream(codec, new_adc, 1042 spec->cur_adc_stream_tag, 0, 1043 spec->cur_adc_format); 1044 } 1045} 1046 1047static void alc_mic_automute(struct hda_codec *codec) 1048{ 1049 struct alc_spec *spec = codec->spec; 1050 struct alc_mic_route *dead, *alive; 1051 unsigned int present, type; 1052 hda_nid_t cap_nid; 1053 1054 if (!spec->auto_mic) 1055 return; 1056 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1057 return; 1058 if (snd_BUG_ON(!spec->adc_nids)) 1059 return; 1060 1061 if (spec->dual_adc_switch) { 1062 alc_dual_mic_adc_auto_switch(codec); 1063 return; 1064 } 1065 1066 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1067 1068 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1069 if (present) { 1070 alive = &spec->ext_mic; 1071 dead = &spec->int_mic; 1072 } else { 1073 alive = &spec->int_mic; 1074 dead = &spec->ext_mic; 1075 } 1076 1077 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1078 if (type == AC_WID_AUD_MIX) { 1079 /* Matrix-mixer style (e.g. ALC882) */ 1080 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1081 alive->mux_idx, 1082 HDA_AMP_MUTE, 0); 1083 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1084 dead->mux_idx, 1085 HDA_AMP_MUTE, HDA_AMP_MUTE); 1086 } else { 1087 /* MUX style (e.g. ALC880) */ 1088 snd_hda_codec_write_cache(codec, cap_nid, 0, 1089 AC_VERB_SET_CONNECT_SEL, 1090 alive->mux_idx); 1091 } 1092 1093 /* FIXME: analog mixer */ 1094} 1095 1096/* unsolicited event for HP jack sensing */ 1097static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1098{ 1099 if (codec->vendor_id == 0x10ec0880) 1100 res >>= 28; 1101 else 1102 res >>= 26; 1103 switch (res) { 1104 case ALC880_HP_EVENT: 1105 alc_automute_pin(codec); 1106 break; 1107 case ALC880_MIC_EVENT: 1108 alc_mic_automute(codec); 1109 break; 1110 } 1111} 1112 1113static void alc_inithook(struct hda_codec *codec) 1114{ 1115 alc_automute_pin(codec); 1116 alc_mic_automute(codec); 1117} 1118 1119/* additional initialization for ALC888 variants */ 1120static void alc888_coef_init(struct hda_codec *codec) 1121{ 1122 unsigned int tmp; 1123 1124 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1125 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1126 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1127 if ((tmp & 0xf0) == 0x20) 1128 /* alc888S-VC */ 1129 snd_hda_codec_read(codec, 0x20, 0, 1130 AC_VERB_SET_PROC_COEF, 0x830); 1131 else 1132 /* alc888-VB */ 1133 snd_hda_codec_read(codec, 0x20, 0, 1134 AC_VERB_SET_PROC_COEF, 0x3030); 1135} 1136 1137static void alc889_coef_init(struct hda_codec *codec) 1138{ 1139 unsigned int tmp; 1140 1141 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1142 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1143 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1145} 1146 1147/* turn on/off EAPD control (only if available) */ 1148static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1149{ 1150 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1151 return; 1152 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1154 on ? 2 : 0); 1155} 1156 1157static void alc_auto_init_amp(struct hda_codec *codec, int type) 1158{ 1159 unsigned int tmp; 1160 1161 switch (type) { 1162 case ALC_INIT_GPIO1: 1163 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1164 break; 1165 case ALC_INIT_GPIO2: 1166 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1167 break; 1168 case ALC_INIT_GPIO3: 1169 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1170 break; 1171 case ALC_INIT_DEFAULT: 1172 switch (codec->vendor_id) { 1173 case 0x10ec0260: 1174 set_eapd(codec, 0x0f, 1); 1175 set_eapd(codec, 0x10, 1); 1176 break; 1177 case 0x10ec0262: 1178 case 0x10ec0267: 1179 case 0x10ec0268: 1180 case 0x10ec0269: 1181 case 0x10ec0270: 1182 case 0x10ec0272: 1183 case 0x10ec0660: 1184 case 0x10ec0662: 1185 case 0x10ec0663: 1186 case 0x10ec0862: 1187 case 0x10ec0889: 1188 set_eapd(codec, 0x14, 1); 1189 set_eapd(codec, 0x15, 1); 1190 break; 1191 } 1192 switch (codec->vendor_id) { 1193 case 0x10ec0260: 1194 snd_hda_codec_write(codec, 0x1a, 0, 1195 AC_VERB_SET_COEF_INDEX, 7); 1196 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1197 AC_VERB_GET_PROC_COEF, 0); 1198 snd_hda_codec_write(codec, 0x1a, 0, 1199 AC_VERB_SET_COEF_INDEX, 7); 1200 snd_hda_codec_write(codec, 0x1a, 0, 1201 AC_VERB_SET_PROC_COEF, 1202 tmp | 0x2010); 1203 break; 1204 case 0x10ec0262: 1205 case 0x10ec0880: 1206 case 0x10ec0882: 1207 case 0x10ec0883: 1208 case 0x10ec0885: 1209 case 0x10ec0887: 1210 case 0x10ec0889: 1211 alc889_coef_init(codec); 1212 break; 1213 case 0x10ec0888: 1214 alc888_coef_init(codec); 1215 break; 1216#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1217 case 0x10ec0267: 1218 case 0x10ec0268: 1219 snd_hda_codec_write(codec, 0x20, 0, 1220 AC_VERB_SET_COEF_INDEX, 7); 1221 tmp = snd_hda_codec_read(codec, 0x20, 0, 1222 AC_VERB_GET_PROC_COEF, 0); 1223 snd_hda_codec_write(codec, 0x20, 0, 1224 AC_VERB_SET_COEF_INDEX, 7); 1225 snd_hda_codec_write(codec, 0x20, 0, 1226 AC_VERB_SET_PROC_COEF, 1227 tmp | 0x3000); 1228 break; 1229#endif /* XXX */ 1230 } 1231 break; 1232 } 1233} 1234 1235static void alc_init_auto_hp(struct hda_codec *codec) 1236{ 1237 struct alc_spec *spec = codec->spec; 1238 1239 if (!spec->autocfg.hp_pins[0]) 1240 return; 1241 1242 if (!spec->autocfg.speaker_pins[0]) { 1243 if (spec->autocfg.line_out_pins[0] && 1244 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 1245 spec->autocfg.speaker_pins[0] = 1246 spec->autocfg.line_out_pins[0]; 1247 else 1248 return; 1249 } 1250 1251 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1252 spec->autocfg.hp_pins[0]); 1253 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, 1254 AC_VERB_SET_UNSOLICITED_ENABLE, 1255 AC_USRSP_EN | ALC880_HP_EVENT); 1256 spec->unsol_event = alc_sku_unsol_event; 1257} 1258 1259static void alc_init_auto_mic(struct hda_codec *codec) 1260{ 1261 struct alc_spec *spec = codec->spec; 1262 struct auto_pin_cfg *cfg = &spec->autocfg; 1263 hda_nid_t fixed, ext; 1264 int i; 1265 1266 /* there must be only two mic inputs exclusively */ 1267 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) 1268 if (cfg->input_pins[i]) 1269 return; 1270 1271 fixed = ext = 0; 1272 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) { 1273 hda_nid_t nid = cfg->input_pins[i]; 1274 unsigned int defcfg; 1275 if (!nid) 1276 return; 1277 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1278 switch (get_defcfg_connect(defcfg)) { 1279 case AC_JACK_PORT_FIXED: 1280 if (fixed) 1281 return; /* already occupied */ 1282 fixed = nid; 1283 break; 1284 case AC_JACK_PORT_COMPLEX: 1285 if (ext) 1286 return; /* already occupied */ 1287 ext = nid; 1288 break; 1289 default: 1290 return; /* invalid entry */ 1291 } 1292 } 1293 if (!ext || !fixed) 1294 return; 1295 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 1296 return; /* no unsol support */ 1297 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", 1298 ext, fixed); 1299 spec->ext_mic.pin = ext; 1300 spec->int_mic.pin = fixed; 1301 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1302 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1303 spec->auto_mic = 1; 1304 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1305 AC_VERB_SET_UNSOLICITED_ENABLE, 1306 AC_USRSP_EN | ALC880_MIC_EVENT); 1307 spec->unsol_event = alc_sku_unsol_event; 1308} 1309 1310static int alc_auto_parse_customize_define(struct hda_codec *codec) 1311{ 1312 unsigned int ass, tmp, i; 1313 unsigned nid = 0; 1314 struct alc_spec *spec = codec->spec; 1315 1316 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1317 1318 ass = codec->subsystem_id & 0xffff; 1319 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1320 goto do_sku; 1321 1322 nid = 0x1d; 1323 if (codec->vendor_id == 0x10ec0260) 1324 nid = 0x17; 1325 ass = snd_hda_codec_get_pincfg(codec, nid); 1326 1327 if (!(ass & 1)) { 1328 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1329 codec->chip_name, ass); 1330 return -1; 1331 } 1332 1333 /* check sum */ 1334 tmp = 0; 1335 for (i = 1; i < 16; i++) { 1336 if ((ass >> i) & 1) 1337 tmp++; 1338 } 1339 if (((ass >> 16) & 0xf) != tmp) 1340 return -1; 1341 1342 spec->cdefine.port_connectivity = ass >> 30; 1343 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1344 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1345 spec->cdefine.customization = ass >> 8; 1346do_sku: 1347 spec->cdefine.sku_cfg = ass; 1348 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1349 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1350 spec->cdefine.swap = (ass & 0x2) >> 1; 1351 spec->cdefine.override = ass & 0x1; 1352 1353 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1354 nid, spec->cdefine.sku_cfg); 1355 snd_printd("SKU: port_connectivity=0x%x\n", 1356 spec->cdefine.port_connectivity); 1357 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1358 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1359 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1360 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1361 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1362 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1363 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1364 1365 return 0; 1366} 1367 1368/* check subsystem ID and set up device-specific initialization; 1369 * return 1 if initialized, 0 if invalid SSID 1370 */ 1371/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1372 * 31 ~ 16 : Manufacture ID 1373 * 15 ~ 8 : SKU ID 1374 * 7 ~ 0 : Assembly ID 1375 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1376 */ 1377static int alc_subsystem_id(struct hda_codec *codec, 1378 hda_nid_t porta, hda_nid_t porte, 1379 hda_nid_t portd, hda_nid_t porti) 1380{ 1381 unsigned int ass, tmp, i; 1382 unsigned nid; 1383 struct alc_spec *spec = codec->spec; 1384 1385 ass = codec->subsystem_id & 0xffff; 1386 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1387 goto do_sku; 1388 1389 /* invalid SSID, check the special NID pin defcfg instead */ 1390 /* 1391 * 31~30 : port connectivity 1392 * 29~21 : reserve 1393 * 20 : PCBEEP input 1394 * 19~16 : Check sum (15:1) 1395 * 15~1 : Custom 1396 * 0 : override 1397 */ 1398 nid = 0x1d; 1399 if (codec->vendor_id == 0x10ec0260) 1400 nid = 0x17; 1401 ass = snd_hda_codec_get_pincfg(codec, nid); 1402 snd_printd("realtek: No valid SSID, " 1403 "checking pincfg 0x%08x for NID 0x%x\n", 1404 ass, nid); 1405 if (!(ass & 1)) 1406 return 0; 1407 if ((ass >> 30) != 1) /* no physical connection */ 1408 return 0; 1409 1410 /* check sum */ 1411 tmp = 0; 1412 for (i = 1; i < 16; i++) { 1413 if ((ass >> i) & 1) 1414 tmp++; 1415 } 1416 if (((ass >> 16) & 0xf) != tmp) 1417 return 0; 1418do_sku: 1419 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1420 ass & 0xffff, codec->vendor_id); 1421 /* 1422 * 0 : override 1423 * 1 : Swap Jack 1424 * 2 : 0 --> Desktop, 1 --> Laptop 1425 * 3~5 : External Amplifier control 1426 * 7~6 : Reserved 1427 */ 1428 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1429 switch (tmp) { 1430 case 1: 1431 spec->init_amp = ALC_INIT_GPIO1; 1432 break; 1433 case 3: 1434 spec->init_amp = ALC_INIT_GPIO2; 1435 break; 1436 case 7: 1437 spec->init_amp = ALC_INIT_GPIO3; 1438 break; 1439 case 5: 1440 spec->init_amp = ALC_INIT_DEFAULT; 1441 break; 1442 } 1443 1444 /* is laptop or Desktop and enable the function "Mute internal speaker 1445 * when the external headphone out jack is plugged" 1446 */ 1447 if (!(ass & 0x8000)) 1448 return 1; 1449 /* 1450 * 10~8 : Jack location 1451 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1452 * 14~13: Resvered 1453 * 15 : 1 --> enable the function "Mute internal speaker 1454 * when the external headphone out jack is plugged" 1455 */ 1456 if (!spec->autocfg.hp_pins[0]) { 1457 hda_nid_t nid; 1458 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1459 if (tmp == 0) 1460 nid = porta; 1461 else if (tmp == 1) 1462 nid = porte; 1463 else if (tmp == 2) 1464 nid = portd; 1465 else if (tmp == 3) 1466 nid = porti; 1467 else 1468 return 1; 1469 for (i = 0; i < spec->autocfg.line_outs; i++) 1470 if (spec->autocfg.line_out_pins[i] == nid) 1471 return 1; 1472 spec->autocfg.hp_pins[0] = nid; 1473 } 1474 1475 alc_init_auto_hp(codec); 1476 alc_init_auto_mic(codec); 1477 return 1; 1478} 1479 1480static void alc_ssid_check(struct hda_codec *codec, 1481 hda_nid_t porta, hda_nid_t porte, 1482 hda_nid_t portd, hda_nid_t porti) 1483{ 1484 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1485 struct alc_spec *spec = codec->spec; 1486 snd_printd("realtek: " 1487 "Enable default setup for auto mode as fallback\n"); 1488 spec->init_amp = ALC_INIT_DEFAULT; 1489 alc_init_auto_hp(codec); 1490 alc_init_auto_mic(codec); 1491 } 1492} 1493 1494/* 1495 * Fix-up pin default configurations and add default verbs 1496 */ 1497 1498struct alc_pincfg { 1499 hda_nid_t nid; 1500 u32 val; 1501}; 1502 1503struct alc_fixup { 1504 const struct alc_pincfg *pins; 1505 const struct hda_verb *verbs; 1506}; 1507 1508static void alc_pick_fixup(struct hda_codec *codec, 1509 const struct snd_pci_quirk *quirk, 1510 const struct alc_fixup *fix, 1511 int pre_init) 1512{ 1513 const struct alc_pincfg *cfg; 1514 1515 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1516 if (!quirk) 1517 return; 1518 fix += quirk->value; 1519 cfg = fix->pins; 1520 if (pre_init && cfg) { 1521#ifdef CONFIG_SND_DEBUG_VERBOSE 1522 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1523 codec->chip_name, quirk->name); 1524#endif 1525 for (; cfg->nid; cfg++) 1526 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1527 } 1528 if (!pre_init && fix->verbs) { 1529#ifdef CONFIG_SND_DEBUG_VERBOSE 1530 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1531 codec->chip_name, quirk->name); 1532#endif 1533 add_verb(codec->spec, fix->verbs); 1534 } 1535} 1536 1537static int alc_read_coef_idx(struct hda_codec *codec, 1538 unsigned int coef_idx) 1539{ 1540 unsigned int val; 1541 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 1542 coef_idx); 1543 val = snd_hda_codec_read(codec, 0x20, 0, 1544 AC_VERB_GET_PROC_COEF, 0); 1545 return val; 1546} 1547 1548/* set right pin controls for digital I/O */ 1549static void alc_auto_init_digital(struct hda_codec *codec) 1550{ 1551 struct alc_spec *spec = codec->spec; 1552 int i; 1553 hda_nid_t pin; 1554 1555 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1556 pin = spec->autocfg.dig_out_pins[i]; 1557 if (pin) { 1558 snd_hda_codec_write(codec, pin, 0, 1559 AC_VERB_SET_PIN_WIDGET_CONTROL, 1560 PIN_OUT); 1561 } 1562 } 1563 pin = spec->autocfg.dig_in_pin; 1564 if (pin) 1565 snd_hda_codec_write(codec, pin, 0, 1566 AC_VERB_SET_PIN_WIDGET_CONTROL, 1567 PIN_IN); 1568} 1569 1570/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 1571static void alc_auto_parse_digital(struct hda_codec *codec) 1572{ 1573 struct alc_spec *spec = codec->spec; 1574 int i, err; 1575 hda_nid_t dig_nid; 1576 1577 /* support multiple SPDIFs; the secondary is set up as a slave */ 1578 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1579 err = snd_hda_get_connections(codec, 1580 spec->autocfg.dig_out_pins[i], 1581 &dig_nid, 1); 1582 if (err < 0) 1583 continue; 1584 if (!i) { 1585 spec->multiout.dig_out_nid = dig_nid; 1586 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1587 } else { 1588 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1589 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1590 break; 1591 spec->slave_dig_outs[i - 1] = dig_nid; 1592 } 1593 } 1594 1595 if (spec->autocfg.dig_in_pin) { 1596 hda_nid_t dig_nid; 1597 err = snd_hda_get_connections(codec, 1598 spec->autocfg.dig_in_pin, 1599 &dig_nid, 1); 1600 if (err > 0) 1601 spec->dig_in_nid = dig_nid; 1602 } 1603} 1604 1605/* 1606 * ALC888 1607 */ 1608 1609/* 1610 * 2ch mode 1611 */ 1612static struct hda_verb alc888_4ST_ch2_intel_init[] = { 1613/* Mic-in jack as mic in */ 1614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1616/* Line-in jack as Line in */ 1617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1619/* Line-Out as Front */ 1620 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1621 { } /* end */ 1622}; 1623 1624/* 1625 * 4ch mode 1626 */ 1627static struct hda_verb alc888_4ST_ch4_intel_init[] = { 1628/* Mic-in jack as mic in */ 1629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1631/* Line-in jack as Surround */ 1632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1634/* Line-Out as Front */ 1635 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 1636 { } /* end */ 1637}; 1638 1639/* 1640 * 6ch mode 1641 */ 1642static struct hda_verb alc888_4ST_ch6_intel_init[] = { 1643/* Mic-in jack as CLFE */ 1644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1646/* Line-in jack as Surround */ 1647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1649/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 1650 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1651 { } /* end */ 1652}; 1653 1654/* 1655 * 8ch mode 1656 */ 1657static struct hda_verb alc888_4ST_ch8_intel_init[] = { 1658/* Mic-in jack as CLFE */ 1659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1661/* Line-in jack as Surround */ 1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1664/* Line-Out as Side */ 1665 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1666 { } /* end */ 1667}; 1668 1669static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 1670 { 2, alc888_4ST_ch2_intel_init }, 1671 { 4, alc888_4ST_ch4_intel_init }, 1672 { 6, alc888_4ST_ch6_intel_init }, 1673 { 8, alc888_4ST_ch8_intel_init }, 1674}; 1675 1676/* 1677 * ALC888 Fujitsu Siemens Amillo xa3530 1678 */ 1679 1680static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 1681/* Front Mic: set to PIN_IN (empty by default) */ 1682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1683/* Connect Internal HP to Front */ 1684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1687/* Connect Bass HP to Front */ 1688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1691/* Connect Line-Out side jack (SPDIF) to Side */ 1692 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1694 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 1695/* Connect Mic jack to CLFE */ 1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 1699/* Connect Line-in jack to Surround */ 1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 1703/* Connect HP out jack to Front */ 1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 1707/* Enable unsolicited event for HP jack and Line-out jack */ 1708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1709 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1710 {} 1711}; 1712 1713static void alc_automute_amp(struct hda_codec *codec) 1714{ 1715 struct alc_spec *spec = codec->spec; 1716 unsigned int mute; 1717 hda_nid_t nid; 1718 int i; 1719 1720 spec->jack_present = 0; 1721 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 1722 nid = spec->autocfg.hp_pins[i]; 1723 if (!nid) 1724 break; 1725 if (snd_hda_jack_detect(codec, nid)) { 1726 spec->jack_present = 1; 1727 break; 1728 } 1729 } 1730 1731 mute = spec->jack_present ? HDA_AMP_MUTE : 0; 1732 /* Toggle internal speakers muting */ 1733 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 1734 nid = spec->autocfg.speaker_pins[i]; 1735 if (!nid) 1736 break; 1737 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1738 HDA_AMP_MUTE, mute); 1739 } 1740} 1741 1742static void alc_automute_amp_unsol_event(struct hda_codec *codec, 1743 unsigned int res) 1744{ 1745 if (codec->vendor_id == 0x10ec0880) 1746 res >>= 28; 1747 else 1748 res >>= 26; 1749 if (res == ALC880_HP_EVENT) 1750 alc_automute_amp(codec); 1751} 1752 1753static void alc889_automute_setup(struct hda_codec *codec) 1754{ 1755 struct alc_spec *spec = codec->spec; 1756 1757 spec->autocfg.hp_pins[0] = 0x15; 1758 spec->autocfg.speaker_pins[0] = 0x14; 1759 spec->autocfg.speaker_pins[1] = 0x16; 1760 spec->autocfg.speaker_pins[2] = 0x17; 1761 spec->autocfg.speaker_pins[3] = 0x19; 1762 spec->autocfg.speaker_pins[4] = 0x1a; 1763} 1764 1765static void alc889_intel_init_hook(struct hda_codec *codec) 1766{ 1767 alc889_coef_init(codec); 1768 alc_automute_amp(codec); 1769} 1770 1771static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 1772{ 1773 struct alc_spec *spec = codec->spec; 1774 1775 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 1776 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 1777 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 1778 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 1779} 1780 1781/* 1782 * ALC888 Acer Aspire 4930G model 1783 */ 1784 1785static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 1786/* Front Mic: set to PIN_IN (empty by default) */ 1787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1788/* Unselect Front Mic by default in input mixer 3 */ 1789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1790/* Enable unsolicited event for HP jack */ 1791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1792/* Connect Internal HP to front */ 1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1796/* Connect HP out to front */ 1797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1800 { } 1801}; 1802 1803/* 1804 * ALC888 Acer Aspire 6530G model 1805 */ 1806 1807static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 1808/* Route to built-in subwoofer as well as speakers */ 1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1813/* Bias voltage on for external mic port */ 1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 1815/* Front Mic: set to PIN_IN (empty by default) */ 1816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1817/* Unselect Front Mic by default in input mixer 3 */ 1818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1819/* Enable unsolicited event for HP jack */ 1820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1821/* Enable speaker output */ 1822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1824 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1825/* Enable headphone output */ 1826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1829 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 1830 { } 1831}; 1832 1833/* 1834 * ALC889 Acer Aspire 8930G model 1835 */ 1836 1837static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 1838/* Front Mic: set to PIN_IN (empty by default) */ 1839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1840/* Unselect Front Mic by default in input mixer 3 */ 1841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 1842/* Enable unsolicited event for HP jack */ 1843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 1844/* Connect Internal Front to Front */ 1845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 1848/* Connect Internal Rear to Rear */ 1849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1850 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 1852/* Connect Internal CLFE to CLFE */ 1853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1855 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 1856/* Connect HP out to Front */ 1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 1860/* Enable all DACs */ 1861/* DAC DISABLE/MUTE 1? */ 1862/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1865/* DAC DISABLE/MUTE 2? */ 1866/* some bit here disables the other DACs. Init=0x4900 */ 1867 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 1868 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 1869/* DMIC fix 1870 * This laptop has a stereo digital microphone. The mics are only 1cm apart 1871 * which makes the stereo useless. However, either the mic or the ALC889 1872 * makes the signal become a difference/sum signal instead of standard 1873 * stereo, which is annoying. So instead we flip this bit which makes the 1874 * codec replicate the sum signal to both channels, turning it into a 1875 * normal mono mic. 1876 */ 1877/* DMIC_CONTROL? Init value = 0x0001 */ 1878 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 1879 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 1880 { } 1881}; 1882 1883static struct hda_input_mux alc888_2_capture_sources[2] = { 1884 /* Front mic only available on one ADC */ 1885 { 1886 .num_items = 4, 1887 .items = { 1888 { "Mic", 0x0 }, 1889 { "Line", 0x2 }, 1890 { "CD", 0x4 }, 1891 { "Front Mic", 0xb }, 1892 }, 1893 }, 1894 { 1895 .num_items = 3, 1896 .items = { 1897 { "Mic", 0x0 }, 1898 { "Line", 0x2 }, 1899 { "CD", 0x4 }, 1900 }, 1901 } 1902}; 1903 1904static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 1905 /* Interal mic only available on one ADC */ 1906 { 1907 .num_items = 5, 1908 .items = { 1909 { "Ext Mic", 0x0 }, 1910 { "Line In", 0x2 }, 1911 { "CD", 0x4 }, 1912 { "Input Mix", 0xa }, 1913 { "Int Mic", 0xb }, 1914 }, 1915 }, 1916 { 1917 .num_items = 4, 1918 .items = { 1919 { "Ext Mic", 0x0 }, 1920 { "Line In", 0x2 }, 1921 { "CD", 0x4 }, 1922 { "Input Mix", 0xa }, 1923 }, 1924 } 1925}; 1926 1927static struct hda_input_mux alc889_capture_sources[3] = { 1928 /* Digital mic only available on first "ADC" */ 1929 { 1930 .num_items = 5, 1931 .items = { 1932 { "Mic", 0x0 }, 1933 { "Line", 0x2 }, 1934 { "CD", 0x4 }, 1935 { "Front Mic", 0xb }, 1936 { "Input Mix", 0xa }, 1937 }, 1938 }, 1939 { 1940 .num_items = 4, 1941 .items = { 1942 { "Mic", 0x0 }, 1943 { "Line", 0x2 }, 1944 { "CD", 0x4 }, 1945 { "Input Mix", 0xa }, 1946 }, 1947 }, 1948 { 1949 .num_items = 4, 1950 .items = { 1951 { "Mic", 0x0 }, 1952 { "Line", 0x2 }, 1953 { "CD", 0x4 }, 1954 { "Input Mix", 0xa }, 1955 }, 1956 } 1957}; 1958 1959static struct snd_kcontrol_new alc888_base_mixer[] = { 1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1965 HDA_OUTPUT), 1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 1970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 1973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1978 { } /* end */ 1979}; 1980 1981static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 1982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 1983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 1984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 1985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 1986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 1987 HDA_OUTPUT), 1988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 1989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 1990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 1991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 1992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 1993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 1994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 1995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 1996 { } /* end */ 1997}; 1998 1999 2000static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2001{ 2002 struct alc_spec *spec = codec->spec; 2003 2004 spec->autocfg.hp_pins[0] = 0x15; 2005 spec->autocfg.speaker_pins[0] = 0x14; 2006 spec->autocfg.speaker_pins[1] = 0x16; 2007 spec->autocfg.speaker_pins[2] = 0x17; 2008} 2009 2010static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2011{ 2012 struct alc_spec *spec = codec->spec; 2013 2014 spec->autocfg.hp_pins[0] = 0x15; 2015 spec->autocfg.speaker_pins[0] = 0x14; 2016 spec->autocfg.speaker_pins[1] = 0x16; 2017 spec->autocfg.speaker_pins[2] = 0x17; 2018} 2019 2020static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2021{ 2022 struct alc_spec *spec = codec->spec; 2023 2024 spec->autocfg.hp_pins[0] = 0x15; 2025 spec->autocfg.speaker_pins[0] = 0x14; 2026 spec->autocfg.speaker_pins[1] = 0x16; 2027 spec->autocfg.speaker_pins[2] = 0x1b; 2028} 2029 2030/* 2031 * ALC880 3-stack model 2032 * 2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2034 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2035 * F-Mic = 0x1b, HP = 0x19 2036 */ 2037 2038static hda_nid_t alc880_dac_nids[4] = { 2039 /* front, rear, clfe, rear_surr */ 2040 0x02, 0x05, 0x04, 0x03 2041}; 2042 2043static hda_nid_t alc880_adc_nids[3] = { 2044 /* ADC0-2 */ 2045 0x07, 0x08, 0x09, 2046}; 2047 2048/* The datasheet says the node 0x07 is connected from inputs, 2049 * but it shows zero connection in the real implementation on some devices. 2050 * Note: this is a 915GAV bug, fixed on 915GLV 2051 */ 2052static hda_nid_t alc880_adc_nids_alt[2] = { 2053 /* ADC1-2 */ 2054 0x08, 0x09, 2055}; 2056 2057#define ALC880_DIGOUT_NID 0x06 2058#define ALC880_DIGIN_NID 0x0a 2059 2060static struct hda_input_mux alc880_capture_source = { 2061 .num_items = 4, 2062 .items = { 2063 { "Mic", 0x0 }, 2064 { "Front Mic", 0x3 }, 2065 { "Line", 0x2 }, 2066 { "CD", 0x4 }, 2067 }, 2068}; 2069 2070/* channel source setting (2/6 channel selection for 3-stack) */ 2071/* 2ch mode */ 2072static struct hda_verb alc880_threestack_ch2_init[] = { 2073 /* set line-in to input, mute it */ 2074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2076 /* set mic-in to input vref 80%, mute it */ 2077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2079 { } /* end */ 2080}; 2081 2082/* 6ch mode */ 2083static struct hda_verb alc880_threestack_ch6_init[] = { 2084 /* set line-in to output, unmute it */ 2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2087 /* set mic-in to output, unmute it */ 2088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2090 { } /* end */ 2091}; 2092 2093static struct hda_channel_mode alc880_threestack_modes[2] = { 2094 { 2, alc880_threestack_ch2_init }, 2095 { 6, alc880_threestack_ch6_init }, 2096}; 2097 2098static struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2113 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2116 { 2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2118 .name = "Channel Mode", 2119 .info = alc_ch_mode_info, 2120 .get = alc_ch_mode_get, 2121 .put = alc_ch_mode_put, 2122 }, 2123 { } /* end */ 2124}; 2125 2126/* capture mixer elements */ 2127static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2128 struct snd_ctl_elem_info *uinfo) 2129{ 2130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2131 struct alc_spec *spec = codec->spec; 2132 int err; 2133 2134 mutex_lock(&codec->control_mutex); 2135 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2136 HDA_INPUT); 2137 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2138 mutex_unlock(&codec->control_mutex); 2139 return err; 2140} 2141 2142static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2143 unsigned int size, unsigned int __user *tlv) 2144{ 2145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2146 struct alc_spec *spec = codec->spec; 2147 int err; 2148 2149 mutex_lock(&codec->control_mutex); 2150 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2151 HDA_INPUT); 2152 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2153 mutex_unlock(&codec->control_mutex); 2154 return err; 2155} 2156 2157typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2158 struct snd_ctl_elem_value *ucontrol); 2159 2160static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2161 struct snd_ctl_elem_value *ucontrol, 2162 getput_call_t func) 2163{ 2164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2165 struct alc_spec *spec = codec->spec; 2166 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2167 int err; 2168 2169 mutex_lock(&codec->control_mutex); 2170 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 2171 3, 0, HDA_INPUT); 2172 err = func(kcontrol, ucontrol); 2173 mutex_unlock(&codec->control_mutex); 2174 return err; 2175} 2176 2177static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2178 struct snd_ctl_elem_value *ucontrol) 2179{ 2180 return alc_cap_getput_caller(kcontrol, ucontrol, 2181 snd_hda_mixer_amp_volume_get); 2182} 2183 2184static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2185 struct snd_ctl_elem_value *ucontrol) 2186{ 2187 return alc_cap_getput_caller(kcontrol, ucontrol, 2188 snd_hda_mixer_amp_volume_put); 2189} 2190 2191/* capture mixer elements */ 2192#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2193 2194static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2195 struct snd_ctl_elem_value *ucontrol) 2196{ 2197 return alc_cap_getput_caller(kcontrol, ucontrol, 2198 snd_hda_mixer_amp_switch_get); 2199} 2200 2201static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2202 struct snd_ctl_elem_value *ucontrol) 2203{ 2204 return alc_cap_getput_caller(kcontrol, ucontrol, 2205 snd_hda_mixer_amp_switch_put); 2206} 2207 2208#define _DEFINE_CAPMIX(num) \ 2209 { \ 2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2211 .name = "Capture Switch", \ 2212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2213 .count = num, \ 2214 .info = alc_cap_sw_info, \ 2215 .get = alc_cap_sw_get, \ 2216 .put = alc_cap_sw_put, \ 2217 }, \ 2218 { \ 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2220 .name = "Capture Volume", \ 2221 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2222 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2223 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2224 .count = num, \ 2225 .info = alc_cap_vol_info, \ 2226 .get = alc_cap_vol_get, \ 2227 .put = alc_cap_vol_put, \ 2228 .tlv = { .c = alc_cap_vol_tlv }, \ 2229 } 2230 2231#define _DEFINE_CAPSRC(num) \ 2232 { \ 2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2234 /* .name = "Capture Source", */ \ 2235 .name = "Input Source", \ 2236 .count = num, \ 2237 .info = alc_mux_enum_info, \ 2238 .get = alc_mux_enum_get, \ 2239 .put = alc_mux_enum_put, \ 2240 } 2241 2242#define DEFINE_CAPMIX(num) \ 2243static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2244 _DEFINE_CAPMIX(num), \ 2245 _DEFINE_CAPSRC(num), \ 2246 { } /* end */ \ 2247} 2248 2249#define DEFINE_CAPMIX_NOSRC(num) \ 2250static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2251 _DEFINE_CAPMIX(num), \ 2252 { } /* end */ \ 2253} 2254 2255/* up to three ADCs */ 2256DEFINE_CAPMIX(1); 2257DEFINE_CAPMIX(2); 2258DEFINE_CAPMIX(3); 2259DEFINE_CAPMIX_NOSRC(1); 2260DEFINE_CAPMIX_NOSRC(2); 2261DEFINE_CAPMIX_NOSRC(3); 2262 2263/* 2264 * ALC880 5-stack model 2265 * 2266 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2267 * Side = 0x02 (0xd) 2268 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2269 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2270 */ 2271 2272/* additional mixers to alc880_three_stack_mixer */ 2273static struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2275 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2276 { } /* end */ 2277}; 2278 2279/* channel source setting (6/8 channel selection for 5-stack) */ 2280/* 6ch mode */ 2281static struct hda_verb alc880_fivestack_ch6_init[] = { 2282 /* set line-in to input, mute it */ 2283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2285 { } /* end */ 2286}; 2287 2288/* 8ch mode */ 2289static struct hda_verb alc880_fivestack_ch8_init[] = { 2290 /* set line-in to output, unmute it */ 2291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2293 { } /* end */ 2294}; 2295 2296static struct hda_channel_mode alc880_fivestack_modes[2] = { 2297 { 6, alc880_fivestack_ch6_init }, 2298 { 8, alc880_fivestack_ch8_init }, 2299}; 2300 2301 2302/* 2303 * ALC880 6-stack model 2304 * 2305 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2306 * Side = 0x05 (0x0f) 2307 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2308 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2309 */ 2310 2311static hda_nid_t alc880_6st_dac_nids[4] = { 2312 /* front, rear, clfe, rear_surr */ 2313 0x02, 0x03, 0x04, 0x05 2314}; 2315 2316static struct hda_input_mux alc880_6stack_capture_source = { 2317 .num_items = 4, 2318 .items = { 2319 { "Mic", 0x0 }, 2320 { "Front Mic", 0x1 }, 2321 { "Line", 0x2 }, 2322 { "CD", 0x4 }, 2323 }, 2324}; 2325 2326/* fixed 8-channels */ 2327static struct hda_channel_mode alc880_sixstack_modes[1] = { 2328 { 8, NULL }, 2329}; 2330 2331static struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2332 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2336 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2338 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2339 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2340 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2341 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2350 { 2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2352 .name = "Channel Mode", 2353 .info = alc_ch_mode_info, 2354 .get = alc_ch_mode_get, 2355 .put = alc_ch_mode_put, 2356 }, 2357 { } /* end */ 2358}; 2359 2360 2361/* 2362 * ALC880 W810 model 2363 * 2364 * W810 has rear IO for: 2365 * Front (DAC 02) 2366 * Surround (DAC 03) 2367 * Center/LFE (DAC 04) 2368 * Digital out (06) 2369 * 2370 * The system also has a pair of internal speakers, and a headphone jack. 2371 * These are both connected to Line2 on the codec, hence to DAC 02. 2372 * 2373 * There is a variable resistor to control the speaker or headphone 2374 * volume. This is a hardware-only device without a software API. 2375 * 2376 * Plugging headphones in will disable the internal speakers. This is 2377 * implemented in hardware, not via the driver using jack sense. In 2378 * a similar fashion, plugging into the rear socket marked "front" will 2379 * disable both the speakers and headphones. 2380 * 2381 * For input, there's a microphone jack, and an "audio in" jack. 2382 * These may not do anything useful with this driver yet, because I 2383 * haven't setup any initialization verbs for these yet... 2384 */ 2385 2386static hda_nid_t alc880_w810_dac_nids[3] = { 2387 /* front, rear/surround, clfe */ 2388 0x02, 0x03, 0x04 2389}; 2390 2391/* fixed 6 channels */ 2392static struct hda_channel_mode alc880_w810_modes[1] = { 2393 { 6, NULL } 2394}; 2395 2396/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2397static struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2400 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2401 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2402 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2403 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2404 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2405 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2407 { } /* end */ 2408}; 2409 2410 2411/* 2412 * Z710V model 2413 * 2414 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2415 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2416 * Line = 0x1a 2417 */ 2418 2419static hda_nid_t alc880_z71v_dac_nids[1] = { 2420 0x02 2421}; 2422#define ALC880_Z71V_HP_DAC 0x03 2423 2424/* fixed 2 channels */ 2425static struct hda_channel_mode alc880_2_jack_modes[1] = { 2426 { 2, NULL } 2427}; 2428 2429static struct snd_kcontrol_new alc880_z71v_mixer[] = { 2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2438 { } /* end */ 2439}; 2440 2441 2442/* 2443 * ALC880 F1734 model 2444 * 2445 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 2446 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 2447 */ 2448 2449static hda_nid_t alc880_f1734_dac_nids[1] = { 2450 0x03 2451}; 2452#define ALC880_F1734_HP_DAC 0x02 2453 2454static struct snd_kcontrol_new alc880_f1734_mixer[] = { 2455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2463 { } /* end */ 2464}; 2465 2466static struct hda_input_mux alc880_f1734_capture_source = { 2467 .num_items = 2, 2468 .items = { 2469 { "Mic", 0x1 }, 2470 { "CD", 0x4 }, 2471 }, 2472}; 2473 2474 2475/* 2476 * ALC880 ASUS model 2477 * 2478 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2479 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2480 * Mic = 0x18, Line = 0x1a 2481 */ 2482 2483#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 2484#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 2485 2486static struct snd_kcontrol_new alc880_asus_mixer[] = { 2487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2488 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2489 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2490 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2491 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2492 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2493 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2494 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2501 { 2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2503 .name = "Channel Mode", 2504 .info = alc_ch_mode_info, 2505 .get = alc_ch_mode_get, 2506 .put = alc_ch_mode_put, 2507 }, 2508 { } /* end */ 2509}; 2510 2511/* 2512 * ALC880 ASUS W1V model 2513 * 2514 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 2515 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 2516 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 2517 */ 2518 2519/* additional mixers to alc880_asus_mixer */ 2520static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 2521 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 2522 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 2523 { } /* end */ 2524}; 2525 2526/* TCL S700 */ 2527static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 2528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2529 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 2531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 2532 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 2534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 2535 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 2536 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 2537 { } /* end */ 2538}; 2539 2540/* Uniwill */ 2541static struct snd_kcontrol_new alc880_uniwill_mixer[] = { 2542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2543 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2544 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2545 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2558 { 2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2560 .name = "Channel Mode", 2561 .info = alc_ch_mode_info, 2562 .get = alc_ch_mode_get, 2563 .put = alc_ch_mode_put, 2564 }, 2565 { } /* end */ 2566}; 2567 2568static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 2569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2570 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2572 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2575 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2576 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2578 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2579 { } /* end */ 2580}; 2581 2582static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 2583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 2585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2586 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2589 { } /* end */ 2590}; 2591 2592/* 2593 * virtual master controls 2594 */ 2595 2596/* 2597 * slave controls for virtual master 2598 */ 2599static const char *alc_slave_vols[] = { 2600 "Front Playback Volume", 2601 "Surround Playback Volume", 2602 "Center Playback Volume", 2603 "LFE Playback Volume", 2604 "Side Playback Volume", 2605 "Headphone Playback Volume", 2606 "Speaker Playback Volume", 2607 "Mono Playback Volume", 2608 "Line-Out Playback Volume", 2609 "PCM Playback Volume", 2610 NULL, 2611}; 2612 2613static const char *alc_slave_sws[] = { 2614 "Front Playback Switch", 2615 "Surround Playback Switch", 2616 "Center Playback Switch", 2617 "LFE Playback Switch", 2618 "Side Playback Switch", 2619 "Headphone Playback Switch", 2620 "Speaker Playback Switch", 2621 "Mono Playback Switch", 2622 "IEC958 Playback Switch", 2623 "Line-Out Playback Switch", 2624 "PCM Playback Switch", 2625 NULL, 2626}; 2627 2628/* 2629 * build control elements 2630 */ 2631 2632#define NID_MAPPING (-1) 2633 2634#define SUBDEV_SPEAKER_ (0 << 6) 2635#define SUBDEV_HP_ (1 << 6) 2636#define SUBDEV_LINE_ (2 << 6) 2637#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 2638#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 2639#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 2640 2641static void alc_free_kctls(struct hda_codec *codec); 2642 2643#ifdef CONFIG_SND_HDA_INPUT_BEEP 2644/* additional beep mixers; the actual parameters are overwritten at build */ 2645static struct snd_kcontrol_new alc_beep_mixer[] = { 2646 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 2647 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 2648 { } /* end */ 2649}; 2650#endif 2651 2652static int alc_build_controls(struct hda_codec *codec) 2653{ 2654 struct alc_spec *spec = codec->spec; 2655 struct snd_kcontrol *kctl = NULL; 2656 struct snd_kcontrol_new *knew; 2657 int i, j, err; 2658 unsigned int u; 2659 hda_nid_t nid; 2660 2661 for (i = 0; i < spec->num_mixers; i++) { 2662 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 2663 if (err < 0) 2664 return err; 2665 } 2666 if (spec->cap_mixer) { 2667 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 2668 if (err < 0) 2669 return err; 2670 } 2671 if (spec->multiout.dig_out_nid) { 2672 err = snd_hda_create_spdif_out_ctls(codec, 2673 spec->multiout.dig_out_nid); 2674 if (err < 0) 2675 return err; 2676 if (!spec->no_analog) { 2677 err = snd_hda_create_spdif_share_sw(codec, 2678 &spec->multiout); 2679 if (err < 0) 2680 return err; 2681 spec->multiout.share_spdif = 1; 2682 } 2683 } 2684 if (spec->dig_in_nid) { 2685 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2686 if (err < 0) 2687 return err; 2688 } 2689 2690#ifdef CONFIG_SND_HDA_INPUT_BEEP 2691 /* create beep controls if needed */ 2692 if (spec->beep_amp) { 2693 struct snd_kcontrol_new *knew; 2694 for (knew = alc_beep_mixer; knew->name; knew++) { 2695 struct snd_kcontrol *kctl; 2696 kctl = snd_ctl_new1(knew, codec); 2697 if (!kctl) 2698 return -ENOMEM; 2699 kctl->private_value = spec->beep_amp; 2700 err = snd_hda_ctl_add(codec, 0, kctl); 2701 if (err < 0) 2702 return err; 2703 } 2704 } 2705#endif 2706 2707 /* if we have no master control, let's create it */ 2708 if (!spec->no_analog && 2709 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2710 unsigned int vmaster_tlv[4]; 2711 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2712 HDA_OUTPUT, vmaster_tlv); 2713 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 2714 vmaster_tlv, alc_slave_vols); 2715 if (err < 0) 2716 return err; 2717 } 2718 if (!spec->no_analog && 2719 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2720 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2721 NULL, alc_slave_sws); 2722 if (err < 0) 2723 return err; 2724 } 2725 2726 /* assign Capture Source enums to NID */ 2727 if (spec->capsrc_nids || spec->adc_nids) { 2728 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 2729 if (!kctl) 2730 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 2731 for (i = 0; kctl && i < kctl->count; i++) { 2732 hda_nid_t *nids = spec->capsrc_nids; 2733 if (!nids) 2734 nids = spec->adc_nids; 2735 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 2736 if (err < 0) 2737 return err; 2738 } 2739 } 2740 if (spec->cap_mixer) { 2741 const char *kname = kctl ? kctl->id.name : NULL; 2742 for (knew = spec->cap_mixer; knew->name; knew++) { 2743 if (kname && strcmp(knew->name, kname) == 0) 2744 continue; 2745 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2746 for (i = 0; kctl && i < kctl->count; i++) { 2747 err = snd_hda_add_nid(codec, kctl, i, 2748 spec->adc_nids[i]); 2749 if (err < 0) 2750 return err; 2751 } 2752 } 2753 } 2754 2755 /* other nid->control mapping */ 2756 for (i = 0; i < spec->num_mixers; i++) { 2757 for (knew = spec->mixers[i]; knew->name; knew++) { 2758 if (knew->iface != NID_MAPPING) 2759 continue; 2760 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 2761 if (kctl == NULL) 2762 continue; 2763 u = knew->subdevice; 2764 for (j = 0; j < 4; j++, u >>= 8) { 2765 nid = u & 0x3f; 2766 if (nid == 0) 2767 continue; 2768 switch (u & 0xc0) { 2769 case SUBDEV_SPEAKER_: 2770 nid = spec->autocfg.speaker_pins[nid]; 2771 break; 2772 case SUBDEV_LINE_: 2773 nid = spec->autocfg.line_out_pins[nid]; 2774 break; 2775 case SUBDEV_HP_: 2776 nid = spec->autocfg.hp_pins[nid]; 2777 break; 2778 default: 2779 continue; 2780 } 2781 err = snd_hda_add_nid(codec, kctl, 0, nid); 2782 if (err < 0) 2783 return err; 2784 } 2785 u = knew->private_value; 2786 for (j = 0; j < 4; j++, u >>= 8) { 2787 nid = u & 0xff; 2788 if (nid == 0) 2789 continue; 2790 err = snd_hda_add_nid(codec, kctl, 0, nid); 2791 if (err < 0) 2792 return err; 2793 } 2794 } 2795 } 2796 2797 alc_free_kctls(codec); /* no longer needed */ 2798 2799 return 0; 2800} 2801 2802 2803/* 2804 * initialize the codec volumes, etc 2805 */ 2806 2807/* 2808 * generic initialization of ADC, input mixers and output mixers 2809 */ 2810static struct hda_verb alc880_volume_init_verbs[] = { 2811 /* 2812 * Unmute ADC0-2 and set the default input to mic-in 2813 */ 2814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 2815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 2817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 2819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2820 2821 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 2822 * mixer widget 2823 * Note: PASD motherboards uses the Line In 2 as the input for front 2824 * panel mic (mic 2) 2825 */ 2826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 2834 2835 /* 2836 * Set up output mixers (0x0c - 0x0f) 2837 */ 2838 /* set vol=0 to output mixers */ 2839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 2843 /* set up input amps for analog loopback */ 2844 /* Amp Indices: DAC = 0, mixer = 1 */ 2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2852 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 2853 2854 { } 2855}; 2856 2857/* 2858 * 3-stack pin configuration: 2859 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 2860 */ 2861static struct hda_verb alc880_pin_3stack_init_verbs[] = { 2862 /* 2863 * preset connection lists of input pins 2864 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2865 */ 2866 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 2867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2868 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 2869 2870 /* 2871 * Set pin mode and muting 2872 */ 2873 /* set front pin widgets 0x14 for output */ 2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2876 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2878 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2879 /* Mic2 (as headphone out) for HP output */ 2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2882 /* Line In pin widget for input */ 2883 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2885 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2888 /* CD pin widget for input */ 2889 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2890 2891 { } 2892}; 2893 2894/* 2895 * 5-stack pin configuration: 2896 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 2897 * line-in/side = 0x1a, f-mic = 0x1b 2898 */ 2899static struct hda_verb alc880_pin_5stack_init_verbs[] = { 2900 /* 2901 * preset connection lists of input pins 2902 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 2903 */ 2904 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2905 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 2906 2907 /* 2908 * Set pin mode and muting 2909 */ 2910 /* set pin widgets 0x14-0x17 for output */ 2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2915 /* unmute pins for output (no gain on this amp) */ 2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2920 2921 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2924 /* Mic2 (as headphone out) for HP output */ 2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2927 /* Line In pin widget for input */ 2928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2930 /* Line2 (as front mic) pin widget for input and vref at 80% */ 2931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2932 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2933 /* CD pin widget for input */ 2934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2935 2936 { } 2937}; 2938 2939/* 2940 * W810 pin configuration: 2941 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 2942 */ 2943static struct hda_verb alc880_pin_w810_init_verbs[] = { 2944 /* hphone/speaker input selector: front DAC */ 2945 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 2946 2947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2953 2954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2956 2957 { } 2958}; 2959 2960/* 2961 * Z71V pin configuration: 2962 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 2963 */ 2964static struct hda_verb alc880_pin_z71v_init_verbs[] = { 2965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 2968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2969 2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2974 2975 { } 2976}; 2977 2978/* 2979 * 6-stack pin configuration: 2980 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 2981 * f-mic = 0x19, line = 0x1a, HP = 0x1b 2982 */ 2983static struct hda_verb alc880_pin_6stack_init_verbs[] = { 2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 2985 2986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2992 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2994 2995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 2998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 2999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3003 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3004 3005 { } 3006}; 3007 3008/* 3009 * Uniwill pin configuration: 3010 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3011 * line = 0x1a 3012 */ 3013static struct hda_verb alc880_uniwill_init_verbs[] = { 3014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3015 3016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3022 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3030 3031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3037 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3038 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3039 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3040 3041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3043 3044 { } 3045}; 3046 3047/* 3048* Uniwill P53 3049* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3050 */ 3051static struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3053 3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3066 3067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3069 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3073 3074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3076 3077 { } 3078}; 3079 3080static struct hda_verb alc880_beep_init_verbs[] = { 3081 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3082 { } 3083}; 3084 3085/* auto-toggle front mic */ 3086static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3087{ 3088 unsigned int present; 3089 unsigned char bits; 3090 3091 present = snd_hda_jack_detect(codec, 0x18); 3092 bits = present ? HDA_AMP_MUTE : 0; 3093 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3094} 3095 3096static void alc880_uniwill_setup(struct hda_codec *codec) 3097{ 3098 struct alc_spec *spec = codec->spec; 3099 3100 spec->autocfg.hp_pins[0] = 0x14; 3101 spec->autocfg.speaker_pins[0] = 0x15; 3102 spec->autocfg.speaker_pins[0] = 0x16; 3103} 3104 3105static void alc880_uniwill_init_hook(struct hda_codec *codec) 3106{ 3107 alc_automute_amp(codec); 3108 alc880_uniwill_mic_automute(codec); 3109} 3110 3111static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3112 unsigned int res) 3113{ 3114 /* Looks like the unsol event is incompatible with the standard 3115 * definition. 4bit tag is placed at 28 bit! 3116 */ 3117 switch (res >> 28) { 3118 case ALC880_MIC_EVENT: 3119 alc880_uniwill_mic_automute(codec); 3120 break; 3121 default: 3122 alc_automute_amp_unsol_event(codec, res); 3123 break; 3124 } 3125} 3126 3127static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3128{ 3129 struct alc_spec *spec = codec->spec; 3130 3131 spec->autocfg.hp_pins[0] = 0x14; 3132 spec->autocfg.speaker_pins[0] = 0x15; 3133} 3134 3135static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3136{ 3137 unsigned int present; 3138 3139 present = snd_hda_codec_read(codec, 0x21, 0, 3140 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3141 present &= HDA_AMP_VOLMASK; 3142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3143 HDA_AMP_VOLMASK, present); 3144 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3145 HDA_AMP_VOLMASK, present); 3146} 3147 3148static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3149 unsigned int res) 3150{ 3151 /* Looks like the unsol event is incompatible with the standard 3152 * definition. 4bit tag is placed at 28 bit! 3153 */ 3154 if ((res >> 28) == ALC880_DCVOL_EVENT) 3155 alc880_uniwill_p53_dcvol_automute(codec); 3156 else 3157 alc_automute_amp_unsol_event(codec, res); 3158} 3159 3160/* 3161 * F1734 pin configuration: 3162 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3163 */ 3164static struct hda_verb alc880_pin_f1734_init_verbs[] = { 3165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3166 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3167 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3168 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3169 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3170 3171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3175 3176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3181 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3185 3186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3187 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3188 3189 { } 3190}; 3191 3192/* 3193 * ASUS pin configuration: 3194 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3195 */ 3196static struct hda_verb alc880_pin_asus_init_verbs[] = { 3197 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3198 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3199 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3200 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3201 3202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3210 3211 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3217 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3220 3221 { } 3222}; 3223 3224/* Enable GPIO mask and set output */ 3225#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3226#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3227#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3228 3229/* Clevo m520g init */ 3230static struct hda_verb alc880_pin_clevo_init_verbs[] = { 3231 /* headphone output */ 3232 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3233 /* line-out */ 3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3236 /* Line-in */ 3237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3239 /* CD */ 3240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3242 /* Mic1 (rear panel) */ 3243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3245 /* Mic2 (front panel) */ 3246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3248 /* headphone */ 3249 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3251 /* change to EAPD mode */ 3252 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3253 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3254 3255 { } 3256}; 3257 3258static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3259 /* change to EAPD mode */ 3260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3262 3263 /* Headphone output */ 3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3265 /* Front output*/ 3266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3267 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3268 3269 /* Line In pin widget for input */ 3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3271 /* CD pin widget for input */ 3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3273 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3275 3276 /* change to EAPD mode */ 3277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3278 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3279 3280 { } 3281}; 3282 3283/* 3284 * LG m1 express dual 3285 * 3286 * Pin assignment: 3287 * Rear Line-In/Out (blue): 0x14 3288 * Build-in Mic-In: 0x15 3289 * Speaker-out: 0x17 3290 * HP-Out (green): 0x1b 3291 * Mic-In/Out (red): 0x19 3292 * SPDIF-Out: 0x1e 3293 */ 3294 3295/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3296static hda_nid_t alc880_lg_dac_nids[3] = { 3297 0x05, 0x02, 0x03 3298}; 3299 3300/* seems analog CD is not working */ 3301static struct hda_input_mux alc880_lg_capture_source = { 3302 .num_items = 3, 3303 .items = { 3304 { "Mic", 0x1 }, 3305 { "Line", 0x5 }, 3306 { "Internal Mic", 0x6 }, 3307 }, 3308}; 3309 3310/* 2,4,6 channel modes */ 3311static struct hda_verb alc880_lg_ch2_init[] = { 3312 /* set line-in and mic-in to input */ 3313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3314 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3315 { } 3316}; 3317 3318static struct hda_verb alc880_lg_ch4_init[] = { 3319 /* set line-in to out and mic-in to input */ 3320 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3321 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3322 { } 3323}; 3324 3325static struct hda_verb alc880_lg_ch6_init[] = { 3326 /* set line-in and mic-in to output */ 3327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3329 { } 3330}; 3331 3332static struct hda_channel_mode alc880_lg_ch_modes[3] = { 3333 { 2, alc880_lg_ch2_init }, 3334 { 4, alc880_lg_ch4_init }, 3335 { 6, alc880_lg_ch6_init }, 3336}; 3337 3338static struct snd_kcontrol_new alc880_lg_mixer[] = { 3339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3340 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3342 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3343 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3345 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3346 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3351 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3352 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3353 { 3354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3355 .name = "Channel Mode", 3356 .info = alc_ch_mode_info, 3357 .get = alc_ch_mode_get, 3358 .put = alc_ch_mode_put, 3359 }, 3360 { } /* end */ 3361}; 3362 3363static struct hda_verb alc880_lg_init_verbs[] = { 3364 /* set capture source to mic-in */ 3365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3368 /* mute all amp mixer inputs */ 3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3372 /* line-in to input */ 3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3375 /* built-in mic */ 3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3378 /* speaker-out */ 3379 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3381 /* mic-in to input */ 3382 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3383 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3384 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3385 /* HP-out */ 3386 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3389 /* jack sense */ 3390 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3391 { } 3392}; 3393 3394/* toggle speaker-output according to the hp-jack state */ 3395static void alc880_lg_setup(struct hda_codec *codec) 3396{ 3397 struct alc_spec *spec = codec->spec; 3398 3399 spec->autocfg.hp_pins[0] = 0x1b; 3400 spec->autocfg.speaker_pins[0] = 0x17; 3401} 3402 3403/* 3404 * LG LW20 3405 * 3406 * Pin assignment: 3407 * Speaker-out: 0x14 3408 * Mic-In: 0x18 3409 * Built-in Mic-In: 0x19 3410 * Line-In: 0x1b 3411 * HP-Out: 0x1a 3412 * SPDIF-Out: 0x1e 3413 */ 3414 3415static struct hda_input_mux alc880_lg_lw_capture_source = { 3416 .num_items = 3, 3417 .items = { 3418 { "Mic", 0x0 }, 3419 { "Internal Mic", 0x1 }, 3420 { "Line In", 0x2 }, 3421 }, 3422}; 3423 3424#define alc880_lg_lw_modes alc880_threestack_modes 3425 3426static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 3427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3430 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 3431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3439 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 3440 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 3441 { 3442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3443 .name = "Channel Mode", 3444 .info = alc_ch_mode_info, 3445 .get = alc_ch_mode_get, 3446 .put = alc_ch_mode_put, 3447 }, 3448 { } /* end */ 3449}; 3450 3451static struct hda_verb alc880_lg_lw_init_verbs[] = { 3452 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3453 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3454 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3455 3456 /* set capture source to mic-in */ 3457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3461 /* speaker-out */ 3462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3464 /* HP-out */ 3465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3467 /* mic-in to input */ 3468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3470 /* built-in mic */ 3471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3473 /* jack sense */ 3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3475 { } 3476}; 3477 3478/* toggle speaker-output according to the hp-jack state */ 3479static void alc880_lg_lw_setup(struct hda_codec *codec) 3480{ 3481 struct alc_spec *spec = codec->spec; 3482 3483 spec->autocfg.hp_pins[0] = 0x1b; 3484 spec->autocfg.speaker_pins[0] = 0x14; 3485} 3486 3487static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3488 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3489 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 3490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3492 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3493 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 3494 { } /* end */ 3495}; 3496 3497static struct hda_input_mux alc880_medion_rim_capture_source = { 3498 .num_items = 2, 3499 .items = { 3500 { "Mic", 0x0 }, 3501 { "Internal Mic", 0x1 }, 3502 }, 3503}; 3504 3505static struct hda_verb alc880_medion_rim_init_verbs[] = { 3506 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3507 3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3510 3511 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3514 /* Mic2 (as headphone out) for HP output */ 3515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3517 /* Internal Speaker */ 3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3520 3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3523 3524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3525 { } 3526}; 3527 3528/* toggle speaker-output according to the hp-jack state */ 3529static void alc880_medion_rim_automute(struct hda_codec *codec) 3530{ 3531 struct alc_spec *spec = codec->spec; 3532 alc_automute_amp(codec); 3533 /* toggle EAPD */ 3534 if (spec->jack_present) 3535 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 3536 else 3537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 3538} 3539 3540static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 3541 unsigned int res) 3542{ 3543 /* Looks like the unsol event is incompatible with the standard 3544 * definition. 4bit tag is placed at 28 bit! 3545 */ 3546 if ((res >> 28) == ALC880_HP_EVENT) 3547 alc880_medion_rim_automute(codec); 3548} 3549 3550static void alc880_medion_rim_setup(struct hda_codec *codec) 3551{ 3552 struct alc_spec *spec = codec->spec; 3553 3554 spec->autocfg.hp_pins[0] = 0x14; 3555 spec->autocfg.speaker_pins[0] = 0x1b; 3556} 3557 3558#ifdef CONFIG_SND_HDA_POWER_SAVE 3559static struct hda_amp_list alc880_loopbacks[] = { 3560 { 0x0b, HDA_INPUT, 0 }, 3561 { 0x0b, HDA_INPUT, 1 }, 3562 { 0x0b, HDA_INPUT, 2 }, 3563 { 0x0b, HDA_INPUT, 3 }, 3564 { 0x0b, HDA_INPUT, 4 }, 3565 { } /* end */ 3566}; 3567 3568static struct hda_amp_list alc880_lg_loopbacks[] = { 3569 { 0x0b, HDA_INPUT, 1 }, 3570 { 0x0b, HDA_INPUT, 6 }, 3571 { 0x0b, HDA_INPUT, 7 }, 3572 { } /* end */ 3573}; 3574#endif 3575 3576/* 3577 * Common callbacks 3578 */ 3579 3580static int alc_init(struct hda_codec *codec) 3581{ 3582 struct alc_spec *spec = codec->spec; 3583 unsigned int i; 3584 3585 alc_fix_pll(codec); 3586 alc_auto_init_amp(codec, spec->init_amp); 3587 3588 for (i = 0; i < spec->num_init_verbs; i++) 3589 snd_hda_sequence_write(codec, spec->init_verbs[i]); 3590 3591 if (spec->init_hook) 3592 spec->init_hook(codec); 3593 3594#ifdef CONFIG_SND_HDA_POWER_SAVE 3595 if (codec->patch_ops.check_power_status) 3596 codec->patch_ops.check_power_status(codec, 0x01); 3597#endif 3598 return 0; 3599} 3600 3601static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 3602{ 3603 struct alc_spec *spec = codec->spec; 3604 3605 if (spec->unsol_event) 3606 spec->unsol_event(codec, res); 3607} 3608 3609#ifdef CONFIG_SND_HDA_POWER_SAVE 3610static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 3611{ 3612 struct alc_spec *spec = codec->spec; 3613 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 3614} 3615#endif 3616 3617/* 3618 * Analog playback callbacks 3619 */ 3620static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 3621 struct hda_codec *codec, 3622 struct snd_pcm_substream *substream) 3623{ 3624 struct alc_spec *spec = codec->spec; 3625 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 3626 hinfo); 3627} 3628 3629static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3630 struct hda_codec *codec, 3631 unsigned int stream_tag, 3632 unsigned int format, 3633 struct snd_pcm_substream *substream) 3634{ 3635 struct alc_spec *spec = codec->spec; 3636 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 3637 stream_tag, format, substream); 3638} 3639 3640static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3641 struct hda_codec *codec, 3642 struct snd_pcm_substream *substream) 3643{ 3644 struct alc_spec *spec = codec->spec; 3645 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 3646} 3647 3648/* 3649 * Digital out 3650 */ 3651static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 3652 struct hda_codec *codec, 3653 struct snd_pcm_substream *substream) 3654{ 3655 struct alc_spec *spec = codec->spec; 3656 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 3657} 3658 3659static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 3660 struct hda_codec *codec, 3661 unsigned int stream_tag, 3662 unsigned int format, 3663 struct snd_pcm_substream *substream) 3664{ 3665 struct alc_spec *spec = codec->spec; 3666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 3667 stream_tag, format, substream); 3668} 3669 3670static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 3671 struct hda_codec *codec, 3672 struct snd_pcm_substream *substream) 3673{ 3674 struct alc_spec *spec = codec->spec; 3675 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 3676} 3677 3678static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 3679 struct hda_codec *codec, 3680 struct snd_pcm_substream *substream) 3681{ 3682 struct alc_spec *spec = codec->spec; 3683 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 3684} 3685 3686/* 3687 * Analog capture 3688 */ 3689static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3690 struct hda_codec *codec, 3691 unsigned int stream_tag, 3692 unsigned int format, 3693 struct snd_pcm_substream *substream) 3694{ 3695 struct alc_spec *spec = codec->spec; 3696 3697 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 3698 stream_tag, 0, format); 3699 return 0; 3700} 3701 3702static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3703 struct hda_codec *codec, 3704 struct snd_pcm_substream *substream) 3705{ 3706 struct alc_spec *spec = codec->spec; 3707 3708 snd_hda_codec_cleanup_stream(codec, 3709 spec->adc_nids[substream->number + 1]); 3710 return 0; 3711} 3712 3713/* analog capture with dynamic dual-adc changes */ 3714static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 3715 struct hda_codec *codec, 3716 unsigned int stream_tag, 3717 unsigned int format, 3718 struct snd_pcm_substream *substream) 3719{ 3720 struct alc_spec *spec = codec->spec; 3721 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 3722 spec->cur_adc_stream_tag = stream_tag; 3723 spec->cur_adc_format = format; 3724 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 3725 return 0; 3726} 3727 3728static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 3729 struct hda_codec *codec, 3730 struct snd_pcm_substream *substream) 3731{ 3732 struct alc_spec *spec = codec->spec; 3733 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 3734 spec->cur_adc = 0; 3735 return 0; 3736} 3737 3738static struct hda_pcm_stream dualmic_pcm_analog_capture = { 3739 .substreams = 1, 3740 .channels_min = 2, 3741 .channels_max = 2, 3742 .nid = 0, /* fill later */ 3743 .ops = { 3744 .prepare = dualmic_capture_pcm_prepare, 3745 .cleanup = dualmic_capture_pcm_cleanup 3746 }, 3747}; 3748 3749/* 3750 */ 3751static struct hda_pcm_stream alc880_pcm_analog_playback = { 3752 .substreams = 1, 3753 .channels_min = 2, 3754 .channels_max = 8, 3755 /* NID is set in alc_build_pcms */ 3756 .ops = { 3757 .open = alc880_playback_pcm_open, 3758 .prepare = alc880_playback_pcm_prepare, 3759 .cleanup = alc880_playback_pcm_cleanup 3760 }, 3761}; 3762 3763static struct hda_pcm_stream alc880_pcm_analog_capture = { 3764 .substreams = 1, 3765 .channels_min = 2, 3766 .channels_max = 2, 3767 /* NID is set in alc_build_pcms */ 3768}; 3769 3770static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 3771 .substreams = 1, 3772 .channels_min = 2, 3773 .channels_max = 2, 3774 /* NID is set in alc_build_pcms */ 3775}; 3776 3777static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 3778 .substreams = 2, /* can be overridden */ 3779 .channels_min = 2, 3780 .channels_max = 2, 3781 /* NID is set in alc_build_pcms */ 3782 .ops = { 3783 .prepare = alc880_alt_capture_pcm_prepare, 3784 .cleanup = alc880_alt_capture_pcm_cleanup 3785 }, 3786}; 3787 3788static struct hda_pcm_stream alc880_pcm_digital_playback = { 3789 .substreams = 1, 3790 .channels_min = 2, 3791 .channels_max = 2, 3792 /* NID is set in alc_build_pcms */ 3793 .ops = { 3794 .open = alc880_dig_playback_pcm_open, 3795 .close = alc880_dig_playback_pcm_close, 3796 .prepare = alc880_dig_playback_pcm_prepare, 3797 .cleanup = alc880_dig_playback_pcm_cleanup 3798 }, 3799}; 3800 3801static struct hda_pcm_stream alc880_pcm_digital_capture = { 3802 .substreams = 1, 3803 .channels_min = 2, 3804 .channels_max = 2, 3805 /* NID is set in alc_build_pcms */ 3806}; 3807 3808/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 3809static struct hda_pcm_stream alc_pcm_null_stream = { 3810 .substreams = 0, 3811 .channels_min = 0, 3812 .channels_max = 0, 3813}; 3814 3815static int alc_build_pcms(struct hda_codec *codec) 3816{ 3817 struct alc_spec *spec = codec->spec; 3818 struct hda_pcm *info = spec->pcm_rec; 3819 int i; 3820 3821 codec->num_pcms = 1; 3822 codec->pcm_info = info; 3823 3824 if (spec->no_analog) 3825 goto skip_analog; 3826 3827 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 3828 "%s Analog", codec->chip_name); 3829 info->name = spec->stream_name_analog; 3830 3831 if (spec->stream_analog_playback) { 3832 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3833 return -EINVAL; 3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 3836 } 3837 if (spec->stream_analog_capture) { 3838 if (snd_BUG_ON(!spec->adc_nids)) 3839 return -EINVAL; 3840 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 3841 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 3842 } 3843 3844 if (spec->channel_mode) { 3845 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 3846 for (i = 0; i < spec->num_channel_mode; i++) { 3847 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 3848 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 3849 } 3850 } 3851 } 3852 3853 skip_analog: 3854 /* SPDIF for stream index #1 */ 3855 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3856 snprintf(spec->stream_name_digital, 3857 sizeof(spec->stream_name_digital), 3858 "%s Digital", codec->chip_name); 3859 codec->num_pcms = 2; 3860 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 3861 info = spec->pcm_rec + 1; 3862 info->name = spec->stream_name_digital; 3863 if (spec->dig_out_type) 3864 info->pcm_type = spec->dig_out_type; 3865 else 3866 info->pcm_type = HDA_PCM_TYPE_SPDIF; 3867 if (spec->multiout.dig_out_nid && 3868 spec->stream_digital_playback) { 3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 3870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 3871 } 3872 if (spec->dig_in_nid && 3873 spec->stream_digital_capture) { 3874 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 3875 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 3876 } 3877 /* FIXME: do we need this for all Realtek codec models? */ 3878 codec->spdif_status_reset = 1; 3879 } 3880 3881 if (spec->no_analog) 3882 return 0; 3883 3884 /* If the use of more than one ADC is requested for the current 3885 * model, configure a second analog capture-only PCM. 3886 */ 3887 /* Additional Analaog capture for index #2 */ 3888 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 3889 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 3890 codec->num_pcms = 3; 3891 info = spec->pcm_rec + 2; 3892 info->name = spec->stream_name_analog; 3893 if (spec->alt_dac_nid) { 3894 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3895 *spec->stream_analog_alt_playback; 3896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 3897 spec->alt_dac_nid; 3898 } else { 3899 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 3900 alc_pcm_null_stream; 3901 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 3902 } 3903 if (spec->num_adc_nids > 1) { 3904 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3905 *spec->stream_analog_alt_capture; 3906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 3907 spec->adc_nids[1]; 3908 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 3909 spec->num_adc_nids - 1; 3910 } else { 3911 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 3912 alc_pcm_null_stream; 3913 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 3914 } 3915 } 3916 3917 return 0; 3918} 3919 3920static inline void alc_shutup(struct hda_codec *codec) 3921{ 3922 snd_hda_shutup_pins(codec); 3923} 3924 3925static void alc_free_kctls(struct hda_codec *codec) 3926{ 3927 struct alc_spec *spec = codec->spec; 3928 3929 if (spec->kctls.list) { 3930 struct snd_kcontrol_new *kctl = spec->kctls.list; 3931 int i; 3932 for (i = 0; i < spec->kctls.used; i++) 3933 kfree(kctl[i].name); 3934 } 3935 snd_array_free(&spec->kctls); 3936} 3937 3938static void alc_free(struct hda_codec *codec) 3939{ 3940 struct alc_spec *spec = codec->spec; 3941 3942 if (!spec) 3943 return; 3944 3945 alc_shutup(codec); 3946 alc_free_kctls(codec); 3947 kfree(spec); 3948 snd_hda_detach_beep_device(codec); 3949} 3950 3951#ifdef CONFIG_SND_HDA_POWER_SAVE 3952static void alc_power_eapd(struct hda_codec *codec) 3953{ 3954 /* We currently only handle front, HP */ 3955 switch (codec->vendor_id) { 3956 case 0x10ec0260: 3957 set_eapd(codec, 0x0f, 0); 3958 set_eapd(codec, 0x10, 0); 3959 break; 3960 case 0x10ec0262: 3961 case 0x10ec0267: 3962 case 0x10ec0268: 3963 case 0x10ec0269: 3964 case 0x10ec0270: 3965 case 0x10ec0272: 3966 case 0x10ec0660: 3967 case 0x10ec0662: 3968 case 0x10ec0663: 3969 case 0x10ec0862: 3970 case 0x10ec0889: 3971 set_eapd(codec, 0x14, 0); 3972 set_eapd(codec, 0x15, 0); 3973 break; 3974 } 3975} 3976 3977static int alc_suspend(struct hda_codec *codec, pm_message_t state) 3978{ 3979 struct alc_spec *spec = codec->spec; 3980 alc_shutup(codec); 3981 if (spec && spec->power_hook) 3982 spec->power_hook(codec); 3983 return 0; 3984} 3985#endif 3986 3987#ifdef SND_HDA_NEEDS_RESUME 3988static int alc_resume(struct hda_codec *codec) 3989{ 3990 codec->patch_ops.init(codec); 3991 snd_hda_codec_resume_amp(codec); 3992 snd_hda_codec_resume_cache(codec); 3993#ifdef CONFIG_SND_HDA_POWER_SAVE 3994 if (codec->patch_ops.check_power_status) 3995 codec->patch_ops.check_power_status(codec, 0x01); 3996#endif 3997 return 0; 3998} 3999#endif 4000 4001/* 4002 */ 4003static struct hda_codec_ops alc_patch_ops = { 4004 .build_controls = alc_build_controls, 4005 .build_pcms = alc_build_pcms, 4006 .init = alc_init, 4007 .free = alc_free, 4008 .unsol_event = alc_unsol_event, 4009#ifdef SND_HDA_NEEDS_RESUME 4010 .resume = alc_resume, 4011#endif 4012#ifdef CONFIG_SND_HDA_POWER_SAVE 4013 .suspend = alc_suspend, 4014 .check_power_status = alc_check_power_status, 4015#endif 4016 .reboot_notify = alc_shutup, 4017}; 4018 4019/* replace the codec chip_name with the given string */ 4020static int alc_codec_rename(struct hda_codec *codec, const char *name) 4021{ 4022 kfree(codec->chip_name); 4023 codec->chip_name = kstrdup(name, GFP_KERNEL); 4024 if (!codec->chip_name) { 4025 alc_free(codec); 4026 return -ENOMEM; 4027 } 4028 return 0; 4029} 4030 4031/* 4032 * Test configuration for debugging 4033 * 4034 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4035 * enum controls. 4036 */ 4037#ifdef CONFIG_SND_DEBUG 4038static hda_nid_t alc880_test_dac_nids[4] = { 4039 0x02, 0x03, 0x04, 0x05 4040}; 4041 4042static struct hda_input_mux alc880_test_capture_source = { 4043 .num_items = 7, 4044 .items = { 4045 { "In-1", 0x0 }, 4046 { "In-2", 0x1 }, 4047 { "In-3", 0x2 }, 4048 { "In-4", 0x3 }, 4049 { "CD", 0x4 }, 4050 { "Front", 0x5 }, 4051 { "Surround", 0x6 }, 4052 }, 4053}; 4054 4055static struct hda_channel_mode alc880_test_modes[4] = { 4056 { 2, NULL }, 4057 { 4, NULL }, 4058 { 6, NULL }, 4059 { 8, NULL }, 4060}; 4061 4062static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4063 struct snd_ctl_elem_info *uinfo) 4064{ 4065 static char *texts[] = { 4066 "N/A", "Line Out", "HP Out", 4067 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4068 }; 4069 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4070 uinfo->count = 1; 4071 uinfo->value.enumerated.items = 8; 4072 if (uinfo->value.enumerated.item >= 8) 4073 uinfo->value.enumerated.item = 7; 4074 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4075 return 0; 4076} 4077 4078static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4079 struct snd_ctl_elem_value *ucontrol) 4080{ 4081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4082 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4083 unsigned int pin_ctl, item = 0; 4084 4085 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4086 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4087 if (pin_ctl & AC_PINCTL_OUT_EN) { 4088 if (pin_ctl & AC_PINCTL_HP_EN) 4089 item = 2; 4090 else 4091 item = 1; 4092 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4093 switch (pin_ctl & AC_PINCTL_VREFEN) { 4094 case AC_PINCTL_VREF_HIZ: item = 3; break; 4095 case AC_PINCTL_VREF_50: item = 4; break; 4096 case AC_PINCTL_VREF_GRD: item = 5; break; 4097 case AC_PINCTL_VREF_80: item = 6; break; 4098 case AC_PINCTL_VREF_100: item = 7; break; 4099 } 4100 } 4101 ucontrol->value.enumerated.item[0] = item; 4102 return 0; 4103} 4104 4105static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4106 struct snd_ctl_elem_value *ucontrol) 4107{ 4108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4109 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4110 static unsigned int ctls[] = { 4111 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4116 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4117 }; 4118 unsigned int old_ctl, new_ctl; 4119 4120 old_ctl = snd_hda_codec_read(codec, nid, 0, 4121 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4122 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4123 if (old_ctl != new_ctl) { 4124 int val; 4125 snd_hda_codec_write_cache(codec, nid, 0, 4126 AC_VERB_SET_PIN_WIDGET_CONTROL, 4127 new_ctl); 4128 val = ucontrol->value.enumerated.item[0] >= 3 ? 4129 HDA_AMP_MUTE : 0; 4130 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4131 HDA_AMP_MUTE, val); 4132 return 1; 4133 } 4134 return 0; 4135} 4136 4137static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4138 struct snd_ctl_elem_info *uinfo) 4139{ 4140 static char *texts[] = { 4141 "Front", "Surround", "CLFE", "Side" 4142 }; 4143 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4144 uinfo->count = 1; 4145 uinfo->value.enumerated.items = 4; 4146 if (uinfo->value.enumerated.item >= 4) 4147 uinfo->value.enumerated.item = 3; 4148 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4149 return 0; 4150} 4151 4152static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4153 struct snd_ctl_elem_value *ucontrol) 4154{ 4155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4156 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4157 unsigned int sel; 4158 4159 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4160 ucontrol->value.enumerated.item[0] = sel & 3; 4161 return 0; 4162} 4163 4164static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4165 struct snd_ctl_elem_value *ucontrol) 4166{ 4167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4168 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4169 unsigned int sel; 4170 4171 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4172 if (ucontrol->value.enumerated.item[0] != sel) { 4173 sel = ucontrol->value.enumerated.item[0] & 3; 4174 snd_hda_codec_write_cache(codec, nid, 0, 4175 AC_VERB_SET_CONNECT_SEL, sel); 4176 return 1; 4177 } 4178 return 0; 4179} 4180 4181#define PIN_CTL_TEST(xname,nid) { \ 4182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4183 .name = xname, \ 4184 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4185 .info = alc_test_pin_ctl_info, \ 4186 .get = alc_test_pin_ctl_get, \ 4187 .put = alc_test_pin_ctl_put, \ 4188 .private_value = nid \ 4189 } 4190 4191#define PIN_SRC_TEST(xname,nid) { \ 4192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4193 .name = xname, \ 4194 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4195 .info = alc_test_pin_src_info, \ 4196 .get = alc_test_pin_src_get, \ 4197 .put = alc_test_pin_src_put, \ 4198 .private_value = nid \ 4199 } 4200 4201static struct snd_kcontrol_new alc880_test_mixer[] = { 4202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4204 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4208 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4210 PIN_CTL_TEST("Front Pin Mode", 0x14), 4211 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4212 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4213 PIN_CTL_TEST("Side Pin Mode", 0x17), 4214 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4215 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4216 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4217 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4218 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4219 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4220 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4221 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4222 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4223 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4224 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4225 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4226 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4227 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4228 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4229 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4232 { 4233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4234 .name = "Channel Mode", 4235 .info = alc_ch_mode_info, 4236 .get = alc_ch_mode_get, 4237 .put = alc_ch_mode_put, 4238 }, 4239 { } /* end */ 4240}; 4241 4242static struct hda_verb alc880_test_init_verbs[] = { 4243 /* Unmute inputs of 0x0c - 0x0f */ 4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4245 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4252 /* Vol output for 0x0c-0x0f */ 4253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4257 /* Set output pins 0x14-0x17 */ 4258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4262 /* Unmute output pins 0x14-0x17 */ 4263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4267 /* Set input pins 0x18-0x1c */ 4268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4273 /* Mute input pins 0x18-0x1b */ 4274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4278 /* ADC set up */ 4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4280 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4282 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4285 /* Analog input/passthru */ 4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4291 { } 4292}; 4293#endif 4294 4295/* 4296 */ 4297 4298static const char *alc880_models[ALC880_MODEL_LAST] = { 4299 [ALC880_3ST] = "3stack", 4300 [ALC880_TCL_S700] = "tcl", 4301 [ALC880_3ST_DIG] = "3stack-digout", 4302 [ALC880_CLEVO] = "clevo", 4303 [ALC880_5ST] = "5stack", 4304 [ALC880_5ST_DIG] = "5stack-digout", 4305 [ALC880_W810] = "w810", 4306 [ALC880_Z71V] = "z71v", 4307 [ALC880_6ST] = "6stack", 4308 [ALC880_6ST_DIG] = "6stack-digout", 4309 [ALC880_ASUS] = "asus", 4310 [ALC880_ASUS_W1V] = "asus-w1v", 4311 [ALC880_ASUS_DIG] = "asus-dig", 4312 [ALC880_ASUS_DIG2] = "asus-dig2", 4313 [ALC880_UNIWILL_DIG] = "uniwill", 4314 [ALC880_UNIWILL_P53] = "uniwill-p53", 4315 [ALC880_FUJITSU] = "fujitsu", 4316 [ALC880_F1734] = "F1734", 4317 [ALC880_LG] = "lg", 4318 [ALC880_LG_LW] = "lg-lw", 4319 [ALC880_MEDION_RIM] = "medion", 4320#ifdef CONFIG_SND_DEBUG 4321 [ALC880_TEST] = "test", 4322#endif 4323 [ALC880_AUTO] = "auto", 4324}; 4325 4326static struct snd_pci_quirk alc880_cfg_tbl[] = { 4327 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4328 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4329 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4330 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4331 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4332 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4333 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4334 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4335 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4336 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4337 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST), 4338 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4339 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4340 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4341 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4342 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4343 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4344 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4345 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4346 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4347 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4348 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4349 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4350 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4351 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4353 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4354 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4355 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4356 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4357 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4358 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4359 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4360 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4361 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4362 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4363 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4364 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4365 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4366 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4367 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), 4368 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4369 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4370 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4371 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4372 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4373 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4374 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4375 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4376 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4377 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4378 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4379 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4380 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4381 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4382 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4383 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4384 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4385 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4386 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4387 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4388 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4389 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4390 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4391 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4392 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4393 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4394 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4395 /* default Intel */ 4396 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4397 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4398 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4399 {} 4400}; 4401 4402/* 4403 * ALC880 codec presets 4404 */ 4405static struct alc_config_preset alc880_presets[] = { 4406 [ALC880_3ST] = { 4407 .mixers = { alc880_three_stack_mixer }, 4408 .init_verbs = { alc880_volume_init_verbs, 4409 alc880_pin_3stack_init_verbs }, 4410 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4411 .dac_nids = alc880_dac_nids, 4412 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4413 .channel_mode = alc880_threestack_modes, 4414 .need_dac_fix = 1, 4415 .input_mux = &alc880_capture_source, 4416 }, 4417 [ALC880_3ST_DIG] = { 4418 .mixers = { alc880_three_stack_mixer }, 4419 .init_verbs = { alc880_volume_init_verbs, 4420 alc880_pin_3stack_init_verbs }, 4421 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4422 .dac_nids = alc880_dac_nids, 4423 .dig_out_nid = ALC880_DIGOUT_NID, 4424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4425 .channel_mode = alc880_threestack_modes, 4426 .need_dac_fix = 1, 4427 .input_mux = &alc880_capture_source, 4428 }, 4429 [ALC880_TCL_S700] = { 4430 .mixers = { alc880_tcl_s700_mixer }, 4431 .init_verbs = { alc880_volume_init_verbs, 4432 alc880_pin_tcl_S700_init_verbs, 4433 alc880_gpio2_init_verbs }, 4434 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4435 .dac_nids = alc880_dac_nids, 4436 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 4437 .num_adc_nids = 1, /* single ADC */ 4438 .hp_nid = 0x03, 4439 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4440 .channel_mode = alc880_2_jack_modes, 4441 .input_mux = &alc880_capture_source, 4442 }, 4443 [ALC880_5ST] = { 4444 .mixers = { alc880_three_stack_mixer, 4445 alc880_five_stack_mixer}, 4446 .init_verbs = { alc880_volume_init_verbs, 4447 alc880_pin_5stack_init_verbs }, 4448 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4449 .dac_nids = alc880_dac_nids, 4450 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4451 .channel_mode = alc880_fivestack_modes, 4452 .input_mux = &alc880_capture_source, 4453 }, 4454 [ALC880_5ST_DIG] = { 4455 .mixers = { alc880_three_stack_mixer, 4456 alc880_five_stack_mixer }, 4457 .init_verbs = { alc880_volume_init_verbs, 4458 alc880_pin_5stack_init_verbs }, 4459 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4460 .dac_nids = alc880_dac_nids, 4461 .dig_out_nid = ALC880_DIGOUT_NID, 4462 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 4463 .channel_mode = alc880_fivestack_modes, 4464 .input_mux = &alc880_capture_source, 4465 }, 4466 [ALC880_6ST] = { 4467 .mixers = { alc880_six_stack_mixer }, 4468 .init_verbs = { alc880_volume_init_verbs, 4469 alc880_pin_6stack_init_verbs }, 4470 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4471 .dac_nids = alc880_6st_dac_nids, 4472 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4473 .channel_mode = alc880_sixstack_modes, 4474 .input_mux = &alc880_6stack_capture_source, 4475 }, 4476 [ALC880_6ST_DIG] = { 4477 .mixers = { alc880_six_stack_mixer }, 4478 .init_verbs = { alc880_volume_init_verbs, 4479 alc880_pin_6stack_init_verbs }, 4480 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 4481 .dac_nids = alc880_6st_dac_nids, 4482 .dig_out_nid = ALC880_DIGOUT_NID, 4483 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 4484 .channel_mode = alc880_sixstack_modes, 4485 .input_mux = &alc880_6stack_capture_source, 4486 }, 4487 [ALC880_W810] = { 4488 .mixers = { alc880_w810_base_mixer }, 4489 .init_verbs = { alc880_volume_init_verbs, 4490 alc880_pin_w810_init_verbs, 4491 alc880_gpio2_init_verbs }, 4492 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 4493 .dac_nids = alc880_w810_dac_nids, 4494 .dig_out_nid = ALC880_DIGOUT_NID, 4495 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4496 .channel_mode = alc880_w810_modes, 4497 .input_mux = &alc880_capture_source, 4498 }, 4499 [ALC880_Z71V] = { 4500 .mixers = { alc880_z71v_mixer }, 4501 .init_verbs = { alc880_volume_init_verbs, 4502 alc880_pin_z71v_init_verbs }, 4503 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 4504 .dac_nids = alc880_z71v_dac_nids, 4505 .dig_out_nid = ALC880_DIGOUT_NID, 4506 .hp_nid = 0x03, 4507 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4508 .channel_mode = alc880_2_jack_modes, 4509 .input_mux = &alc880_capture_source, 4510 }, 4511 [ALC880_F1734] = { 4512 .mixers = { alc880_f1734_mixer }, 4513 .init_verbs = { alc880_volume_init_verbs, 4514 alc880_pin_f1734_init_verbs }, 4515 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 4516 .dac_nids = alc880_f1734_dac_nids, 4517 .hp_nid = 0x02, 4518 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4519 .channel_mode = alc880_2_jack_modes, 4520 .input_mux = &alc880_f1734_capture_source, 4521 .unsol_event = alc880_uniwill_p53_unsol_event, 4522 .setup = alc880_uniwill_p53_setup, 4523 .init_hook = alc_automute_amp, 4524 }, 4525 [ALC880_ASUS] = { 4526 .mixers = { alc880_asus_mixer }, 4527 .init_verbs = { alc880_volume_init_verbs, 4528 alc880_pin_asus_init_verbs, 4529 alc880_gpio1_init_verbs }, 4530 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4531 .dac_nids = alc880_asus_dac_nids, 4532 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4533 .channel_mode = alc880_asus_modes, 4534 .need_dac_fix = 1, 4535 .input_mux = &alc880_capture_source, 4536 }, 4537 [ALC880_ASUS_DIG] = { 4538 .mixers = { alc880_asus_mixer }, 4539 .init_verbs = { alc880_volume_init_verbs, 4540 alc880_pin_asus_init_verbs, 4541 alc880_gpio1_init_verbs }, 4542 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4543 .dac_nids = alc880_asus_dac_nids, 4544 .dig_out_nid = ALC880_DIGOUT_NID, 4545 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4546 .channel_mode = alc880_asus_modes, 4547 .need_dac_fix = 1, 4548 .input_mux = &alc880_capture_source, 4549 }, 4550 [ALC880_ASUS_DIG2] = { 4551 .mixers = { alc880_asus_mixer }, 4552 .init_verbs = { alc880_volume_init_verbs, 4553 alc880_pin_asus_init_verbs, 4554 alc880_gpio2_init_verbs }, /* use GPIO2 */ 4555 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4556 .dac_nids = alc880_asus_dac_nids, 4557 .dig_out_nid = ALC880_DIGOUT_NID, 4558 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4559 .channel_mode = alc880_asus_modes, 4560 .need_dac_fix = 1, 4561 .input_mux = &alc880_capture_source, 4562 }, 4563 [ALC880_ASUS_W1V] = { 4564 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 4565 .init_verbs = { alc880_volume_init_verbs, 4566 alc880_pin_asus_init_verbs, 4567 alc880_gpio1_init_verbs }, 4568 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4569 .dac_nids = alc880_asus_dac_nids, 4570 .dig_out_nid = ALC880_DIGOUT_NID, 4571 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4572 .channel_mode = alc880_asus_modes, 4573 .need_dac_fix = 1, 4574 .input_mux = &alc880_capture_source, 4575 }, 4576 [ALC880_UNIWILL_DIG] = { 4577 .mixers = { alc880_asus_mixer }, 4578 .init_verbs = { alc880_volume_init_verbs, 4579 alc880_pin_asus_init_verbs }, 4580 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4581 .dac_nids = alc880_asus_dac_nids, 4582 .dig_out_nid = ALC880_DIGOUT_NID, 4583 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 4584 .channel_mode = alc880_asus_modes, 4585 .need_dac_fix = 1, 4586 .input_mux = &alc880_capture_source, 4587 }, 4588 [ALC880_UNIWILL] = { 4589 .mixers = { alc880_uniwill_mixer }, 4590 .init_verbs = { alc880_volume_init_verbs, 4591 alc880_uniwill_init_verbs }, 4592 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4593 .dac_nids = alc880_asus_dac_nids, 4594 .dig_out_nid = ALC880_DIGOUT_NID, 4595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4596 .channel_mode = alc880_threestack_modes, 4597 .need_dac_fix = 1, 4598 .input_mux = &alc880_capture_source, 4599 .unsol_event = alc880_uniwill_unsol_event, 4600 .setup = alc880_uniwill_setup, 4601 .init_hook = alc880_uniwill_init_hook, 4602 }, 4603 [ALC880_UNIWILL_P53] = { 4604 .mixers = { alc880_uniwill_p53_mixer }, 4605 .init_verbs = { alc880_volume_init_verbs, 4606 alc880_uniwill_p53_init_verbs }, 4607 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 4608 .dac_nids = alc880_asus_dac_nids, 4609 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 4610 .channel_mode = alc880_threestack_modes, 4611 .input_mux = &alc880_capture_source, 4612 .unsol_event = alc880_uniwill_p53_unsol_event, 4613 .setup = alc880_uniwill_p53_setup, 4614 .init_hook = alc_automute_amp, 4615 }, 4616 [ALC880_FUJITSU] = { 4617 .mixers = { alc880_fujitsu_mixer }, 4618 .init_verbs = { alc880_volume_init_verbs, 4619 alc880_uniwill_p53_init_verbs, 4620 alc880_beep_init_verbs }, 4621 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4622 .dac_nids = alc880_dac_nids, 4623 .dig_out_nid = ALC880_DIGOUT_NID, 4624 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4625 .channel_mode = alc880_2_jack_modes, 4626 .input_mux = &alc880_capture_source, 4627 .unsol_event = alc880_uniwill_p53_unsol_event, 4628 .setup = alc880_uniwill_p53_setup, 4629 .init_hook = alc_automute_amp, 4630 }, 4631 [ALC880_CLEVO] = { 4632 .mixers = { alc880_three_stack_mixer }, 4633 .init_verbs = { alc880_volume_init_verbs, 4634 alc880_pin_clevo_init_verbs }, 4635 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4636 .dac_nids = alc880_dac_nids, 4637 .hp_nid = 0x03, 4638 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4639 .channel_mode = alc880_threestack_modes, 4640 .need_dac_fix = 1, 4641 .input_mux = &alc880_capture_source, 4642 }, 4643 [ALC880_LG] = { 4644 .mixers = { alc880_lg_mixer }, 4645 .init_verbs = { alc880_volume_init_verbs, 4646 alc880_lg_init_verbs }, 4647 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 4648 .dac_nids = alc880_lg_dac_nids, 4649 .dig_out_nid = ALC880_DIGOUT_NID, 4650 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 4651 .channel_mode = alc880_lg_ch_modes, 4652 .need_dac_fix = 1, 4653 .input_mux = &alc880_lg_capture_source, 4654 .unsol_event = alc_automute_amp_unsol_event, 4655 .setup = alc880_lg_setup, 4656 .init_hook = alc_automute_amp, 4657#ifdef CONFIG_SND_HDA_POWER_SAVE 4658 .loopbacks = alc880_lg_loopbacks, 4659#endif 4660 }, 4661 [ALC880_LG_LW] = { 4662 .mixers = { alc880_lg_lw_mixer }, 4663 .init_verbs = { alc880_volume_init_verbs, 4664 alc880_lg_lw_init_verbs }, 4665 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4666 .dac_nids = alc880_dac_nids, 4667 .dig_out_nid = ALC880_DIGOUT_NID, 4668 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 4669 .channel_mode = alc880_lg_lw_modes, 4670 .input_mux = &alc880_lg_lw_capture_source, 4671 .unsol_event = alc_automute_amp_unsol_event, 4672 .setup = alc880_lg_lw_setup, 4673 .init_hook = alc_automute_amp, 4674 }, 4675 [ALC880_MEDION_RIM] = { 4676 .mixers = { alc880_medion_rim_mixer }, 4677 .init_verbs = { alc880_volume_init_verbs, 4678 alc880_medion_rim_init_verbs, 4679 alc_gpio2_init_verbs }, 4680 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4681 .dac_nids = alc880_dac_nids, 4682 .dig_out_nid = ALC880_DIGOUT_NID, 4683 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 4684 .channel_mode = alc880_2_jack_modes, 4685 .input_mux = &alc880_medion_rim_capture_source, 4686 .unsol_event = alc880_medion_rim_unsol_event, 4687 .setup = alc880_medion_rim_setup, 4688 .init_hook = alc880_medion_rim_automute, 4689 }, 4690#ifdef CONFIG_SND_DEBUG 4691 [ALC880_TEST] = { 4692 .mixers = { alc880_test_mixer }, 4693 .init_verbs = { alc880_test_init_verbs }, 4694 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 4695 .dac_nids = alc880_test_dac_nids, 4696 .dig_out_nid = ALC880_DIGOUT_NID, 4697 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 4698 .channel_mode = alc880_test_modes, 4699 .input_mux = &alc880_test_capture_source, 4700 }, 4701#endif 4702}; 4703 4704/* 4705 * Automatic parse of I/O pins from the BIOS configuration 4706 */ 4707 4708enum { 4709 ALC_CTL_WIDGET_VOL, 4710 ALC_CTL_WIDGET_MUTE, 4711 ALC_CTL_BIND_MUTE, 4712}; 4713static struct snd_kcontrol_new alc880_control_templates[] = { 4714 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 4715 HDA_CODEC_MUTE(NULL, 0, 0, 0), 4716 HDA_BIND_MUTE(NULL, 0, 0, 0), 4717}; 4718 4719/* add dynamic controls */ 4720static int add_control(struct alc_spec *spec, int type, const char *name, 4721 unsigned long val) 4722{ 4723 struct snd_kcontrol_new *knew; 4724 4725 snd_array_init(&spec->kctls, sizeof(*knew), 32); 4726 knew = snd_array_new(&spec->kctls); 4727 if (!knew) 4728 return -ENOMEM; 4729 *knew = alc880_control_templates[type]; 4730 knew->name = kstrdup(name, GFP_KERNEL); 4731 if (!knew->name) 4732 return -ENOMEM; 4733 if (get_amp_nid_(val)) 4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 4735 knew->private_value = val; 4736 return 0; 4737} 4738 4739static int add_control_with_pfx(struct alc_spec *spec, int type, 4740 const char *pfx, const char *dir, 4741 const char *sfx, unsigned long val) 4742{ 4743 char name[32]; 4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 4745 return add_control(spec, type, name, val); 4746} 4747 4748#define add_pb_vol_ctrl(spec, type, pfx, val) \ 4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val) 4750#define add_pb_sw_ctrl(spec, type, pfx, val) \ 4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val) 4752 4753#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 4754#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4755#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4756#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 4757#define alc880_idx_to_dac(nid) ((nid) + 0x02) 4758#define alc880_dac_to_idx(nid) ((nid) - 0x02) 4759#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 4760#define alc880_idx_to_selector(nid) ((nid) + 0x10) 4761#define ALC880_PIN_CD_NID 0x1c 4762 4763/* fill in the dac_nids table from the parsed pin configuration */ 4764static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 4765 const struct auto_pin_cfg *cfg) 4766{ 4767 hda_nid_t nid; 4768 int assigned[4]; 4769 int i, j; 4770 4771 memset(assigned, 0, sizeof(assigned)); 4772 spec->multiout.dac_nids = spec->private_dac_nids; 4773 4774 /* check the pins hardwired to audio widget */ 4775 for (i = 0; i < cfg->line_outs; i++) { 4776 nid = cfg->line_out_pins[i]; 4777 if (alc880_is_fixed_pin(nid)) { 4778 int idx = alc880_fixed_pin_idx(nid); 4779 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); 4780 assigned[idx] = 1; 4781 } 4782 } 4783 /* left pins can be connect to any audio widget */ 4784 for (i = 0; i < cfg->line_outs; i++) { 4785 nid = cfg->line_out_pins[i]; 4786 if (alc880_is_fixed_pin(nid)) 4787 continue; 4788 /* search for an empty channel */ 4789 for (j = 0; j < cfg->line_outs; j++) { 4790 if (!assigned[j]) { 4791 spec->multiout.dac_nids[i] = 4792 alc880_idx_to_dac(j); 4793 assigned[j] = 1; 4794 break; 4795 } 4796 } 4797 } 4798 spec->multiout.num_dacs = cfg->line_outs; 4799 return 0; 4800} 4801 4802/* add playback controls from the parsed DAC table */ 4803static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 4804 const struct auto_pin_cfg *cfg) 4805{ 4806 static const char *chname[4] = { 4807 "Front", "Surround", NULL /*CLFE*/, "Side" 4808 }; 4809 hda_nid_t nid; 4810 int i, err; 4811 4812 for (i = 0; i < cfg->line_outs; i++) { 4813 if (!spec->multiout.dac_nids[i]) 4814 continue; 4815 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 4816 if (i == 2) { 4817 /* Center/LFE */ 4818 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4819 "Center", 4820 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 4821 HDA_OUTPUT)); 4822 if (err < 0) 4823 return err; 4824 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 4825 "LFE", 4826 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 4827 HDA_OUTPUT)); 4828 if (err < 0) 4829 return err; 4830 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4831 "Center", 4832 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 4833 HDA_INPUT)); 4834 if (err < 0) 4835 return err; 4836 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 4837 "LFE", 4838 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 4839 HDA_INPUT)); 4840 if (err < 0) 4841 return err; 4842 } else { 4843 const char *pfx; 4844 if (cfg->line_outs == 1 && 4845 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 4846 pfx = "Speaker"; 4847 else 4848 pfx = chname[i]; 4849 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4850 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4851 HDA_OUTPUT)); 4852 if (err < 0) 4853 return err; 4854 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4855 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4856 HDA_INPUT)); 4857 if (err < 0) 4858 return err; 4859 } 4860 } 4861 return 0; 4862} 4863 4864/* add playback controls for speaker and HP outputs */ 4865static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 4866 const char *pfx) 4867{ 4868 hda_nid_t nid; 4869 int err; 4870 4871 if (!pin) 4872 return 0; 4873 4874 if (alc880_is_fixed_pin(pin)) { 4875 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 4876 /* specify the DAC as the extra output */ 4877 if (!spec->multiout.hp_nid) 4878 spec->multiout.hp_nid = nid; 4879 else 4880 spec->multiout.extra_out_nid[0] = nid; 4881 /* control HP volume/switch on the output mixer amp */ 4882 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 4883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 4884 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 4885 if (err < 0) 4886 return err; 4887 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 4888 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 4889 if (err < 0) 4890 return err; 4891 } else if (alc880_is_multi_pin(pin)) { 4892 /* set manual connection */ 4893 /* we have only a switch on HP-out PIN */ 4894 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 4895 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 4896 if (err < 0) 4897 return err; 4898 } 4899 return 0; 4900} 4901 4902/* create input playback/capture controls for the given pin */ 4903static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 4904 const char *ctlname, 4905 int idx, hda_nid_t mix_nid) 4906{ 4907 int err; 4908 4909 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4911 if (err < 0) 4912 return err; 4913 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 4915 if (err < 0) 4916 return err; 4917 return 0; 4918} 4919 4920static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 4921{ 4922 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 4923 return (pincap & AC_PINCAP_IN) != 0; 4924} 4925 4926/* create playback/capture controls for input pins */ 4927static int alc_auto_create_input_ctls(struct hda_codec *codec, 4928 const struct auto_pin_cfg *cfg, 4929 hda_nid_t mixer, 4930 hda_nid_t cap1, hda_nid_t cap2) 4931{ 4932 struct alc_spec *spec = codec->spec; 4933 struct hda_input_mux *imux = &spec->private_imux[0]; 4934 int i, err, idx; 4935 4936 for (i = 0; i < AUTO_PIN_LAST; i++) { 4937 hda_nid_t pin; 4938 4939 pin = cfg->input_pins[i]; 4940 if (!alc_is_input_pin(codec, pin)) 4941 continue; 4942 4943 if (mixer) { 4944 idx = get_connection_index(codec, mixer, pin); 4945 if (idx >= 0) { 4946 err = new_analog_input(spec, pin, 4947 auto_pin_cfg_labels[i], 4948 idx, mixer); 4949 if (err < 0) 4950 return err; 4951 } 4952 } 4953 4954 if (!cap1) 4955 continue; 4956 idx = get_connection_index(codec, cap1, pin); 4957 if (idx < 0 && cap2) 4958 idx = get_connection_index(codec, cap2, pin); 4959 if (idx >= 0) { 4960 imux->items[imux->num_items].label = 4961 auto_pin_cfg_labels[i]; 4962 imux->items[imux->num_items].index = idx; 4963 imux->num_items++; 4964 } 4965 } 4966 return 0; 4967} 4968 4969static int alc880_auto_create_input_ctls(struct hda_codec *codec, 4970 const struct auto_pin_cfg *cfg) 4971{ 4972 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 4973} 4974 4975static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 4976 unsigned int pin_type) 4977{ 4978 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4979 pin_type); 4980 /* unmute pin */ 4981 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 4982 AMP_OUT_UNMUTE); 4983} 4984 4985static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 4986 hda_nid_t nid, int pin_type, 4987 int dac_idx) 4988{ 4989 alc_set_pin_output(codec, nid, pin_type); 4990 /* need the manual connection? */ 4991 if (alc880_is_multi_pin(nid)) { 4992 struct alc_spec *spec = codec->spec; 4993 int idx = alc880_multi_pin_idx(nid); 4994 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 4995 AC_VERB_SET_CONNECT_SEL, 4996 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 4997 } 4998} 4999 5000static int get_pin_type(int line_out_type) 5001{ 5002 if (line_out_type == AUTO_PIN_HP_OUT) 5003 return PIN_HP; 5004 else 5005 return PIN_OUT; 5006} 5007 5008static void alc880_auto_init_multi_out(struct hda_codec *codec) 5009{ 5010 struct alc_spec *spec = codec->spec; 5011 int i; 5012 5013 for (i = 0; i < spec->autocfg.line_outs; i++) { 5014 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5015 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5016 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5017 } 5018} 5019 5020static void alc880_auto_init_extra_out(struct hda_codec *codec) 5021{ 5022 struct alc_spec *spec = codec->spec; 5023 hda_nid_t pin; 5024 5025 pin = spec->autocfg.speaker_pins[0]; 5026 if (pin) /* connect to front */ 5027 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5028 pin = spec->autocfg.hp_pins[0]; 5029 if (pin) /* connect to front */ 5030 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5031} 5032 5033static void alc880_auto_init_analog_input(struct hda_codec *codec) 5034{ 5035 struct alc_spec *spec = codec->spec; 5036 int i; 5037 5038 for (i = 0; i < AUTO_PIN_LAST; i++) { 5039 hda_nid_t nid = spec->autocfg.input_pins[i]; 5040 if (alc_is_input_pin(codec, nid)) { 5041 alc_set_input_pin(codec, nid, i); 5042 if (nid != ALC880_PIN_CD_NID && 5043 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5044 snd_hda_codec_write(codec, nid, 0, 5045 AC_VERB_SET_AMP_GAIN_MUTE, 5046 AMP_OUT_MUTE); 5047 } 5048 } 5049} 5050 5051static void alc880_auto_init_input_src(struct hda_codec *codec) 5052{ 5053 struct alc_spec *spec = codec->spec; 5054 int c; 5055 5056 for (c = 0; c < spec->num_adc_nids; c++) { 5057 unsigned int mux_idx; 5058 const struct hda_input_mux *imux; 5059 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5060 imux = &spec->input_mux[mux_idx]; 5061 if (!imux->num_items && mux_idx > 0) 5062 imux = &spec->input_mux[0]; 5063 if (imux) 5064 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5065 AC_VERB_SET_CONNECT_SEL, 5066 imux->items[0].index); 5067 } 5068} 5069 5070/* parse the BIOS configuration and set up the alc_spec */ 5071/* return 1 if successful, 0 if the proper config is not found, 5072 * or a negative error code 5073 */ 5074static int alc880_parse_auto_config(struct hda_codec *codec) 5075{ 5076 struct alc_spec *spec = codec->spec; 5077 int err; 5078 static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5079 5080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5081 alc880_ignore); 5082 if (err < 0) 5083 return err; 5084 if (!spec->autocfg.line_outs) 5085 return 0; /* can't find valid BIOS pin config */ 5086 5087 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5088 if (err < 0) 5089 return err; 5090 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5091 if (err < 0) 5092 return err; 5093 err = alc880_auto_create_extra_out(spec, 5094 spec->autocfg.speaker_pins[0], 5095 "Speaker"); 5096 if (err < 0) 5097 return err; 5098 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5099 "Headphone"); 5100 if (err < 0) 5101 return err; 5102 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5103 if (err < 0) 5104 return err; 5105 5106 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5107 5108 alc_auto_parse_digital(codec); 5109 5110 if (spec->kctls.list) 5111 add_mixer(spec, spec->kctls.list); 5112 5113 add_verb(spec, alc880_volume_init_verbs); 5114 5115 spec->num_mux_defs = 1; 5116 spec->input_mux = &spec->private_imux[0]; 5117 5118 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5119 5120 return 1; 5121} 5122 5123/* additional initialization for auto-configuration model */ 5124static void alc880_auto_init(struct hda_codec *codec) 5125{ 5126 struct alc_spec *spec = codec->spec; 5127 alc880_auto_init_multi_out(codec); 5128 alc880_auto_init_extra_out(codec); 5129 alc880_auto_init_analog_input(codec); 5130 alc880_auto_init_input_src(codec); 5131 alc_auto_init_digital(codec); 5132 if (spec->unsol_event) 5133 alc_inithook(codec); 5134} 5135 5136/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5137 * one of two digital mic pins, e.g. on ALC272 5138 */ 5139static void fixup_automic_adc(struct hda_codec *codec) 5140{ 5141 struct alc_spec *spec = codec->spec; 5142 int i; 5143 5144 for (i = 0; i < spec->num_adc_nids; i++) { 5145 hda_nid_t cap = spec->capsrc_nids ? 5146 spec->capsrc_nids[i] : spec->adc_nids[i]; 5147 int iidx, eidx; 5148 5149 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5150 if (iidx < 0) 5151 continue; 5152 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5153 if (eidx < 0) 5154 continue; 5155 spec->int_mic.mux_idx = iidx; 5156 spec->ext_mic.mux_idx = eidx; 5157 if (spec->capsrc_nids) 5158 spec->capsrc_nids += i; 5159 spec->adc_nids += i; 5160 spec->num_adc_nids = 1; 5161 return; 5162 } 5163 snd_printd(KERN_INFO "hda_codec: %s: " 5164 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5165 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5166 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5167} 5168 5169/* select or unmute the given capsrc route */ 5170static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5171 int idx) 5172{ 5173 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5174 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5175 HDA_AMP_MUTE, 0); 5176 } else { 5177 snd_hda_codec_write_cache(codec, cap, 0, 5178 AC_VERB_SET_CONNECT_SEL, idx); 5179 } 5180} 5181 5182/* set the default connection to that pin */ 5183static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5184{ 5185 struct alc_spec *spec = codec->spec; 5186 int i; 5187 5188 for (i = 0; i < spec->num_adc_nids; i++) { 5189 hda_nid_t cap = spec->capsrc_nids ? 5190 spec->capsrc_nids[i] : spec->adc_nids[i]; 5191 int idx; 5192 5193 idx = get_connection_index(codec, cap, pin); 5194 if (idx < 0) 5195 continue; 5196 select_or_unmute_capsrc(codec, cap, idx); 5197 return i; /* return the found index */ 5198 } 5199 return -1; /* not found */ 5200} 5201 5202/* choose the ADC/MUX containing the input pin and initialize the setup */ 5203static void fixup_single_adc(struct hda_codec *codec) 5204{ 5205 struct alc_spec *spec = codec->spec; 5206 hda_nid_t pin = 0; 5207 int i; 5208 5209 /* search for the input pin; there must be only one */ 5210 for (i = 0; i < AUTO_PIN_LAST; i++) { 5211 if (spec->autocfg.input_pins[i]) { 5212 pin = spec->autocfg.input_pins[i]; 5213 break; 5214 } 5215 } 5216 if (!pin) 5217 return; 5218 i = init_capsrc_for_pin(codec, pin); 5219 if (i >= 0) { 5220 /* use only this ADC */ 5221 if (spec->capsrc_nids) 5222 spec->capsrc_nids += i; 5223 spec->adc_nids += i; 5224 spec->num_adc_nids = 1; 5225 } 5226} 5227 5228/* initialize dual adcs */ 5229static void fixup_dual_adc_switch(struct hda_codec *codec) 5230{ 5231 struct alc_spec *spec = codec->spec; 5232 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5233 init_capsrc_for_pin(codec, spec->int_mic.pin); 5234} 5235 5236static void set_capture_mixer(struct hda_codec *codec) 5237{ 5238 struct alc_spec *spec = codec->spec; 5239 static struct snd_kcontrol_new *caps[2][3] = { 5240 { alc_capture_mixer_nosrc1, 5241 alc_capture_mixer_nosrc2, 5242 alc_capture_mixer_nosrc3 }, 5243 { alc_capture_mixer1, 5244 alc_capture_mixer2, 5245 alc_capture_mixer3 }, 5246 }; 5247 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5248 int mux = 0; 5249 int num_adcs = spec->num_adc_nids; 5250 if (spec->dual_adc_switch) 5251 fixup_dual_adc_switch(codec); 5252 else if (spec->auto_mic) 5253 fixup_automic_adc(codec); 5254 else if (spec->input_mux) { 5255 if (spec->input_mux->num_items > 1) 5256 mux = 1; 5257 else if (spec->input_mux->num_items == 1) 5258 fixup_single_adc(codec); 5259 } 5260 if (spec->dual_adc_switch) 5261 num_adcs = 1; 5262 spec->cap_mixer = caps[mux][num_adcs - 1]; 5263 } 5264} 5265 5266/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5267static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, 5268 int num_nids) 5269{ 5270 struct alc_spec *spec = codec->spec; 5271 int n; 5272 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5273 5274 for (n = 0; n < num_nids; n++) { 5275 hda_nid_t adc, cap; 5276 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5277 int nconns, i, j; 5278 5279 adc = nids[n]; 5280 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5281 continue; 5282 cap = adc; 5283 nconns = snd_hda_get_connections(codec, cap, conn, 5284 ARRAY_SIZE(conn)); 5285 if (nconns == 1) { 5286 cap = conn[0]; 5287 nconns = snd_hda_get_connections(codec, cap, conn, 5288 ARRAY_SIZE(conn)); 5289 } 5290 if (nconns <= 0) 5291 continue; 5292 if (!fallback_adc) { 5293 fallback_adc = adc; 5294 fallback_cap = cap; 5295 } 5296 for (i = 0; i < AUTO_PIN_LAST; i++) { 5297 hda_nid_t nid = spec->autocfg.input_pins[i]; 5298 if (!nid) 5299 continue; 5300 for (j = 0; j < nconns; j++) { 5301 if (conn[j] == nid) 5302 break; 5303 } 5304 if (j >= nconns) 5305 break; 5306 } 5307 if (i >= AUTO_PIN_LAST) { 5308 int num_adcs = spec->num_adc_nids; 5309 spec->private_adc_nids[num_adcs] = adc; 5310 spec->private_capsrc_nids[num_adcs] = cap; 5311 spec->num_adc_nids++; 5312 spec->adc_nids = spec->private_adc_nids; 5313 if (adc != cap) 5314 spec->capsrc_nids = spec->private_capsrc_nids; 5315 } 5316 } 5317 if (!spec->num_adc_nids) { 5318 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5319 " using fallback 0x%x\n", 5320 codec->chip_name, fallback_adc); 5321 spec->private_adc_nids[0] = fallback_adc; 5322 spec->adc_nids = spec->private_adc_nids; 5323 if (fallback_adc != fallback_cap) { 5324 spec->private_capsrc_nids[0] = fallback_cap; 5325 spec->capsrc_nids = spec->private_adc_nids; 5326 } 5327 } 5328} 5329 5330#ifdef CONFIG_SND_HDA_INPUT_BEEP 5331#define set_beep_amp(spec, nid, idx, dir) \ 5332 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5333 5334static struct snd_pci_quirk beep_white_list[] = { 5335 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5336 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5337 {} 5338}; 5339 5340static inline int has_cdefine_beep(struct hda_codec *codec) 5341{ 5342 struct alc_spec *spec = codec->spec; 5343 const struct snd_pci_quirk *q; 5344 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5345 if (q) 5346 return q->value; 5347 return spec->cdefine.enable_pcbeep; 5348} 5349#else 5350#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5351#define has_cdefine_beep(codec) 0 5352#endif 5353 5354/* 5355 * OK, here we have finally the patch for ALC880 5356 */ 5357 5358static int patch_alc880(struct hda_codec *codec) 5359{ 5360 struct alc_spec *spec; 5361 int board_config; 5362 int err; 5363 5364 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5365 if (spec == NULL) 5366 return -ENOMEM; 5367 5368 codec->spec = spec; 5369 5370 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 5371 alc880_models, 5372 alc880_cfg_tbl); 5373 if (board_config < 0) { 5374 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5375 codec->chip_name); 5376 board_config = ALC880_AUTO; 5377 } 5378 5379 if (board_config == ALC880_AUTO) { 5380 /* automatic parse from the BIOS config */ 5381 err = alc880_parse_auto_config(codec); 5382 if (err < 0) { 5383 alc_free(codec); 5384 return err; 5385 } else if (!err) { 5386 printk(KERN_INFO 5387 "hda_codec: Cannot set up configuration " 5388 "from BIOS. Using 3-stack mode...\n"); 5389 board_config = ALC880_3ST; 5390 } 5391 } 5392 5393 err = snd_hda_attach_beep_device(codec, 0x1); 5394 if (err < 0) { 5395 alc_free(codec); 5396 return err; 5397 } 5398 5399 if (board_config != ALC880_AUTO) 5400 setup_preset(codec, &alc880_presets[board_config]); 5401 5402 spec->stream_analog_playback = &alc880_pcm_analog_playback; 5403 spec->stream_analog_capture = &alc880_pcm_analog_capture; 5404 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 5405 5406 spec->stream_digital_playback = &alc880_pcm_digital_playback; 5407 spec->stream_digital_capture = &alc880_pcm_digital_capture; 5408 5409 if (!spec->adc_nids && spec->input_mux) { 5410 /* check whether NID 0x07 is valid */ 5411 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 5412 /* get type */ 5413 wcap = get_wcaps_type(wcap); 5414 if (wcap != AC_WID_AUD_IN) { 5415 spec->adc_nids = alc880_adc_nids_alt; 5416 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 5417 } else { 5418 spec->adc_nids = alc880_adc_nids; 5419 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 5420 } 5421 } 5422 set_capture_mixer(codec); 5423 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5424 5425 spec->vmaster_nid = 0x0c; 5426 5427 codec->patch_ops = alc_patch_ops; 5428 if (board_config == ALC880_AUTO) 5429 spec->init_hook = alc880_auto_init; 5430#ifdef CONFIG_SND_HDA_POWER_SAVE 5431 if (!spec->loopback.amplist) 5432 spec->loopback.amplist = alc880_loopbacks; 5433#endif 5434 5435 return 0; 5436} 5437 5438 5439/* 5440 * ALC260 support 5441 */ 5442 5443static hda_nid_t alc260_dac_nids[1] = { 5444 /* front */ 5445 0x02, 5446}; 5447 5448static hda_nid_t alc260_adc_nids[1] = { 5449 /* ADC0 */ 5450 0x04, 5451}; 5452 5453static hda_nid_t alc260_adc_nids_alt[1] = { 5454 /* ADC1 */ 5455 0x05, 5456}; 5457 5458/* NIDs used when simultaneous access to both ADCs makes sense. Note that 5459 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 5460 */ 5461static hda_nid_t alc260_dual_adc_nids[2] = { 5462 /* ADC0, ADC1 */ 5463 0x04, 0x05 5464}; 5465 5466#define ALC260_DIGOUT_NID 0x03 5467#define ALC260_DIGIN_NID 0x06 5468 5469static struct hda_input_mux alc260_capture_source = { 5470 .num_items = 4, 5471 .items = { 5472 { "Mic", 0x0 }, 5473 { "Front Mic", 0x1 }, 5474 { "Line", 0x2 }, 5475 { "CD", 0x4 }, 5476 }, 5477}; 5478 5479/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 5480 * headphone jack and the internal CD lines since these are the only pins at 5481 * which audio can appear. For flexibility, also allow the option of 5482 * recording the mixer output on the second ADC (ADC0 doesn't have a 5483 * connection to the mixer output). 5484 */ 5485static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 5486 { 5487 .num_items = 3, 5488 .items = { 5489 { "Mic/Line", 0x0 }, 5490 { "CD", 0x4 }, 5491 { "Headphone", 0x2 }, 5492 }, 5493 }, 5494 { 5495 .num_items = 4, 5496 .items = { 5497 { "Mic/Line", 0x0 }, 5498 { "CD", 0x4 }, 5499 { "Headphone", 0x2 }, 5500 { "Mixer", 0x5 }, 5501 }, 5502 }, 5503 5504}; 5505 5506/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 5507 * the Fujitsu S702x, but jacks are marked differently. 5508 */ 5509static struct hda_input_mux alc260_acer_capture_sources[2] = { 5510 { 5511 .num_items = 4, 5512 .items = { 5513 { "Mic", 0x0 }, 5514 { "Line", 0x2 }, 5515 { "CD", 0x4 }, 5516 { "Headphone", 0x5 }, 5517 }, 5518 }, 5519 { 5520 .num_items = 5, 5521 .items = { 5522 { "Mic", 0x0 }, 5523 { "Line", 0x2 }, 5524 { "CD", 0x4 }, 5525 { "Headphone", 0x6 }, 5526 { "Mixer", 0x5 }, 5527 }, 5528 }, 5529}; 5530 5531/* Maxdata Favorit 100XS */ 5532static struct hda_input_mux alc260_favorit100_capture_sources[2] = { 5533 { 5534 .num_items = 2, 5535 .items = { 5536 { "Line/Mic", 0x0 }, 5537 { "CD", 0x4 }, 5538 }, 5539 }, 5540 { 5541 .num_items = 3, 5542 .items = { 5543 { "Line/Mic", 0x0 }, 5544 { "CD", 0x4 }, 5545 { "Mixer", 0x5 }, 5546 }, 5547 }, 5548}; 5549 5550/* 5551 * This is just place-holder, so there's something for alc_build_pcms to look 5552 * at when it calculates the maximum number of channels. ALC260 has no mixer 5553 * element which allows changing the channel mode, so the verb list is 5554 * never used. 5555 */ 5556static struct hda_channel_mode alc260_modes[1] = { 5557 { 2, NULL }, 5558}; 5559 5560 5561/* Mixer combinations 5562 * 5563 * basic: base_output + input + pc_beep + capture 5564 * HP: base_output + input + capture_alt 5565 * HP_3013: hp_3013 + input + capture 5566 * fujitsu: fujitsu + capture 5567 * acer: acer + capture 5568 */ 5569 5570static struct snd_kcontrol_new alc260_base_output_mixer[] = { 5571 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5572 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5574 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5575 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5576 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5577 { } /* end */ 5578}; 5579 5580static struct snd_kcontrol_new alc260_input_mixer[] = { 5581 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5582 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5583 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5584 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5586 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 5588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 5589 { } /* end */ 5590}; 5591 5592/* update HP, line and mono out pins according to the master switch */ 5593static void alc260_hp_master_update(struct hda_codec *codec, 5594 hda_nid_t hp, hda_nid_t line, 5595 hda_nid_t mono) 5596{ 5597 struct alc_spec *spec = codec->spec; 5598 unsigned int val = spec->master_sw ? PIN_HP : 0; 5599 /* change HP and line-out pins */ 5600 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5601 val); 5602 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5603 val); 5604 /* mono (speaker) depending on the HP jack sense */ 5605 val = (val && !spec->jack_present) ? PIN_OUT : 0; 5606 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5607 val); 5608} 5609 5610static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 5611 struct snd_ctl_elem_value *ucontrol) 5612{ 5613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5614 struct alc_spec *spec = codec->spec; 5615 *ucontrol->value.integer.value = spec->master_sw; 5616 return 0; 5617} 5618 5619static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 5620 struct snd_ctl_elem_value *ucontrol) 5621{ 5622 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 5623 struct alc_spec *spec = codec->spec; 5624 int val = !!*ucontrol->value.integer.value; 5625 hda_nid_t hp, line, mono; 5626 5627 if (val == spec->master_sw) 5628 return 0; 5629 spec->master_sw = val; 5630 hp = (kcontrol->private_value >> 16) & 0xff; 5631 line = (kcontrol->private_value >> 8) & 0xff; 5632 mono = kcontrol->private_value & 0xff; 5633 alc260_hp_master_update(codec, hp, line, mono); 5634 return 1; 5635} 5636 5637static struct snd_kcontrol_new alc260_hp_output_mixer[] = { 5638 { 5639 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5640 .name = "Master Playback Switch", 5641 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5642 .info = snd_ctl_boolean_mono_info, 5643 .get = alc260_hp_master_sw_get, 5644 .put = alc260_hp_master_sw_put, 5645 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 5646 }, 5647 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5648 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 5649 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5650 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 5651 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5652 HDA_OUTPUT), 5653 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 5654 { } /* end */ 5655}; 5656 5657static struct hda_verb alc260_hp_unsol_verbs[] = { 5658 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5659 {}, 5660}; 5661 5662static void alc260_hp_automute(struct hda_codec *codec) 5663{ 5664 struct alc_spec *spec = codec->spec; 5665 5666 spec->jack_present = snd_hda_jack_detect(codec, 0x10); 5667 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); 5668} 5669 5670static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) 5671{ 5672 if ((res >> 26) == ALC880_HP_EVENT) 5673 alc260_hp_automute(codec); 5674} 5675 5676static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 5677 { 5678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5679 .name = "Master Playback Switch", 5680 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 5681 .info = snd_ctl_boolean_mono_info, 5682 .get = alc260_hp_master_sw_get, 5683 .put = alc260_hp_master_sw_put, 5684 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 5685 }, 5686 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5687 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5688 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 5689 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 5690 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5692 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 5693 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 5694 { } /* end */ 5695}; 5696 5697static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 5698 .ops = &snd_hda_bind_vol, 5699 .values = { 5700 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 5701 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 5702 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 5703 0 5704 }, 5705}; 5706 5707static struct hda_bind_ctls alc260_dc7600_bind_switch = { 5708 .ops = &snd_hda_bind_sw, 5709 .values = { 5710 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 5711 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 5712 0 5713 }, 5714}; 5715 5716static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 5717 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 5718 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 5719 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 5720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 5721 { } /* end */ 5722}; 5723 5724static struct hda_verb alc260_hp_3013_unsol_verbs[] = { 5725 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 5726 {}, 5727}; 5728 5729static void alc260_hp_3013_automute(struct hda_codec *codec) 5730{ 5731 struct alc_spec *spec = codec->spec; 5732 5733 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 5734 alc260_hp_master_update(codec, 0x15, 0x10, 0x11); 5735} 5736 5737static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 5738 unsigned int res) 5739{ 5740 if ((res >> 26) == ALC880_HP_EVENT) 5741 alc260_hp_3013_automute(codec); 5742} 5743 5744static void alc260_hp_3012_automute(struct hda_codec *codec) 5745{ 5746 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; 5747 5748 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5749 bits); 5750 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5751 bits); 5752 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5753 bits); 5754} 5755 5756static void alc260_hp_3012_unsol_event(struct hda_codec *codec, 5757 unsigned int res) 5758{ 5759 if ((res >> 26) == ALC880_HP_EVENT) 5760 alc260_hp_3012_automute(codec); 5761} 5762 5763/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 5764 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 5765 */ 5766static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 5767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5768 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 5769 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5770 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5771 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5772 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 5773 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 5774 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 5775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 5776 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 5777 { } /* end */ 5778}; 5779 5780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 5781 * versions of the ALC260 don't act on requests to enable mic bias from NID 5782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 5783 * datasheet doesn't mention this restriction. At this stage it's not clear 5784 * whether this behaviour is intentional or is a hardware bug in chip 5785 * revisions available in early 2006. Therefore for now allow the 5786 * "Headphone Jack Mode" control to span all choices, but if it turns out 5787 * that the lack of mic bias for this NID is intentional we could change the 5788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 5789 * 5790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 5791 * don't appear to make the mic bias available from the "line" jack, even 5792 * though the NID used for this jack (0x14) can supply it. The theory is 5793 * that perhaps Acer have included blocking capacitors between the ALC260 5794 * and the output jack. If this turns out to be the case for all such 5795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 5796 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 5797 * 5798 * The C20x Tablet series have a mono internal speaker which is controlled 5799 * via the chip's Mono sum widget and pin complex, so include the necessary 5800 * controls for such models. On models without a "mono speaker" the control 5801 * won't do anything. 5802 */ 5803static struct snd_kcontrol_new alc260_acer_mixer[] = { 5804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5807 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 5808 HDA_OUTPUT), 5809 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 5810 HDA_INPUT), 5811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5819 { } /* end */ 5820}; 5821 5822/* Maxdata Favorit 100XS: one output and one input (0x12) jack 5823 */ 5824static struct snd_kcontrol_new alc260_favorit100_mixer[] = { 5825 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5826 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 5827 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 5828 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5829 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5830 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5831 { } /* end */ 5832}; 5833 5834/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 5835 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 5836 */ 5837static struct snd_kcontrol_new alc260_will_mixer[] = { 5838 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5839 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5841 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5842 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5845 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5846 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 5847 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 5848 { } /* end */ 5849}; 5850 5851/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 5852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 5853 */ 5854static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 5855 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 5856 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 5857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 5858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 5859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 5860 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 5861 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 5862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 5863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 5864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 5865 { } /* end */ 5866}; 5867 5868/* 5869 * initialization verbs 5870 */ 5871static struct hda_verb alc260_init_verbs[] = { 5872 /* Line In pin widget for input */ 5873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5874 /* CD pin widget for input */ 5875 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 5876 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5878 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5879 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 5880 /* LINE-2 is used for line-out in rear */ 5881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5882 /* select line-out */ 5883 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 5884 /* LINE-OUT pin */ 5885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5886 /* enable HP */ 5887 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 5888 /* enable Mono */ 5889 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 5890 /* mute capture amp left and right */ 5891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5892 /* set connection select to line in (default select for this ADC) */ 5893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5894 /* mute capture amp left and right */ 5895 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 5896 /* set connection select to line in (default select for this ADC) */ 5897 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 5898 /* set vol=0 Line-Out mixer amp left and right */ 5899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5900 /* unmute pin widget amp left and right (no gain on this amp) */ 5901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5902 /* set vol=0 HP mixer amp left and right */ 5903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5904 /* unmute pin widget amp left and right (no gain on this amp) */ 5905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5906 /* set vol=0 Mono mixer amp left and right */ 5907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 5908 /* unmute pin widget amp left and right (no gain on this amp) */ 5909 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5910 /* unmute LINE-2 out pin */ 5911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 5912 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5913 * Line In 2 = 0x03 5914 */ 5915 /* mute analog inputs */ 5916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5921 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5922 /* mute Front out path */ 5923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5925 /* mute Headphone out path */ 5926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5928 /* mute Mono out path */ 5929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5931 { } 5932}; 5933 5934#if 0 /* should be identical with alc260_init_verbs? */ 5935static struct hda_verb alc260_hp_init_verbs[] = { 5936 /* Headphone and output */ 5937 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5938 /* mono output */ 5939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5940 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5942 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5944 /* Line In pin widget for input */ 5945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5946 /* Line-2 pin widget for output */ 5947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5948 /* CD pin widget for input */ 5949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5950 /* unmute amp left and right */ 5951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 5952 /* set connection select to line in (default select for this ADC) */ 5953 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 5954 /* unmute Line-Out mixer amp left and right (volume = 0) */ 5955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5956 /* mute pin widget amp left and right (no gain on this amp) */ 5957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5958 /* unmute HP mixer amp left and right (volume = 0) */ 5959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 5960 /* mute pin widget amp left and right (no gain on this amp) */ 5961 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 5962 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 5963 * Line In 2 = 0x03 5964 */ 5965 /* mute analog inputs */ 5966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 5967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 5968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 5969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 5970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 5971 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 5972 /* Unmute Front out path */ 5973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5975 /* Unmute Headphone out path */ 5976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5978 /* Unmute Mono out path */ 5979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 5980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 5981 { } 5982}; 5983#endif 5984 5985static struct hda_verb alc260_hp_3013_init_verbs[] = { 5986 /* Line out and output */ 5987 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5988 /* mono output */ 5989 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 5990 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 5991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5992 /* Mic2 (front panel) pin widget for input and vref at 80% */ 5993 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 5994 /* Line In pin widget for input */ 5995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 5996 /* Headphone pin widget for output */ 5997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 5998 /* CD pin widget for input */ 5999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6000 /* unmute amp left and right */ 6001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6002 /* set connection select to line in (default select for this ADC) */ 6003 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6004 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6006 /* mute pin widget amp left and right (no gain on this amp) */ 6007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6008 /* unmute HP mixer amp left and right (volume = 0) */ 6009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6010 /* mute pin widget amp left and right (no gain on this amp) */ 6011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6012 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6013 * Line In 2 = 0x03 6014 */ 6015 /* mute analog inputs */ 6016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6022 /* Unmute Front out path */ 6023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6025 /* Unmute Headphone out path */ 6026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6028 /* Unmute Mono out path */ 6029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6031 { } 6032}; 6033 6034/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6035 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6036 * audio = 0x16, internal speaker = 0x10. 6037 */ 6038static struct hda_verb alc260_fujitsu_init_verbs[] = { 6039 /* Disable all GPIOs */ 6040 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6041 /* Internal speaker is connected to headphone pin */ 6042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6043 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6045 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6047 /* Ensure all other unused pins are disabled and muted. */ 6048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6050 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6051 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6053 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6056 6057 /* Disable digital (SPDIF) pins */ 6058 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6059 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6060 6061 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6062 * when acting as an output. 6063 */ 6064 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6065 6066 /* Start with output sum widgets muted and their output gains at min */ 6067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6076 6077 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6078 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6079 /* Unmute Line1 pin widget output buffer since it starts as an output. 6080 * If the pin mode is changed by the user the pin mode control will 6081 * take care of enabling the pin's input/output buffers as needed. 6082 * Therefore there's no need to enable the input buffer at this 6083 * stage. 6084 */ 6085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6086 /* Unmute input buffer of pin widget used for Line-in (no equiv 6087 * mixer ctrl) 6088 */ 6089 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6090 6091 /* Mute capture amp left and right */ 6092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6093 /* Set ADC connection select to match default mixer setting - line 6094 * in (on mic1 pin) 6095 */ 6096 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6097 6098 /* Do the same for the second ADC: mute capture input amp and 6099 * set ADC connection to line in (on mic1 pin) 6100 */ 6101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6102 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6103 6104 /* Mute all inputs to mixer widget (even unconnected ones) */ 6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6113 6114 { } 6115}; 6116 6117/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6118 * similar laptops (adapted from Fujitsu init verbs). 6119 */ 6120static struct hda_verb alc260_acer_init_verbs[] = { 6121 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6122 * the headphone jack. Turn this on and rely on the standard mute 6123 * methods whenever the user wants to turn these outputs off. 6124 */ 6125 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6126 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6127 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6128 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6129 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6130 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6132 /* Line In jack is connected to Line1 pin */ 6133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6134 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6135 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6136 /* Ensure all other unused pins are disabled and muted. */ 6137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6140 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6143 /* Disable digital (SPDIF) pins */ 6144 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6145 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6146 6147 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6148 * bus when acting as outputs. 6149 */ 6150 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6151 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6152 6153 /* Start with output sum widgets muted and their output gains at min */ 6154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6163 6164 /* Unmute Line-out pin widget amp left and right 6165 * (no equiv mixer ctrl) 6166 */ 6167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6168 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6169 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6170 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6171 * inputs. If the pin mode is changed by the user the pin mode control 6172 * will take care of enabling the pin's input/output buffers as needed. 6173 * Therefore there's no need to enable the input buffer at this 6174 * stage. 6175 */ 6176 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6178 6179 /* Mute capture amp left and right */ 6180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6181 /* Set ADC connection select to match default mixer setting - mic 6182 * (on mic1 pin) 6183 */ 6184 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6185 6186 /* Do similar with the second ADC: mute capture input amp and 6187 * set ADC connection to mic to match ALSA's default state. 6188 */ 6189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6190 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6191 6192 /* Mute all inputs to mixer widget (even unconnected ones) */ 6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6201 6202 { } 6203}; 6204 6205/* Initialisation sequence for Maxdata Favorit 100XS 6206 * (adapted from Acer init verbs). 6207 */ 6208static struct hda_verb alc260_favorit100_init_verbs[] = { 6209 /* GPIO 0 enables the output jack. 6210 * Turn this on and rely on the standard mute 6211 * methods whenever the user wants to turn these outputs off. 6212 */ 6213 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6214 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6215 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6216 /* Line/Mic input jack is connected to Mic1 pin */ 6217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6218 /* Ensure all other unused pins are disabled and muted. */ 6219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6221 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6222 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6223 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6224 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6229 /* Disable digital (SPDIF) pins */ 6230 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6231 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6232 6233 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6234 * bus when acting as outputs. 6235 */ 6236 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6237 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6238 6239 /* Start with output sum widgets muted and their output gains at min */ 6240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6246 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6249 6250 /* Unmute Line-out pin widget amp left and right 6251 * (no equiv mixer ctrl) 6252 */ 6253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6254 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6255 * inputs. If the pin mode is changed by the user the pin mode control 6256 * will take care of enabling the pin's input/output buffers as needed. 6257 * Therefore there's no need to enable the input buffer at this 6258 * stage. 6259 */ 6260 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6261 6262 /* Mute capture amp left and right */ 6263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6264 /* Set ADC connection select to match default mixer setting - mic 6265 * (on mic1 pin) 6266 */ 6267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6268 6269 /* Do similar with the second ADC: mute capture input amp and 6270 * set ADC connection to mic to match ALSA's default state. 6271 */ 6272 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6273 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6274 6275 /* Mute all inputs to mixer widget (even unconnected ones) */ 6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6284 6285 { } 6286}; 6287 6288static struct hda_verb alc260_will_verbs[] = { 6289 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6290 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6291 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6295 {} 6296}; 6297 6298static struct hda_verb alc260_replacer_672v_verbs[] = { 6299 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6300 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6301 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6302 6303 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6304 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6305 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6306 6307 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6308 {} 6309}; 6310 6311/* toggle speaker-output according to the hp-jack state */ 6312static void alc260_replacer_672v_automute(struct hda_codec *codec) 6313{ 6314 unsigned int present; 6315 6316 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6317 present = snd_hda_jack_detect(codec, 0x0f); 6318 if (present) { 6319 snd_hda_codec_write_cache(codec, 0x01, 0, 6320 AC_VERB_SET_GPIO_DATA, 1); 6321 snd_hda_codec_write_cache(codec, 0x0f, 0, 6322 AC_VERB_SET_PIN_WIDGET_CONTROL, 6323 PIN_HP); 6324 } else { 6325 snd_hda_codec_write_cache(codec, 0x01, 0, 6326 AC_VERB_SET_GPIO_DATA, 0); 6327 snd_hda_codec_write_cache(codec, 0x0f, 0, 6328 AC_VERB_SET_PIN_WIDGET_CONTROL, 6329 PIN_OUT); 6330 } 6331} 6332 6333static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6334 unsigned int res) 6335{ 6336 if ((res >> 26) == ALC880_HP_EVENT) 6337 alc260_replacer_672v_automute(codec); 6338} 6339 6340static struct hda_verb alc260_hp_dc7600_verbs[] = { 6341 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6342 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6343 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6344 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6345 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6347 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6348 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6349 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6350 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6351 {} 6352}; 6353 6354/* Test configuration for debugging, modelled after the ALC880 test 6355 * configuration. 6356 */ 6357#ifdef CONFIG_SND_DEBUG 6358static hda_nid_t alc260_test_dac_nids[1] = { 6359 0x02, 6360}; 6361static hda_nid_t alc260_test_adc_nids[2] = { 6362 0x04, 0x05, 6363}; 6364/* For testing the ALC260, each input MUX needs its own definition since 6365 * the signal assignments are different. This assumes that the first ADC 6366 * is NID 0x04. 6367 */ 6368static struct hda_input_mux alc260_test_capture_sources[2] = { 6369 { 6370 .num_items = 7, 6371 .items = { 6372 { "MIC1 pin", 0x0 }, 6373 { "MIC2 pin", 0x1 }, 6374 { "LINE1 pin", 0x2 }, 6375 { "LINE2 pin", 0x3 }, 6376 { "CD pin", 0x4 }, 6377 { "LINE-OUT pin", 0x5 }, 6378 { "HP-OUT pin", 0x6 }, 6379 }, 6380 }, 6381 { 6382 .num_items = 8, 6383 .items = { 6384 { "MIC1 pin", 0x0 }, 6385 { "MIC2 pin", 0x1 }, 6386 { "LINE1 pin", 0x2 }, 6387 { "LINE2 pin", 0x3 }, 6388 { "CD pin", 0x4 }, 6389 { "Mixer", 0x5 }, 6390 { "LINE-OUT pin", 0x6 }, 6391 { "HP-OUT pin", 0x7 }, 6392 }, 6393 }, 6394}; 6395static struct snd_kcontrol_new alc260_test_mixer[] = { 6396 /* Output driver widgets */ 6397 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6398 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6399 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6400 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 6401 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6402 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 6403 6404 /* Modes for retasking pin widgets 6405 * Note: the ALC260 doesn't seem to act on requests to enable mic 6406 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 6407 * mention this restriction. At this stage it's not clear whether 6408 * this behaviour is intentional or is a hardware bug in chip 6409 * revisions available at least up until early 2006. Therefore for 6410 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 6411 * choices, but if it turns out that the lack of mic bias for these 6412 * NIDs is intentional we could change their modes from 6413 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6414 */ 6415 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 6416 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 6417 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 6418 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 6419 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 6420 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 6421 6422 /* Loopback mixer controls */ 6423 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 6424 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 6425 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 6426 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 6427 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 6428 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 6429 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 6430 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 6431 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6432 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6433 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 6434 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 6435 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 6436 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 6437 6438 /* Controls for GPIO pins, assuming they are configured as outputs */ 6439 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 6440 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 6441 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 6442 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 6443 6444 /* Switches to allow the digital IO pins to be enabled. The datasheet 6445 * is ambigious as to which NID is which; testing on laptops which 6446 * make this output available should provide clarification. 6447 */ 6448 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 6449 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 6450 6451 /* A switch allowing EAPD to be enabled. Some laptops seem to use 6452 * this output to turn on an external amplifier. 6453 */ 6454 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 6455 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 6456 6457 { } /* end */ 6458}; 6459static struct hda_verb alc260_test_init_verbs[] = { 6460 /* Enable all GPIOs as outputs with an initial value of 0 */ 6461 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 6462 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6463 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 6464 6465 /* Enable retasking pins as output, initially without power amp */ 6466 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6469 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6470 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6472 6473 /* Disable digital (SPDIF) pins initially, but users can enable 6474 * them via a mixer switch. In the case of SPDIF-out, this initverb 6475 * payload also sets the generation to 0, output to be in "consumer" 6476 * PCM format, copyright asserted, no pre-emphasis and no validity 6477 * control. 6478 */ 6479 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6480 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6481 6482 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 6483 * OUT1 sum bus when acting as an output. 6484 */ 6485 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6486 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 6487 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6488 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 6489 6490 /* Start with output sum widgets muted and their output gains at min */ 6491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6497 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6500 6501 /* Unmute retasking pin widget output buffers since the default 6502 * state appears to be output. As the pin mode is changed by the 6503 * user the pin mode control will take care of enabling the pin's 6504 * input/output buffers as needed. 6505 */ 6506 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6510 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6511 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6512 /* Also unmute the mono-out pin widget */ 6513 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6514 6515 /* Mute capture amp left and right */ 6516 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6517 /* Set ADC connection select to match default mixer setting (mic1 6518 * pin) 6519 */ 6520 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6521 6522 /* Do the same for the second ADC: mute capture input amp and 6523 * set ADC connection to mic1 pin 6524 */ 6525 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6526 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6527 6528 /* Mute all inputs to mixer widget (even unconnected ones) */ 6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6537 6538 { } 6539}; 6540#endif 6541 6542#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 6543#define alc260_pcm_analog_capture alc880_pcm_analog_capture 6544 6545#define alc260_pcm_digital_playback alc880_pcm_digital_playback 6546#define alc260_pcm_digital_capture alc880_pcm_digital_capture 6547 6548/* 6549 * for BIOS auto-configuration 6550 */ 6551 6552static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 6553 const char *pfx, int *vol_bits) 6554{ 6555 hda_nid_t nid_vol; 6556 unsigned long vol_val, sw_val; 6557 int err; 6558 6559 if (nid >= 0x0f && nid < 0x11) { 6560 nid_vol = nid - 0x7; 6561 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6562 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6563 } else if (nid == 0x11) { 6564 nid_vol = nid - 0x7; 6565 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 6566 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 6567 } else if (nid >= 0x12 && nid <= 0x15) { 6568 nid_vol = 0x08; 6569 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 6570 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 6571 } else 6572 return 0; /* N/A */ 6573 6574 if (!(*vol_bits & (1 << nid_vol))) { 6575 /* first control for the volume widget */ 6576 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 6577 if (err < 0) 6578 return err; 6579 *vol_bits |= (1 << nid_vol); 6580 } 6581 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 6582 if (err < 0) 6583 return err; 6584 return 1; 6585} 6586 6587/* add playback controls from the parsed DAC table */ 6588static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 6589 const struct auto_pin_cfg *cfg) 6590{ 6591 hda_nid_t nid; 6592 int err; 6593 int vols = 0; 6594 6595 spec->multiout.num_dacs = 1; 6596 spec->multiout.dac_nids = spec->private_dac_nids; 6597 spec->multiout.dac_nids[0] = 0x02; 6598 6599 nid = cfg->line_out_pins[0]; 6600 if (nid) { 6601 const char *pfx; 6602 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 6603 pfx = "Master"; 6604 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 6605 pfx = "Speaker"; 6606 else 6607 pfx = "Front"; 6608 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 6609 if (err < 0) 6610 return err; 6611 } 6612 6613 nid = cfg->speaker_pins[0]; 6614 if (nid) { 6615 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 6616 if (err < 0) 6617 return err; 6618 } 6619 6620 nid = cfg->hp_pins[0]; 6621 if (nid) { 6622 err = alc260_add_playback_controls(spec, nid, "Headphone", 6623 &vols); 6624 if (err < 0) 6625 return err; 6626 } 6627 return 0; 6628} 6629 6630/* create playback/capture controls for input pins */ 6631static int alc260_auto_create_input_ctls(struct hda_codec *codec, 6632 const struct auto_pin_cfg *cfg) 6633{ 6634 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 6635} 6636 6637static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6638 hda_nid_t nid, int pin_type, 6639 int sel_idx) 6640{ 6641 alc_set_pin_output(codec, nid, pin_type); 6642 /* need the manual connection? */ 6643 if (nid >= 0x12) { 6644 int idx = nid - 0x12; 6645 snd_hda_codec_write(codec, idx + 0x0b, 0, 6646 AC_VERB_SET_CONNECT_SEL, sel_idx); 6647 } 6648} 6649 6650static void alc260_auto_init_multi_out(struct hda_codec *codec) 6651{ 6652 struct alc_spec *spec = codec->spec; 6653 hda_nid_t nid; 6654 6655 nid = spec->autocfg.line_out_pins[0]; 6656 if (nid) { 6657 int pin_type = get_pin_type(spec->autocfg.line_out_type); 6658 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 6659 } 6660 6661 nid = spec->autocfg.speaker_pins[0]; 6662 if (nid) 6663 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 6664 6665 nid = spec->autocfg.hp_pins[0]; 6666 if (nid) 6667 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 6668} 6669 6670#define ALC260_PIN_CD_NID 0x16 6671static void alc260_auto_init_analog_input(struct hda_codec *codec) 6672{ 6673 struct alc_spec *spec = codec->spec; 6674 int i; 6675 6676 for (i = 0; i < AUTO_PIN_LAST; i++) { 6677 hda_nid_t nid = spec->autocfg.input_pins[i]; 6678 if (nid >= 0x12) { 6679 alc_set_input_pin(codec, nid, i); 6680 if (nid != ALC260_PIN_CD_NID && 6681 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 6682 snd_hda_codec_write(codec, nid, 0, 6683 AC_VERB_SET_AMP_GAIN_MUTE, 6684 AMP_OUT_MUTE); 6685 } 6686 } 6687} 6688 6689#define alc260_auto_init_input_src alc880_auto_init_input_src 6690 6691/* 6692 * generic initialization of ADC, input mixers and output mixers 6693 */ 6694static struct hda_verb alc260_volume_init_verbs[] = { 6695 /* 6696 * Unmute ADC0-1 and set the default input to mic-in 6697 */ 6698 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6699 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6700 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6701 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6702 6703 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 6704 * mixer widget 6705 * Note: PASD motherboards uses the Line In 2 as the input for 6706 * front panel mic (mic 2) 6707 */ 6708 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 6709 /* mute analog inputs */ 6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6715 6716 /* 6717 * Set up output mixers (0x08 - 0x0a) 6718 */ 6719 /* set vol=0 to output mixers */ 6720 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6723 /* set up input amps for analog loopback */ 6724 /* Amp Indices: DAC = 0, mixer = 1 */ 6725 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6726 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6727 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6728 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6729 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6730 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 6731 6732 { } 6733}; 6734 6735static int alc260_parse_auto_config(struct hda_codec *codec) 6736{ 6737 struct alc_spec *spec = codec->spec; 6738 int err; 6739 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 6740 6741 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 6742 alc260_ignore); 6743 if (err < 0) 6744 return err; 6745 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 6746 if (err < 0) 6747 return err; 6748 if (!spec->kctls.list) 6749 return 0; /* can't find valid BIOS pin config */ 6750 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 6751 if (err < 0) 6752 return err; 6753 6754 spec->multiout.max_channels = 2; 6755 6756 if (spec->autocfg.dig_outs) 6757 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 6758 if (spec->kctls.list) 6759 add_mixer(spec, spec->kctls.list); 6760 6761 add_verb(spec, alc260_volume_init_verbs); 6762 6763 spec->num_mux_defs = 1; 6764 spec->input_mux = &spec->private_imux[0]; 6765 6766 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 6767 6768 return 1; 6769} 6770 6771/* additional initialization for auto-configuration model */ 6772static void alc260_auto_init(struct hda_codec *codec) 6773{ 6774 struct alc_spec *spec = codec->spec; 6775 alc260_auto_init_multi_out(codec); 6776 alc260_auto_init_analog_input(codec); 6777 alc260_auto_init_input_src(codec); 6778 alc_auto_init_digital(codec); 6779 if (spec->unsol_event) 6780 alc_inithook(codec); 6781} 6782 6783#ifdef CONFIG_SND_HDA_POWER_SAVE 6784static struct hda_amp_list alc260_loopbacks[] = { 6785 { 0x07, HDA_INPUT, 0 }, 6786 { 0x07, HDA_INPUT, 1 }, 6787 { 0x07, HDA_INPUT, 2 }, 6788 { 0x07, HDA_INPUT, 3 }, 6789 { 0x07, HDA_INPUT, 4 }, 6790 { } /* end */ 6791}; 6792#endif 6793 6794/* 6795 * Pin config fixes 6796 */ 6797enum { 6798 PINFIX_HP_DC5750, 6799}; 6800 6801static struct alc_pincfg alc260_hp_dc5750_pinfix[] = { 6802 { 0x11, 0x90130110 }, /* speaker */ 6803 { } 6804}; 6805 6806static const struct alc_fixup alc260_fixups[] = { 6807 [PINFIX_HP_DC5750] = { 6808 .pins = alc260_hp_dc5750_pinfix 6809 }, 6810}; 6811 6812static struct snd_pci_quirk alc260_fixup_tbl[] = { 6813 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 6814 {} 6815}; 6816 6817/* 6818 * ALC260 configurations 6819 */ 6820static const char *alc260_models[ALC260_MODEL_LAST] = { 6821 [ALC260_BASIC] = "basic", 6822 [ALC260_HP] = "hp", 6823 [ALC260_HP_3013] = "hp-3013", 6824 [ALC260_HP_DC7600] = "hp-dc7600", 6825 [ALC260_FUJITSU_S702X] = "fujitsu", 6826 [ALC260_ACER] = "acer", 6827 [ALC260_WILL] = "will", 6828 [ALC260_REPLACER_672V] = "replacer", 6829 [ALC260_FAVORIT100] = "favorit100", 6830#ifdef CONFIG_SND_DEBUG 6831 [ALC260_TEST] = "test", 6832#endif 6833 [ALC260_AUTO] = "auto", 6834}; 6835 6836static struct snd_pci_quirk alc260_cfg_tbl[] = { 6837 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 6838 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 6839 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 6840 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 6841 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 6842 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 6843 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 6844 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 6845 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 6846 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 6847 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 6848 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 6849 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 6850 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 6851 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 6852 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 6853 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 6854 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 6855 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 6856 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 6857 {} 6858}; 6859 6860static struct alc_config_preset alc260_presets[] = { 6861 [ALC260_BASIC] = { 6862 .mixers = { alc260_base_output_mixer, 6863 alc260_input_mixer }, 6864 .init_verbs = { alc260_init_verbs }, 6865 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6866 .dac_nids = alc260_dac_nids, 6867 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6868 .adc_nids = alc260_dual_adc_nids, 6869 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6870 .channel_mode = alc260_modes, 6871 .input_mux = &alc260_capture_source, 6872 }, 6873 [ALC260_HP] = { 6874 .mixers = { alc260_hp_output_mixer, 6875 alc260_input_mixer }, 6876 .init_verbs = { alc260_init_verbs, 6877 alc260_hp_unsol_verbs }, 6878 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6879 .dac_nids = alc260_dac_nids, 6880 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6881 .adc_nids = alc260_adc_nids_alt, 6882 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6883 .channel_mode = alc260_modes, 6884 .input_mux = &alc260_capture_source, 6885 .unsol_event = alc260_hp_unsol_event, 6886 .init_hook = alc260_hp_automute, 6887 }, 6888 [ALC260_HP_DC7600] = { 6889 .mixers = { alc260_hp_dc7600_mixer, 6890 alc260_input_mixer }, 6891 .init_verbs = { alc260_init_verbs, 6892 alc260_hp_dc7600_verbs }, 6893 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6894 .dac_nids = alc260_dac_nids, 6895 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6896 .adc_nids = alc260_adc_nids_alt, 6897 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6898 .channel_mode = alc260_modes, 6899 .input_mux = &alc260_capture_source, 6900 .unsol_event = alc260_hp_3012_unsol_event, 6901 .init_hook = alc260_hp_3012_automute, 6902 }, 6903 [ALC260_HP_3013] = { 6904 .mixers = { alc260_hp_3013_mixer, 6905 alc260_input_mixer }, 6906 .init_verbs = { alc260_hp_3013_init_verbs, 6907 alc260_hp_3013_unsol_verbs }, 6908 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6909 .dac_nids = alc260_dac_nids, 6910 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 6911 .adc_nids = alc260_adc_nids_alt, 6912 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6913 .channel_mode = alc260_modes, 6914 .input_mux = &alc260_capture_source, 6915 .unsol_event = alc260_hp_3013_unsol_event, 6916 .init_hook = alc260_hp_3013_automute, 6917 }, 6918 [ALC260_FUJITSU_S702X] = { 6919 .mixers = { alc260_fujitsu_mixer }, 6920 .init_verbs = { alc260_fujitsu_init_verbs }, 6921 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6922 .dac_nids = alc260_dac_nids, 6923 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6924 .adc_nids = alc260_dual_adc_nids, 6925 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6926 .channel_mode = alc260_modes, 6927 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 6928 .input_mux = alc260_fujitsu_capture_sources, 6929 }, 6930 [ALC260_ACER] = { 6931 .mixers = { alc260_acer_mixer }, 6932 .init_verbs = { alc260_acer_init_verbs }, 6933 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6934 .dac_nids = alc260_dac_nids, 6935 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6936 .adc_nids = alc260_dual_adc_nids, 6937 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6938 .channel_mode = alc260_modes, 6939 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 6940 .input_mux = alc260_acer_capture_sources, 6941 }, 6942 [ALC260_FAVORIT100] = { 6943 .mixers = { alc260_favorit100_mixer }, 6944 .init_verbs = { alc260_favorit100_init_verbs }, 6945 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6946 .dac_nids = alc260_dac_nids, 6947 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 6948 .adc_nids = alc260_dual_adc_nids, 6949 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6950 .channel_mode = alc260_modes, 6951 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 6952 .input_mux = alc260_favorit100_capture_sources, 6953 }, 6954 [ALC260_WILL] = { 6955 .mixers = { alc260_will_mixer }, 6956 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 6957 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6958 .dac_nids = alc260_dac_nids, 6959 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6960 .adc_nids = alc260_adc_nids, 6961 .dig_out_nid = ALC260_DIGOUT_NID, 6962 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6963 .channel_mode = alc260_modes, 6964 .input_mux = &alc260_capture_source, 6965 }, 6966 [ALC260_REPLACER_672V] = { 6967 .mixers = { alc260_replacer_672v_mixer }, 6968 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 6969 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 6970 .dac_nids = alc260_dac_nids, 6971 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 6972 .adc_nids = alc260_adc_nids, 6973 .dig_out_nid = ALC260_DIGOUT_NID, 6974 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6975 .channel_mode = alc260_modes, 6976 .input_mux = &alc260_capture_source, 6977 .unsol_event = alc260_replacer_672v_unsol_event, 6978 .init_hook = alc260_replacer_672v_automute, 6979 }, 6980#ifdef CONFIG_SND_DEBUG 6981 [ALC260_TEST] = { 6982 .mixers = { alc260_test_mixer }, 6983 .init_verbs = { alc260_test_init_verbs }, 6984 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 6985 .dac_nids = alc260_test_dac_nids, 6986 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 6987 .adc_nids = alc260_test_adc_nids, 6988 .num_channel_mode = ARRAY_SIZE(alc260_modes), 6989 .channel_mode = alc260_modes, 6990 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 6991 .input_mux = alc260_test_capture_sources, 6992 }, 6993#endif 6994}; 6995 6996static int patch_alc260(struct hda_codec *codec) 6997{ 6998 struct alc_spec *spec; 6999 int err, board_config; 7000 7001 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7002 if (spec == NULL) 7003 return -ENOMEM; 7004 7005 codec->spec = spec; 7006 7007 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7008 alc260_models, 7009 alc260_cfg_tbl); 7010 if (board_config < 0) { 7011 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7012 codec->chip_name); 7013 board_config = ALC260_AUTO; 7014 } 7015 7016 if (board_config == ALC260_AUTO) 7017 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); 7018 7019 if (board_config == ALC260_AUTO) { 7020 /* automatic parse from the BIOS config */ 7021 err = alc260_parse_auto_config(codec); 7022 if (err < 0) { 7023 alc_free(codec); 7024 return err; 7025 } else if (!err) { 7026 printk(KERN_INFO 7027 "hda_codec: Cannot set up configuration " 7028 "from BIOS. Using base mode...\n"); 7029 board_config = ALC260_BASIC; 7030 } 7031 } 7032 7033 err = snd_hda_attach_beep_device(codec, 0x1); 7034 if (err < 0) { 7035 alc_free(codec); 7036 return err; 7037 } 7038 7039 if (board_config != ALC260_AUTO) 7040 setup_preset(codec, &alc260_presets[board_config]); 7041 7042 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7043 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7044 7045 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7046 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7047 7048 if (!spec->adc_nids && spec->input_mux) { 7049 /* check whether NID 0x04 is valid */ 7050 unsigned int wcap = get_wcaps(codec, 0x04); 7051 wcap = get_wcaps_type(wcap); 7052 /* get type */ 7053 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7054 spec->adc_nids = alc260_adc_nids_alt; 7055 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7056 } else { 7057 spec->adc_nids = alc260_adc_nids; 7058 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7059 } 7060 } 7061 set_capture_mixer(codec); 7062 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7063 7064 if (board_config == ALC260_AUTO) 7065 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); 7066 7067 spec->vmaster_nid = 0x08; 7068 7069 codec->patch_ops = alc_patch_ops; 7070 if (board_config == ALC260_AUTO) 7071 spec->init_hook = alc260_auto_init; 7072#ifdef CONFIG_SND_HDA_POWER_SAVE 7073 if (!spec->loopback.amplist) 7074 spec->loopback.amplist = alc260_loopbacks; 7075#endif 7076 7077 return 0; 7078} 7079 7080 7081/* 7082 * ALC882/883/885/888/889 support 7083 * 7084 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7085 * configuration. Each pin widget can choose any input DACs and a mixer. 7086 * Each ADC is connected from a mixer of all inputs. This makes possible 7087 * 6-channel independent captures. 7088 * 7089 * In addition, an independent DAC for the multi-playback (not used in this 7090 * driver yet). 7091 */ 7092#define ALC882_DIGOUT_NID 0x06 7093#define ALC882_DIGIN_NID 0x0a 7094#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7095#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7096#define ALC1200_DIGOUT_NID 0x10 7097 7098 7099static struct hda_channel_mode alc882_ch_modes[1] = { 7100 { 8, NULL } 7101}; 7102 7103/* DACs */ 7104static hda_nid_t alc882_dac_nids[4] = { 7105 /* front, rear, clfe, rear_surr */ 7106 0x02, 0x03, 0x04, 0x05 7107}; 7108#define alc883_dac_nids alc882_dac_nids 7109 7110/* ADCs */ 7111#define alc882_adc_nids alc880_adc_nids 7112#define alc882_adc_nids_alt alc880_adc_nids_alt 7113#define alc883_adc_nids alc882_adc_nids_alt 7114static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7115static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7116#define alc889_adc_nids alc880_adc_nids 7117 7118static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7119static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7120#define alc883_capsrc_nids alc882_capsrc_nids_alt 7121static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7122#define alc889_capsrc_nids alc882_capsrc_nids 7123 7124/* input MUX */ 7125/* FIXME: should be a matrix-type input source selection */ 7126 7127static struct hda_input_mux alc882_capture_source = { 7128 .num_items = 4, 7129 .items = { 7130 { "Mic", 0x0 }, 7131 { "Front Mic", 0x1 }, 7132 { "Line", 0x2 }, 7133 { "CD", 0x4 }, 7134 }, 7135}; 7136 7137#define alc883_capture_source alc882_capture_source 7138 7139static struct hda_input_mux alc889_capture_source = { 7140 .num_items = 3, 7141 .items = { 7142 { "Front Mic", 0x0 }, 7143 { "Mic", 0x3 }, 7144 { "Line", 0x2 }, 7145 }, 7146}; 7147 7148static struct hda_input_mux mb5_capture_source = { 7149 .num_items = 3, 7150 .items = { 7151 { "Mic", 0x1 }, 7152 { "Line", 0x7 }, 7153 { "CD", 0x4 }, 7154 }, 7155}; 7156 7157static struct hda_input_mux macmini3_capture_source = { 7158 .num_items = 2, 7159 .items = { 7160 { "Line", 0x2 }, 7161 { "CD", 0x4 }, 7162 }, 7163}; 7164 7165static struct hda_input_mux alc883_3stack_6ch_intel = { 7166 .num_items = 4, 7167 .items = { 7168 { "Mic", 0x1 }, 7169 { "Front Mic", 0x0 }, 7170 { "Line", 0x2 }, 7171 { "CD", 0x4 }, 7172 }, 7173}; 7174 7175static struct hda_input_mux alc883_lenovo_101e_capture_source = { 7176 .num_items = 2, 7177 .items = { 7178 { "Mic", 0x1 }, 7179 { "Line", 0x2 }, 7180 }, 7181}; 7182 7183static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7184 .num_items = 4, 7185 .items = { 7186 { "Mic", 0x0 }, 7187 { "Int Mic", 0x1 }, 7188 { "Line", 0x2 }, 7189 { "CD", 0x4 }, 7190 }, 7191}; 7192 7193static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7194 .num_items = 2, 7195 .items = { 7196 { "Mic", 0x0 }, 7197 { "Int Mic", 0x1 }, 7198 }, 7199}; 7200 7201static struct hda_input_mux alc883_lenovo_sky_capture_source = { 7202 .num_items = 3, 7203 .items = { 7204 { "Mic", 0x0 }, 7205 { "Front Mic", 0x1 }, 7206 { "Line", 0x4 }, 7207 }, 7208}; 7209 7210static struct hda_input_mux alc883_asus_eee1601_capture_source = { 7211 .num_items = 2, 7212 .items = { 7213 { "Mic", 0x0 }, 7214 { "Line", 0x2 }, 7215 }, 7216}; 7217 7218static struct hda_input_mux alc889A_mb31_capture_source = { 7219 .num_items = 2, 7220 .items = { 7221 { "Mic", 0x0 }, 7222 /* Front Mic (0x01) unused */ 7223 { "Line", 0x2 }, 7224 /* Line 2 (0x03) unused */ 7225 /* CD (0x04) unused? */ 7226 }, 7227}; 7228 7229static struct hda_input_mux alc889A_imac91_capture_source = { 7230 .num_items = 2, 7231 .items = { 7232 { "Mic", 0x01 }, 7233 { "Line", 0x2 }, /* Not sure! */ 7234 }, 7235}; 7236 7237/* 7238 * 2ch mode 7239 */ 7240static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7241 { 2, NULL } 7242}; 7243 7244/* 7245 * 2ch mode 7246 */ 7247static struct hda_verb alc882_3ST_ch2_init[] = { 7248 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7249 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7250 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7251 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7252 { } /* end */ 7253}; 7254 7255/* 7256 * 4ch mode 7257 */ 7258static struct hda_verb alc882_3ST_ch4_init[] = { 7259 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7260 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7261 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7262 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7263 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7264 { } /* end */ 7265}; 7266 7267/* 7268 * 6ch mode 7269 */ 7270static struct hda_verb alc882_3ST_ch6_init[] = { 7271 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7272 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7273 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7274 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7275 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7276 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7277 { } /* end */ 7278}; 7279 7280static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7281 { 2, alc882_3ST_ch2_init }, 7282 { 4, alc882_3ST_ch4_init }, 7283 { 6, alc882_3ST_ch6_init }, 7284}; 7285 7286#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7287 7288/* 7289 * 2ch mode 7290 */ 7291static struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7292 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7293 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7294 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7297 { } /* end */ 7298}; 7299 7300/* 7301 * 4ch mode 7302 */ 7303static struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7307 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7308 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7309 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7310 { } /* end */ 7311}; 7312 7313/* 7314 * 6ch mode 7315 */ 7316static struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7317 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7318 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7319 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7320 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7321 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7322 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7323 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7324 { } /* end */ 7325}; 7326 7327static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7328 { 2, alc883_3ST_ch2_clevo_init }, 7329 { 4, alc883_3ST_ch4_clevo_init }, 7330 { 6, alc883_3ST_ch6_clevo_init }, 7331}; 7332 7333 7334/* 7335 * 6ch mode 7336 */ 7337static struct hda_verb alc882_sixstack_ch6_init[] = { 7338 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7339 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7340 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7341 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7342 { } /* end */ 7343}; 7344 7345/* 7346 * 8ch mode 7347 */ 7348static struct hda_verb alc882_sixstack_ch8_init[] = { 7349 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7350 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7351 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7352 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7353 { } /* end */ 7354}; 7355 7356static struct hda_channel_mode alc882_sixstack_modes[2] = { 7357 { 6, alc882_sixstack_ch6_init }, 7358 { 8, alc882_sixstack_ch8_init }, 7359}; 7360 7361 7362/* Macbook Air 2,1 */ 7363 7364static struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7365 { 2, NULL }, 7366}; 7367 7368/* 7369 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7370 */ 7371 7372/* 7373 * 2ch mode 7374 */ 7375static struct hda_verb alc885_mbp_ch2_init[] = { 7376 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7377 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7378 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7379 { } /* end */ 7380}; 7381 7382/* 7383 * 4ch mode 7384 */ 7385static struct hda_verb alc885_mbp_ch4_init[] = { 7386 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7387 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7388 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7389 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7390 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7391 { } /* end */ 7392}; 7393 7394static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 7395 { 2, alc885_mbp_ch2_init }, 7396 { 4, alc885_mbp_ch4_init }, 7397}; 7398 7399/* 7400 * 2ch 7401 * Speakers/Woofer/HP = Front 7402 * LineIn = Input 7403 */ 7404static struct hda_verb alc885_mb5_ch2_init[] = { 7405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7407 { } /* end */ 7408}; 7409 7410/* 7411 * 6ch mode 7412 * Speakers/HP = Front 7413 * Woofer = LFE 7414 * LineIn = Surround 7415 */ 7416static struct hda_verb alc885_mb5_ch6_init[] = { 7417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7419 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7420 { } /* end */ 7421}; 7422 7423static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 7424 { 2, alc885_mb5_ch2_init }, 7425 { 6, alc885_mb5_ch6_init }, 7426}; 7427 7428#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 7429 7430/* 7431 * 2ch mode 7432 */ 7433static struct hda_verb alc883_4ST_ch2_init[] = { 7434 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7435 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7438 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7439 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7440 { } /* end */ 7441}; 7442 7443/* 7444 * 4ch mode 7445 */ 7446static struct hda_verb alc883_4ST_ch4_init[] = { 7447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7448 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7449 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7450 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7451 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7452 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7453 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7454 { } /* end */ 7455}; 7456 7457/* 7458 * 6ch mode 7459 */ 7460static struct hda_verb alc883_4ST_ch6_init[] = { 7461 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7462 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7463 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7464 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7465 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7468 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7469 { } /* end */ 7470}; 7471 7472/* 7473 * 8ch mode 7474 */ 7475static struct hda_verb alc883_4ST_ch8_init[] = { 7476 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7477 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7478 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7479 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7480 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7481 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7482 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7483 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7484 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7485 { } /* end */ 7486}; 7487 7488static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 7489 { 2, alc883_4ST_ch2_init }, 7490 { 4, alc883_4ST_ch4_init }, 7491 { 6, alc883_4ST_ch6_init }, 7492 { 8, alc883_4ST_ch8_init }, 7493}; 7494 7495 7496/* 7497 * 2ch mode 7498 */ 7499static struct hda_verb alc883_3ST_ch2_intel_init[] = { 7500 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7501 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7502 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7503 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7504 { } /* end */ 7505}; 7506 7507/* 7508 * 4ch mode 7509 */ 7510static struct hda_verb alc883_3ST_ch4_intel_init[] = { 7511 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7512 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7513 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7514 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7515 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7516 { } /* end */ 7517}; 7518 7519/* 7520 * 6ch mode 7521 */ 7522static struct hda_verb alc883_3ST_ch6_intel_init[] = { 7523 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7524 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7525 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7526 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7527 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7528 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7529 { } /* end */ 7530}; 7531 7532static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 7533 { 2, alc883_3ST_ch2_intel_init }, 7534 { 4, alc883_3ST_ch4_intel_init }, 7535 { 6, alc883_3ST_ch6_intel_init }, 7536}; 7537 7538/* 7539 * 2ch mode 7540 */ 7541static struct hda_verb alc889_ch2_intel_init[] = { 7542 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7543 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7544 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7545 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7546 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7547 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7548 { } /* end */ 7549}; 7550 7551/* 7552 * 6ch mode 7553 */ 7554static struct hda_verb alc889_ch6_intel_init[] = { 7555 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7556 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7557 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7558 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7559 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7560 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7561 { } /* end */ 7562}; 7563 7564/* 7565 * 8ch mode 7566 */ 7567static struct hda_verb alc889_ch8_intel_init[] = { 7568 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 7569 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7570 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7571 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7572 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 7573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7575 { } /* end */ 7576}; 7577 7578static struct hda_channel_mode alc889_8ch_intel_modes[3] = { 7579 { 2, alc889_ch2_intel_init }, 7580 { 6, alc889_ch6_intel_init }, 7581 { 8, alc889_ch8_intel_init }, 7582}; 7583 7584/* 7585 * 6ch mode 7586 */ 7587static struct hda_verb alc883_sixstack_ch6_init[] = { 7588 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7589 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7590 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7591 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7592 { } /* end */ 7593}; 7594 7595/* 7596 * 8ch mode 7597 */ 7598static struct hda_verb alc883_sixstack_ch8_init[] = { 7599 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7600 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7601 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7602 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7603 { } /* end */ 7604}; 7605 7606static struct hda_channel_mode alc883_sixstack_modes[2] = { 7607 { 6, alc883_sixstack_ch6_init }, 7608 { 8, alc883_sixstack_ch8_init }, 7609}; 7610 7611 7612/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7613 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 7614 */ 7615static struct snd_kcontrol_new alc882_base_mixer[] = { 7616 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7617 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 7619 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 7620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 7621 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 7622 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 7623 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 7624 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 7625 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 7626 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7635 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7637 { } /* end */ 7638}; 7639 7640/* Macbook Air 2,1 same control for HP and internal Speaker */ 7641 7642static struct snd_kcontrol_new alc885_mba21_mixer[] = { 7643 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7644 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 7645 { } 7646}; 7647 7648 7649static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7650 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7651 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7653 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 7654 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7658 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7659 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 7660 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 7661 { } /* end */ 7662}; 7663 7664static struct snd_kcontrol_new alc885_mb5_mixer[] = { 7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7666 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7668 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7669 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7670 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7671 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7672 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7674 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7676 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7677 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7678 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 7679 { } /* end */ 7680}; 7681 7682static struct snd_kcontrol_new alc885_macmini3_mixer[] = { 7683 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7684 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7685 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7686 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 7687 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 7688 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 7689 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 7690 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7691 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7692 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7693 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7694 { } /* end */ 7695}; 7696 7697static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7698 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7699 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7700 { } /* end */ 7701}; 7702 7703 7704static struct snd_kcontrol_new alc882_w2jc_mixer[] = { 7705 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7706 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7707 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7708 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7709 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7710 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7711 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7712 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7714 { } /* end */ 7715}; 7716 7717static struct snd_kcontrol_new alc882_targa_mixer[] = { 7718 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7719 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 7721 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7722 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7723 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7724 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7730 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7731 { } /* end */ 7732}; 7733 7734/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 7735 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 7736 */ 7737static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 7738 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7739 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 7740 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7741 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 7742 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7743 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7744 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7745 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7746 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 7747 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 7748 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7749 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7750 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7751 { } /* end */ 7752}; 7753 7754static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 7755 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7756 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 7758 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 7759 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 7760 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7761 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7765 { } /* end */ 7766}; 7767 7768static struct snd_kcontrol_new alc882_chmode_mixer[] = { 7769 { 7770 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 7771 .name = "Channel Mode", 7772 .info = alc_ch_mode_info, 7773 .get = alc_ch_mode_get, 7774 .put = alc_ch_mode_put, 7775 }, 7776 { } /* end */ 7777}; 7778 7779static struct hda_verb alc882_base_init_verbs[] = { 7780 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7783 /* Rear mixer */ 7784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7785 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7786 /* CLFE mixer */ 7787 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7788 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7789 /* Side mixer */ 7790 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7791 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7792 7793 /* Front Pin: output 0 (0x0c) */ 7794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7796 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7797 /* Rear Pin: output 1 (0x0d) */ 7798 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7800 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 7801 /* CLFE Pin: output 2 (0x0e) */ 7802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7804 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7805 /* Side Pin: output 3 (0x0f) */ 7806 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7807 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7808 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7809 /* Mic (rear) pin: input vref at 80% */ 7810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7811 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7812 /* Front Mic pin: input vref at 80% */ 7813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7815 /* Line In pin: input */ 7816 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7817 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7818 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 7819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7821 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 7822 /* CD pin widget for input */ 7823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7824 7825 /* FIXME: use matrix-type input source selection */ 7826 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7827 /* Input mixer2 */ 7828 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7829 /* Input mixer3 */ 7830 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7831 /* ADC2: mute amp left and right */ 7832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7834 /* ADC3: mute amp left and right */ 7835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7837 7838 { } 7839}; 7840 7841static struct hda_verb alc882_adc1_init_verbs[] = { 7842 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7843 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7844 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7845 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7846 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7847 /* ADC1: mute amp left and right */ 7848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7849 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 7850 { } 7851}; 7852 7853static struct hda_verb alc882_eapd_verbs[] = { 7854 /* change to EAPD mode */ 7855 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7856 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 7857 { } 7858}; 7859 7860static struct hda_verb alc889_eapd_verbs[] = { 7861 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7862 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 7863 { } 7864}; 7865 7866static struct hda_verb alc_hp15_unsol_verbs[] = { 7867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 7868 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7869 {} 7870}; 7871 7872static struct hda_verb alc885_init_verbs[] = { 7873 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7876 /* Rear mixer */ 7877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7879 /* CLFE mixer */ 7880 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7882 /* Side mixer */ 7883 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7884 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7885 7886 /* Front HP Pin: output 0 (0x0c) */ 7887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7889 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7890 /* Front Pin: output 0 (0x0c) */ 7891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7894 /* Rear Pin: output 1 (0x0d) */ 7895 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7896 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7897 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 7898 /* CLFE Pin: output 2 (0x0e) */ 7899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7901 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 7902 /* Side Pin: output 3 (0x0f) */ 7903 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7904 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7905 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 7906 /* Mic (rear) pin: input vref at 80% */ 7907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7908 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7909 /* Front Mic pin: input vref at 80% */ 7910 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7911 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7912 /* Line In pin: input */ 7913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 7914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7915 7916 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7917 /* Input mixer1 */ 7918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7919 /* Input mixer2 */ 7920 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7921 /* Input mixer3 */ 7922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7923 /* ADC2: mute amp left and right */ 7924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7925 /* ADC3: mute amp left and right */ 7926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7927 7928 { } 7929}; 7930 7931static struct hda_verb alc885_init_input_verbs[] = { 7932 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7933 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7934 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7935 { } 7936}; 7937 7938 7939/* Unmute Selector 24h and set the default input to front mic */ 7940static struct hda_verb alc889_init_input_verbs[] = { 7941 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 7942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7943 { } 7944}; 7945 7946 7947#define alc883_init_verbs alc882_base_init_verbs 7948 7949/* Mac Pro test */ 7950static struct snd_kcontrol_new alc882_macpro_mixer[] = { 7951 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7952 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7953 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 7954 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 7955 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 7956 /* FIXME: this looks suspicious... 7957 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 7958 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 7959 */ 7960 { } /* end */ 7961}; 7962 7963static struct hda_verb alc882_macpro_init_verbs[] = { 7964 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7968 /* Front Pin: output 0 (0x0c) */ 7969 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7971 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7972 /* Front Mic pin: input vref at 80% */ 7973 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7975 /* Speaker: output */ 7976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7978 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 7979 /* Headphone output (output 0 - 0x0c) */ 7980 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7981 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7982 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 7983 7984 /* FIXME: use matrix-type input source selection */ 7985 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7986 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 7987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7988 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7989 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7990 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7991 /* Input mixer2 */ 7992 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7993 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7995 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7996 /* Input mixer3 */ 7997 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7998 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7999 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8000 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8001 /* ADC1: mute amp left and right */ 8002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8003 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8004 /* ADC2: mute amp left and right */ 8005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8006 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8007 /* ADC3: mute amp left and right */ 8008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8009 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8010 8011 { } 8012}; 8013 8014/* Macbook 5,1 */ 8015static struct hda_verb alc885_mb5_init_verbs[] = { 8016 /* DACs */ 8017 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8018 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8019 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8020 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8021 /* Front mixer */ 8022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8025 /* Surround mixer */ 8026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8029 /* LFE mixer */ 8030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8033 /* HP mixer */ 8034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8035 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8036 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8037 /* Front Pin (0x0c) */ 8038 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8039 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8040 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8041 /* LFE Pin (0x0e) */ 8042 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8043 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8044 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8045 /* HP Pin (0x0f) */ 8046 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8047 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8048 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8049 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8050 /* Front Mic pin: input vref at 80% */ 8051 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8052 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8053 /* Line In pin */ 8054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8056 8057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8060 { } 8061}; 8062 8063/* Macmini 3,1 */ 8064static struct hda_verb alc885_macmini3_init_verbs[] = { 8065 /* DACs */ 8066 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8067 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8068 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8069 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8070 /* Front mixer */ 8071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8074 /* Surround mixer */ 8075 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8076 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8078 /* LFE mixer */ 8079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8082 /* HP mixer */ 8083 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8084 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8085 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8086 /* Front Pin (0x0c) */ 8087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8088 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8089 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8090 /* LFE Pin (0x0e) */ 8091 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8092 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8093 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8094 /* HP Pin (0x0f) */ 8095 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8096 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8097 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8098 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8099 /* Line In pin */ 8100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8102 8103 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8104 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8105 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8106 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8107 { } 8108}; 8109 8110 8111static struct hda_verb alc885_mba21_init_verbs[] = { 8112 /*Internal and HP Speaker Mixer*/ 8113 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8116 /*Internal Speaker Pin (0x0c)*/ 8117 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8118 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8119 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8120 /* HP Pin: output 0 (0x0e) */ 8121 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8122 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8123 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8124 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8125 /* Line in (is hp when jack connected)*/ 8126 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8127 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8128 8129 { } 8130 }; 8131 8132 8133/* Macbook Pro rev3 */ 8134static struct hda_verb alc885_mbp3_init_verbs[] = { 8135 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8139 /* Rear mixer */ 8140 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8141 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8143 /* HP mixer */ 8144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8145 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8146 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8147 /* Front Pin: output 0 (0x0c) */ 8148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8150 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8151 /* HP Pin: output 0 (0x0e) */ 8152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8154 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8155 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8156 /* Mic (rear) pin: input vref at 80% */ 8157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8159 /* Front Mic pin: input vref at 80% */ 8160 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8161 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8162 /* Line In pin: use output 1 when in LineOut mode */ 8163 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8164 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8165 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8166 8167 /* FIXME: use matrix-type input source selection */ 8168 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8169 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8170 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8171 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8172 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8173 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8174 /* Input mixer2 */ 8175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8176 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8177 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8179 /* Input mixer3 */ 8180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8182 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8184 /* ADC1: mute amp left and right */ 8185 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8186 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8187 /* ADC2: mute amp left and right */ 8188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8189 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8190 /* ADC3: mute amp left and right */ 8191 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8192 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8193 8194 { } 8195}; 8196 8197/* iMac 9,1 */ 8198static struct hda_verb alc885_imac91_init_verbs[] = { 8199 /* Internal Speaker Pin (0x0c) */ 8200 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8201 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8202 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8203 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8205 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8206 /* HP Pin: Rear */ 8207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8209 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8211 /* Line in Rear */ 8212 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8213 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8214 /* Front Mic pin: input vref at 80% */ 8215 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8217 /* Rear mixer */ 8218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8221 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8222 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8225 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8226 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8228 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8230 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8231 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8232 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8233 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8235 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8238 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8240 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8241 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8242 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8243 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8245 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8246 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8247 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8248 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8249 { } 8250}; 8251 8252/* iMac 24 mixer. */ 8253static struct snd_kcontrol_new alc885_imac24_mixer[] = { 8254 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8255 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8256 { } /* end */ 8257}; 8258 8259/* iMac 24 init verbs. */ 8260static struct hda_verb alc885_imac24_init_verbs[] = { 8261 /* Internal speakers: output 0 (0x0c) */ 8262 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8263 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8264 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8265 /* Internal speakers: output 0 (0x0c) */ 8266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8267 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8268 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8269 /* Headphone: output 0 (0x0c) */ 8270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8271 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8272 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8273 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8274 /* Front Mic: input vref at 80% */ 8275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8276 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8277 { } 8278}; 8279 8280/* Toggle speaker-output according to the hp-jack state */ 8281static void alc885_imac24_setup(struct hda_codec *codec) 8282{ 8283 struct alc_spec *spec = codec->spec; 8284 8285 spec->autocfg.hp_pins[0] = 0x14; 8286 spec->autocfg.speaker_pins[0] = 0x18; 8287 spec->autocfg.speaker_pins[1] = 0x1a; 8288} 8289 8290#define alc885_mb5_setup alc885_imac24_setup 8291#define alc885_macmini3_setup alc885_imac24_setup 8292 8293/* Macbook Air 2,1 */ 8294static void alc885_mba21_setup(struct hda_codec *codec) 8295{ 8296 struct alc_spec *spec = codec->spec; 8297 8298 spec->autocfg.hp_pins[0] = 0x14; 8299 spec->autocfg.speaker_pins[0] = 0x18; 8300} 8301 8302 8303 8304static void alc885_mbp3_setup(struct hda_codec *codec) 8305{ 8306 struct alc_spec *spec = codec->spec; 8307 8308 spec->autocfg.hp_pins[0] = 0x15; 8309 spec->autocfg.speaker_pins[0] = 0x14; 8310} 8311 8312static void alc885_imac91_setup(struct hda_codec *codec) 8313{ 8314 struct alc_spec *spec = codec->spec; 8315 8316 spec->autocfg.hp_pins[0] = 0x14; 8317 spec->autocfg.speaker_pins[0] = 0x18; 8318 spec->autocfg.speaker_pins[1] = 0x1a; 8319} 8320 8321static struct hda_verb alc882_targa_verbs[] = { 8322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8324 8325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8326 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8327 8328 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8329 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8330 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8331 8332 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8333 { } /* end */ 8334}; 8335 8336/* toggle speaker-output according to the hp-jack state */ 8337static void alc882_targa_automute(struct hda_codec *codec) 8338{ 8339 struct alc_spec *spec = codec->spec; 8340 alc_automute_amp(codec); 8341 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8342 spec->jack_present ? 1 : 3); 8343} 8344 8345static void alc882_targa_setup(struct hda_codec *codec) 8346{ 8347 struct alc_spec *spec = codec->spec; 8348 8349 spec->autocfg.hp_pins[0] = 0x14; 8350 spec->autocfg.speaker_pins[0] = 0x1b; 8351} 8352 8353static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8354{ 8355 if ((res >> 26) == ALC880_HP_EVENT) 8356 alc882_targa_automute(codec); 8357} 8358 8359static struct hda_verb alc882_asus_a7j_verbs[] = { 8360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8362 8363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8365 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8366 8367 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8369 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8370 8371 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8372 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8373 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8374 { } /* end */ 8375}; 8376 8377static struct hda_verb alc882_asus_a7m_verbs[] = { 8378 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8380 8381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8383 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8384 8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8386 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8387 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8388 8389 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8390 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8391 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8392 { } /* end */ 8393}; 8394 8395static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 8396{ 8397 unsigned int gpiostate, gpiomask, gpiodir; 8398 8399 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 8400 AC_VERB_GET_GPIO_DATA, 0); 8401 8402 if (!muted) 8403 gpiostate |= (1 << pin); 8404 else 8405 gpiostate &= ~(1 << pin); 8406 8407 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 8408 AC_VERB_GET_GPIO_MASK, 0); 8409 gpiomask |= (1 << pin); 8410 8411 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 8412 AC_VERB_GET_GPIO_DIRECTION, 0); 8413 gpiodir |= (1 << pin); 8414 8415 8416 snd_hda_codec_write(codec, codec->afg, 0, 8417 AC_VERB_SET_GPIO_MASK, gpiomask); 8418 snd_hda_codec_write(codec, codec->afg, 0, 8419 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 8420 8421 msleep(1); 8422 8423 snd_hda_codec_write(codec, codec->afg, 0, 8424 AC_VERB_SET_GPIO_DATA, gpiostate); 8425} 8426 8427/* set up GPIO at initialization */ 8428static void alc885_macpro_init_hook(struct hda_codec *codec) 8429{ 8430 alc882_gpio_mute(codec, 0, 0); 8431 alc882_gpio_mute(codec, 1, 0); 8432} 8433 8434/* set up GPIO and update auto-muting at initialization */ 8435static void alc885_imac24_init_hook(struct hda_codec *codec) 8436{ 8437 alc885_macpro_init_hook(codec); 8438 alc_automute_amp(codec); 8439} 8440 8441/* 8442 * generic initialization of ADC, input mixers and output mixers 8443 */ 8444static struct hda_verb alc883_auto_init_verbs[] = { 8445 /* 8446 * Unmute ADC0-2 and set the default input to mic-in 8447 */ 8448 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8449 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8450 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8452 8453 /* 8454 * Set up output mixers (0x0c - 0x0f) 8455 */ 8456 /* set vol=0 to output mixers */ 8457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8459 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8460 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8461 /* set up input amps for analog loopback */ 8462 /* Amp Indices: DAC = 0, mixer = 1 */ 8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8469 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8470 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8471 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8472 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8473 8474 /* FIXME: use matrix-type input source selection */ 8475 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8476 /* Input mixer2 */ 8477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8478 /* Input mixer3 */ 8479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8480 { } 8481}; 8482 8483/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 8484static struct hda_verb alc889A_mb31_ch2_init[] = { 8485 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8486 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8487 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8488 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8489 { } /* end */ 8490}; 8491 8492/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 8493static struct hda_verb alc889A_mb31_ch4_init[] = { 8494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 8495 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8496 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8497 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8498 { } /* end */ 8499}; 8500 8501/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 8502static struct hda_verb alc889A_mb31_ch5_init[] = { 8503 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 8504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 8505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 8506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 8507 { } /* end */ 8508}; 8509 8510/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 8511static struct hda_verb alc889A_mb31_ch6_init[] = { 8512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 8513 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 8514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 8515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 8516 { } /* end */ 8517}; 8518 8519static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 8520 { 2, alc889A_mb31_ch2_init }, 8521 { 4, alc889A_mb31_ch4_init }, 8522 { 5, alc889A_mb31_ch5_init }, 8523 { 6, alc889A_mb31_ch6_init }, 8524}; 8525 8526static struct hda_verb alc883_medion_eapd_verbs[] = { 8527 /* eanable EAPD on medion laptop */ 8528 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8529 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 8530 { } 8531}; 8532 8533#define alc883_base_mixer alc882_base_mixer 8534 8535static struct snd_kcontrol_new alc883_mitac_mixer[] = { 8536 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8537 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8538 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8539 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8540 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8541 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8543 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8544 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8546 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8547 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8548 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8549 { } /* end */ 8550}; 8551 8552static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 8553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8554 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8555 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8556 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8557 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8558 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8560 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8561 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8562 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8563 { } /* end */ 8564}; 8565 8566static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 8567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8568 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 8569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8570 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8571 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8572 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8574 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8575 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8576 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8577 { } /* end */ 8578}; 8579 8580static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 8581 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8582 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8591 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8592 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8593 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8594 { } /* end */ 8595}; 8596 8597static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 8598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8600 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8601 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8604 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8605 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8612 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8613 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8614 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8615 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8616 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8617 { } /* end */ 8618}; 8619 8620static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 8621 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8622 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8623 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8624 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8625 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8626 HDA_OUTPUT), 8627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8631 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8632 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8634 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8636 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8638 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8639 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8641 { } /* end */ 8642}; 8643 8644static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 8645 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8646 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8647 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8648 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8649 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 8650 HDA_OUTPUT), 8651 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8652 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8653 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8654 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8655 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 8656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8657 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8658 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8660 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 8661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8663 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8665 { } /* end */ 8666}; 8667 8668static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 8669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8671 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8672 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8673 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8674 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8675 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8676 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8677 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8678 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8679 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8680 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8681 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8683 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8685 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8686 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8688 { } /* end */ 8689}; 8690 8691static struct snd_kcontrol_new alc883_targa_mixer[] = { 8692 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8693 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8694 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8695 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8696 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8697 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8698 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8699 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8700 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8701 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8709 { } /* end */ 8710}; 8711 8712static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 8713 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8714 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8716 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8720 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8722 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8723 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8724 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8725 { } /* end */ 8726}; 8727 8728static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 8729 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8730 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8731 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8732 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8733 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8734 { } /* end */ 8735}; 8736 8737static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 8738 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8739 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8740 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8741 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8744 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8746 { } /* end */ 8747}; 8748 8749static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 8750 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8751 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 8752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8755 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8756 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8757 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8758 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8759 { } /* end */ 8760}; 8761 8762static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { 8763 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8765 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8766 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8772 { } /* end */ 8773}; 8774 8775static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8778 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 8780 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 8781 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 8782 { } /* end */ 8783}; 8784 8785static struct hda_verb alc883_medion_wim2160_verbs[] = { 8786 /* Unmute front mixer */ 8787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8789 8790 /* Set speaker pin to front mixer */ 8791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8792 8793 /* Init headphone pin */ 8794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8795 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8796 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8797 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8798 8799 { } /* end */ 8800}; 8801 8802/* toggle speaker-output according to the hp-jack state */ 8803static void alc883_medion_wim2160_setup(struct hda_codec *codec) 8804{ 8805 struct alc_spec *spec = codec->spec; 8806 8807 spec->autocfg.hp_pins[0] = 0x1a; 8808 spec->autocfg.speaker_pins[0] = 0x15; 8809} 8810 8811static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 8812 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8813 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8814 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8820 { } /* end */ 8821}; 8822 8823static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 8824 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8825 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8828 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8829 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8832 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8833 { } /* end */ 8834}; 8835 8836static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 8837 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8838 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8839 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 8840 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 8841 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 8842 0x0d, 1, 0x0, HDA_OUTPUT), 8843 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 8844 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 8845 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 8846 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8847 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8848 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8849 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8855 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8856 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8857 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8858 { } /* end */ 8859}; 8860 8861static struct snd_kcontrol_new alc889A_mb31_mixer[] = { 8862 /* Output mixers */ 8863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8864 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8865 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8866 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8867 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 8868 HDA_OUTPUT), 8869 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 8870 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 8871 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 8872 /* Output switches */ 8873 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 8874 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 8875 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 8876 /* Boost mixers */ 8877 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 8878 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 8879 /* Input mixers */ 8880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8882 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8883 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8884 { } /* end */ 8885}; 8886 8887static struct snd_kcontrol_new alc883_vaiott_mixer[] = { 8888 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8889 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8890 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8892 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8893 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8894 { } /* end */ 8895}; 8896 8897static struct hda_bind_ctls alc883_bind_cap_vol = { 8898 .ops = &snd_hda_bind_vol, 8899 .values = { 8900 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8901 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8902 0 8903 }, 8904}; 8905 8906static struct hda_bind_ctls alc883_bind_cap_switch = { 8907 .ops = &snd_hda_bind_sw, 8908 .values = { 8909 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 8910 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 8911 0 8912 }, 8913}; 8914 8915static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 8916 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8917 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8922 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8923 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8924 { } /* end */ 8925}; 8926 8927static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 8928 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 8929 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 8930 { 8931 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8932 /* .name = "Capture Source", */ 8933 .name = "Input Source", 8934 .count = 1, 8935 .info = alc_mux_enum_info, 8936 .get = alc_mux_enum_get, 8937 .put = alc_mux_enum_put, 8938 }, 8939 { } /* end */ 8940}; 8941 8942static struct snd_kcontrol_new alc883_chmode_mixer[] = { 8943 { 8944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8945 .name = "Channel Mode", 8946 .info = alc_ch_mode_info, 8947 .get = alc_ch_mode_get, 8948 .put = alc_ch_mode_put, 8949 }, 8950 { } /* end */ 8951}; 8952 8953/* toggle speaker-output according to the hp-jack state */ 8954static void alc883_mitac_setup(struct hda_codec *codec) 8955{ 8956 struct alc_spec *spec = codec->spec; 8957 8958 spec->autocfg.hp_pins[0] = 0x15; 8959 spec->autocfg.speaker_pins[0] = 0x14; 8960 spec->autocfg.speaker_pins[1] = 0x17; 8961} 8962 8963/* auto-toggle front mic */ 8964/* 8965static void alc883_mitac_mic_automute(struct hda_codec *codec) 8966{ 8967 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; 8968 8969 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 8970} 8971*/ 8972 8973static struct hda_verb alc883_mitac_verbs[] = { 8974 /* HP */ 8975 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8977 /* Subwoofer */ 8978 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 8979 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8980 8981 /* enable unsolicited event */ 8982 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8983 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 8984 8985 { } /* end */ 8986}; 8987 8988static struct hda_verb alc883_clevo_m540r_verbs[] = { 8989 /* HP */ 8990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8992 /* Int speaker */ 8993 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 8994 8995 /* enable unsolicited event */ 8996 /* 8997 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8998 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 8999 */ 9000 9001 { } /* end */ 9002}; 9003 9004static struct hda_verb alc883_clevo_m720_verbs[] = { 9005 /* HP */ 9006 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9008 /* Int speaker */ 9009 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9010 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9011 9012 /* enable unsolicited event */ 9013 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9014 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9015 9016 { } /* end */ 9017}; 9018 9019static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9020 /* HP */ 9021 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9023 /* Subwoofer */ 9024 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9025 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9026 9027 /* enable unsolicited event */ 9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9029 9030 { } /* end */ 9031}; 9032 9033static struct hda_verb alc883_targa_verbs[] = { 9034 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9036 9037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9039 9040/* Connect Line-Out side jack (SPDIF) to Side */ 9041 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9042 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9043 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9044/* Connect Mic jack to CLFE */ 9045 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9046 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9047 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9048/* Connect Line-in jack to Surround */ 9049 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9051 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9052/* Connect HP out jack to Front */ 9053 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9054 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9055 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9056 9057 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9058 9059 { } /* end */ 9060}; 9061 9062static struct hda_verb alc883_lenovo_101e_verbs[] = { 9063 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9064 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9066 { } /* end */ 9067}; 9068 9069static struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9070 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9072 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9074 { } /* end */ 9075}; 9076 9077static struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9081 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9082 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9083 { } /* end */ 9084}; 9085 9086static struct hda_verb alc883_haier_w66_verbs[] = { 9087 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9088 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9089 9090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9091 9092 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9094 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9096 { } /* end */ 9097}; 9098 9099static struct hda_verb alc888_lenovo_sky_verbs[] = { 9100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9105 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9106 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9107 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9108 { } /* end */ 9109}; 9110 9111static struct hda_verb alc888_6st_dell_verbs[] = { 9112 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9113 { } 9114}; 9115 9116static struct hda_verb alc883_vaiott_verbs[] = { 9117 /* HP */ 9118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9120 9121 /* enable unsolicited event */ 9122 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9123 9124 { } /* end */ 9125}; 9126 9127static void alc888_3st_hp_setup(struct hda_codec *codec) 9128{ 9129 struct alc_spec *spec = codec->spec; 9130 9131 spec->autocfg.hp_pins[0] = 0x1b; 9132 spec->autocfg.speaker_pins[0] = 0x14; 9133 spec->autocfg.speaker_pins[1] = 0x16; 9134 spec->autocfg.speaker_pins[2] = 0x18; 9135} 9136 9137static struct hda_verb alc888_3st_hp_verbs[] = { 9138 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9139 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9140 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9141 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9142 { } /* end */ 9143}; 9144 9145/* 9146 * 2ch mode 9147 */ 9148static struct hda_verb alc888_3st_hp_2ch_init[] = { 9149 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9150 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9151 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9152 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9153 { } /* end */ 9154}; 9155 9156/* 9157 * 4ch mode 9158 */ 9159static struct hda_verb alc888_3st_hp_4ch_init[] = { 9160 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9161 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9162 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9163 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9164 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9165 { } /* end */ 9166}; 9167 9168/* 9169 * 6ch mode 9170 */ 9171static struct hda_verb alc888_3st_hp_6ch_init[] = { 9172 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9173 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9174 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9175 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9176 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9177 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9178 { } /* end */ 9179}; 9180 9181static struct hda_channel_mode alc888_3st_hp_modes[3] = { 9182 { 2, alc888_3st_hp_2ch_init }, 9183 { 4, alc888_3st_hp_4ch_init }, 9184 { 6, alc888_3st_hp_6ch_init }, 9185}; 9186 9187/* toggle front-jack and RCA according to the hp-jack state */ 9188static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) 9189{ 9190 unsigned int present = snd_hda_jack_detect(codec, 0x1b); 9191 9192 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9193 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9194 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9195 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9196} 9197 9198/* toggle RCA according to the front-jack state */ 9199static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) 9200{ 9201 unsigned int present = snd_hda_jack_detect(codec, 0x14); 9202 9203 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9204 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9205} 9206 9207static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, 9208 unsigned int res) 9209{ 9210 if ((res >> 26) == ALC880_HP_EVENT) 9211 alc888_lenovo_ms7195_front_automute(codec); 9212 if ((res >> 26) == ALC880_FRONT_EVENT) 9213 alc888_lenovo_ms7195_rca_automute(codec); 9214} 9215 9216static struct hda_verb alc883_medion_md2_verbs[] = { 9217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9219 9220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9221 9222 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9223 { } /* end */ 9224}; 9225 9226/* toggle speaker-output according to the hp-jack state */ 9227static void alc883_medion_md2_setup(struct hda_codec *codec) 9228{ 9229 struct alc_spec *spec = codec->spec; 9230 9231 spec->autocfg.hp_pins[0] = 0x14; 9232 spec->autocfg.speaker_pins[0] = 0x15; 9233} 9234 9235/* toggle speaker-output according to the hp-jack state */ 9236#define alc883_targa_init_hook alc882_targa_init_hook 9237#define alc883_targa_unsol_event alc882_targa_unsol_event 9238 9239static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) 9240{ 9241 unsigned int present; 9242 9243 present = snd_hda_jack_detect(codec, 0x18); 9244 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 9245 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9246} 9247 9248static void alc883_clevo_m720_setup(struct hda_codec *codec) 9249{ 9250 struct alc_spec *spec = codec->spec; 9251 9252 spec->autocfg.hp_pins[0] = 0x15; 9253 spec->autocfg.speaker_pins[0] = 0x14; 9254} 9255 9256static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9257{ 9258 alc_automute_amp(codec); 9259 alc883_clevo_m720_mic_automute(codec); 9260} 9261 9262static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9263 unsigned int res) 9264{ 9265 switch (res >> 26) { 9266 case ALC880_MIC_EVENT: 9267 alc883_clevo_m720_mic_automute(codec); 9268 break; 9269 default: 9270 alc_automute_amp_unsol_event(codec, res); 9271 break; 9272 } 9273} 9274 9275/* toggle speaker-output according to the hp-jack state */ 9276static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9277{ 9278 struct alc_spec *spec = codec->spec; 9279 9280 spec->autocfg.hp_pins[0] = 0x14; 9281 spec->autocfg.speaker_pins[0] = 0x15; 9282} 9283 9284static void alc883_haier_w66_setup(struct hda_codec *codec) 9285{ 9286 struct alc_spec *spec = codec->spec; 9287 9288 spec->autocfg.hp_pins[0] = 0x1b; 9289 spec->autocfg.speaker_pins[0] = 0x14; 9290} 9291 9292static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 9293{ 9294 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; 9295 9296 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9297 HDA_AMP_MUTE, bits); 9298} 9299 9300static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) 9301{ 9302 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; 9303 9304 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 9305 HDA_AMP_MUTE, bits); 9306 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9307 HDA_AMP_MUTE, bits); 9308} 9309 9310static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, 9311 unsigned int res) 9312{ 9313 if ((res >> 26) == ALC880_HP_EVENT) 9314 alc883_lenovo_101e_all_automute(codec); 9315 if ((res >> 26) == ALC880_FRONT_EVENT) 9316 alc883_lenovo_101e_ispeaker_automute(codec); 9317} 9318 9319/* toggle speaker-output according to the hp-jack state */ 9320static void alc883_acer_aspire_setup(struct hda_codec *codec) 9321{ 9322 struct alc_spec *spec = codec->spec; 9323 9324 spec->autocfg.hp_pins[0] = 0x14; 9325 spec->autocfg.speaker_pins[0] = 0x15; 9326 spec->autocfg.speaker_pins[1] = 0x16; 9327} 9328 9329static struct hda_verb alc883_acer_eapd_verbs[] = { 9330 /* HP Pin: output 0 (0x0c) */ 9331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9332 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9333 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9334 /* Front Pin: output 0 (0x0c) */ 9335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9337 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9338 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9339 /* eanable EAPD on medion laptop */ 9340 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9341 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9342 /* enable unsolicited event */ 9343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9344 { } 9345}; 9346 9347static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 9348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9349 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9350 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9351 { } /* end */ 9352}; 9353 9354static void alc888_6st_dell_setup(struct hda_codec *codec) 9355{ 9356 struct alc_spec *spec = codec->spec; 9357 9358 spec->autocfg.hp_pins[0] = 0x1b; 9359 spec->autocfg.speaker_pins[0] = 0x14; 9360 spec->autocfg.speaker_pins[1] = 0x15; 9361 spec->autocfg.speaker_pins[2] = 0x16; 9362 spec->autocfg.speaker_pins[3] = 0x17; 9363} 9364 9365static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9366{ 9367 struct alc_spec *spec = codec->spec; 9368 9369 spec->autocfg.hp_pins[0] = 0x1b; 9370 spec->autocfg.speaker_pins[0] = 0x14; 9371 spec->autocfg.speaker_pins[1] = 0x15; 9372 spec->autocfg.speaker_pins[2] = 0x16; 9373 spec->autocfg.speaker_pins[3] = 0x17; 9374 spec->autocfg.speaker_pins[4] = 0x1a; 9375} 9376 9377static void alc883_vaiott_setup(struct hda_codec *codec) 9378{ 9379 struct alc_spec *spec = codec->spec; 9380 9381 spec->autocfg.hp_pins[0] = 0x15; 9382 spec->autocfg.speaker_pins[0] = 0x14; 9383 spec->autocfg.speaker_pins[1] = 0x17; 9384} 9385 9386static struct hda_verb alc888_asus_m90v_verbs[] = { 9387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9390 /* enable unsolicited event */ 9391 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9392 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9393 { } /* end */ 9394}; 9395 9396static void alc883_mode2_setup(struct hda_codec *codec) 9397{ 9398 struct alc_spec *spec = codec->spec; 9399 9400 spec->autocfg.hp_pins[0] = 0x1b; 9401 spec->autocfg.speaker_pins[0] = 0x14; 9402 spec->autocfg.speaker_pins[1] = 0x15; 9403 spec->autocfg.speaker_pins[2] = 0x16; 9404 spec->ext_mic.pin = 0x18; 9405 spec->int_mic.pin = 0x19; 9406 spec->ext_mic.mux_idx = 0; 9407 spec->int_mic.mux_idx = 1; 9408 spec->auto_mic = 1; 9409} 9410 9411static struct hda_verb alc888_asus_eee1601_verbs[] = { 9412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9417 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9418 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9419 /* enable unsolicited event */ 9420 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9421 { } /* end */ 9422}; 9423 9424static void alc883_eee1601_inithook(struct hda_codec *codec) 9425{ 9426 struct alc_spec *spec = codec->spec; 9427 9428 spec->autocfg.hp_pins[0] = 0x14; 9429 spec->autocfg.speaker_pins[0] = 0x1b; 9430 alc_automute_pin(codec); 9431} 9432 9433static struct hda_verb alc889A_mb31_verbs[] = { 9434 /* Init rear pin (used as headphone output) */ 9435 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 9436 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 9437 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9438 /* Init line pin (used as output in 4ch and 6ch mode) */ 9439 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 9440 /* Init line 2 pin (used as headphone out by default) */ 9441 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 9442 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 9443 { } /* end */ 9444}; 9445 9446/* Mute speakers according to the headphone jack state */ 9447static void alc889A_mb31_automute(struct hda_codec *codec) 9448{ 9449 unsigned int present; 9450 9451 /* Mute only in 2ch or 4ch mode */ 9452 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 9453 == 0x00) { 9454 present = snd_hda_jack_detect(codec, 0x15); 9455 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 9456 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9457 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 9458 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 9459 } 9460} 9461 9462static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 9463{ 9464 if ((res >> 26) == ALC880_HP_EVENT) 9465 alc889A_mb31_automute(codec); 9466} 9467 9468 9469#ifdef CONFIG_SND_HDA_POWER_SAVE 9470#define alc882_loopbacks alc880_loopbacks 9471#endif 9472 9473/* pcm configuration: identical with ALC880 */ 9474#define alc882_pcm_analog_playback alc880_pcm_analog_playback 9475#define alc882_pcm_analog_capture alc880_pcm_analog_capture 9476#define alc882_pcm_digital_playback alc880_pcm_digital_playback 9477#define alc882_pcm_digital_capture alc880_pcm_digital_capture 9478 9479static hda_nid_t alc883_slave_dig_outs[] = { 9480 ALC1200_DIGOUT_NID, 0, 9481}; 9482 9483static hda_nid_t alc1200_slave_dig_outs[] = { 9484 ALC883_DIGOUT_NID, 0, 9485}; 9486 9487/* 9488 * configuration and preset 9489 */ 9490static const char *alc882_models[ALC882_MODEL_LAST] = { 9491 [ALC882_3ST_DIG] = "3stack-dig", 9492 [ALC882_6ST_DIG] = "6stack-dig", 9493 [ALC882_ARIMA] = "arima", 9494 [ALC882_W2JC] = "w2jc", 9495 [ALC882_TARGA] = "targa", 9496 [ALC882_ASUS_A7J] = "asus-a7j", 9497 [ALC882_ASUS_A7M] = "asus-a7m", 9498 [ALC885_MACPRO] = "macpro", 9499 [ALC885_MB5] = "mb5", 9500 [ALC885_MACMINI3] = "macmini3", 9501 [ALC885_MBA21] = "mba21", 9502 [ALC885_MBP3] = "mbp3", 9503 [ALC885_IMAC24] = "imac24", 9504 [ALC885_IMAC91] = "imac91", 9505 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 9506 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 9507 [ALC883_3ST_6ch] = "3stack-6ch", 9508 [ALC883_6ST_DIG] = "alc883-6stack-dig", 9509 [ALC883_TARGA_DIG] = "targa-dig", 9510 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 9511 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 9512 [ALC883_ACER] = "acer", 9513 [ALC883_ACER_ASPIRE] = "acer-aspire", 9514 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 9515 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 9516 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9517 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9518 [ALC883_MEDION] = "medion", 9519 [ALC883_MEDION_MD2] = "medion-md2", 9520 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9521 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9522 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9523 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 9524 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 9525 [ALC888_LENOVO_SKY] = "lenovo-sky", 9526 [ALC883_HAIER_W66] = "haier-w66", 9527 [ALC888_3ST_HP] = "3stack-hp", 9528 [ALC888_6ST_DELL] = "6stack-dell", 9529 [ALC883_MITAC] = "mitac", 9530 [ALC883_CLEVO_M540R] = "clevo-m540r", 9531 [ALC883_CLEVO_M720] = "clevo-m720", 9532 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 9533 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 9534 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 9535 [ALC889A_INTEL] = "intel-alc889a", 9536 [ALC889_INTEL] = "intel-x58", 9537 [ALC1200_ASUS_P5Q] = "asus-p5q", 9538 [ALC889A_MB31] = "mb31", 9539 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 9540 [ALC882_AUTO] = "auto", 9541}; 9542 9543static struct snd_pci_quirk alc882_cfg_tbl[] = { 9544 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 9545 9546 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 9547 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 9548 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 9549 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 9550 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 9551 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 9552 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 9553 ALC888_ACER_ASPIRE_4930G), 9554 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 9555 ALC888_ACER_ASPIRE_4930G), 9556 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 9557 ALC888_ACER_ASPIRE_8930G), 9558 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 9559 ALC888_ACER_ASPIRE_8930G), 9560 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 9561 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 9562 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 9563 ALC888_ACER_ASPIRE_6530G), 9564 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 9565 ALC888_ACER_ASPIRE_6530G), 9566 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 9567 ALC888_ACER_ASPIRE_7730G), 9568 /* default Acer -- disabled as it causes more problems. 9569 * model=auto should work fine now 9570 */ 9571 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 9572 9573 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 9574 9575 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 9576 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 9577 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 9578 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 9579 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 9580 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 9581 9582 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 9583 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 9584 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 9585 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 9586 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 9587 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 9588 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 9589 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 9590 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 9591 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 9592 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 9593 9594 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 9595 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 9596 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 9597 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 9598 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 9599 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 9600 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 9601 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 9602 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 9603 9604 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 9605 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 9606 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 9607 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 9608 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 9609 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 9610 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 9611 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 9612 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 9613 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 9614 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 9615 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 9616 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 9617 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 9618 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 9619 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 9620 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 9621 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 9622 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 9623 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 9624 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 9625 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 9626 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 9627 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 9628 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 9629 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 9630 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 9631 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 9632 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 9633 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 9634 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 9635 9636 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 9637 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 9638 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 9639 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 9640 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 9641 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 9642 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 9643 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 9644 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 9645 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 9646 ALC883_FUJITSU_PI2515), 9647 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 9648 ALC888_FUJITSU_XA3530), 9649 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 9650 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9651 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9652 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 9653 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 9654 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), 9655 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 9656 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 9657 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 9658 9659 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 9660 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 9661 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 9662 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 9663 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 9664 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 9665 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 9666 9667 {} 9668}; 9669 9670/* codec SSID table for Intel Mac */ 9671static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 9672 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 9673 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 9674 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 9675 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 9676 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 9677 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 9678 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 9679 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 9680 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 9681 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 9682 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 9683 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 9684 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 9685 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 9686 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 9687 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 9688 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 9689 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 9690 * so apparently no perfect solution yet 9691 */ 9692 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9693 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9694 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 9695 {} /* terminator */ 9696}; 9697 9698static struct alc_config_preset alc882_presets[] = { 9699 [ALC882_3ST_DIG] = { 9700 .mixers = { alc882_base_mixer }, 9701 .init_verbs = { alc882_base_init_verbs, 9702 alc882_adc1_init_verbs }, 9703 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9704 .dac_nids = alc882_dac_nids, 9705 .dig_out_nid = ALC882_DIGOUT_NID, 9706 .dig_in_nid = ALC882_DIGIN_NID, 9707 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9708 .channel_mode = alc882_ch_modes, 9709 .need_dac_fix = 1, 9710 .input_mux = &alc882_capture_source, 9711 }, 9712 [ALC882_6ST_DIG] = { 9713 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9714 .init_verbs = { alc882_base_init_verbs, 9715 alc882_adc1_init_verbs }, 9716 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9717 .dac_nids = alc882_dac_nids, 9718 .dig_out_nid = ALC882_DIGOUT_NID, 9719 .dig_in_nid = ALC882_DIGIN_NID, 9720 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9721 .channel_mode = alc882_sixstack_modes, 9722 .input_mux = &alc882_capture_source, 9723 }, 9724 [ALC882_ARIMA] = { 9725 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 9726 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9727 alc882_eapd_verbs }, 9728 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9729 .dac_nids = alc882_dac_nids, 9730 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 9731 .channel_mode = alc882_sixstack_modes, 9732 .input_mux = &alc882_capture_source, 9733 }, 9734 [ALC882_W2JC] = { 9735 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 9736 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9737 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 9738 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9739 .dac_nids = alc882_dac_nids, 9740 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9741 .channel_mode = alc880_threestack_modes, 9742 .need_dac_fix = 1, 9743 .input_mux = &alc882_capture_source, 9744 .dig_out_nid = ALC882_DIGOUT_NID, 9745 }, 9746 [ALC885_MBA21] = { 9747 .mixers = { alc885_mba21_mixer }, 9748 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 9749 .num_dacs = 2, 9750 .dac_nids = alc882_dac_nids, 9751 .channel_mode = alc885_mba21_ch_modes, 9752 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9753 .input_mux = &alc882_capture_source, 9754 .unsol_event = alc_automute_amp_unsol_event, 9755 .setup = alc885_mba21_setup, 9756 .init_hook = alc_automute_amp, 9757 }, 9758 [ALC885_MBP3] = { 9759 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9760 .init_verbs = { alc885_mbp3_init_verbs, 9761 alc880_gpio1_init_verbs }, 9762 .num_dacs = 2, 9763 .dac_nids = alc882_dac_nids, 9764 .hp_nid = 0x04, 9765 .channel_mode = alc885_mbp_4ch_modes, 9766 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 9767 .input_mux = &alc882_capture_source, 9768 .dig_out_nid = ALC882_DIGOUT_NID, 9769 .dig_in_nid = ALC882_DIGIN_NID, 9770 .unsol_event = alc_automute_amp_unsol_event, 9771 .setup = alc885_mbp3_setup, 9772 .init_hook = alc_automute_amp, 9773 }, 9774 [ALC885_MB5] = { 9775 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 9776 .init_verbs = { alc885_mb5_init_verbs, 9777 alc880_gpio1_init_verbs }, 9778 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9779 .dac_nids = alc882_dac_nids, 9780 .channel_mode = alc885_mb5_6ch_modes, 9781 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 9782 .input_mux = &mb5_capture_source, 9783 .dig_out_nid = ALC882_DIGOUT_NID, 9784 .dig_in_nid = ALC882_DIGIN_NID, 9785 .unsol_event = alc_automute_amp_unsol_event, 9786 .setup = alc885_mb5_setup, 9787 .init_hook = alc_automute_amp, 9788 }, 9789 [ALC885_MACMINI3] = { 9790 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 9791 .init_verbs = { alc885_macmini3_init_verbs, 9792 alc880_gpio1_init_verbs }, 9793 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9794 .dac_nids = alc882_dac_nids, 9795 .channel_mode = alc885_macmini3_6ch_modes, 9796 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 9797 .input_mux = &macmini3_capture_source, 9798 .dig_out_nid = ALC882_DIGOUT_NID, 9799 .dig_in_nid = ALC882_DIGIN_NID, 9800 .unsol_event = alc_automute_amp_unsol_event, 9801 .setup = alc885_macmini3_setup, 9802 .init_hook = alc_automute_amp, 9803 }, 9804 [ALC885_MACPRO] = { 9805 .mixers = { alc882_macpro_mixer }, 9806 .init_verbs = { alc882_macpro_init_verbs }, 9807 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9808 .dac_nids = alc882_dac_nids, 9809 .dig_out_nid = ALC882_DIGOUT_NID, 9810 .dig_in_nid = ALC882_DIGIN_NID, 9811 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9812 .channel_mode = alc882_ch_modes, 9813 .input_mux = &alc882_capture_source, 9814 .init_hook = alc885_macpro_init_hook, 9815 }, 9816 [ALC885_IMAC24] = { 9817 .mixers = { alc885_imac24_mixer }, 9818 .init_verbs = { alc885_imac24_init_verbs }, 9819 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9820 .dac_nids = alc882_dac_nids, 9821 .dig_out_nid = ALC882_DIGOUT_NID, 9822 .dig_in_nid = ALC882_DIGIN_NID, 9823 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 9824 .channel_mode = alc882_ch_modes, 9825 .input_mux = &alc882_capture_source, 9826 .unsol_event = alc_automute_amp_unsol_event, 9827 .setup = alc885_imac24_setup, 9828 .init_hook = alc885_imac24_init_hook, 9829 }, 9830 [ALC885_IMAC91] = { 9831 .mixers = {alc885_imac91_mixer}, 9832 .init_verbs = { alc885_imac91_init_verbs, 9833 alc880_gpio1_init_verbs }, 9834 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9835 .dac_nids = alc882_dac_nids, 9836 .channel_mode = alc885_mba21_ch_modes, 9837 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 9838 .input_mux = &alc889A_imac91_capture_source, 9839 .dig_out_nid = ALC882_DIGOUT_NID, 9840 .dig_in_nid = ALC882_DIGIN_NID, 9841 .unsol_event = alc_automute_amp_unsol_event, 9842 .setup = alc885_imac91_setup, 9843 .init_hook = alc_automute_amp, 9844 }, 9845 [ALC882_TARGA] = { 9846 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9847 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9848 alc880_gpio3_init_verbs, alc882_targa_verbs}, 9849 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9850 .dac_nids = alc882_dac_nids, 9851 .dig_out_nid = ALC882_DIGOUT_NID, 9852 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9853 .adc_nids = alc882_adc_nids, 9854 .capsrc_nids = alc882_capsrc_nids, 9855 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9856 .channel_mode = alc882_3ST_6ch_modes, 9857 .need_dac_fix = 1, 9858 .input_mux = &alc882_capture_source, 9859 .unsol_event = alc882_targa_unsol_event, 9860 .setup = alc882_targa_setup, 9861 .init_hook = alc882_targa_automute, 9862 }, 9863 [ALC882_ASUS_A7J] = { 9864 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 9865 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9866 alc882_asus_a7j_verbs}, 9867 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9868 .dac_nids = alc882_dac_nids, 9869 .dig_out_nid = ALC882_DIGOUT_NID, 9870 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 9871 .adc_nids = alc882_adc_nids, 9872 .capsrc_nids = alc882_capsrc_nids, 9873 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 9874 .channel_mode = alc882_3ST_6ch_modes, 9875 .need_dac_fix = 1, 9876 .input_mux = &alc882_capture_source, 9877 }, 9878 [ALC882_ASUS_A7M] = { 9879 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 9880 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 9881 alc882_eapd_verbs, alc880_gpio1_init_verbs, 9882 alc882_asus_a7m_verbs }, 9883 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 9884 .dac_nids = alc882_dac_nids, 9885 .dig_out_nid = ALC882_DIGOUT_NID, 9886 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 9887 .channel_mode = alc880_threestack_modes, 9888 .need_dac_fix = 1, 9889 .input_mux = &alc882_capture_source, 9890 }, 9891 [ALC883_3ST_2ch_DIG] = { 9892 .mixers = { alc883_3ST_2ch_mixer }, 9893 .init_verbs = { alc883_init_verbs }, 9894 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9895 .dac_nids = alc883_dac_nids, 9896 .dig_out_nid = ALC883_DIGOUT_NID, 9897 .dig_in_nid = ALC883_DIGIN_NID, 9898 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 9899 .channel_mode = alc883_3ST_2ch_modes, 9900 .input_mux = &alc883_capture_source, 9901 }, 9902 [ALC883_3ST_6ch_DIG] = { 9903 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9904 .init_verbs = { alc883_init_verbs }, 9905 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9906 .dac_nids = alc883_dac_nids, 9907 .dig_out_nid = ALC883_DIGOUT_NID, 9908 .dig_in_nid = ALC883_DIGIN_NID, 9909 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9910 .channel_mode = alc883_3ST_6ch_modes, 9911 .need_dac_fix = 1, 9912 .input_mux = &alc883_capture_source, 9913 }, 9914 [ALC883_3ST_6ch] = { 9915 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9916 .init_verbs = { alc883_init_verbs }, 9917 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9918 .dac_nids = alc883_dac_nids, 9919 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9920 .channel_mode = alc883_3ST_6ch_modes, 9921 .need_dac_fix = 1, 9922 .input_mux = &alc883_capture_source, 9923 }, 9924 [ALC883_3ST_6ch_INTEL] = { 9925 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 9926 .init_verbs = { alc883_init_verbs }, 9927 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9928 .dac_nids = alc883_dac_nids, 9929 .dig_out_nid = ALC883_DIGOUT_NID, 9930 .dig_in_nid = ALC883_DIGIN_NID, 9931 .slave_dig_outs = alc883_slave_dig_outs, 9932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 9933 .channel_mode = alc883_3ST_6ch_intel_modes, 9934 .need_dac_fix = 1, 9935 .input_mux = &alc883_3stack_6ch_intel, 9936 }, 9937 [ALC889A_INTEL] = { 9938 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9939 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 9940 alc_hp15_unsol_verbs }, 9941 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9942 .dac_nids = alc883_dac_nids, 9943 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9944 .adc_nids = alc889_adc_nids, 9945 .dig_out_nid = ALC883_DIGOUT_NID, 9946 .dig_in_nid = ALC883_DIGIN_NID, 9947 .slave_dig_outs = alc883_slave_dig_outs, 9948 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9949 .channel_mode = alc889_8ch_intel_modes, 9950 .capsrc_nids = alc889_capsrc_nids, 9951 .input_mux = &alc889_capture_source, 9952 .setup = alc889_automute_setup, 9953 .init_hook = alc_automute_amp, 9954 .unsol_event = alc_automute_amp_unsol_event, 9955 .need_dac_fix = 1, 9956 }, 9957 [ALC889_INTEL] = { 9958 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 9959 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 9960 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 9961 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9962 .dac_nids = alc883_dac_nids, 9963 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9964 .adc_nids = alc889_adc_nids, 9965 .dig_out_nid = ALC883_DIGOUT_NID, 9966 .dig_in_nid = ALC883_DIGIN_NID, 9967 .slave_dig_outs = alc883_slave_dig_outs, 9968 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 9969 .channel_mode = alc889_8ch_intel_modes, 9970 .capsrc_nids = alc889_capsrc_nids, 9971 .input_mux = &alc889_capture_source, 9972 .setup = alc889_automute_setup, 9973 .init_hook = alc889_intel_init_hook, 9974 .unsol_event = alc_automute_amp_unsol_event, 9975 .need_dac_fix = 1, 9976 }, 9977 [ALC883_6ST_DIG] = { 9978 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9979 .init_verbs = { alc883_init_verbs }, 9980 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9981 .dac_nids = alc883_dac_nids, 9982 .dig_out_nid = ALC883_DIGOUT_NID, 9983 .dig_in_nid = ALC883_DIGIN_NID, 9984 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 9985 .channel_mode = alc883_sixstack_modes, 9986 .input_mux = &alc883_capture_source, 9987 }, 9988 [ALC883_TARGA_DIG] = { 9989 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 9990 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 9991 alc883_targa_verbs}, 9992 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 9993 .dac_nids = alc883_dac_nids, 9994 .dig_out_nid = ALC883_DIGOUT_NID, 9995 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 9996 .channel_mode = alc883_3ST_6ch_modes, 9997 .need_dac_fix = 1, 9998 .input_mux = &alc883_capture_source, 9999 .unsol_event = alc883_targa_unsol_event, 10000 .setup = alc882_targa_setup, 10001 .init_hook = alc882_targa_automute, 10002 }, 10003 [ALC883_TARGA_2ch_DIG] = { 10004 .mixers = { alc883_targa_2ch_mixer}, 10005 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10006 alc883_targa_verbs}, 10007 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10008 .dac_nids = alc883_dac_nids, 10009 .adc_nids = alc883_adc_nids_alt, 10010 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10011 .capsrc_nids = alc883_capsrc_nids, 10012 .dig_out_nid = ALC883_DIGOUT_NID, 10013 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10014 .channel_mode = alc883_3ST_2ch_modes, 10015 .input_mux = &alc883_capture_source, 10016 .unsol_event = alc883_targa_unsol_event, 10017 .setup = alc882_targa_setup, 10018 .init_hook = alc882_targa_automute, 10019 }, 10020 [ALC883_TARGA_8ch_DIG] = { 10021 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10022 alc883_chmode_mixer }, 10023 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10024 alc883_targa_verbs }, 10025 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10026 .dac_nids = alc883_dac_nids, 10027 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10028 .adc_nids = alc883_adc_nids_rev, 10029 .capsrc_nids = alc883_capsrc_nids_rev, 10030 .dig_out_nid = ALC883_DIGOUT_NID, 10031 .dig_in_nid = ALC883_DIGIN_NID, 10032 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10033 .channel_mode = alc883_4ST_8ch_modes, 10034 .need_dac_fix = 1, 10035 .input_mux = &alc883_capture_source, 10036 .unsol_event = alc883_targa_unsol_event, 10037 .setup = alc882_targa_setup, 10038 .init_hook = alc882_targa_automute, 10039 }, 10040 [ALC883_ACER] = { 10041 .mixers = { alc883_base_mixer }, 10042 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10043 * and the headphone jack. Turn this on and rely on the 10044 * standard mute methods whenever the user wants to turn 10045 * these outputs off. 10046 */ 10047 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10048 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10049 .dac_nids = alc883_dac_nids, 10050 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10051 .channel_mode = alc883_3ST_2ch_modes, 10052 .input_mux = &alc883_capture_source, 10053 }, 10054 [ALC883_ACER_ASPIRE] = { 10055 .mixers = { alc883_acer_aspire_mixer }, 10056 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10057 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10058 .dac_nids = alc883_dac_nids, 10059 .dig_out_nid = ALC883_DIGOUT_NID, 10060 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10061 .channel_mode = alc883_3ST_2ch_modes, 10062 .input_mux = &alc883_capture_source, 10063 .unsol_event = alc_automute_amp_unsol_event, 10064 .setup = alc883_acer_aspire_setup, 10065 .init_hook = alc_automute_amp, 10066 }, 10067 [ALC888_ACER_ASPIRE_4930G] = { 10068 .mixers = { alc888_base_mixer, 10069 alc883_chmode_mixer }, 10070 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10071 alc888_acer_aspire_4930g_verbs }, 10072 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10073 .dac_nids = alc883_dac_nids, 10074 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10075 .adc_nids = alc883_adc_nids_rev, 10076 .capsrc_nids = alc883_capsrc_nids_rev, 10077 .dig_out_nid = ALC883_DIGOUT_NID, 10078 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10079 .channel_mode = alc883_3ST_6ch_modes, 10080 .need_dac_fix = 1, 10081 .const_channel_count = 6, 10082 .num_mux_defs = 10083 ARRAY_SIZE(alc888_2_capture_sources), 10084 .input_mux = alc888_2_capture_sources, 10085 .unsol_event = alc_automute_amp_unsol_event, 10086 .setup = alc888_acer_aspire_4930g_setup, 10087 .init_hook = alc_automute_amp, 10088 }, 10089 [ALC888_ACER_ASPIRE_6530G] = { 10090 .mixers = { alc888_acer_aspire_6530_mixer }, 10091 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10092 alc888_acer_aspire_6530g_verbs }, 10093 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10094 .dac_nids = alc883_dac_nids, 10095 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10096 .adc_nids = alc883_adc_nids_rev, 10097 .capsrc_nids = alc883_capsrc_nids_rev, 10098 .dig_out_nid = ALC883_DIGOUT_NID, 10099 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10100 .channel_mode = alc883_3ST_2ch_modes, 10101 .num_mux_defs = 10102 ARRAY_SIZE(alc888_2_capture_sources), 10103 .input_mux = alc888_acer_aspire_6530_sources, 10104 .unsol_event = alc_automute_amp_unsol_event, 10105 .setup = alc888_acer_aspire_6530g_setup, 10106 .init_hook = alc_automute_amp, 10107 }, 10108 [ALC888_ACER_ASPIRE_8930G] = { 10109 .mixers = { alc889_acer_aspire_8930g_mixer, 10110 alc883_chmode_mixer }, 10111 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10112 alc889_acer_aspire_8930g_verbs, 10113 alc889_eapd_verbs}, 10114 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10115 .dac_nids = alc883_dac_nids, 10116 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10117 .adc_nids = alc889_adc_nids, 10118 .capsrc_nids = alc889_capsrc_nids, 10119 .dig_out_nid = ALC883_DIGOUT_NID, 10120 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10121 .channel_mode = alc883_3ST_6ch_modes, 10122 .need_dac_fix = 1, 10123 .const_channel_count = 6, 10124 .num_mux_defs = 10125 ARRAY_SIZE(alc889_capture_sources), 10126 .input_mux = alc889_capture_sources, 10127 .unsol_event = alc_automute_amp_unsol_event, 10128 .setup = alc889_acer_aspire_8930g_setup, 10129 .init_hook = alc_automute_amp, 10130#ifdef CONFIG_SND_HDA_POWER_SAVE 10131 .power_hook = alc_power_eapd, 10132#endif 10133 }, 10134 [ALC888_ACER_ASPIRE_7730G] = { 10135 .mixers = { alc883_3ST_6ch_mixer, 10136 alc883_chmode_mixer }, 10137 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10138 alc888_acer_aspire_7730G_verbs }, 10139 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10140 .dac_nids = alc883_dac_nids, 10141 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10142 .adc_nids = alc883_adc_nids_rev, 10143 .capsrc_nids = alc883_capsrc_nids_rev, 10144 .dig_out_nid = ALC883_DIGOUT_NID, 10145 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10146 .channel_mode = alc883_3ST_6ch_modes, 10147 .need_dac_fix = 1, 10148 .const_channel_count = 6, 10149 .input_mux = &alc883_capture_source, 10150 .unsol_event = alc_automute_amp_unsol_event, 10151 .setup = alc888_acer_aspire_6530g_setup, 10152 .init_hook = alc_automute_amp, 10153 }, 10154 [ALC883_MEDION] = { 10155 .mixers = { alc883_fivestack_mixer, 10156 alc883_chmode_mixer }, 10157 .init_verbs = { alc883_init_verbs, 10158 alc883_medion_eapd_verbs }, 10159 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10160 .dac_nids = alc883_dac_nids, 10161 .adc_nids = alc883_adc_nids_alt, 10162 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10163 .capsrc_nids = alc883_capsrc_nids, 10164 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10165 .channel_mode = alc883_sixstack_modes, 10166 .input_mux = &alc883_capture_source, 10167 }, 10168 [ALC883_MEDION_MD2] = { 10169 .mixers = { alc883_medion_md2_mixer}, 10170 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, 10171 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10172 .dac_nids = alc883_dac_nids, 10173 .dig_out_nid = ALC883_DIGOUT_NID, 10174 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10175 .channel_mode = alc883_3ST_2ch_modes, 10176 .input_mux = &alc883_capture_source, 10177 .unsol_event = alc_automute_amp_unsol_event, 10178 .setup = alc883_medion_md2_setup, 10179 .init_hook = alc_automute_amp, 10180 }, 10181 [ALC883_MEDION_WIM2160] = { 10182 .mixers = { alc883_medion_wim2160_mixer }, 10183 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10184 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10185 .dac_nids = alc883_dac_nids, 10186 .dig_out_nid = ALC883_DIGOUT_NID, 10187 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10188 .adc_nids = alc883_adc_nids, 10189 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10190 .channel_mode = alc883_3ST_2ch_modes, 10191 .input_mux = &alc883_capture_source, 10192 .unsol_event = alc_automute_amp_unsol_event, 10193 .setup = alc883_medion_wim2160_setup, 10194 .init_hook = alc_automute_amp, 10195 }, 10196 [ALC883_LAPTOP_EAPD] = { 10197 .mixers = { alc883_base_mixer }, 10198 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10199 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10200 .dac_nids = alc883_dac_nids, 10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10202 .channel_mode = alc883_3ST_2ch_modes, 10203 .input_mux = &alc883_capture_source, 10204 }, 10205 [ALC883_CLEVO_M540R] = { 10206 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10207 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10208 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10209 .dac_nids = alc883_dac_nids, 10210 .dig_out_nid = ALC883_DIGOUT_NID, 10211 .dig_in_nid = ALC883_DIGIN_NID, 10212 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10213 .channel_mode = alc883_3ST_6ch_clevo_modes, 10214 .need_dac_fix = 1, 10215 .input_mux = &alc883_capture_source, 10216 /* This machine has the hardware HP auto-muting, thus 10217 * we need no software mute via unsol event 10218 */ 10219 }, 10220 [ALC883_CLEVO_M720] = { 10221 .mixers = { alc883_clevo_m720_mixer }, 10222 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10223 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10224 .dac_nids = alc883_dac_nids, 10225 .dig_out_nid = ALC883_DIGOUT_NID, 10226 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10227 .channel_mode = alc883_3ST_2ch_modes, 10228 .input_mux = &alc883_capture_source, 10229 .unsol_event = alc883_clevo_m720_unsol_event, 10230 .setup = alc883_clevo_m720_setup, 10231 .init_hook = alc883_clevo_m720_init_hook, 10232 }, 10233 [ALC883_LENOVO_101E_2ch] = { 10234 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10235 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10236 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10237 .dac_nids = alc883_dac_nids, 10238 .adc_nids = alc883_adc_nids_alt, 10239 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10240 .capsrc_nids = alc883_capsrc_nids, 10241 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10242 .channel_mode = alc883_3ST_2ch_modes, 10243 .input_mux = &alc883_lenovo_101e_capture_source, 10244 .unsol_event = alc883_lenovo_101e_unsol_event, 10245 .init_hook = alc883_lenovo_101e_all_automute, 10246 }, 10247 [ALC883_LENOVO_NB0763] = { 10248 .mixers = { alc883_lenovo_nb0763_mixer }, 10249 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10250 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10251 .dac_nids = alc883_dac_nids, 10252 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10253 .channel_mode = alc883_3ST_2ch_modes, 10254 .need_dac_fix = 1, 10255 .input_mux = &alc883_lenovo_nb0763_capture_source, 10256 .unsol_event = alc_automute_amp_unsol_event, 10257 .setup = alc883_medion_md2_setup, 10258 .init_hook = alc_automute_amp, 10259 }, 10260 [ALC888_LENOVO_MS7195_DIG] = { 10261 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10262 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10264 .dac_nids = alc883_dac_nids, 10265 .dig_out_nid = ALC883_DIGOUT_NID, 10266 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10267 .channel_mode = alc883_3ST_6ch_modes, 10268 .need_dac_fix = 1, 10269 .input_mux = &alc883_capture_source, 10270 .unsol_event = alc883_lenovo_ms7195_unsol_event, 10271 .init_hook = alc888_lenovo_ms7195_front_automute, 10272 }, 10273 [ALC883_HAIER_W66] = { 10274 .mixers = { alc883_targa_2ch_mixer}, 10275 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10276 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10277 .dac_nids = alc883_dac_nids, 10278 .dig_out_nid = ALC883_DIGOUT_NID, 10279 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10280 .channel_mode = alc883_3ST_2ch_modes, 10281 .input_mux = &alc883_capture_source, 10282 .unsol_event = alc_automute_amp_unsol_event, 10283 .setup = alc883_haier_w66_setup, 10284 .init_hook = alc_automute_amp, 10285 }, 10286 [ALC888_3ST_HP] = { 10287 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10288 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10289 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10290 .dac_nids = alc883_dac_nids, 10291 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10292 .channel_mode = alc888_3st_hp_modes, 10293 .need_dac_fix = 1, 10294 .input_mux = &alc883_capture_source, 10295 .unsol_event = alc_automute_amp_unsol_event, 10296 .setup = alc888_3st_hp_setup, 10297 .init_hook = alc_automute_amp, 10298 }, 10299 [ALC888_6ST_DELL] = { 10300 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10301 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10302 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10303 .dac_nids = alc883_dac_nids, 10304 .dig_out_nid = ALC883_DIGOUT_NID, 10305 .dig_in_nid = ALC883_DIGIN_NID, 10306 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10307 .channel_mode = alc883_sixstack_modes, 10308 .input_mux = &alc883_capture_source, 10309 .unsol_event = alc_automute_amp_unsol_event, 10310 .setup = alc888_6st_dell_setup, 10311 .init_hook = alc_automute_amp, 10312 }, 10313 [ALC883_MITAC] = { 10314 .mixers = { alc883_mitac_mixer }, 10315 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10316 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10317 .dac_nids = alc883_dac_nids, 10318 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10319 .channel_mode = alc883_3ST_2ch_modes, 10320 .input_mux = &alc883_capture_source, 10321 .unsol_event = alc_automute_amp_unsol_event, 10322 .setup = alc883_mitac_setup, 10323 .init_hook = alc_automute_amp, 10324 }, 10325 [ALC883_FUJITSU_PI2515] = { 10326 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10327 .init_verbs = { alc883_init_verbs, 10328 alc883_2ch_fujitsu_pi2515_verbs}, 10329 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10330 .dac_nids = alc883_dac_nids, 10331 .dig_out_nid = ALC883_DIGOUT_NID, 10332 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10333 .channel_mode = alc883_3ST_2ch_modes, 10334 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10335 .unsol_event = alc_automute_amp_unsol_event, 10336 .setup = alc883_2ch_fujitsu_pi2515_setup, 10337 .init_hook = alc_automute_amp, 10338 }, 10339 [ALC888_FUJITSU_XA3530] = { 10340 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10341 .init_verbs = { alc883_init_verbs, 10342 alc888_fujitsu_xa3530_verbs }, 10343 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10344 .dac_nids = alc883_dac_nids, 10345 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10346 .adc_nids = alc883_adc_nids_rev, 10347 .capsrc_nids = alc883_capsrc_nids_rev, 10348 .dig_out_nid = ALC883_DIGOUT_NID, 10349 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10350 .channel_mode = alc888_4ST_8ch_intel_modes, 10351 .num_mux_defs = 10352 ARRAY_SIZE(alc888_2_capture_sources), 10353 .input_mux = alc888_2_capture_sources, 10354 .unsol_event = alc_automute_amp_unsol_event, 10355 .setup = alc888_fujitsu_xa3530_setup, 10356 .init_hook = alc_automute_amp, 10357 }, 10358 [ALC888_LENOVO_SKY] = { 10359 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10360 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10361 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10362 .dac_nids = alc883_dac_nids, 10363 .dig_out_nid = ALC883_DIGOUT_NID, 10364 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10365 .channel_mode = alc883_sixstack_modes, 10366 .need_dac_fix = 1, 10367 .input_mux = &alc883_lenovo_sky_capture_source, 10368 .unsol_event = alc_automute_amp_unsol_event, 10369 .setup = alc888_lenovo_sky_setup, 10370 .init_hook = alc_automute_amp, 10371 }, 10372 [ALC888_ASUS_M90V] = { 10373 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10374 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10375 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10376 .dac_nids = alc883_dac_nids, 10377 .dig_out_nid = ALC883_DIGOUT_NID, 10378 .dig_in_nid = ALC883_DIGIN_NID, 10379 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10380 .channel_mode = alc883_3ST_6ch_modes, 10381 .need_dac_fix = 1, 10382 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10383 .unsol_event = alc_sku_unsol_event, 10384 .setup = alc883_mode2_setup, 10385 .init_hook = alc_inithook, 10386 }, 10387 [ALC888_ASUS_EEE1601] = { 10388 .mixers = { alc883_asus_eee1601_mixer }, 10389 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10390 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10391 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10392 .dac_nids = alc883_dac_nids, 10393 .dig_out_nid = ALC883_DIGOUT_NID, 10394 .dig_in_nid = ALC883_DIGIN_NID, 10395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10396 .channel_mode = alc883_3ST_2ch_modes, 10397 .need_dac_fix = 1, 10398 .input_mux = &alc883_asus_eee1601_capture_source, 10399 .unsol_event = alc_sku_unsol_event, 10400 .init_hook = alc883_eee1601_inithook, 10401 }, 10402 [ALC1200_ASUS_P5Q] = { 10403 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10404 .init_verbs = { alc883_init_verbs }, 10405 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10406 .dac_nids = alc883_dac_nids, 10407 .dig_out_nid = ALC1200_DIGOUT_NID, 10408 .dig_in_nid = ALC883_DIGIN_NID, 10409 .slave_dig_outs = alc1200_slave_dig_outs, 10410 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10411 .channel_mode = alc883_sixstack_modes, 10412 .input_mux = &alc883_capture_source, 10413 }, 10414 [ALC889A_MB31] = { 10415 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10416 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10417 alc880_gpio1_init_verbs }, 10418 .adc_nids = alc883_adc_nids, 10419 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10420 .capsrc_nids = alc883_capsrc_nids, 10421 .dac_nids = alc883_dac_nids, 10422 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10423 .channel_mode = alc889A_mb31_6ch_modes, 10424 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10425 .input_mux = &alc889A_mb31_capture_source, 10426 .dig_out_nid = ALC883_DIGOUT_NID, 10427 .unsol_event = alc889A_mb31_unsol_event, 10428 .init_hook = alc889A_mb31_automute, 10429 }, 10430 [ALC883_SONY_VAIO_TT] = { 10431 .mixers = { alc883_vaiott_mixer }, 10432 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10434 .dac_nids = alc883_dac_nids, 10435 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10436 .channel_mode = alc883_3ST_2ch_modes, 10437 .input_mux = &alc883_capture_source, 10438 .unsol_event = alc_automute_amp_unsol_event, 10439 .setup = alc883_vaiott_setup, 10440 .init_hook = alc_automute_amp, 10441 }, 10442}; 10443 10444 10445/* 10446 * Pin config fixes 10447 */ 10448enum { 10449 PINFIX_ABIT_AW9D_MAX, 10450 PINFIX_PB_M5210, 10451}; 10452 10453static struct alc_pincfg alc882_abit_aw9d_pinfix[] = { 10454 { 0x15, 0x01080104 }, /* side */ 10455 { 0x16, 0x01011012 }, /* rear */ 10456 { 0x17, 0x01016011 }, /* clfe */ 10457 { } 10458}; 10459 10460static const struct hda_verb pb_m5210_verbs[] = { 10461 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10462 {} 10463}; 10464 10465static const struct alc_fixup alc882_fixups[] = { 10466 [PINFIX_ABIT_AW9D_MAX] = { 10467 .pins = alc882_abit_aw9d_pinfix 10468 }, 10469 [PINFIX_PB_M5210] = { 10470 .verbs = pb_m5210_verbs 10471 }, 10472}; 10473 10474static struct snd_pci_quirk alc882_fixup_tbl[] = { 10475 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 10476 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 10477 {} 10478}; 10479 10480/* 10481 * BIOS auto configuration 10482 */ 10483static int alc882_auto_create_input_ctls(struct hda_codec *codec, 10484 const struct auto_pin_cfg *cfg) 10485{ 10486 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 10487} 10488 10489static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 10490 hda_nid_t nid, int pin_type, 10491 hda_nid_t dac) 10492{ 10493 int idx; 10494 10495 /* set as output */ 10496 alc_set_pin_output(codec, nid, pin_type); 10497 10498 if (dac == 0x25) 10499 idx = 4; 10500 else if (dac >= 0x02 && dac <= 0x05) 10501 idx = dac - 2; 10502 else 10503 return; 10504 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 10505} 10506 10507static void alc882_auto_init_multi_out(struct hda_codec *codec) 10508{ 10509 struct alc_spec *spec = codec->spec; 10510 int i; 10511 10512 for (i = 0; i <= HDA_SIDE; i++) { 10513 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 10514 int pin_type = get_pin_type(spec->autocfg.line_out_type); 10515 if (nid) 10516 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 10517 spec->multiout.dac_nids[i]); 10518 } 10519} 10520 10521static void alc882_auto_init_hp_out(struct hda_codec *codec) 10522{ 10523 struct alc_spec *spec = codec->spec; 10524 hda_nid_t pin, dac; 10525 10526 pin = spec->autocfg.hp_pins[0]; 10527 if (pin) { 10528 dac = spec->multiout.hp_nid; 10529 if (!dac) 10530 dac = spec->multiout.dac_nids[0]; /* to front */ 10531 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 10532 } 10533 pin = spec->autocfg.speaker_pins[0]; 10534 if (pin) { 10535 dac = spec->multiout.extra_out_nid[0]; 10536 if (!dac) 10537 dac = spec->multiout.dac_nids[0]; /* to front */ 10538 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 10539 } 10540} 10541 10542static void alc882_auto_init_analog_input(struct hda_codec *codec) 10543{ 10544 struct alc_spec *spec = codec->spec; 10545 int i; 10546 10547 for (i = 0; i < AUTO_PIN_LAST; i++) { 10548 hda_nid_t nid = spec->autocfg.input_pins[i]; 10549 if (!nid) 10550 continue; 10551 alc_set_input_pin(codec, nid, i); 10552 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 10553 snd_hda_codec_write(codec, nid, 0, 10554 AC_VERB_SET_AMP_GAIN_MUTE, 10555 AMP_OUT_MUTE); 10556 } 10557} 10558 10559static void alc882_auto_init_input_src(struct hda_codec *codec) 10560{ 10561 struct alc_spec *spec = codec->spec; 10562 int c; 10563 10564 for (c = 0; c < spec->num_adc_nids; c++) { 10565 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 10566 hda_nid_t nid = spec->capsrc_nids[c]; 10567 unsigned int mux_idx; 10568 const struct hda_input_mux *imux; 10569 int conns, mute, idx, item; 10570 10571 conns = snd_hda_get_connections(codec, nid, conn_list, 10572 ARRAY_SIZE(conn_list)); 10573 if (conns < 0) 10574 continue; 10575 mux_idx = c >= spec->num_mux_defs ? 0 : c; 10576 imux = &spec->input_mux[mux_idx]; 10577 if (!imux->num_items && mux_idx > 0) 10578 imux = &spec->input_mux[0]; 10579 for (idx = 0; idx < conns; idx++) { 10580 /* if the current connection is the selected one, 10581 * unmute it as default - otherwise mute it 10582 */ 10583 mute = AMP_IN_MUTE(idx); 10584 for (item = 0; item < imux->num_items; item++) { 10585 if (imux->items[item].index == idx) { 10586 if (spec->cur_mux[c] == item) 10587 mute = AMP_IN_UNMUTE(idx); 10588 break; 10589 } 10590 } 10591 /* check if we have a selector or mixer 10592 * we could check for the widget type instead, but 10593 * just check for Amp-In presence (in case of mixer 10594 * without amp-in there is something wrong, this 10595 * function shouldn't be used or capsrc nid is wrong) 10596 */ 10597 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 10598 snd_hda_codec_write(codec, nid, 0, 10599 AC_VERB_SET_AMP_GAIN_MUTE, 10600 mute); 10601 else if (mute != AMP_IN_MUTE(idx)) 10602 snd_hda_codec_write(codec, nid, 0, 10603 AC_VERB_SET_CONNECT_SEL, 10604 idx); 10605 } 10606 } 10607} 10608 10609/* add mic boosts if needed */ 10610static int alc_auto_add_mic_boost(struct hda_codec *codec) 10611{ 10612 struct alc_spec *spec = codec->spec; 10613 int err; 10614 hda_nid_t nid; 10615 10616 nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 10617 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 10618 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10619 "Mic Boost", 10620 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10621 if (err < 0) 10622 return err; 10623 } 10624 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 10625 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) { 10626 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10627 "Front Mic Boost", 10628 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10629 if (err < 0) 10630 return err; 10631 } 10632 return 0; 10633} 10634 10635/* almost identical with ALC880 parser... */ 10636static int alc882_parse_auto_config(struct hda_codec *codec) 10637{ 10638 struct alc_spec *spec = codec->spec; 10639 static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 10640 int err; 10641 10642 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 10643 alc882_ignore); 10644 if (err < 0) 10645 return err; 10646 if (!spec->autocfg.line_outs) 10647 return 0; /* can't find valid BIOS pin config */ 10648 10649 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10650 if (err < 0) 10651 return err; 10652 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10653 if (err < 0) 10654 return err; 10655 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10656 "Headphone"); 10657 if (err < 0) 10658 return err; 10659 err = alc880_auto_create_extra_out(spec, 10660 spec->autocfg.speaker_pins[0], 10661 "Speaker"); 10662 if (err < 0) 10663 return err; 10664 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 10665 if (err < 0) 10666 return err; 10667 10668 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10669 10670 alc_auto_parse_digital(codec); 10671 10672 if (spec->kctls.list) 10673 add_mixer(spec, spec->kctls.list); 10674 10675 add_verb(spec, alc883_auto_init_verbs); 10676 /* if ADC 0x07 is available, initialize it, too */ 10677 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 10678 add_verb(spec, alc882_adc1_init_verbs); 10679 10680 spec->num_mux_defs = 1; 10681 spec->input_mux = &spec->private_imux[0]; 10682 10683 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 10684 10685 err = alc_auto_add_mic_boost(codec); 10686 if (err < 0) 10687 return err; 10688 10689 return 1; /* config found */ 10690} 10691 10692/* additional initialization for auto-configuration model */ 10693static void alc882_auto_init(struct hda_codec *codec) 10694{ 10695 struct alc_spec *spec = codec->spec; 10696 alc882_auto_init_multi_out(codec); 10697 alc882_auto_init_hp_out(codec); 10698 alc882_auto_init_analog_input(codec); 10699 alc882_auto_init_input_src(codec); 10700 alc_auto_init_digital(codec); 10701 if (spec->unsol_event) 10702 alc_inithook(codec); 10703} 10704 10705static int patch_alc882(struct hda_codec *codec) 10706{ 10707 struct alc_spec *spec; 10708 int err, board_config; 10709 10710 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 10711 if (spec == NULL) 10712 return -ENOMEM; 10713 10714 codec->spec = spec; 10715 10716 alc_auto_parse_customize_define(codec); 10717 10718 switch (codec->vendor_id) { 10719 case 0x10ec0882: 10720 case 0x10ec0885: 10721 break; 10722 default: 10723 /* ALC883 and variants */ 10724 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 10725 break; 10726 } 10727 10728 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 10729 alc882_models, 10730 alc882_cfg_tbl); 10731 10732 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 10733 board_config = snd_hda_check_board_codec_sid_config(codec, 10734 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 10735 10736 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 10737 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 10738 codec->chip_name); 10739 board_config = ALC882_AUTO; 10740 } 10741 10742 if (board_config == ALC882_AUTO) 10743 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 10744 10745 if (board_config == ALC882_AUTO) { 10746 /* automatic parse from the BIOS config */ 10747 err = alc882_parse_auto_config(codec); 10748 if (err < 0) { 10749 alc_free(codec); 10750 return err; 10751 } else if (!err) { 10752 printk(KERN_INFO 10753 "hda_codec: Cannot set up configuration " 10754 "from BIOS. Using base mode...\n"); 10755 board_config = ALC882_3ST_DIG; 10756 } 10757 } 10758 10759 if (has_cdefine_beep(codec)) { 10760 err = snd_hda_attach_beep_device(codec, 0x1); 10761 if (err < 0) { 10762 alc_free(codec); 10763 return err; 10764 } 10765 } 10766 10767 if (board_config != ALC882_AUTO) 10768 setup_preset(codec, &alc882_presets[board_config]); 10769 10770 spec->stream_analog_playback = &alc882_pcm_analog_playback; 10771 spec->stream_analog_capture = &alc882_pcm_analog_capture; 10772 /* FIXME: setup DAC5 */ 10773 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 10774 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 10775 10776 spec->stream_digital_playback = &alc882_pcm_digital_playback; 10777 spec->stream_digital_capture = &alc882_pcm_digital_capture; 10778 10779 if (!spec->adc_nids && spec->input_mux) { 10780 int i, j; 10781 spec->num_adc_nids = 0; 10782 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 10783 const struct hda_input_mux *imux = spec->input_mux; 10784 hda_nid_t cap; 10785 hda_nid_t items[16]; 10786 hda_nid_t nid = alc882_adc_nids[i]; 10787 unsigned int wcap = get_wcaps(codec, nid); 10788 /* get type */ 10789 wcap = get_wcaps_type(wcap); 10790 if (wcap != AC_WID_AUD_IN) 10791 continue; 10792 spec->private_adc_nids[spec->num_adc_nids] = nid; 10793 err = snd_hda_get_connections(codec, nid, &cap, 1); 10794 if (err < 0) 10795 continue; 10796 err = snd_hda_get_connections(codec, cap, items, 10797 ARRAY_SIZE(items)); 10798 if (err < 0) 10799 continue; 10800 for (j = 0; j < imux->num_items; j++) 10801 if (imux->items[j].index >= err) 10802 break; 10803 if (j < imux->num_items) 10804 continue; 10805 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 10806 spec->num_adc_nids++; 10807 } 10808 spec->adc_nids = spec->private_adc_nids; 10809 spec->capsrc_nids = spec->private_capsrc_nids; 10810 } 10811 10812 set_capture_mixer(codec); 10813 10814 if (has_cdefine_beep(codec)) 10815 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 10816 10817 if (board_config == ALC882_AUTO) 10818 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); 10819 10820 spec->vmaster_nid = 0x0c; 10821 10822 codec->patch_ops = alc_patch_ops; 10823 if (board_config == ALC882_AUTO) 10824 spec->init_hook = alc882_auto_init; 10825#ifdef CONFIG_SND_HDA_POWER_SAVE 10826 if (!spec->loopback.amplist) 10827 spec->loopback.amplist = alc882_loopbacks; 10828#endif 10829 10830 return 0; 10831} 10832 10833 10834/* 10835 * ALC262 support 10836 */ 10837 10838#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 10839#define ALC262_DIGIN_NID ALC880_DIGIN_NID 10840 10841#define alc262_dac_nids alc260_dac_nids 10842#define alc262_adc_nids alc882_adc_nids 10843#define alc262_adc_nids_alt alc882_adc_nids_alt 10844#define alc262_capsrc_nids alc882_capsrc_nids 10845#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 10846 10847#define alc262_modes alc260_modes 10848#define alc262_capture_source alc882_capture_source 10849 10850static hda_nid_t alc262_dmic_adc_nids[1] = { 10851 /* ADC0 */ 10852 0x09 10853}; 10854 10855static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 10856 10857static struct snd_kcontrol_new alc262_base_mixer[] = { 10858 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10859 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10860 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10861 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10862 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10863 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10864 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10865 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10866 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10867 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10868 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10869 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 10871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10872 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 10873 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 10874 { } /* end */ 10875}; 10876 10877/* update HP, line and mono-out pins according to the master switch */ 10878static void alc262_hp_master_update(struct hda_codec *codec) 10879{ 10880 struct alc_spec *spec = codec->spec; 10881 int val = spec->master_sw; 10882 10883 /* HP & line-out */ 10884 snd_hda_codec_write_cache(codec, 0x1b, 0, 10885 AC_VERB_SET_PIN_WIDGET_CONTROL, 10886 val ? PIN_HP : 0); 10887 snd_hda_codec_write_cache(codec, 0x15, 0, 10888 AC_VERB_SET_PIN_WIDGET_CONTROL, 10889 val ? PIN_HP : 0); 10890 /* mono (speaker) depending on the HP jack sense */ 10891 val = val && !spec->jack_present; 10892 snd_hda_codec_write_cache(codec, 0x16, 0, 10893 AC_VERB_SET_PIN_WIDGET_CONTROL, 10894 val ? PIN_OUT : 0); 10895} 10896 10897static void alc262_hp_bpc_automute(struct hda_codec *codec) 10898{ 10899 struct alc_spec *spec = codec->spec; 10900 10901 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 10902 alc262_hp_master_update(codec); 10903} 10904 10905static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) 10906{ 10907 if ((res >> 26) != ALC880_HP_EVENT) 10908 return; 10909 alc262_hp_bpc_automute(codec); 10910} 10911 10912static void alc262_hp_wildwest_automute(struct hda_codec *codec) 10913{ 10914 struct alc_spec *spec = codec->spec; 10915 10916 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 10917 alc262_hp_master_update(codec); 10918} 10919 10920static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, 10921 unsigned int res) 10922{ 10923 if ((res >> 26) != ALC880_HP_EVENT) 10924 return; 10925 alc262_hp_wildwest_automute(codec); 10926} 10927 10928#define alc262_hp_master_sw_get alc260_hp_master_sw_get 10929 10930static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, 10931 struct snd_ctl_elem_value *ucontrol) 10932{ 10933 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 10934 struct alc_spec *spec = codec->spec; 10935 int val = !!*ucontrol->value.integer.value; 10936 10937 if (val == spec->master_sw) 10938 return 0; 10939 spec->master_sw = val; 10940 alc262_hp_master_update(codec); 10941 return 1; 10942} 10943 10944#define ALC262_HP_MASTER_SWITCH \ 10945 { \ 10946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 10947 .name = "Master Playback Switch", \ 10948 .info = snd_ctl_boolean_mono_info, \ 10949 .get = alc262_hp_master_sw_get, \ 10950 .put = alc262_hp_master_sw_put, \ 10951 }, \ 10952 { \ 10953 .iface = NID_MAPPING, \ 10954 .name = "Master Playback Switch", \ 10955 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 10956 } 10957 10958 10959static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 10960 ALC262_HP_MASTER_SWITCH, 10961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10962 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10964 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10965 HDA_OUTPUT), 10966 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10967 HDA_OUTPUT), 10968 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 10969 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 10970 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 10971 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 10972 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 10973 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 10974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 10975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 10976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 10978 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 10979 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 10980 { } /* end */ 10981}; 10982 10983static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 10984 ALC262_HP_MASTER_SWITCH, 10985 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10986 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 10987 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 10988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 10989 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 10990 HDA_OUTPUT), 10991 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 10992 HDA_OUTPUT), 10993 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 10994 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 10995 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 10996 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 10997 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 10998 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 10999 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11000 { } /* end */ 11001}; 11002 11003static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11004 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11005 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11006 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11007 { } /* end */ 11008}; 11009 11010/* mute/unmute internal speaker according to the hp jack and mute state */ 11011static void alc262_hp_t5735_setup(struct hda_codec *codec) 11012{ 11013 struct alc_spec *spec = codec->spec; 11014 11015 spec->autocfg.hp_pins[0] = 0x15; 11016 spec->autocfg.speaker_pins[0] = 0x14; 11017} 11018 11019static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11020 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11021 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11022 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11023 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11026 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11027 { } /* end */ 11028}; 11029 11030static struct hda_verb alc262_hp_t5735_verbs[] = { 11031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11033 11034 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11035 { } 11036}; 11037 11038static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11039 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11040 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11041 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11042 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11045 { } /* end */ 11046}; 11047 11048static struct hda_verb alc262_hp_rp5700_verbs[] = { 11049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11050 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11051 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11052 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11053 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11054 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11059 {} 11060}; 11061 11062static struct hda_input_mux alc262_hp_rp5700_capture_source = { 11063 .num_items = 1, 11064 .items = { 11065 { "Line", 0x1 }, 11066 }, 11067}; 11068 11069/* bind hp and internal speaker mute (with plug check) as master switch */ 11070static void alc262_hippo_master_update(struct hda_codec *codec) 11071{ 11072 struct alc_spec *spec = codec->spec; 11073 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11074 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 11075 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 11076 unsigned int mute; 11077 11078 /* HP */ 11079 mute = spec->master_sw ? 0 : HDA_AMP_MUTE; 11080 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, 11081 HDA_AMP_MUTE, mute); 11082 /* mute internal speaker per jack sense */ 11083 if (spec->jack_present) 11084 mute = HDA_AMP_MUTE; 11085 if (line_nid) 11086 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, 11087 HDA_AMP_MUTE, mute); 11088 if (speaker_nid && speaker_nid != line_nid) 11089 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, 11090 HDA_AMP_MUTE, mute); 11091} 11092 11093#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11094 11095static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, 11096 struct snd_ctl_elem_value *ucontrol) 11097{ 11098 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11099 struct alc_spec *spec = codec->spec; 11100 int val = !!*ucontrol->value.integer.value; 11101 11102 if (val == spec->master_sw) 11103 return 0; 11104 spec->master_sw = val; 11105 alc262_hippo_master_update(codec); 11106 return 1; 11107} 11108 11109#define ALC262_HIPPO_MASTER_SWITCH \ 11110 { \ 11111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11112 .name = "Master Playback Switch", \ 11113 .info = snd_ctl_boolean_mono_info, \ 11114 .get = alc262_hippo_master_sw_get, \ 11115 .put = alc262_hippo_master_sw_put, \ 11116 }, \ 11117 { \ 11118 .iface = NID_MAPPING, \ 11119 .name = "Master Playback Switch", \ 11120 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11121 (SUBDEV_SPEAKER(0) << 16), \ 11122 } 11123 11124static struct snd_kcontrol_new alc262_hippo_mixer[] = { 11125 ALC262_HIPPO_MASTER_SWITCH, 11126 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11133 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11134 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11135 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11136 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11137 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11138 { } /* end */ 11139}; 11140 11141static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11142 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11143 ALC262_HIPPO_MASTER_SWITCH, 11144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11150 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11153 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11154 { } /* end */ 11155}; 11156 11157/* mute/unmute internal speaker according to the hp jack and mute state */ 11158static void alc262_hippo_automute(struct hda_codec *codec) 11159{ 11160 struct alc_spec *spec = codec->spec; 11161 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 11162 11163 spec->jack_present = snd_hda_jack_detect(codec, hp_nid); 11164 alc262_hippo_master_update(codec); 11165} 11166 11167static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) 11168{ 11169 if ((res >> 26) != ALC880_HP_EVENT) 11170 return; 11171 alc262_hippo_automute(codec); 11172} 11173 11174static void alc262_hippo_setup(struct hda_codec *codec) 11175{ 11176 struct alc_spec *spec = codec->spec; 11177 11178 spec->autocfg.hp_pins[0] = 0x15; 11179 spec->autocfg.speaker_pins[0] = 0x14; 11180} 11181 11182static void alc262_hippo1_setup(struct hda_codec *codec) 11183{ 11184 struct alc_spec *spec = codec->spec; 11185 11186 spec->autocfg.hp_pins[0] = 0x1b; 11187 spec->autocfg.speaker_pins[0] = 0x14; 11188} 11189 11190 11191static struct snd_kcontrol_new alc262_sony_mixer[] = { 11192 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11193 ALC262_HIPPO_MASTER_SWITCH, 11194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11196 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11197 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11198 { } /* end */ 11199}; 11200 11201static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11202 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11203 ALC262_HIPPO_MASTER_SWITCH, 11204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11207 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11208 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11209 { } /* end */ 11210}; 11211 11212static struct snd_kcontrol_new alc262_tyan_mixer[] = { 11213 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11214 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11215 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11216 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11220 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11221 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11223 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11224 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11225 { } /* end */ 11226}; 11227 11228static struct hda_verb alc262_tyan_verbs[] = { 11229 /* Headphone automute */ 11230 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11232 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11233 11234 /* P11 AUX_IN, white 4-pin connector */ 11235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11236 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11237 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11238 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11239 11240 {} 11241}; 11242 11243/* unsolicited event for HP jack sensing */ 11244static void alc262_tyan_setup(struct hda_codec *codec) 11245{ 11246 struct alc_spec *spec = codec->spec; 11247 11248 spec->autocfg.hp_pins[0] = 0x1b; 11249 spec->autocfg.speaker_pins[0] = 0x15; 11250} 11251 11252 11253#define alc262_capture_mixer alc882_capture_mixer 11254#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11255 11256/* 11257 * generic initialization of ADC, input mixers and output mixers 11258 */ 11259static struct hda_verb alc262_init_verbs[] = { 11260 /* 11261 * Unmute ADC0-2 and set the default input to mic-in 11262 */ 11263 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11265 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11267 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11269 11270 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11271 * mixer widget 11272 * Note: PASD motherboards uses the Line In 2 as the input for 11273 * front panel mic (mic 2) 11274 */ 11275 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11276 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11277 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11278 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11279 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11280 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11281 11282 /* 11283 * Set up output mixers (0x0c - 0x0e) 11284 */ 11285 /* set vol=0 to output mixers */ 11286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11287 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11288 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11289 /* set up input amps for analog loopback */ 11290 /* Amp Indices: DAC = 0, mixer = 1 */ 11291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11292 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11293 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11294 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11295 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11296 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11297 11298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11300 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11302 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11303 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11304 11305 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11307 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11308 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11309 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11310 11311 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11313 11314 /* FIXME: use matrix-type input source selection */ 11315 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11316 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11321 /* Input mixer2 */ 11322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11323 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11326 /* Input mixer3 */ 11327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11331 11332 { } 11333}; 11334 11335static struct hda_verb alc262_eapd_verbs[] = { 11336 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11337 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11338 { } 11339}; 11340 11341static struct hda_verb alc262_hippo1_unsol_verbs[] = { 11342 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11343 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11344 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11345 11346 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11348 {} 11349}; 11350 11351static struct hda_verb alc262_sony_unsol_verbs[] = { 11352 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11355 11356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11357 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11358 {} 11359}; 11360 11361static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11365 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11366 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11367 { } /* end */ 11368}; 11369 11370static struct hda_verb alc262_toshiba_s06_verbs[] = { 11371 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11374 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11375 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11376 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11377 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11378 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11379 {} 11380}; 11381 11382static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11383{ 11384 struct alc_spec *spec = codec->spec; 11385 11386 spec->autocfg.hp_pins[0] = 0x15; 11387 spec->autocfg.speaker_pins[0] = 0x14; 11388 spec->ext_mic.pin = 0x18; 11389 spec->ext_mic.mux_idx = 0; 11390 spec->int_mic.pin = 0x12; 11391 spec->int_mic.mux_idx = 9; 11392 spec->auto_mic = 1; 11393} 11394 11395/* 11396 * nec model 11397 * 0x15 = headphone 11398 * 0x16 = internal speaker 11399 * 0x18 = external mic 11400 */ 11401 11402static struct snd_kcontrol_new alc262_nec_mixer[] = { 11403 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11404 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11405 11406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11408 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11409 11410 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11412 { } /* end */ 11413}; 11414 11415static struct hda_verb alc262_nec_verbs[] = { 11416 /* Unmute Speaker */ 11417 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11418 11419 /* Headphone */ 11420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11422 11423 /* External mic to headphone */ 11424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11425 /* External mic to speaker */ 11426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11427 {} 11428}; 11429 11430/* 11431 * fujitsu model 11432 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11433 * 0x1b = port replicator headphone out 11434 */ 11435 11436#define ALC_HP_EVENT 0x37 11437 11438static struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11441 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11442 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11443 {} 11444}; 11445 11446static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11447 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11448 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11449 {} 11450}; 11451 11452static struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11453 /* Front Mic pin: input vref at 50% */ 11454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11456 {} 11457}; 11458 11459static struct hda_input_mux alc262_fujitsu_capture_source = { 11460 .num_items = 3, 11461 .items = { 11462 { "Mic", 0x0 }, 11463 { "Int Mic", 0x1 }, 11464 { "CD", 0x4 }, 11465 }, 11466}; 11467 11468static struct hda_input_mux alc262_HP_capture_source = { 11469 .num_items = 5, 11470 .items = { 11471 { "Mic", 0x0 }, 11472 { "Front Mic", 0x1 }, 11473 { "Line", 0x2 }, 11474 { "CD", 0x4 }, 11475 { "AUX IN", 0x6 }, 11476 }, 11477}; 11478 11479static struct hda_input_mux alc262_HP_D7000_capture_source = { 11480 .num_items = 4, 11481 .items = { 11482 { "Mic", 0x0 }, 11483 { "Front Mic", 0x2 }, 11484 { "Line", 0x1 }, 11485 { "CD", 0x4 }, 11486 }, 11487}; 11488 11489/* mute/unmute internal speaker according to the hp jacks and mute state */ 11490static void alc262_fujitsu_automute(struct hda_codec *codec, int force) 11491{ 11492 struct alc_spec *spec = codec->spec; 11493 unsigned int mute; 11494 11495 if (force || !spec->sense_updated) { 11496 spec->jack_present = snd_hda_jack_detect(codec, 0x14) || 11497 snd_hda_jack_detect(codec, 0x1b); 11498 spec->sense_updated = 1; 11499 } 11500 /* unmute internal speaker only if both HPs are unplugged and 11501 * master switch is on 11502 */ 11503 if (spec->jack_present) 11504 mute = HDA_AMP_MUTE; 11505 else 11506 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 11507 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11508 HDA_AMP_MUTE, mute); 11509} 11510 11511/* unsolicited event for HP jack sensing */ 11512static void alc262_fujitsu_unsol_event(struct hda_codec *codec, 11513 unsigned int res) 11514{ 11515 if ((res >> 26) != ALC_HP_EVENT) 11516 return; 11517 alc262_fujitsu_automute(codec, 1); 11518} 11519 11520static void alc262_fujitsu_init_hook(struct hda_codec *codec) 11521{ 11522 alc262_fujitsu_automute(codec, 1); 11523} 11524 11525/* bind volumes of both NID 0x0c and 0x0d */ 11526static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 11527 .ops = &snd_hda_bind_vol, 11528 .values = { 11529 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 11530 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 11531 0 11532 }, 11533}; 11534 11535/* mute/unmute internal speaker according to the hp jack and mute state */ 11536static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) 11537{ 11538 struct alc_spec *spec = codec->spec; 11539 unsigned int mute; 11540 11541 if (force || !spec->sense_updated) { 11542 spec->jack_present = snd_hda_jack_detect(codec, 0x1b); 11543 spec->sense_updated = 1; 11544 } 11545 if (spec->jack_present) { 11546 /* mute internal speaker */ 11547 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11548 HDA_AMP_MUTE, HDA_AMP_MUTE); 11549 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11550 HDA_AMP_MUTE, HDA_AMP_MUTE); 11551 } else { 11552 /* unmute internal speaker if necessary */ 11553 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); 11554 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11555 HDA_AMP_MUTE, mute); 11556 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 11557 HDA_AMP_MUTE, mute); 11558 } 11559} 11560 11561/* unsolicited event for HP jack sensing */ 11562static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, 11563 unsigned int res) 11564{ 11565 if ((res >> 26) != ALC_HP_EVENT) 11566 return; 11567 alc262_lenovo_3000_automute(codec, 1); 11568} 11569 11570static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, 11571 int dir, int idx, long *valp) 11572{ 11573 int i, change = 0; 11574 11575 for (i = 0; i < 2; i++, valp++) 11576 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, 11577 HDA_AMP_MUTE, 11578 *valp ? 0 : HDA_AMP_MUTE); 11579 return change; 11580} 11581 11582/* bind hp and internal speaker mute (with plug check) */ 11583static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, 11584 struct snd_ctl_elem_value *ucontrol) 11585{ 11586 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11587 long *valp = ucontrol->value.integer.value; 11588 int change; 11589 11590 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 11591 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11592 if (change) 11593 alc262_fujitsu_automute(codec, 0); 11594 return change; 11595} 11596 11597static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 11598 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11599 { 11600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11601 .name = "Master Playback Switch", 11602 .subdevice = HDA_SUBDEV_AMP_FLAG, 11603 .info = snd_hda_mixer_amp_switch_info, 11604 .get = snd_hda_mixer_amp_switch_get, 11605 .put = alc262_fujitsu_master_sw_put, 11606 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 11607 }, 11608 { 11609 .iface = NID_MAPPING, 11610 .name = "Master Playback Switch", 11611 .private_value = 0x1b, 11612 }, 11613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11618 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11619 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11620 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11621 { } /* end */ 11622}; 11623 11624/* bind hp and internal speaker mute (with plug check) */ 11625static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, 11626 struct snd_ctl_elem_value *ucontrol) 11627{ 11628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11629 long *valp = ucontrol->value.integer.value; 11630 int change; 11631 11632 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); 11633 if (change) 11634 alc262_lenovo_3000_automute(codec, 0); 11635 return change; 11636} 11637 11638static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 11639 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11640 { 11641 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11642 .name = "Master Playback Switch", 11643 .subdevice = HDA_SUBDEV_AMP_FLAG, 11644 .info = snd_hda_mixer_amp_switch_info, 11645 .get = snd_hda_mixer_amp_switch_get, 11646 .put = alc262_lenovo_3000_master_sw_put, 11647 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 11648 }, 11649 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11650 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11651 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11654 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11655 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11656 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11657 { } /* end */ 11658}; 11659 11660static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 11661 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 11662 ALC262_HIPPO_MASTER_SWITCH, 11663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11665 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11666 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11667 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11668 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11669 { } /* end */ 11670}; 11671 11672/* additional init verbs for Benq laptops */ 11673static struct hda_verb alc262_EAPD_verbs[] = { 11674 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11675 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 11676 {} 11677}; 11678 11679static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 11680 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11681 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11682 11683 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 11684 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 11685 {} 11686}; 11687 11688/* Samsung Q1 Ultra Vista model setup */ 11689static struct snd_kcontrol_new alc262_ultra_mixer[] = { 11690 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11691 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11694 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11695 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11696 { } /* end */ 11697}; 11698 11699static struct hda_verb alc262_ultra_verbs[] = { 11700 /* output mixer */ 11701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11704 /* speaker */ 11705 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11706 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11708 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11709 /* HP */ 11710 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11711 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11713 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11714 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11715 /* internal mic */ 11716 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 11717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11718 /* ADC, choose mic */ 11719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11720 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11721 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11722 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11723 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11724 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11725 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11726 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11727 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 11728 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 11729 {} 11730}; 11731 11732/* mute/unmute internal speaker according to the hp jack and mute state */ 11733static void alc262_ultra_automute(struct hda_codec *codec) 11734{ 11735 struct alc_spec *spec = codec->spec; 11736 unsigned int mute; 11737 11738 mute = 0; 11739 /* auto-mute only when HP is used as HP */ 11740 if (!spec->cur_mux[0]) { 11741 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 11742 if (spec->jack_present) 11743 mute = HDA_AMP_MUTE; 11744 } 11745 /* mute/unmute internal speaker */ 11746 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 11747 HDA_AMP_MUTE, mute); 11748 /* mute/unmute HP */ 11749 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 11750 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 11751} 11752 11753/* unsolicited event for HP jack sensing */ 11754static void alc262_ultra_unsol_event(struct hda_codec *codec, 11755 unsigned int res) 11756{ 11757 if ((res >> 26) != ALC880_HP_EVENT) 11758 return; 11759 alc262_ultra_automute(codec); 11760} 11761 11762static struct hda_input_mux alc262_ultra_capture_source = { 11763 .num_items = 2, 11764 .items = { 11765 { "Mic", 0x1 }, 11766 { "Headphone", 0x7 }, 11767 }, 11768}; 11769 11770static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 11771 struct snd_ctl_elem_value *ucontrol) 11772{ 11773 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 11774 struct alc_spec *spec = codec->spec; 11775 int ret; 11776 11777 ret = alc_mux_enum_put(kcontrol, ucontrol); 11778 if (!ret) 11779 return 0; 11780 /* reprogram the HP pin as mic or HP according to the input source */ 11781 snd_hda_codec_write_cache(codec, 0x15, 0, 11782 AC_VERB_SET_PIN_WIDGET_CONTROL, 11783 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 11784 alc262_ultra_automute(codec); /* mute/unmute HP */ 11785 return ret; 11786} 11787 11788static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 11789 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 11790 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 11791 { 11792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 11793 .name = "Capture Source", 11794 .info = alc_mux_enum_info, 11795 .get = alc_mux_enum_get, 11796 .put = alc262_ultra_mux_enum_put, 11797 }, 11798 { 11799 .iface = NID_MAPPING, 11800 .name = "Capture Source", 11801 .private_value = 0x15, 11802 }, 11803 { } /* end */ 11804}; 11805 11806/* We use two mixers depending on the output pin; 0x16 is a mono output 11807 * and thus it's bound with a different mixer. 11808 * This function returns which mixer amp should be used. 11809 */ 11810static int alc262_check_volbit(hda_nid_t nid) 11811{ 11812 if (!nid) 11813 return 0; 11814 else if (nid == 0x16) 11815 return 2; 11816 else 11817 return 1; 11818} 11819 11820static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 11821 const char *pfx, int *vbits) 11822{ 11823 unsigned long val; 11824 int vbit; 11825 11826 vbit = alc262_check_volbit(nid); 11827 if (!vbit) 11828 return 0; 11829 if (*vbits & vbit) /* a volume control for this mixer already there */ 11830 return 0; 11831 *vbits |= vbit; 11832 if (vbit == 2) 11833 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 11834 else 11835 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 11836 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val); 11837} 11838 11839static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 11840 const char *pfx) 11841{ 11842 unsigned long val; 11843 11844 if (!nid) 11845 return 0; 11846 if (nid == 0x16) 11847 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 11848 else 11849 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 11850 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); 11851} 11852 11853/* add playback controls from the parsed DAC table */ 11854static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 11855 const struct auto_pin_cfg *cfg) 11856{ 11857 const char *pfx; 11858 int vbits; 11859 int err; 11860 11861 spec->multiout.num_dacs = 1; /* only use one dac */ 11862 spec->multiout.dac_nids = spec->private_dac_nids; 11863 spec->multiout.dac_nids[0] = 2; 11864 11865 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 11866 pfx = "Master"; 11867 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11868 pfx = "Speaker"; 11869 else 11870 pfx = "Front"; 11871 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx); 11872 if (err < 0) 11873 return err; 11874 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker"); 11875 if (err < 0) 11876 return err; 11877 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone"); 11878 if (err < 0) 11879 return err; 11880 11881 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 11882 alc262_check_volbit(cfg->speaker_pins[0]) | 11883 alc262_check_volbit(cfg->hp_pins[0]); 11884 if (vbits == 1 || vbits == 2) 11885 pfx = "Master"; /* only one mixer is used */ 11886 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 11887 pfx = "Speaker"; 11888 else 11889 pfx = "Front"; 11890 vbits = 0; 11891 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits); 11892 if (err < 0) 11893 return err; 11894 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker", 11895 &vbits); 11896 if (err < 0) 11897 return err; 11898 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone", 11899 &vbits); 11900 if (err < 0) 11901 return err; 11902 return 0; 11903} 11904 11905#define alc262_auto_create_input_ctls \ 11906 alc882_auto_create_input_ctls 11907 11908/* 11909 * generic initialization of ADC, input mixers and output mixers 11910 */ 11911static struct hda_verb alc262_volume_init_verbs[] = { 11912 /* 11913 * Unmute ADC0-2 and set the default input to mic-in 11914 */ 11915 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11917 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11918 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11921 11922 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11923 * mixer widget 11924 * Note: PASD motherboards uses the Line In 2 as the input for 11925 * front panel mic (mic 2) 11926 */ 11927 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11933 11934 /* 11935 * Set up output mixers (0x0c - 0x0f) 11936 */ 11937 /* set vol=0 to output mixers */ 11938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11939 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11940 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11941 11942 /* set up input amps for analog loopback */ 11943 /* Amp Indices: DAC = 0, mixer = 1 */ 11944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11948 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11950 11951 /* FIXME: use matrix-type input source selection */ 11952 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11953 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11955 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11956 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11957 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11958 /* Input mixer2 */ 11959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11960 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11961 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11962 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11963 /* Input mixer3 */ 11964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11965 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11966 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11967 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11968 11969 { } 11970}; 11971 11972static struct hda_verb alc262_HP_BPC_init_verbs[] = { 11973 /* 11974 * Unmute ADC0-2 and set the default input to mic-in 11975 */ 11976 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11978 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11979 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11980 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11982 11983 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11984 * mixer widget 11985 * Note: PASD motherboards uses the Line In 2 as the input for 11986 * front panel mic (mic 2) 11987 */ 11988 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11990 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11991 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11992 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11993 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11994 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 11995 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 11996 11997 /* 11998 * Set up output mixers (0x0c - 0x0e) 11999 */ 12000 /* set vol=0 to output mixers */ 12001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12002 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12004 12005 /* set up input amps for analog loopback */ 12006 /* Amp Indices: DAC = 0, mixer = 1 */ 12007 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12008 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12009 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12010 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12011 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12012 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12013 12014 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12017 12018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12020 12021 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12022 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12023 12024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12025 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12026 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12027 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12028 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12029 12030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12031 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12033 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12034 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12035 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12036 12037 12038 /* FIXME: use matrix-type input source selection */ 12039 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12040 /* Input mixer1: only unmute Mic */ 12041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12042 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12044 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12049 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12050 /* Input mixer2 */ 12051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12058 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12059 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12060 /* Input mixer3 */ 12061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12070 12071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12072 12073 { } 12074}; 12075 12076static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12077 /* 12078 * Unmute ADC0-2 and set the default input to mic-in 12079 */ 12080 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12082 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12083 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12084 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12085 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12086 12087 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12088 * mixer widget 12089 * Note: PASD motherboards uses the Line In 2 as the input for front 12090 * panel mic (mic 2) 12091 */ 12092 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12101 /* 12102 * Set up output mixers (0x0c - 0x0e) 12103 */ 12104 /* set vol=0 to output mixers */ 12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12108 12109 /* set up input amps for analog loopback */ 12110 /* Amp Indices: DAC = 0, mixer = 1 */ 12111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12114 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12117 12118 12119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12120 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12124 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12125 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12126 12127 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12128 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12129 12130 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12132 12133 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12137 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12138 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12139 12140 /* FIXME: use matrix-type input source selection */ 12141 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12142 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12148 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12150 /* Input mixer2 */ 12151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12155 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12156 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12158 /* Input mixer3 */ 12159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12160 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12164 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12166 12167 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12168 12169 { } 12170}; 12171 12172static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12173 12174 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12175 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12176 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12177 12178 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12180 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12182 12183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12184 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12185 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12186 {} 12187}; 12188 12189 12190#ifdef CONFIG_SND_HDA_POWER_SAVE 12191#define alc262_loopbacks alc880_loopbacks 12192#endif 12193 12194/* pcm configuration: identical with ALC880 */ 12195#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12196#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12197#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12198#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12199 12200/* 12201 * BIOS auto configuration 12202 */ 12203static int alc262_parse_auto_config(struct hda_codec *codec) 12204{ 12205 struct alc_spec *spec = codec->spec; 12206 int err; 12207 static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12208 12209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12210 alc262_ignore); 12211 if (err < 0) 12212 return err; 12213 if (!spec->autocfg.line_outs) { 12214 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12215 spec->multiout.max_channels = 2; 12216 spec->no_analog = 1; 12217 goto dig_only; 12218 } 12219 return 0; /* can't find valid BIOS pin config */ 12220 } 12221 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12222 if (err < 0) 12223 return err; 12224 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12225 if (err < 0) 12226 return err; 12227 12228 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12229 12230 dig_only: 12231 alc_auto_parse_digital(codec); 12232 12233 if (spec->kctls.list) 12234 add_mixer(spec, spec->kctls.list); 12235 12236 add_verb(spec, alc262_volume_init_verbs); 12237 spec->num_mux_defs = 1; 12238 spec->input_mux = &spec->private_imux[0]; 12239 12240 err = alc_auto_add_mic_boost(codec); 12241 if (err < 0) 12242 return err; 12243 12244 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12245 12246 return 1; 12247} 12248 12249#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12250#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12251#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12252#define alc262_auto_init_input_src alc882_auto_init_input_src 12253 12254 12255/* init callback for auto-configuration model -- overriding the default init */ 12256static void alc262_auto_init(struct hda_codec *codec) 12257{ 12258 struct alc_spec *spec = codec->spec; 12259 alc262_auto_init_multi_out(codec); 12260 alc262_auto_init_hp_out(codec); 12261 alc262_auto_init_analog_input(codec); 12262 alc262_auto_init_input_src(codec); 12263 alc_auto_init_digital(codec); 12264 if (spec->unsol_event) 12265 alc_inithook(codec); 12266} 12267 12268/* 12269 * configuration and preset 12270 */ 12271static const char *alc262_models[ALC262_MODEL_LAST] = { 12272 [ALC262_BASIC] = "basic", 12273 [ALC262_HIPPO] = "hippo", 12274 [ALC262_HIPPO_1] = "hippo_1", 12275 [ALC262_FUJITSU] = "fujitsu", 12276 [ALC262_HP_BPC] = "hp-bpc", 12277 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12278 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12279 [ALC262_HP_RP5700] = "hp-rp5700", 12280 [ALC262_BENQ_ED8] = "benq", 12281 [ALC262_BENQ_T31] = "benq-t31", 12282 [ALC262_SONY_ASSAMD] = "sony-assamd", 12283 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12284 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12285 [ALC262_ULTRA] = "ultra", 12286 [ALC262_LENOVO_3000] = "lenovo-3000", 12287 [ALC262_NEC] = "nec", 12288 [ALC262_TYAN] = "tyan", 12289 [ALC262_AUTO] = "auto", 12290}; 12291 12292static struct snd_pci_quirk alc262_cfg_tbl[] = { 12293 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12294 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12295 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12296 ALC262_HP_BPC), 12297 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12298 ALC262_HP_BPC), 12299 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12300 ALC262_HP_BPC), 12301 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12302 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12303 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12304 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12305 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12306 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12307 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12308 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12309 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12310 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12311 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12312 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12313 ALC262_HP_TC_T5735), 12314 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12315 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12316 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12317 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12318 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12319 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12320 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12321 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12322#if 0 /* disable the quirk since model=auto works better in recent versions */ 12323 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12324 ALC262_SONY_ASSAMD), 12325#endif 12326 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12327 ALC262_TOSHIBA_RX1), 12328 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12329 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12330 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12331 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12332 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12333 ALC262_ULTRA), 12334 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12335 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12336 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12337 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12338 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12339 {} 12340}; 12341 12342static struct alc_config_preset alc262_presets[] = { 12343 [ALC262_BASIC] = { 12344 .mixers = { alc262_base_mixer }, 12345 .init_verbs = { alc262_init_verbs }, 12346 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12347 .dac_nids = alc262_dac_nids, 12348 .hp_nid = 0x03, 12349 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12350 .channel_mode = alc262_modes, 12351 .input_mux = &alc262_capture_source, 12352 }, 12353 [ALC262_HIPPO] = { 12354 .mixers = { alc262_hippo_mixer }, 12355 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12356 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12357 .dac_nids = alc262_dac_nids, 12358 .hp_nid = 0x03, 12359 .dig_out_nid = ALC262_DIGOUT_NID, 12360 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12361 .channel_mode = alc262_modes, 12362 .input_mux = &alc262_capture_source, 12363 .unsol_event = alc262_hippo_unsol_event, 12364 .setup = alc262_hippo_setup, 12365 .init_hook = alc262_hippo_automute, 12366 }, 12367 [ALC262_HIPPO_1] = { 12368 .mixers = { alc262_hippo1_mixer }, 12369 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12370 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12371 .dac_nids = alc262_dac_nids, 12372 .hp_nid = 0x02, 12373 .dig_out_nid = ALC262_DIGOUT_NID, 12374 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12375 .channel_mode = alc262_modes, 12376 .input_mux = &alc262_capture_source, 12377 .unsol_event = alc262_hippo_unsol_event, 12378 .setup = alc262_hippo1_setup, 12379 .init_hook = alc262_hippo_automute, 12380 }, 12381 [ALC262_FUJITSU] = { 12382 .mixers = { alc262_fujitsu_mixer }, 12383 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12384 alc262_fujitsu_unsol_verbs }, 12385 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12386 .dac_nids = alc262_dac_nids, 12387 .hp_nid = 0x03, 12388 .dig_out_nid = ALC262_DIGOUT_NID, 12389 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12390 .channel_mode = alc262_modes, 12391 .input_mux = &alc262_fujitsu_capture_source, 12392 .unsol_event = alc262_fujitsu_unsol_event, 12393 .init_hook = alc262_fujitsu_init_hook, 12394 }, 12395 [ALC262_HP_BPC] = { 12396 .mixers = { alc262_HP_BPC_mixer }, 12397 .init_verbs = { alc262_HP_BPC_init_verbs }, 12398 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12399 .dac_nids = alc262_dac_nids, 12400 .hp_nid = 0x03, 12401 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12402 .channel_mode = alc262_modes, 12403 .input_mux = &alc262_HP_capture_source, 12404 .unsol_event = alc262_hp_bpc_unsol_event, 12405 .init_hook = alc262_hp_bpc_automute, 12406 }, 12407 [ALC262_HP_BPC_D7000_WF] = { 12408 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12409 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12410 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12411 .dac_nids = alc262_dac_nids, 12412 .hp_nid = 0x03, 12413 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12414 .channel_mode = alc262_modes, 12415 .input_mux = &alc262_HP_D7000_capture_source, 12416 .unsol_event = alc262_hp_wildwest_unsol_event, 12417 .init_hook = alc262_hp_wildwest_automute, 12418 }, 12419 [ALC262_HP_BPC_D7000_WL] = { 12420 .mixers = { alc262_HP_BPC_WildWest_mixer, 12421 alc262_HP_BPC_WildWest_option_mixer }, 12422 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12423 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12424 .dac_nids = alc262_dac_nids, 12425 .hp_nid = 0x03, 12426 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12427 .channel_mode = alc262_modes, 12428 .input_mux = &alc262_HP_D7000_capture_source, 12429 .unsol_event = alc262_hp_wildwest_unsol_event, 12430 .init_hook = alc262_hp_wildwest_automute, 12431 }, 12432 [ALC262_HP_TC_T5735] = { 12433 .mixers = { alc262_hp_t5735_mixer }, 12434 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12435 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12436 .dac_nids = alc262_dac_nids, 12437 .hp_nid = 0x03, 12438 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12439 .channel_mode = alc262_modes, 12440 .input_mux = &alc262_capture_source, 12441 .unsol_event = alc_sku_unsol_event, 12442 .setup = alc262_hp_t5735_setup, 12443 .init_hook = alc_inithook, 12444 }, 12445 [ALC262_HP_RP5700] = { 12446 .mixers = { alc262_hp_rp5700_mixer }, 12447 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12448 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12449 .dac_nids = alc262_dac_nids, 12450 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12451 .channel_mode = alc262_modes, 12452 .input_mux = &alc262_hp_rp5700_capture_source, 12453 }, 12454 [ALC262_BENQ_ED8] = { 12455 .mixers = { alc262_base_mixer }, 12456 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12457 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12458 .dac_nids = alc262_dac_nids, 12459 .hp_nid = 0x03, 12460 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12461 .channel_mode = alc262_modes, 12462 .input_mux = &alc262_capture_source, 12463 }, 12464 [ALC262_SONY_ASSAMD] = { 12465 .mixers = { alc262_sony_mixer }, 12466 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12467 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12468 .dac_nids = alc262_dac_nids, 12469 .hp_nid = 0x02, 12470 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12471 .channel_mode = alc262_modes, 12472 .input_mux = &alc262_capture_source, 12473 .unsol_event = alc262_hippo_unsol_event, 12474 .setup = alc262_hippo_setup, 12475 .init_hook = alc262_hippo_automute, 12476 }, 12477 [ALC262_BENQ_T31] = { 12478 .mixers = { alc262_benq_t31_mixer }, 12479 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12480 alc_hp15_unsol_verbs }, 12481 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12482 .dac_nids = alc262_dac_nids, 12483 .hp_nid = 0x03, 12484 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12485 .channel_mode = alc262_modes, 12486 .input_mux = &alc262_capture_source, 12487 .unsol_event = alc262_hippo_unsol_event, 12488 .setup = alc262_hippo_setup, 12489 .init_hook = alc262_hippo_automute, 12490 }, 12491 [ALC262_ULTRA] = { 12492 .mixers = { alc262_ultra_mixer }, 12493 .cap_mixer = alc262_ultra_capture_mixer, 12494 .init_verbs = { alc262_ultra_verbs }, 12495 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12496 .dac_nids = alc262_dac_nids, 12497 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12498 .channel_mode = alc262_modes, 12499 .input_mux = &alc262_ultra_capture_source, 12500 .adc_nids = alc262_adc_nids, /* ADC0 */ 12501 .capsrc_nids = alc262_capsrc_nids, 12502 .num_adc_nids = 1, /* single ADC */ 12503 .unsol_event = alc262_ultra_unsol_event, 12504 .init_hook = alc262_ultra_automute, 12505 }, 12506 [ALC262_LENOVO_3000] = { 12507 .mixers = { alc262_lenovo_3000_mixer }, 12508 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12509 alc262_lenovo_3000_unsol_verbs, 12510 alc262_lenovo_3000_init_verbs }, 12511 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12512 .dac_nids = alc262_dac_nids, 12513 .hp_nid = 0x03, 12514 .dig_out_nid = ALC262_DIGOUT_NID, 12515 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12516 .channel_mode = alc262_modes, 12517 .input_mux = &alc262_fujitsu_capture_source, 12518 .unsol_event = alc262_lenovo_3000_unsol_event, 12519 }, 12520 [ALC262_NEC] = { 12521 .mixers = { alc262_nec_mixer }, 12522 .init_verbs = { alc262_nec_verbs }, 12523 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12524 .dac_nids = alc262_dac_nids, 12525 .hp_nid = 0x03, 12526 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12527 .channel_mode = alc262_modes, 12528 .input_mux = &alc262_capture_source, 12529 }, 12530 [ALC262_TOSHIBA_S06] = { 12531 .mixers = { alc262_toshiba_s06_mixer }, 12532 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 12533 alc262_eapd_verbs }, 12534 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12535 .capsrc_nids = alc262_dmic_capsrc_nids, 12536 .dac_nids = alc262_dac_nids, 12537 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 12538 .num_adc_nids = 1, /* single ADC */ 12539 .dig_out_nid = ALC262_DIGOUT_NID, 12540 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12541 .channel_mode = alc262_modes, 12542 .unsol_event = alc_sku_unsol_event, 12543 .setup = alc262_toshiba_s06_setup, 12544 .init_hook = alc_inithook, 12545 }, 12546 [ALC262_TOSHIBA_RX1] = { 12547 .mixers = { alc262_toshiba_rx1_mixer }, 12548 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 12549 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12550 .dac_nids = alc262_dac_nids, 12551 .hp_nid = 0x03, 12552 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12553 .channel_mode = alc262_modes, 12554 .input_mux = &alc262_capture_source, 12555 .unsol_event = alc262_hippo_unsol_event, 12556 .setup = alc262_hippo_setup, 12557 .init_hook = alc262_hippo_automute, 12558 }, 12559 [ALC262_TYAN] = { 12560 .mixers = { alc262_tyan_mixer }, 12561 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 12562 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12563 .dac_nids = alc262_dac_nids, 12564 .hp_nid = 0x02, 12565 .dig_out_nid = ALC262_DIGOUT_NID, 12566 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12567 .channel_mode = alc262_modes, 12568 .input_mux = &alc262_capture_source, 12569 .unsol_event = alc_automute_amp_unsol_event, 12570 .setup = alc262_tyan_setup, 12571 .init_hook = alc_automute_amp, 12572 }, 12573}; 12574 12575static int patch_alc262(struct hda_codec *codec) 12576{ 12577 struct alc_spec *spec; 12578 int board_config; 12579 int err; 12580 12581 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 12582 if (spec == NULL) 12583 return -ENOMEM; 12584 12585 codec->spec = spec; 12586#if 0 12587 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 12588 * under-run 12589 */ 12590 { 12591 int tmp; 12592 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12593 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 12594 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 12595 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 12596 } 12597#endif 12598 alc_auto_parse_customize_define(codec); 12599 12600 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 12601 12602 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 12603 alc262_models, 12604 alc262_cfg_tbl); 12605 12606 if (board_config < 0) { 12607 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 12608 codec->chip_name); 12609 board_config = ALC262_AUTO; 12610 } 12611 12612 if (board_config == ALC262_AUTO) { 12613 /* automatic parse from the BIOS config */ 12614 err = alc262_parse_auto_config(codec); 12615 if (err < 0) { 12616 alc_free(codec); 12617 return err; 12618 } else if (!err) { 12619 printk(KERN_INFO 12620 "hda_codec: Cannot set up configuration " 12621 "from BIOS. Using base mode...\n"); 12622 board_config = ALC262_BASIC; 12623 } 12624 } 12625 12626 if (!spec->no_analog && has_cdefine_beep(codec)) { 12627 err = snd_hda_attach_beep_device(codec, 0x1); 12628 if (err < 0) { 12629 alc_free(codec); 12630 return err; 12631 } 12632 } 12633 12634 if (board_config != ALC262_AUTO) 12635 setup_preset(codec, &alc262_presets[board_config]); 12636 12637 spec->stream_analog_playback = &alc262_pcm_analog_playback; 12638 spec->stream_analog_capture = &alc262_pcm_analog_capture; 12639 12640 spec->stream_digital_playback = &alc262_pcm_digital_playback; 12641 spec->stream_digital_capture = &alc262_pcm_digital_capture; 12642 12643 if (!spec->adc_nids && spec->input_mux) { 12644 int i; 12645 /* check whether the digital-mic has to be supported */ 12646 for (i = 0; i < spec->input_mux->num_items; i++) { 12647 if (spec->input_mux->items[i].index >= 9) 12648 break; 12649 } 12650 if (i < spec->input_mux->num_items) { 12651 /* use only ADC0 */ 12652 spec->adc_nids = alc262_dmic_adc_nids; 12653 spec->num_adc_nids = 1; 12654 spec->capsrc_nids = alc262_dmic_capsrc_nids; 12655 } else { 12656 /* all analog inputs */ 12657 /* check whether NID 0x07 is valid */ 12658 unsigned int wcap = get_wcaps(codec, 0x07); 12659 12660 /* get type */ 12661 wcap = get_wcaps_type(wcap); 12662 if (wcap != AC_WID_AUD_IN) { 12663 spec->adc_nids = alc262_adc_nids_alt; 12664 spec->num_adc_nids = 12665 ARRAY_SIZE(alc262_adc_nids_alt); 12666 spec->capsrc_nids = alc262_capsrc_nids_alt; 12667 } else { 12668 spec->adc_nids = alc262_adc_nids; 12669 spec->num_adc_nids = 12670 ARRAY_SIZE(alc262_adc_nids); 12671 spec->capsrc_nids = alc262_capsrc_nids; 12672 } 12673 } 12674 } 12675 if (!spec->cap_mixer && !spec->no_analog) 12676 set_capture_mixer(codec); 12677 if (!spec->no_analog && has_cdefine_beep(codec)) 12678 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 12679 12680 spec->vmaster_nid = 0x0c; 12681 12682 codec->patch_ops = alc_patch_ops; 12683 if (board_config == ALC262_AUTO) 12684 spec->init_hook = alc262_auto_init; 12685#ifdef CONFIG_SND_HDA_POWER_SAVE 12686 if (!spec->loopback.amplist) 12687 spec->loopback.amplist = alc262_loopbacks; 12688#endif 12689 12690 return 0; 12691} 12692 12693/* 12694 * ALC268 channel source setting (2 channel) 12695 */ 12696#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 12697#define alc268_modes alc260_modes 12698 12699static hda_nid_t alc268_dac_nids[2] = { 12700 /* front, hp */ 12701 0x02, 0x03 12702}; 12703 12704static hda_nid_t alc268_adc_nids[2] = { 12705 /* ADC0-1 */ 12706 0x08, 0x07 12707}; 12708 12709static hda_nid_t alc268_adc_nids_alt[1] = { 12710 /* ADC0 */ 12711 0x08 12712}; 12713 12714static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 12715 12716static struct snd_kcontrol_new alc268_base_mixer[] = { 12717 /* output mixer control */ 12718 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12719 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12720 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12722 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12723 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12724 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12725 { } 12726}; 12727 12728static struct snd_kcontrol_new alc268_toshiba_mixer[] = { 12729 /* output mixer control */ 12730 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12731 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12732 ALC262_HIPPO_MASTER_SWITCH, 12733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12734 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 12735 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12736 { } 12737}; 12738 12739/* bind Beep switches of both NID 0x0f and 0x10 */ 12740static struct hda_bind_ctls alc268_bind_beep_sw = { 12741 .ops = &snd_hda_bind_sw, 12742 .values = { 12743 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 12744 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 12745 0 12746 }, 12747}; 12748 12749static struct snd_kcontrol_new alc268_beep_mixer[] = { 12750 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 12751 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 12752 { } 12753}; 12754 12755static struct hda_verb alc268_eapd_verbs[] = { 12756 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12757 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 12758 { } 12759}; 12760 12761/* Toshiba specific */ 12762static struct hda_verb alc268_toshiba_verbs[] = { 12763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12764 { } /* end */ 12765}; 12766 12767/* Acer specific */ 12768/* bind volumes of both NID 0x02 and 0x03 */ 12769static struct hda_bind_ctls alc268_acer_bind_master_vol = { 12770 .ops = &snd_hda_bind_vol, 12771 .values = { 12772 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 12773 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 12774 0 12775 }, 12776}; 12777 12778/* mute/unmute internal speaker according to the hp jack and mute state */ 12779static void alc268_acer_automute(struct hda_codec *codec, int force) 12780{ 12781 struct alc_spec *spec = codec->spec; 12782 unsigned int mute; 12783 12784 if (force || !spec->sense_updated) { 12785 spec->jack_present = snd_hda_jack_detect(codec, 0x14); 12786 spec->sense_updated = 1; 12787 } 12788 if (spec->jack_present) 12789 mute = HDA_AMP_MUTE; /* mute internal speaker */ 12790 else /* unmute internal speaker if necessary */ 12791 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); 12792 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12793 HDA_AMP_MUTE, mute); 12794} 12795 12796 12797/* bind hp and internal speaker mute (with plug check) */ 12798static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, 12799 struct snd_ctl_elem_value *ucontrol) 12800{ 12801 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12802 long *valp = ucontrol->value.integer.value; 12803 int change; 12804 12805 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); 12806 if (change) 12807 alc268_acer_automute(codec, 0); 12808 return change; 12809} 12810 12811static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 12812 /* output mixer control */ 12813 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12814 { 12815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12816 .name = "Master Playback Switch", 12817 .subdevice = HDA_SUBDEV_AMP_FLAG, 12818 .info = snd_hda_mixer_amp_switch_info, 12819 .get = snd_hda_mixer_amp_switch_get, 12820 .put = alc268_acer_master_sw_put, 12821 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12822 }, 12823 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 12824 { } 12825}; 12826 12827static struct snd_kcontrol_new alc268_acer_mixer[] = { 12828 /* output mixer control */ 12829 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12830 { 12831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12832 .name = "Master Playback Switch", 12833 .subdevice = HDA_SUBDEV_AMP_FLAG, 12834 .info = snd_hda_mixer_amp_switch_info, 12835 .get = snd_hda_mixer_amp_switch_get, 12836 .put = alc268_acer_master_sw_put, 12837 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12838 }, 12839 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12840 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12841 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12842 { } 12843}; 12844 12845static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 12846 /* output mixer control */ 12847 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 12848 { 12849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12850 .name = "Master Playback Switch", 12851 .subdevice = HDA_SUBDEV_AMP_FLAG, 12852 .info = snd_hda_mixer_amp_switch_info, 12853 .get = snd_hda_mixer_amp_switch_get, 12854 .put = alc268_acer_master_sw_put, 12855 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 12856 }, 12857 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12858 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 12859 { } 12860}; 12861 12862static struct hda_verb alc268_acer_aspire_one_verbs[] = { 12863 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12865 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 12867 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 12868 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 12869 { } 12870}; 12871 12872static struct hda_verb alc268_acer_verbs[] = { 12873 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 12874 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 12875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12879 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12880 { } 12881}; 12882 12883/* unsolicited event for HP jack sensing */ 12884#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 12885#define alc268_toshiba_setup alc262_hippo_setup 12886#define alc268_toshiba_automute alc262_hippo_automute 12887 12888static void alc268_acer_unsol_event(struct hda_codec *codec, 12889 unsigned int res) 12890{ 12891 if ((res >> 26) != ALC880_HP_EVENT) 12892 return; 12893 alc268_acer_automute(codec, 1); 12894} 12895 12896static void alc268_acer_init_hook(struct hda_codec *codec) 12897{ 12898 alc268_acer_automute(codec, 1); 12899} 12900 12901/* toggle speaker-output according to the hp-jack state */ 12902static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) 12903{ 12904 unsigned int present; 12905 unsigned char bits; 12906 12907 present = snd_hda_jack_detect(codec, 0x15); 12908 bits = present ? HDA_AMP_MUTE : 0; 12909 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, 12910 HDA_AMP_MUTE, bits); 12911 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, 12912 HDA_AMP_MUTE, bits); 12913} 12914 12915static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12916 unsigned int res) 12917{ 12918 switch (res >> 26) { 12919 case ALC880_HP_EVENT: 12920 alc268_aspire_one_speaker_automute(codec); 12921 break; 12922 case ALC880_MIC_EVENT: 12923 alc_mic_automute(codec); 12924 break; 12925 } 12926} 12927 12928static void alc268_acer_lc_setup(struct hda_codec *codec) 12929{ 12930 struct alc_spec *spec = codec->spec; 12931 spec->ext_mic.pin = 0x18; 12932 spec->ext_mic.mux_idx = 0; 12933 spec->int_mic.pin = 0x12; 12934 spec->int_mic.mux_idx = 6; 12935 spec->auto_mic = 1; 12936} 12937 12938static void alc268_acer_lc_init_hook(struct hda_codec *codec) 12939{ 12940 alc268_aspire_one_speaker_automute(codec); 12941 alc_mic_automute(codec); 12942} 12943 12944static struct snd_kcontrol_new alc268_dell_mixer[] = { 12945 /* output mixer control */ 12946 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 12947 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12948 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 12949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12950 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 12951 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 12952 { } 12953}; 12954 12955static struct hda_verb alc268_dell_verbs[] = { 12956 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12958 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12959 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12960 { } 12961}; 12962 12963/* mute/unmute internal speaker according to the hp jack and mute state */ 12964static void alc268_dell_setup(struct hda_codec *codec) 12965{ 12966 struct alc_spec *spec = codec->spec; 12967 12968 spec->autocfg.hp_pins[0] = 0x15; 12969 spec->autocfg.speaker_pins[0] = 0x14; 12970 spec->ext_mic.pin = 0x18; 12971 spec->ext_mic.mux_idx = 0; 12972 spec->int_mic.pin = 0x19; 12973 spec->int_mic.mux_idx = 1; 12974 spec->auto_mic = 1; 12975} 12976 12977static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 12978 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 12979 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 12980 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 12981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 12982 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 12983 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 12984 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 12985 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 12986 { } 12987}; 12988 12989static struct hda_verb alc267_quanta_il1_verbs[] = { 12990 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12991 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 12992 { } 12993}; 12994 12995static void alc267_quanta_il1_setup(struct hda_codec *codec) 12996{ 12997 struct alc_spec *spec = codec->spec; 12998 spec->autocfg.hp_pins[0] = 0x15; 12999 spec->autocfg.speaker_pins[0] = 0x14; 13000 spec->ext_mic.pin = 0x18; 13001 spec->ext_mic.mux_idx = 0; 13002 spec->int_mic.pin = 0x19; 13003 spec->int_mic.mux_idx = 1; 13004 spec->auto_mic = 1; 13005} 13006 13007/* 13008 * generic initialization of ADC, input mixers and output mixers 13009 */ 13010static struct hda_verb alc268_base_init_verbs[] = { 13011 /* Unmute DAC0-1 and set vol = 0 */ 13012 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13013 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13014 13015 /* 13016 * Set up output mixers (0x0c - 0x0e) 13017 */ 13018 /* set vol=0 to output mixers */ 13019 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13020 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13021 13022 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13023 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13024 13025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13027 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13028 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13029 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13030 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13031 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13032 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13033 13034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13036 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13039 13040 /* set PCBEEP vol = 0, mute connections */ 13041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13044 13045 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13046 13047 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13049 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13051 13052 { } 13053}; 13054 13055/* 13056 * generic initialization of ADC, input mixers and output mixers 13057 */ 13058static struct hda_verb alc268_volume_init_verbs[] = { 13059 /* set output DAC */ 13060 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13061 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13062 13063 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13064 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13065 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13066 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13067 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13068 13069 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13070 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13072 13073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13074 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13075 13076 /* set PCBEEP vol = 0, mute connections */ 13077 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13078 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13079 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13080 13081 { } 13082}; 13083 13084static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13085 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13086 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13087 { } /* end */ 13088}; 13089 13090static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13091 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13092 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13093 _DEFINE_CAPSRC(1), 13094 { } /* end */ 13095}; 13096 13097static struct snd_kcontrol_new alc268_capture_mixer[] = { 13098 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13099 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13100 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13101 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13102 _DEFINE_CAPSRC(2), 13103 { } /* end */ 13104}; 13105 13106static struct hda_input_mux alc268_capture_source = { 13107 .num_items = 4, 13108 .items = { 13109 { "Mic", 0x0 }, 13110 { "Front Mic", 0x1 }, 13111 { "Line", 0x2 }, 13112 { "CD", 0x3 }, 13113 }, 13114}; 13115 13116static struct hda_input_mux alc268_acer_capture_source = { 13117 .num_items = 3, 13118 .items = { 13119 { "Mic", 0x0 }, 13120 { "Internal Mic", 0x1 }, 13121 { "Line", 0x2 }, 13122 }, 13123}; 13124 13125static struct hda_input_mux alc268_acer_dmic_capture_source = { 13126 .num_items = 3, 13127 .items = { 13128 { "Mic", 0x0 }, 13129 { "Internal Mic", 0x6 }, 13130 { "Line", 0x2 }, 13131 }, 13132}; 13133 13134#ifdef CONFIG_SND_DEBUG 13135static struct snd_kcontrol_new alc268_test_mixer[] = { 13136 /* Volume widgets */ 13137 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13138 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13139 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13140 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13141 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13142 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13143 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13144 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13145 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13146 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13147 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13148 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13149 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13150 /* The below appears problematic on some hardwares */ 13151 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13152 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13153 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13154 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13155 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13156 13157 /* Modes for retasking pin widgets */ 13158 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13159 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13160 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13161 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13162 13163 /* Controls for GPIO pins, assuming they are configured as outputs */ 13164 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13165 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13166 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13167 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13168 13169 /* Switches to allow the digital SPDIF output pin to be enabled. 13170 * The ALC268 does not have an SPDIF input. 13171 */ 13172 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13173 13174 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13175 * this output to turn on an external amplifier. 13176 */ 13177 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13178 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13179 13180 { } /* end */ 13181}; 13182#endif 13183 13184/* create input playback/capture controls for the given pin */ 13185static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13186 const char *ctlname, int idx) 13187{ 13188 hda_nid_t dac; 13189 int err; 13190 13191 switch (nid) { 13192 case 0x14: 13193 case 0x16: 13194 dac = 0x02; 13195 break; 13196 case 0x15: 13197 case 0x1a: /* ALC259/269 only */ 13198 case 0x1b: /* ALC259/269 only */ 13199 case 0x21: /* ALC269vb has this pin, too */ 13200 dac = 0x03; 13201 break; 13202 default: 13203 snd_printd(KERN_WARNING "hda_codec: " 13204 "ignoring pin 0x%x as unknown\n", nid); 13205 return 0; 13206 } 13207 if (spec->multiout.dac_nids[0] != dac && 13208 spec->multiout.dac_nids[1] != dac) { 13209 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13210 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13211 HDA_OUTPUT)); 13212 if (err < 0) 13213 return err; 13214 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 13215 } 13216 13217 if (nid != 0x16) 13218 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13219 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13220 else /* mono */ 13221 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13222 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13223 if (err < 0) 13224 return err; 13225 return 0; 13226} 13227 13228/* add playback controls from the parsed DAC table */ 13229static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13230 const struct auto_pin_cfg *cfg) 13231{ 13232 hda_nid_t nid; 13233 int err; 13234 13235 spec->multiout.dac_nids = spec->private_dac_nids; 13236 13237 nid = cfg->line_out_pins[0]; 13238 if (nid) { 13239 const char *name; 13240 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13241 name = "Speaker"; 13242 else 13243 name = "Front"; 13244 err = alc268_new_analog_output(spec, nid, name, 0); 13245 if (err < 0) 13246 return err; 13247 } 13248 13249 nid = cfg->speaker_pins[0]; 13250 if (nid == 0x1d) { 13251 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13252 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13253 if (err < 0) 13254 return err; 13255 } else if (nid) { 13256 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13257 if (err < 0) 13258 return err; 13259 } 13260 nid = cfg->hp_pins[0]; 13261 if (nid) { 13262 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13263 if (err < 0) 13264 return err; 13265 } 13266 13267 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13268 if (nid == 0x16) { 13269 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13270 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13271 if (err < 0) 13272 return err; 13273 } 13274 return 0; 13275} 13276 13277/* create playback/capture controls for input pins */ 13278static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13279 const struct auto_pin_cfg *cfg) 13280{ 13281 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13282} 13283 13284static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13285 hda_nid_t nid, int pin_type) 13286{ 13287 int idx; 13288 13289 alc_set_pin_output(codec, nid, pin_type); 13290 if (nid == 0x14 || nid == 0x16) 13291 idx = 0; 13292 else 13293 idx = 1; 13294 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13295} 13296 13297static void alc268_auto_init_multi_out(struct hda_codec *codec) 13298{ 13299 struct alc_spec *spec = codec->spec; 13300 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 13301 if (nid) { 13302 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13303 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13304 } 13305} 13306 13307static void alc268_auto_init_hp_out(struct hda_codec *codec) 13308{ 13309 struct alc_spec *spec = codec->spec; 13310 hda_nid_t pin; 13311 13312 pin = spec->autocfg.hp_pins[0]; 13313 if (pin) 13314 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13315 pin = spec->autocfg.speaker_pins[0]; 13316 if (pin) 13317 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13318} 13319 13320static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13321{ 13322 struct alc_spec *spec = codec->spec; 13323 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13324 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13325 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13326 unsigned int dac_vol1, dac_vol2; 13327 13328 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13329 snd_hda_codec_write(codec, speaker_nid, 0, 13330 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13331 /* mute mixer inputs from 0x1d */ 13332 snd_hda_codec_write(codec, 0x0f, 0, 13333 AC_VERB_SET_AMP_GAIN_MUTE, 13334 AMP_IN_UNMUTE(1)); 13335 snd_hda_codec_write(codec, 0x10, 0, 13336 AC_VERB_SET_AMP_GAIN_MUTE, 13337 AMP_IN_UNMUTE(1)); 13338 } else { 13339 /* unmute mixer inputs from 0x1d */ 13340 snd_hda_codec_write(codec, 0x0f, 0, 13341 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13342 snd_hda_codec_write(codec, 0x10, 0, 13343 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13344 } 13345 13346 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13347 if (line_nid == 0x14) 13348 dac_vol2 = AMP_OUT_ZERO; 13349 else if (line_nid == 0x15) 13350 dac_vol1 = AMP_OUT_ZERO; 13351 if (hp_nid == 0x14) 13352 dac_vol2 = AMP_OUT_ZERO; 13353 else if (hp_nid == 0x15) 13354 dac_vol1 = AMP_OUT_ZERO; 13355 if (line_nid != 0x16 || hp_nid != 0x16 || 13356 spec->autocfg.line_out_pins[1] != 0x16 || 13357 spec->autocfg.line_out_pins[2] != 0x16) 13358 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13359 13360 snd_hda_codec_write(codec, 0x02, 0, 13361 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13362 snd_hda_codec_write(codec, 0x03, 0, 13363 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13364} 13365 13366/* pcm configuration: identical with ALC880 */ 13367#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13368#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13369#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13370#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13371 13372/* 13373 * BIOS auto configuration 13374 */ 13375static int alc268_parse_auto_config(struct hda_codec *codec) 13376{ 13377 struct alc_spec *spec = codec->spec; 13378 int err; 13379 static hda_nid_t alc268_ignore[] = { 0 }; 13380 13381 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13382 alc268_ignore); 13383 if (err < 0) 13384 return err; 13385 if (!spec->autocfg.line_outs) { 13386 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13387 spec->multiout.max_channels = 2; 13388 spec->no_analog = 1; 13389 goto dig_only; 13390 } 13391 return 0; /* can't find valid BIOS pin config */ 13392 } 13393 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13394 if (err < 0) 13395 return err; 13396 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13397 if (err < 0) 13398 return err; 13399 13400 spec->multiout.max_channels = 2; 13401 13402 dig_only: 13403 /* digital only support output */ 13404 alc_auto_parse_digital(codec); 13405 if (spec->kctls.list) 13406 add_mixer(spec, spec->kctls.list); 13407 13408 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13409 add_mixer(spec, alc268_beep_mixer); 13410 13411 add_verb(spec, alc268_volume_init_verbs); 13412 spec->num_mux_defs = 2; 13413 spec->input_mux = &spec->private_imux[0]; 13414 13415 err = alc_auto_add_mic_boost(codec); 13416 if (err < 0) 13417 return err; 13418 13419 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13420 13421 return 1; 13422} 13423 13424#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13425 13426/* init callback for auto-configuration model -- overriding the default init */ 13427static void alc268_auto_init(struct hda_codec *codec) 13428{ 13429 struct alc_spec *spec = codec->spec; 13430 alc268_auto_init_multi_out(codec); 13431 alc268_auto_init_hp_out(codec); 13432 alc268_auto_init_mono_speaker_out(codec); 13433 alc268_auto_init_analog_input(codec); 13434 alc_auto_init_digital(codec); 13435 if (spec->unsol_event) 13436 alc_inithook(codec); 13437} 13438 13439/* 13440 * configuration and preset 13441 */ 13442static const char *alc268_models[ALC268_MODEL_LAST] = { 13443 [ALC267_QUANTA_IL1] = "quanta-il1", 13444 [ALC268_3ST] = "3stack", 13445 [ALC268_TOSHIBA] = "toshiba", 13446 [ALC268_ACER] = "acer", 13447 [ALC268_ACER_DMIC] = "acer-dmic", 13448 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13449 [ALC268_DELL] = "dell", 13450 [ALC268_ZEPTO] = "zepto", 13451#ifdef CONFIG_SND_DEBUG 13452 [ALC268_TEST] = "test", 13453#endif 13454 [ALC268_AUTO] = "auto", 13455}; 13456 13457static struct snd_pci_quirk alc268_cfg_tbl[] = { 13458 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13459 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13460 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13461 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13462 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13463 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13464 ALC268_ACER_ASPIRE_ONE), 13465 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13466 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13467 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13468 /* almost compatible with toshiba but with optional digital outs; 13469 * auto-probing seems working fine 13470 */ 13471 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13472 ALC268_AUTO), 13473 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13474 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13475 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13476 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), 13477 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13478 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL), 13479 {} 13480}; 13481 13482/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13483static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13484 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13485 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13486 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13487 ALC268_TOSHIBA), 13488 {} 13489}; 13490 13491static struct alc_config_preset alc268_presets[] = { 13492 [ALC267_QUANTA_IL1] = { 13493 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13494 alc268_capture_nosrc_mixer }, 13495 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13496 alc267_quanta_il1_verbs }, 13497 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13498 .dac_nids = alc268_dac_nids, 13499 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13500 .adc_nids = alc268_adc_nids_alt, 13501 .hp_nid = 0x03, 13502 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13503 .channel_mode = alc268_modes, 13504 .unsol_event = alc_sku_unsol_event, 13505 .setup = alc267_quanta_il1_setup, 13506 .init_hook = alc_inithook, 13507 }, 13508 [ALC268_3ST] = { 13509 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13510 alc268_beep_mixer }, 13511 .init_verbs = { alc268_base_init_verbs }, 13512 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13513 .dac_nids = alc268_dac_nids, 13514 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13515 .adc_nids = alc268_adc_nids_alt, 13516 .capsrc_nids = alc268_capsrc_nids, 13517 .hp_nid = 0x03, 13518 .dig_out_nid = ALC268_DIGOUT_NID, 13519 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13520 .channel_mode = alc268_modes, 13521 .input_mux = &alc268_capture_source, 13522 }, 13523 [ALC268_TOSHIBA] = { 13524 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13525 alc268_beep_mixer }, 13526 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13527 alc268_toshiba_verbs }, 13528 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13529 .dac_nids = alc268_dac_nids, 13530 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13531 .adc_nids = alc268_adc_nids_alt, 13532 .capsrc_nids = alc268_capsrc_nids, 13533 .hp_nid = 0x03, 13534 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13535 .channel_mode = alc268_modes, 13536 .input_mux = &alc268_capture_source, 13537 .unsol_event = alc268_toshiba_unsol_event, 13538 .setup = alc268_toshiba_setup, 13539 .init_hook = alc268_toshiba_automute, 13540 }, 13541 [ALC268_ACER] = { 13542 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13543 alc268_beep_mixer }, 13544 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13545 alc268_acer_verbs }, 13546 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13547 .dac_nids = alc268_dac_nids, 13548 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13549 .adc_nids = alc268_adc_nids_alt, 13550 .capsrc_nids = alc268_capsrc_nids, 13551 .hp_nid = 0x02, 13552 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13553 .channel_mode = alc268_modes, 13554 .input_mux = &alc268_acer_capture_source, 13555 .unsol_event = alc268_acer_unsol_event, 13556 .init_hook = alc268_acer_init_hook, 13557 }, 13558 [ALC268_ACER_DMIC] = { 13559 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13560 alc268_beep_mixer }, 13561 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13562 alc268_acer_verbs }, 13563 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13564 .dac_nids = alc268_dac_nids, 13565 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13566 .adc_nids = alc268_adc_nids_alt, 13567 .capsrc_nids = alc268_capsrc_nids, 13568 .hp_nid = 0x02, 13569 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13570 .channel_mode = alc268_modes, 13571 .input_mux = &alc268_acer_dmic_capture_source, 13572 .unsol_event = alc268_acer_unsol_event, 13573 .init_hook = alc268_acer_init_hook, 13574 }, 13575 [ALC268_ACER_ASPIRE_ONE] = { 13576 .mixers = { alc268_acer_aspire_one_mixer, 13577 alc268_beep_mixer, 13578 alc268_capture_nosrc_mixer }, 13579 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13580 alc268_acer_aspire_one_verbs }, 13581 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13582 .dac_nids = alc268_dac_nids, 13583 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13584 .adc_nids = alc268_adc_nids_alt, 13585 .capsrc_nids = alc268_capsrc_nids, 13586 .hp_nid = 0x03, 13587 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13588 .channel_mode = alc268_modes, 13589 .unsol_event = alc268_acer_lc_unsol_event, 13590 .setup = alc268_acer_lc_setup, 13591 .init_hook = alc268_acer_lc_init_hook, 13592 }, 13593 [ALC268_DELL] = { 13594 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 13595 alc268_capture_nosrc_mixer }, 13596 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13597 alc268_dell_verbs }, 13598 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13599 .dac_nids = alc268_dac_nids, 13600 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13601 .adc_nids = alc268_adc_nids_alt, 13602 .capsrc_nids = alc268_capsrc_nids, 13603 .hp_nid = 0x02, 13604 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13605 .channel_mode = alc268_modes, 13606 .unsol_event = alc_sku_unsol_event, 13607 .setup = alc268_dell_setup, 13608 .init_hook = alc_inithook, 13609 }, 13610 [ALC268_ZEPTO] = { 13611 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13612 alc268_beep_mixer }, 13613 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13614 alc268_toshiba_verbs }, 13615 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13616 .dac_nids = alc268_dac_nids, 13617 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13618 .adc_nids = alc268_adc_nids_alt, 13619 .capsrc_nids = alc268_capsrc_nids, 13620 .hp_nid = 0x03, 13621 .dig_out_nid = ALC268_DIGOUT_NID, 13622 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13623 .channel_mode = alc268_modes, 13624 .input_mux = &alc268_capture_source, 13625 .setup = alc268_toshiba_setup, 13626 .init_hook = alc268_toshiba_automute, 13627 }, 13628#ifdef CONFIG_SND_DEBUG 13629 [ALC268_TEST] = { 13630 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 13631 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13632 alc268_volume_init_verbs }, 13633 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13634 .dac_nids = alc268_dac_nids, 13635 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13636 .adc_nids = alc268_adc_nids_alt, 13637 .capsrc_nids = alc268_capsrc_nids, 13638 .hp_nid = 0x03, 13639 .dig_out_nid = ALC268_DIGOUT_NID, 13640 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13641 .channel_mode = alc268_modes, 13642 .input_mux = &alc268_capture_source, 13643 }, 13644#endif 13645}; 13646 13647static int patch_alc268(struct hda_codec *codec) 13648{ 13649 struct alc_spec *spec; 13650 int board_config; 13651 int i, has_beep, err; 13652 13653 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13654 if (spec == NULL) 13655 return -ENOMEM; 13656 13657 codec->spec = spec; 13658 13659 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 13660 alc268_models, 13661 alc268_cfg_tbl); 13662 13663 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 13664 board_config = snd_hda_check_board_codec_sid_config(codec, 13665 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 13666 13667 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 13668 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13669 codec->chip_name); 13670 board_config = ALC268_AUTO; 13671 } 13672 13673 if (board_config == ALC268_AUTO) { 13674 /* automatic parse from the BIOS config */ 13675 err = alc268_parse_auto_config(codec); 13676 if (err < 0) { 13677 alc_free(codec); 13678 return err; 13679 } else if (!err) { 13680 printk(KERN_INFO 13681 "hda_codec: Cannot set up configuration " 13682 "from BIOS. Using base mode...\n"); 13683 board_config = ALC268_3ST; 13684 } 13685 } 13686 13687 if (board_config != ALC268_AUTO) 13688 setup_preset(codec, &alc268_presets[board_config]); 13689 13690 spec->stream_analog_playback = &alc268_pcm_analog_playback; 13691 spec->stream_analog_capture = &alc268_pcm_analog_capture; 13692 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 13693 13694 spec->stream_digital_playback = &alc268_pcm_digital_playback; 13695 13696 has_beep = 0; 13697 for (i = 0; i < spec->num_mixers; i++) { 13698 if (spec->mixers[i] == alc268_beep_mixer) { 13699 has_beep = 1; 13700 break; 13701 } 13702 } 13703 13704 if (has_beep) { 13705 err = snd_hda_attach_beep_device(codec, 0x1); 13706 if (err < 0) { 13707 alc_free(codec); 13708 return err; 13709 } 13710 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 13711 /* override the amp caps for beep generator */ 13712 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 13713 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 13714 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 13715 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 13716 (0 << AC_AMPCAP_MUTE_SHIFT)); 13717 } 13718 13719 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 13720 /* check whether NID 0x07 is valid */ 13721 unsigned int wcap = get_wcaps(codec, 0x07); 13722 int i; 13723 13724 spec->capsrc_nids = alc268_capsrc_nids; 13725 /* get type */ 13726 wcap = get_wcaps_type(wcap); 13727 if (spec->auto_mic || 13728 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 13729 spec->adc_nids = alc268_adc_nids_alt; 13730 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 13731 if (spec->auto_mic) 13732 fixup_automic_adc(codec); 13733 if (spec->auto_mic || spec->input_mux->num_items == 1) 13734 add_mixer(spec, alc268_capture_nosrc_mixer); 13735 else 13736 add_mixer(spec, alc268_capture_alt_mixer); 13737 } else { 13738 spec->adc_nids = alc268_adc_nids; 13739 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 13740 add_mixer(spec, alc268_capture_mixer); 13741 } 13742 /* set default input source */ 13743 for (i = 0; i < spec->num_adc_nids; i++) 13744 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 13745 0, AC_VERB_SET_CONNECT_SEL, 13746 i < spec->num_mux_defs ? 13747 spec->input_mux[i].items[0].index : 13748 spec->input_mux->items[0].index); 13749 } 13750 13751 spec->vmaster_nid = 0x02; 13752 13753 codec->patch_ops = alc_patch_ops; 13754 if (board_config == ALC268_AUTO) 13755 spec->init_hook = alc268_auto_init; 13756 13757 return 0; 13758} 13759 13760/* 13761 * ALC269 channel source setting (2 channel) 13762 */ 13763#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 13764 13765#define alc269_dac_nids alc260_dac_nids 13766 13767static hda_nid_t alc269_adc_nids[1] = { 13768 /* ADC1 */ 13769 0x08, 13770}; 13771 13772static hda_nid_t alc269_capsrc_nids[1] = { 13773 0x23, 13774}; 13775 13776static hda_nid_t alc269vb_adc_nids[1] = { 13777 /* ADC1 */ 13778 0x09, 13779}; 13780 13781static hda_nid_t alc269vb_capsrc_nids[1] = { 13782 0x22, 13783}; 13784 13785static hda_nid_t alc269_adc_candidates[] = { 13786 0x08, 0x09, 0x07, 13787}; 13788 13789#define alc269_modes alc260_modes 13790#define alc269_capture_source alc880_lg_lw_capture_source 13791 13792static struct snd_kcontrol_new alc269_base_mixer[] = { 13793 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13794 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13795 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 13796 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 13797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13800 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13801 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13802 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13804 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 13805 { } /* end */ 13806}; 13807 13808static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 13809 /* output mixer control */ 13810 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13811 { 13812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13813 .name = "Master Playback Switch", 13814 .subdevice = HDA_SUBDEV_AMP_FLAG, 13815 .info = snd_hda_mixer_amp_switch_info, 13816 .get = snd_hda_mixer_amp_switch_get, 13817 .put = alc268_acer_master_sw_put, 13818 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13819 }, 13820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13822 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13823 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13824 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13825 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13826 { } 13827}; 13828 13829static struct snd_kcontrol_new alc269_lifebook_mixer[] = { 13830 /* output mixer control */ 13831 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13832 { 13833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13834 .name = "Master Playback Switch", 13835 .subdevice = HDA_SUBDEV_AMP_FLAG, 13836 .info = snd_hda_mixer_amp_switch_info, 13837 .get = snd_hda_mixer_amp_switch_get, 13838 .put = alc268_acer_master_sw_put, 13839 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13840 }, 13841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 13842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 13843 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13844 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 13845 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 13846 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13847 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 13848 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 13849 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 13850 { } 13851}; 13852 13853static struct snd_kcontrol_new alc269_laptop_mixer[] = { 13854 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13855 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13857 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13858 { } /* end */ 13859}; 13860 13861static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 13862 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 13865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13866 { } /* end */ 13867}; 13868 13869/* capture mixer elements */ 13870static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 13871 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13872 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13873 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13874 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13875 { } /* end */ 13876}; 13877 13878static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 13879 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13880 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13881 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13882 { } /* end */ 13883}; 13884 13885static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 13886 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13887 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13888 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13889 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 13890 { } /* end */ 13891}; 13892 13893static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 13894 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 13895 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 13896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13897 { } /* end */ 13898}; 13899 13900/* FSC amilo */ 13901#define alc269_fujitsu_mixer alc269_laptop_mixer 13902 13903static struct hda_verb alc269_quanta_fl1_verbs[] = { 13904 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13905 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13907 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13908 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13909 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13910 { } 13911}; 13912 13913static struct hda_verb alc269_lifebook_verbs[] = { 13914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13915 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 13916 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13918 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13920 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13921 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13922 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13923 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13924 { } 13925}; 13926 13927/* toggle speaker-output according to the hp-jack state */ 13928static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 13929{ 13930 unsigned int present; 13931 unsigned char bits; 13932 13933 present = snd_hda_jack_detect(codec, 0x15); 13934 bits = present ? HDA_AMP_MUTE : 0; 13935 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13936 HDA_AMP_MUTE, bits); 13937 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13938 HDA_AMP_MUTE, bits); 13939 13940 snd_hda_codec_write(codec, 0x20, 0, 13941 AC_VERB_SET_COEF_INDEX, 0x0c); 13942 snd_hda_codec_write(codec, 0x20, 0, 13943 AC_VERB_SET_PROC_COEF, 0x680); 13944 13945 snd_hda_codec_write(codec, 0x20, 0, 13946 AC_VERB_SET_COEF_INDEX, 0x0c); 13947 snd_hda_codec_write(codec, 0x20, 0, 13948 AC_VERB_SET_PROC_COEF, 0x480); 13949} 13950 13951/* toggle speaker-output according to the hp-jacks state */ 13952static void alc269_lifebook_speaker_automute(struct hda_codec *codec) 13953{ 13954 unsigned int present; 13955 unsigned char bits; 13956 13957 /* Check laptop headphone socket */ 13958 present = snd_hda_jack_detect(codec, 0x15); 13959 13960 /* Check port replicator headphone socket */ 13961 present |= snd_hda_jack_detect(codec, 0x1a); 13962 13963 bits = present ? HDA_AMP_MUTE : 0; 13964 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 13965 HDA_AMP_MUTE, bits); 13966 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 13967 HDA_AMP_MUTE, bits); 13968 13969 snd_hda_codec_write(codec, 0x20, 0, 13970 AC_VERB_SET_COEF_INDEX, 0x0c); 13971 snd_hda_codec_write(codec, 0x20, 0, 13972 AC_VERB_SET_PROC_COEF, 0x680); 13973 13974 snd_hda_codec_write(codec, 0x20, 0, 13975 AC_VERB_SET_COEF_INDEX, 0x0c); 13976 snd_hda_codec_write(codec, 0x20, 0, 13977 AC_VERB_SET_PROC_COEF, 0x480); 13978} 13979 13980static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 13981{ 13982 unsigned int present_laptop; 13983 unsigned int present_dock; 13984 13985 present_laptop = snd_hda_jack_detect(codec, 0x18); 13986 present_dock = snd_hda_jack_detect(codec, 0x1b); 13987 13988 /* Laptop mic port overrides dock mic port, design decision */ 13989 if (present_dock) 13990 snd_hda_codec_write(codec, 0x23, 0, 13991 AC_VERB_SET_CONNECT_SEL, 0x3); 13992 if (present_laptop) 13993 snd_hda_codec_write(codec, 0x23, 0, 13994 AC_VERB_SET_CONNECT_SEL, 0x0); 13995 if (!present_dock && !present_laptop) 13996 snd_hda_codec_write(codec, 0x23, 0, 13997 AC_VERB_SET_CONNECT_SEL, 0x1); 13998} 13999 14000static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14001 unsigned int res) 14002{ 14003 switch (res >> 26) { 14004 case ALC880_HP_EVENT: 14005 alc269_quanta_fl1_speaker_automute(codec); 14006 break; 14007 case ALC880_MIC_EVENT: 14008 alc_mic_automute(codec); 14009 break; 14010 } 14011} 14012 14013static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14014 unsigned int res) 14015{ 14016 if ((res >> 26) == ALC880_HP_EVENT) 14017 alc269_lifebook_speaker_automute(codec); 14018 if ((res >> 26) == ALC880_MIC_EVENT) 14019 alc269_lifebook_mic_autoswitch(codec); 14020} 14021 14022static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14023{ 14024 struct alc_spec *spec = codec->spec; 14025 spec->autocfg.hp_pins[0] = 0x15; 14026 spec->autocfg.speaker_pins[0] = 0x14; 14027 spec->ext_mic.pin = 0x18; 14028 spec->ext_mic.mux_idx = 0; 14029 spec->int_mic.pin = 0x19; 14030 spec->int_mic.mux_idx = 1; 14031 spec->auto_mic = 1; 14032} 14033 14034static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14035{ 14036 alc269_quanta_fl1_speaker_automute(codec); 14037 alc_mic_automute(codec); 14038} 14039 14040static void alc269_lifebook_init_hook(struct hda_codec *codec) 14041{ 14042 alc269_lifebook_speaker_automute(codec); 14043 alc269_lifebook_mic_autoswitch(codec); 14044} 14045 14046static struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14048 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14049 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14050 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14051 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14052 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14054 {} 14055}; 14056 14057static struct hda_verb alc269_laptop_amic_init_verbs[] = { 14058 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14059 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14060 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14062 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14063 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14064 {} 14065}; 14066 14067static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14068 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14069 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14070 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14072 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14073 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14074 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14075 {} 14076}; 14077 14078static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14079 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14080 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14081 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14082 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14083 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14085 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14086 {} 14087}; 14088 14089/* toggle speaker-output according to the hp-jack state */ 14090static void alc269_speaker_automute(struct hda_codec *codec) 14091{ 14092 struct alc_spec *spec = codec->spec; 14093 unsigned int nid = spec->autocfg.hp_pins[0]; 14094 unsigned int present; 14095 unsigned char bits; 14096 14097 present = snd_hda_jack_detect(codec, nid); 14098 bits = present ? HDA_AMP_MUTE : 0; 14099 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 14100 HDA_AMP_MUTE, bits); 14101 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 14102 HDA_AMP_MUTE, bits); 14103} 14104 14105/* unsolicited event for HP jack sensing */ 14106static void alc269_laptop_unsol_event(struct hda_codec *codec, 14107 unsigned int res) 14108{ 14109 switch (res >> 26) { 14110 case ALC880_HP_EVENT: 14111 alc269_speaker_automute(codec); 14112 break; 14113 case ALC880_MIC_EVENT: 14114 alc_mic_automute(codec); 14115 break; 14116 } 14117} 14118 14119static void alc269_laptop_amic_setup(struct hda_codec *codec) 14120{ 14121 struct alc_spec *spec = codec->spec; 14122 spec->autocfg.hp_pins[0] = 0x15; 14123 spec->autocfg.speaker_pins[0] = 0x14; 14124 spec->ext_mic.pin = 0x18; 14125 spec->ext_mic.mux_idx = 0; 14126 spec->int_mic.pin = 0x19; 14127 spec->int_mic.mux_idx = 1; 14128 spec->auto_mic = 1; 14129} 14130 14131static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14132{ 14133 struct alc_spec *spec = codec->spec; 14134 spec->autocfg.hp_pins[0] = 0x15; 14135 spec->autocfg.speaker_pins[0] = 0x14; 14136 spec->ext_mic.pin = 0x18; 14137 spec->ext_mic.mux_idx = 0; 14138 spec->int_mic.pin = 0x12; 14139 spec->int_mic.mux_idx = 5; 14140 spec->auto_mic = 1; 14141} 14142 14143static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14144{ 14145 struct alc_spec *spec = codec->spec; 14146 spec->autocfg.hp_pins[0] = 0x21; 14147 spec->autocfg.speaker_pins[0] = 0x14; 14148 spec->ext_mic.pin = 0x18; 14149 spec->ext_mic.mux_idx = 0; 14150 spec->int_mic.pin = 0x19; 14151 spec->int_mic.mux_idx = 1; 14152 spec->auto_mic = 1; 14153} 14154 14155static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14156{ 14157 struct alc_spec *spec = codec->spec; 14158 spec->autocfg.hp_pins[0] = 0x21; 14159 spec->autocfg.speaker_pins[0] = 0x14; 14160 spec->ext_mic.pin = 0x18; 14161 spec->ext_mic.mux_idx = 0; 14162 spec->int_mic.pin = 0x12; 14163 spec->int_mic.mux_idx = 6; 14164 spec->auto_mic = 1; 14165} 14166 14167static void alc269_laptop_inithook(struct hda_codec *codec) 14168{ 14169 alc269_speaker_automute(codec); 14170 alc_mic_automute(codec); 14171} 14172 14173/* 14174 * generic initialization of ADC, input mixers and output mixers 14175 */ 14176static struct hda_verb alc269_init_verbs[] = { 14177 /* 14178 * Unmute ADC0 and set the default input to mic-in 14179 */ 14180 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14181 14182 /* 14183 * Set up output mixers (0x02 - 0x03) 14184 */ 14185 /* set vol=0 to output mixers */ 14186 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14187 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14188 14189 /* set up input amps for analog loopback */ 14190 /* Amp Indices: DAC = 0, mixer = 1 */ 14191 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14192 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14193 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14194 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14195 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14196 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14197 14198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14200 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14201 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14202 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14203 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14204 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14205 14206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14208 14209 /* FIXME: use Mux-type input source selection */ 14210 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14211 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14212 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14213 14214 /* set EAPD */ 14215 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14216 { } 14217}; 14218 14219static struct hda_verb alc269vb_init_verbs[] = { 14220 /* 14221 * Unmute ADC0 and set the default input to mic-in 14222 */ 14223 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14224 14225 /* 14226 * Set up output mixers (0x02 - 0x03) 14227 */ 14228 /* set vol=0 to output mixers */ 14229 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14230 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14231 14232 /* set up input amps for analog loopback */ 14233 /* Amp Indices: DAC = 0, mixer = 1 */ 14234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14235 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14236 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14237 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14239 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14240 14241 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14242 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14243 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14244 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14247 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14248 14249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14250 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14251 14252 /* FIXME: use Mux-type input source selection */ 14253 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14254 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14255 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14256 14257 /* set EAPD */ 14258 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14259 { } 14260}; 14261 14262#define alc269_auto_create_multi_out_ctls \ 14263 alc268_auto_create_multi_out_ctls 14264#define alc269_auto_create_input_ctls \ 14265 alc268_auto_create_input_ctls 14266 14267#ifdef CONFIG_SND_HDA_POWER_SAVE 14268#define alc269_loopbacks alc880_loopbacks 14269#endif 14270 14271/* pcm configuration: identical with ALC880 */ 14272#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14273#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14274#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14275#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14276 14277static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14278 .substreams = 1, 14279 .channels_min = 2, 14280 .channels_max = 8, 14281 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14282 /* NID is set in alc_build_pcms */ 14283 .ops = { 14284 .open = alc880_playback_pcm_open, 14285 .prepare = alc880_playback_pcm_prepare, 14286 .cleanup = alc880_playback_pcm_cleanup 14287 }, 14288}; 14289 14290static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14291 .substreams = 1, 14292 .channels_min = 2, 14293 .channels_max = 2, 14294 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14295 /* NID is set in alc_build_pcms */ 14296}; 14297 14298#ifdef CONFIG_SND_HDA_POWER_SAVE 14299static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14300{ 14301 switch (codec->subsystem_id) { 14302 case 0x103c1586: 14303 return 1; 14304 } 14305 return 0; 14306} 14307 14308static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14309{ 14310 /* update mute-LED according to the speaker mute state */ 14311 if (nid == 0x01 || nid == 0x14) { 14312 int pinval; 14313 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14314 HDA_AMP_MUTE) 14315 pinval = 0x24; 14316 else 14317 pinval = 0x20; 14318 /* mic2 vref pin is used for mute LED control */ 14319 snd_hda_codec_update_cache(codec, 0x19, 0, 14320 AC_VERB_SET_PIN_WIDGET_CONTROL, 14321 pinval); 14322 } 14323 return alc_check_power_status(codec, nid); 14324} 14325#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14326 14327static int alc275_setup_dual_adc(struct hda_codec *codec) 14328{ 14329 struct alc_spec *spec = codec->spec; 14330 14331 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14332 return 0; 14333 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14334 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14335 if (spec->ext_mic.pin <= 0x12) { 14336 spec->private_adc_nids[0] = 0x08; 14337 spec->private_adc_nids[1] = 0x11; 14338 spec->private_capsrc_nids[0] = 0x23; 14339 spec->private_capsrc_nids[1] = 0x22; 14340 } else { 14341 spec->private_adc_nids[0] = 0x11; 14342 spec->private_adc_nids[1] = 0x08; 14343 spec->private_capsrc_nids[0] = 0x22; 14344 spec->private_capsrc_nids[1] = 0x23; 14345 } 14346 spec->adc_nids = spec->private_adc_nids; 14347 spec->capsrc_nids = spec->private_capsrc_nids; 14348 spec->num_adc_nids = 2; 14349 spec->dual_adc_switch = 1; 14350 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14351 spec->adc_nids[0], spec->adc_nids[1]); 14352 return 1; 14353 } 14354 return 0; 14355} 14356 14357/* 14358 * BIOS auto configuration 14359 */ 14360static int alc269_parse_auto_config(struct hda_codec *codec) 14361{ 14362 struct alc_spec *spec = codec->spec; 14363 int err; 14364 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14365 14366 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14367 alc269_ignore); 14368 if (err < 0) 14369 return err; 14370 14371 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14372 if (err < 0) 14373 return err; 14374 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14375 if (err < 0) 14376 return err; 14377 14378 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14379 14380 alc_auto_parse_digital(codec); 14381 14382 if (spec->kctls.list) 14383 add_mixer(spec, spec->kctls.list); 14384 14385 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { 14386 add_verb(spec, alc269vb_init_verbs); 14387 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14388 } else { 14389 add_verb(spec, alc269_init_verbs); 14390 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14391 } 14392 14393 spec->num_mux_defs = 1; 14394 spec->input_mux = &spec->private_imux[0]; 14395 14396 if (!alc275_setup_dual_adc(codec)) 14397 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14398 sizeof(alc269_adc_candidates)); 14399 14400 /* set default input source */ 14401 if (!spec->dual_adc_switch) 14402 select_or_unmute_capsrc(codec, spec->capsrc_nids[0], 14403 spec->input_mux->items[0].index); 14404 14405 err = alc_auto_add_mic_boost(codec); 14406 if (err < 0) 14407 return err; 14408 14409 if (!spec->cap_mixer && !spec->no_analog) 14410 set_capture_mixer(codec); 14411 14412 return 1; 14413} 14414 14415#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14416#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14417#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14418 14419 14420/* init callback for auto-configuration model -- overriding the default init */ 14421static void alc269_auto_init(struct hda_codec *codec) 14422{ 14423 struct alc_spec *spec = codec->spec; 14424 alc269_auto_init_multi_out(codec); 14425 alc269_auto_init_hp_out(codec); 14426 alc269_auto_init_analog_input(codec); 14427 alc_auto_init_digital(codec); 14428 if (spec->unsol_event) 14429 alc_inithook(codec); 14430} 14431 14432enum { 14433 ALC269_FIXUP_SONY_VAIO, 14434}; 14435 14436static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = { 14437 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14438 {} 14439}; 14440 14441static const struct alc_fixup alc269_fixups[] = { 14442 [ALC269_FIXUP_SONY_VAIO] = { 14443 .verbs = alc269_sony_vaio_fixup_verbs 14444 }, 14445}; 14446 14447static struct snd_pci_quirk alc269_fixup_tbl[] = { 14448 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14449 {} 14450}; 14451 14452 14453/* 14454 * configuration and preset 14455 */ 14456static const char *alc269_models[ALC269_MODEL_LAST] = { 14457 [ALC269_BASIC] = "basic", 14458 [ALC269_QUANTA_FL1] = "quanta", 14459 [ALC269_AMIC] = "laptop-amic", 14460 [ALC269_DMIC] = "laptop-dmic", 14461 [ALC269_FUJITSU] = "fujitsu", 14462 [ALC269_LIFEBOOK] = "lifebook", 14463 [ALC269_AUTO] = "auto", 14464}; 14465 14466static struct snd_pci_quirk alc269_cfg_tbl[] = { 14467 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 14468 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 14469 ALC269_AMIC), 14470 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 14471 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 14472 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 14473 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 14474 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 14475 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 14476 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 14477 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 14478 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 14479 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), 14480 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 14481 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 14482 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 14483 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 14484 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 14485 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 14486 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 14487 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 14488 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 14489 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 14490 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 14491 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 14492 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 14493 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 14494 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 14495 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 14496 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 14497 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 14498 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 14499 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 14500 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 14501 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 14502 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 14503 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 14504 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 14505 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 14506 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 14507 ALC269_DMIC), 14508 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 14509 ALC269_DMIC), 14510 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 14511 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 14512 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 14513 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 14514 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 14515 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 14516 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 14517 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 14518 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 14519 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 14520 {} 14521}; 14522 14523static struct alc_config_preset alc269_presets[] = { 14524 [ALC269_BASIC] = { 14525 .mixers = { alc269_base_mixer }, 14526 .init_verbs = { alc269_init_verbs }, 14527 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14528 .dac_nids = alc269_dac_nids, 14529 .hp_nid = 0x03, 14530 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14531 .channel_mode = alc269_modes, 14532 .input_mux = &alc269_capture_source, 14533 }, 14534 [ALC269_QUANTA_FL1] = { 14535 .mixers = { alc269_quanta_fl1_mixer }, 14536 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 14537 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14538 .dac_nids = alc269_dac_nids, 14539 .hp_nid = 0x03, 14540 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14541 .channel_mode = alc269_modes, 14542 .input_mux = &alc269_capture_source, 14543 .unsol_event = alc269_quanta_fl1_unsol_event, 14544 .setup = alc269_quanta_fl1_setup, 14545 .init_hook = alc269_quanta_fl1_init_hook, 14546 }, 14547 [ALC269_AMIC] = { 14548 .mixers = { alc269_laptop_mixer }, 14549 .cap_mixer = alc269_laptop_analog_capture_mixer, 14550 .init_verbs = { alc269_init_verbs, 14551 alc269_laptop_amic_init_verbs }, 14552 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14553 .dac_nids = alc269_dac_nids, 14554 .hp_nid = 0x03, 14555 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14556 .channel_mode = alc269_modes, 14557 .unsol_event = alc269_laptop_unsol_event, 14558 .setup = alc269_laptop_amic_setup, 14559 .init_hook = alc269_laptop_inithook, 14560 }, 14561 [ALC269_DMIC] = { 14562 .mixers = { alc269_laptop_mixer }, 14563 .cap_mixer = alc269_laptop_digital_capture_mixer, 14564 .init_verbs = { alc269_init_verbs, 14565 alc269_laptop_dmic_init_verbs }, 14566 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14567 .dac_nids = alc269_dac_nids, 14568 .hp_nid = 0x03, 14569 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14570 .channel_mode = alc269_modes, 14571 .unsol_event = alc269_laptop_unsol_event, 14572 .setup = alc269_laptop_dmic_setup, 14573 .init_hook = alc269_laptop_inithook, 14574 }, 14575 [ALC269VB_AMIC] = { 14576 .mixers = { alc269vb_laptop_mixer }, 14577 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 14578 .init_verbs = { alc269vb_init_verbs, 14579 alc269vb_laptop_amic_init_verbs }, 14580 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14581 .dac_nids = alc269_dac_nids, 14582 .hp_nid = 0x03, 14583 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14584 .channel_mode = alc269_modes, 14585 .unsol_event = alc269_laptop_unsol_event, 14586 .setup = alc269vb_laptop_amic_setup, 14587 .init_hook = alc269_laptop_inithook, 14588 }, 14589 [ALC269VB_DMIC] = { 14590 .mixers = { alc269vb_laptop_mixer }, 14591 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 14592 .init_verbs = { alc269vb_init_verbs, 14593 alc269vb_laptop_dmic_init_verbs }, 14594 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14595 .dac_nids = alc269_dac_nids, 14596 .hp_nid = 0x03, 14597 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14598 .channel_mode = alc269_modes, 14599 .unsol_event = alc269_laptop_unsol_event, 14600 .setup = alc269vb_laptop_dmic_setup, 14601 .init_hook = alc269_laptop_inithook, 14602 }, 14603 [ALC269_FUJITSU] = { 14604 .mixers = { alc269_fujitsu_mixer }, 14605 .cap_mixer = alc269_laptop_digital_capture_mixer, 14606 .init_verbs = { alc269_init_verbs, 14607 alc269_laptop_dmic_init_verbs }, 14608 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14609 .dac_nids = alc269_dac_nids, 14610 .hp_nid = 0x03, 14611 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14612 .channel_mode = alc269_modes, 14613 .unsol_event = alc269_laptop_unsol_event, 14614 .setup = alc269_laptop_dmic_setup, 14615 .init_hook = alc269_laptop_inithook, 14616 }, 14617 [ALC269_LIFEBOOK] = { 14618 .mixers = { alc269_lifebook_mixer }, 14619 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 14620 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14621 .dac_nids = alc269_dac_nids, 14622 .hp_nid = 0x03, 14623 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14624 .channel_mode = alc269_modes, 14625 .input_mux = &alc269_capture_source, 14626 .unsol_event = alc269_lifebook_unsol_event, 14627 .init_hook = alc269_lifebook_init_hook, 14628 }, 14629}; 14630 14631static int patch_alc269(struct hda_codec *codec) 14632{ 14633 struct alc_spec *spec; 14634 int board_config; 14635 int err; 14636 int is_alc269vb = 0; 14637 14638 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14639 if (spec == NULL) 14640 return -ENOMEM; 14641 14642 codec->spec = spec; 14643 14644 alc_auto_parse_customize_define(codec); 14645 14646 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ 14647 if (codec->bus->pci->subsystem_vendor == 0x1025 && 14648 spec->cdefine.platform_type == 1) 14649 alc_codec_rename(codec, "ALC271X"); 14650 else 14651 alc_codec_rename(codec, "ALC259"); 14652 is_alc269vb = 1; 14653 } else 14654 alc_fix_pll_init(codec, 0x20, 0x04, 15); 14655 14656 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14657 alc269_models, 14658 alc269_cfg_tbl); 14659 14660 if (board_config < 0) { 14661 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14662 codec->chip_name); 14663 board_config = ALC269_AUTO; 14664 } 14665 14666 if (board_config == ALC269_AUTO) 14667 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 14668 14669 if (board_config == ALC269_AUTO) { 14670 /* automatic parse from the BIOS config */ 14671 err = alc269_parse_auto_config(codec); 14672 if (err < 0) { 14673 alc_free(codec); 14674 return err; 14675 } else if (!err) { 14676 printk(KERN_INFO 14677 "hda_codec: Cannot set up configuration " 14678 "from BIOS. Using base mode...\n"); 14679 board_config = ALC269_BASIC; 14680 } 14681 } 14682 14683 if (has_cdefine_beep(codec)) { 14684 err = snd_hda_attach_beep_device(codec, 0x1); 14685 if (err < 0) { 14686 alc_free(codec); 14687 return err; 14688 } 14689 } 14690 14691 if (board_config != ALC269_AUTO) 14692 setup_preset(codec, &alc269_presets[board_config]); 14693 14694 if (board_config == ALC269_QUANTA_FL1) { 14695 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14696 * fix the sample rate of analog I/O to 44.1kHz 14697 */ 14698 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 14699 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 14700 } else if (spec->dual_adc_switch) { 14701 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14702 /* switch ADC dynamically */ 14703 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 14704 } else { 14705 spec->stream_analog_playback = &alc269_pcm_analog_playback; 14706 spec->stream_analog_capture = &alc269_pcm_analog_capture; 14707 } 14708 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14709 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14710 14711 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 14712 if (!is_alc269vb) { 14713 spec->adc_nids = alc269_adc_nids; 14714 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14715 spec->capsrc_nids = alc269_capsrc_nids; 14716 } else { 14717 spec->adc_nids = alc269vb_adc_nids; 14718 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 14719 spec->capsrc_nids = alc269vb_capsrc_nids; 14720 } 14721 } 14722 14723 if (!spec->cap_mixer) 14724 set_capture_mixer(codec); 14725 if (has_cdefine_beep(codec)) 14726 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14727 14728 if (board_config == ALC269_AUTO) 14729 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); 14730 14731 spec->vmaster_nid = 0x02; 14732 14733 codec->patch_ops = alc_patch_ops; 14734 if (board_config == ALC269_AUTO) 14735 spec->init_hook = alc269_auto_init; 14736#ifdef CONFIG_SND_HDA_POWER_SAVE 14737 if (!spec->loopback.amplist) 14738 spec->loopback.amplist = alc269_loopbacks; 14739 if (alc269_mic2_for_mute_led(codec)) 14740 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 14741#endif 14742 14743 return 0; 14744} 14745 14746/* 14747 * ALC861 channel source setting (2/6 channel selection for 3-stack) 14748 */ 14749 14750/* 14751 * set the path ways for 2 channel output 14752 * need to set the codec line out and mic 1 pin widgets to inputs 14753 */ 14754static struct hda_verb alc861_threestack_ch2_init[] = { 14755 /* set pin widget 1Ah (line in) for input */ 14756 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14757 /* set pin widget 18h (mic1/2) for input, for mic also enable 14758 * the vref 14759 */ 14760 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14761 14762 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14763#if 0 14764 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14765 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14766#endif 14767 { } /* end */ 14768}; 14769/* 14770 * 6ch mode 14771 * need to set the codec line out and mic 1 pin widgets to outputs 14772 */ 14773static struct hda_verb alc861_threestack_ch6_init[] = { 14774 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14775 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14776 /* set pin widget 18h (mic1) for output (CLFE)*/ 14777 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14778 14779 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14780 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14781 14782 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14783#if 0 14784 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14785 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14786#endif 14787 { } /* end */ 14788}; 14789 14790static struct hda_channel_mode alc861_threestack_modes[2] = { 14791 { 2, alc861_threestack_ch2_init }, 14792 { 6, alc861_threestack_ch6_init }, 14793}; 14794/* Set mic1 as input and unmute the mixer */ 14795static struct hda_verb alc861_uniwill_m31_ch2_init[] = { 14796 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14797 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14798 { } /* end */ 14799}; 14800/* Set mic1 as output and mute mixer */ 14801static struct hda_verb alc861_uniwill_m31_ch4_init[] = { 14802 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14803 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14804 { } /* end */ 14805}; 14806 14807static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 14808 { 2, alc861_uniwill_m31_ch2_init }, 14809 { 4, alc861_uniwill_m31_ch4_init }, 14810}; 14811 14812/* Set mic1 and line-in as input and unmute the mixer */ 14813static struct hda_verb alc861_asus_ch2_init[] = { 14814 /* set pin widget 1Ah (line in) for input */ 14815 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 14816 /* set pin widget 18h (mic1/2) for input, for mic also enable 14817 * the vref 14818 */ 14819 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14820 14821 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 14822#if 0 14823 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 14824 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 14825#endif 14826 { } /* end */ 14827}; 14828/* Set mic1 nad line-in as output and mute mixer */ 14829static struct hda_verb alc861_asus_ch6_init[] = { 14830 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 14831 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14832 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14833 /* set pin widget 18h (mic1) for output (CLFE)*/ 14834 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14835 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 14836 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14837 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14838 14839 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 14840#if 0 14841 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 14842 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 14843#endif 14844 { } /* end */ 14845}; 14846 14847static struct hda_channel_mode alc861_asus_modes[2] = { 14848 { 2, alc861_asus_ch2_init }, 14849 { 6, alc861_asus_ch6_init }, 14850}; 14851 14852/* patch-ALC861 */ 14853 14854static struct snd_kcontrol_new alc861_base_mixer[] = { 14855 /* output mixer control */ 14856 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14857 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14858 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14859 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14860 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14861 14862 /*Input mixer control */ 14863 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14864 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14865 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14866 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14867 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14868 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14869 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14870 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14871 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14873 14874 { } /* end */ 14875}; 14876 14877static struct snd_kcontrol_new alc861_3ST_mixer[] = { 14878 /* output mixer control */ 14879 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14880 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14881 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14882 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14883 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14884 14885 /* Input mixer control */ 14886 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14887 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14888 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14889 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14890 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14891 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14893 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14896 14897 { 14898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14899 .name = "Channel Mode", 14900 .info = alc_ch_mode_info, 14901 .get = alc_ch_mode_get, 14902 .put = alc_ch_mode_put, 14903 .private_value = ARRAY_SIZE(alc861_threestack_modes), 14904 }, 14905 { } /* end */ 14906}; 14907 14908static struct snd_kcontrol_new alc861_toshiba_mixer[] = { 14909 /* output mixer control */ 14910 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14912 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14913 14914 { } /* end */ 14915}; 14916 14917static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 14918 /* output mixer control */ 14919 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14920 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14921 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14922 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14923 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 14924 14925 /* Input mixer control */ 14926 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14927 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 14928 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14929 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14930 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14931 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14933 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14934 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14935 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 14936 14937 { 14938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14939 .name = "Channel Mode", 14940 .info = alc_ch_mode_info, 14941 .get = alc_ch_mode_get, 14942 .put = alc_ch_mode_put, 14943 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 14944 }, 14945 { } /* end */ 14946}; 14947 14948static struct snd_kcontrol_new alc861_asus_mixer[] = { 14949 /* output mixer control */ 14950 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 14951 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 14952 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 14953 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 14954 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 14955 14956 /* Input mixer control */ 14957 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 14958 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14959 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14960 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14961 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 14962 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 14963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 14964 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 14965 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 14966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 14967 14968 { 14969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14970 .name = "Channel Mode", 14971 .info = alc_ch_mode_info, 14972 .get = alc_ch_mode_get, 14973 .put = alc_ch_mode_put, 14974 .private_value = ARRAY_SIZE(alc861_asus_modes), 14975 }, 14976 { } 14977}; 14978 14979/* additional mixer */ 14980static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 14981 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 14982 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 14983 { } 14984}; 14985 14986/* 14987 * generic initialization of ADC, input mixers and output mixers 14988 */ 14989static struct hda_verb alc861_base_init_verbs[] = { 14990 /* 14991 * Unmute ADC0 and set the default input to mic-in 14992 */ 14993 /* port-A for surround (rear panel) */ 14994 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 14995 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 14996 /* port-B for mic-in (rear panel) with vref */ 14997 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 14998 /* port-C for line-in (rear panel) */ 14999 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15000 /* port-D for Front */ 15001 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15002 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15003 /* port-E for HP out (front panel) */ 15004 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15005 /* route front PCM to HP */ 15006 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15007 /* port-F for mic-in (front panel) with vref */ 15008 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15009 /* port-G for CLFE (rear panel) */ 15010 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15011 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15012 /* port-H for side (rear panel) */ 15013 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15014 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15015 /* CD-in */ 15016 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15017 /* route front mic to ADC1*/ 15018 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15020 15021 /* Unmute DAC0~3 & spdif out*/ 15022 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15023 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15024 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15025 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15026 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15027 15028 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15029 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15030 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15031 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15032 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15033 15034 /* Unmute Stereo Mixer 15 */ 15035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15039 15040 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15041 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15042 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15043 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15044 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15045 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15047 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15048 /* hp used DAC 3 (Front) */ 15049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15051 15052 { } 15053}; 15054 15055static struct hda_verb alc861_threestack_init_verbs[] = { 15056 /* 15057 * Unmute ADC0 and set the default input to mic-in 15058 */ 15059 /* port-A for surround (rear panel) */ 15060 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15061 /* port-B for mic-in (rear panel) with vref */ 15062 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15063 /* port-C for line-in (rear panel) */ 15064 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15065 /* port-D for Front */ 15066 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15067 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15068 /* port-E for HP out (front panel) */ 15069 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15070 /* route front PCM to HP */ 15071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15072 /* port-F for mic-in (front panel) with vref */ 15073 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15074 /* port-G for CLFE (rear panel) */ 15075 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15076 /* port-H for side (rear panel) */ 15077 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15078 /* CD-in */ 15079 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15080 /* route front mic to ADC1*/ 15081 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15082 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15083 /* Unmute DAC0~3 & spdif out*/ 15084 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15085 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15086 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15087 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15088 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15089 15090 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15091 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15092 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15093 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15094 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15095 15096 /* Unmute Stereo Mixer 15 */ 15097 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15100 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15101 15102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15104 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15105 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15106 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15107 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15108 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15109 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15110 /* hp used DAC 3 (Front) */ 15111 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15112 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15113 { } 15114}; 15115 15116static struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15117 /* 15118 * Unmute ADC0 and set the default input to mic-in 15119 */ 15120 /* port-A for surround (rear panel) */ 15121 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15122 /* port-B for mic-in (rear panel) with vref */ 15123 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15124 /* port-C for line-in (rear panel) */ 15125 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15126 /* port-D for Front */ 15127 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15128 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15129 /* port-E for HP out (front panel) */ 15130 /* this has to be set to VREF80 */ 15131 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15132 /* route front PCM to HP */ 15133 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15134 /* port-F for mic-in (front panel) with vref */ 15135 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15136 /* port-G for CLFE (rear panel) */ 15137 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15138 /* port-H for side (rear panel) */ 15139 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15140 /* CD-in */ 15141 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15142 /* route front mic to ADC1*/ 15143 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15145 /* Unmute DAC0~3 & spdif out*/ 15146 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15147 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15148 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15149 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15151 15152 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15153 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15154 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15155 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15156 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15157 15158 /* Unmute Stereo Mixer 15 */ 15159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15160 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15163 15164 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15165 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15166 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15167 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15168 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15169 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15170 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15171 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15172 /* hp used DAC 3 (Front) */ 15173 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15174 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15175 { } 15176}; 15177 15178static struct hda_verb alc861_asus_init_verbs[] = { 15179 /* 15180 * Unmute ADC0 and set the default input to mic-in 15181 */ 15182 /* port-A for surround (rear panel) 15183 * according to codec#0 this is the HP jack 15184 */ 15185 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15186 /* route front PCM to HP */ 15187 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15188 /* port-B for mic-in (rear panel) with vref */ 15189 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15190 /* port-C for line-in (rear panel) */ 15191 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15192 /* port-D for Front */ 15193 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15194 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15195 /* port-E for HP out (front panel) */ 15196 /* this has to be set to VREF80 */ 15197 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15198 /* route front PCM to HP */ 15199 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15200 /* port-F for mic-in (front panel) with vref */ 15201 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15202 /* port-G for CLFE (rear panel) */ 15203 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15204 /* port-H for side (rear panel) */ 15205 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15206 /* CD-in */ 15207 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15208 /* route front mic to ADC1*/ 15209 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15210 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15211 /* Unmute DAC0~3 & spdif out*/ 15212 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15213 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15214 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15215 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15217 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15218 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15219 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15220 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15221 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15222 15223 /* Unmute Stereo Mixer 15 */ 15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15227 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15228 15229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15231 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15235 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15237 /* hp used DAC 3 (Front) */ 15238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15240 { } 15241}; 15242 15243/* additional init verbs for ASUS laptops */ 15244static struct hda_verb alc861_asus_laptop_init_verbs[] = { 15245 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15246 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15247 { } 15248}; 15249 15250/* 15251 * generic initialization of ADC, input mixers and output mixers 15252 */ 15253static struct hda_verb alc861_auto_init_verbs[] = { 15254 /* 15255 * Unmute ADC0 and set the default input to mic-in 15256 */ 15257 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15259 15260 /* Unmute DAC0~3 & spdif out*/ 15261 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15262 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15263 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15264 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15266 15267 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15268 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15269 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15270 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15271 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15272 15273 /* Unmute Stereo Mixer 15 */ 15274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15275 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15278 15279 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15280 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15281 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15282 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15283 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15284 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15285 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15286 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15287 15288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15289 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15290 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15291 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15293 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15294 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15295 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15296 15297 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15298 15299 { } 15300}; 15301 15302static struct hda_verb alc861_toshiba_init_verbs[] = { 15303 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15304 15305 { } 15306}; 15307 15308/* toggle speaker-output according to the hp-jack state */ 15309static void alc861_toshiba_automute(struct hda_codec *codec) 15310{ 15311 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15312 15313 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15314 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15315 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15316 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15317} 15318 15319static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15320 unsigned int res) 15321{ 15322 if ((res >> 26) == ALC880_HP_EVENT) 15323 alc861_toshiba_automute(codec); 15324} 15325 15326/* pcm configuration: identical with ALC880 */ 15327#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15328#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15329#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15330#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15331 15332 15333#define ALC861_DIGOUT_NID 0x07 15334 15335static struct hda_channel_mode alc861_8ch_modes[1] = { 15336 { 8, NULL } 15337}; 15338 15339static hda_nid_t alc861_dac_nids[4] = { 15340 /* front, surround, clfe, side */ 15341 0x03, 0x06, 0x05, 0x04 15342}; 15343 15344static hda_nid_t alc660_dac_nids[3] = { 15345 /* front, clfe, surround */ 15346 0x03, 0x05, 0x06 15347}; 15348 15349static hda_nid_t alc861_adc_nids[1] = { 15350 /* ADC0-2 */ 15351 0x08, 15352}; 15353 15354static struct hda_input_mux alc861_capture_source = { 15355 .num_items = 5, 15356 .items = { 15357 { "Mic", 0x0 }, 15358 { "Front Mic", 0x3 }, 15359 { "Line", 0x1 }, 15360 { "CD", 0x4 }, 15361 { "Mixer", 0x5 }, 15362 }, 15363}; 15364 15365static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 15366{ 15367 struct alc_spec *spec = codec->spec; 15368 hda_nid_t mix, srcs[5]; 15369 int i, j, num; 15370 15371 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 15372 return 0; 15373 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15374 if (num < 0) 15375 return 0; 15376 for (i = 0; i < num; i++) { 15377 unsigned int type; 15378 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 15379 if (type != AC_WID_AUD_OUT) 15380 continue; 15381 for (j = 0; j < spec->multiout.num_dacs; j++) 15382 if (spec->multiout.dac_nids[j] == srcs[i]) 15383 break; 15384 if (j >= spec->multiout.num_dacs) 15385 return srcs[i]; 15386 } 15387 return 0; 15388} 15389 15390/* fill in the dac_nids table from the parsed pin configuration */ 15391static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 15392 const struct auto_pin_cfg *cfg) 15393{ 15394 struct alc_spec *spec = codec->spec; 15395 int i; 15396 hda_nid_t nid, dac; 15397 15398 spec->multiout.dac_nids = spec->private_dac_nids; 15399 for (i = 0; i < cfg->line_outs; i++) { 15400 nid = cfg->line_out_pins[i]; 15401 dac = alc861_look_for_dac(codec, nid); 15402 if (!dac) 15403 continue; 15404 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 15405 } 15406 return 0; 15407} 15408 15409static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15410 hda_nid_t nid, unsigned int chs) 15411{ 15412 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 15413 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15414} 15415 15416/* add playback controls from the parsed DAC table */ 15417static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15418 const struct auto_pin_cfg *cfg) 15419{ 15420 struct alc_spec *spec = codec->spec; 15421 static const char *chname[4] = { 15422 "Front", "Surround", NULL /*CLFE*/, "Side" 15423 }; 15424 hda_nid_t nid; 15425 int i, err; 15426 15427 if (cfg->line_outs == 1) { 15428 const char *pfx = NULL; 15429 if (!cfg->hp_outs) 15430 pfx = "Master"; 15431 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 15432 pfx = "Speaker"; 15433 if (pfx) { 15434 nid = spec->multiout.dac_nids[0]; 15435 return alc861_create_out_sw(codec, pfx, nid, 3); 15436 } 15437 } 15438 15439 for (i = 0; i < cfg->line_outs; i++) { 15440 nid = spec->multiout.dac_nids[i]; 15441 if (!nid) 15442 continue; 15443 if (i == 2) { 15444 /* Center/LFE */ 15445 err = alc861_create_out_sw(codec, "Center", nid, 1); 15446 if (err < 0) 15447 return err; 15448 err = alc861_create_out_sw(codec, "LFE", nid, 2); 15449 if (err < 0) 15450 return err; 15451 } else { 15452 err = alc861_create_out_sw(codec, chname[i], nid, 3); 15453 if (err < 0) 15454 return err; 15455 } 15456 } 15457 return 0; 15458} 15459 15460static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 15461{ 15462 struct alc_spec *spec = codec->spec; 15463 int err; 15464 hda_nid_t nid; 15465 15466 if (!pin) 15467 return 0; 15468 15469 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 15470 nid = alc861_look_for_dac(codec, pin); 15471 if (nid) { 15472 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 15473 if (err < 0) 15474 return err; 15475 spec->multiout.hp_nid = nid; 15476 } 15477 } 15478 return 0; 15479} 15480 15481/* create playback/capture controls for input pins */ 15482static int alc861_auto_create_input_ctls(struct hda_codec *codec, 15483 const struct auto_pin_cfg *cfg) 15484{ 15485 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 15486} 15487 15488static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 15489 hda_nid_t nid, 15490 int pin_type, hda_nid_t dac) 15491{ 15492 hda_nid_t mix, srcs[5]; 15493 int i, num; 15494 15495 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 15496 pin_type); 15497 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15498 AMP_OUT_UNMUTE); 15499 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 15500 return; 15501 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 15502 if (num < 0) 15503 return; 15504 for (i = 0; i < num; i++) { 15505 unsigned int mute; 15506 if (srcs[i] == dac || srcs[i] == 0x15) 15507 mute = AMP_IN_UNMUTE(i); 15508 else 15509 mute = AMP_IN_MUTE(i); 15510 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 15511 mute); 15512 } 15513} 15514 15515static void alc861_auto_init_multi_out(struct hda_codec *codec) 15516{ 15517 struct alc_spec *spec = codec->spec; 15518 int i; 15519 15520 for (i = 0; i < spec->autocfg.line_outs; i++) { 15521 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 15522 int pin_type = get_pin_type(spec->autocfg.line_out_type); 15523 if (nid) 15524 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 15525 spec->multiout.dac_nids[i]); 15526 } 15527} 15528 15529static void alc861_auto_init_hp_out(struct hda_codec *codec) 15530{ 15531 struct alc_spec *spec = codec->spec; 15532 15533 if (spec->autocfg.hp_outs) 15534 alc861_auto_set_output_and_unmute(codec, 15535 spec->autocfg.hp_pins[0], 15536 PIN_HP, 15537 spec->multiout.hp_nid); 15538 if (spec->autocfg.speaker_outs) 15539 alc861_auto_set_output_and_unmute(codec, 15540 spec->autocfg.speaker_pins[0], 15541 PIN_OUT, 15542 spec->multiout.dac_nids[0]); 15543} 15544 15545static void alc861_auto_init_analog_input(struct hda_codec *codec) 15546{ 15547 struct alc_spec *spec = codec->spec; 15548 int i; 15549 15550 for (i = 0; i < AUTO_PIN_LAST; i++) { 15551 hda_nid_t nid = spec->autocfg.input_pins[i]; 15552 if (nid >= 0x0c && nid <= 0x11) 15553 alc_set_input_pin(codec, nid, i); 15554 } 15555} 15556 15557/* parse the BIOS configuration and set up the alc_spec */ 15558/* return 1 if successful, 0 if the proper config is not found, 15559 * or a negative error code 15560 */ 15561static int alc861_parse_auto_config(struct hda_codec *codec) 15562{ 15563 struct alc_spec *spec = codec->spec; 15564 int err; 15565 static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 15566 15567 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 15568 alc861_ignore); 15569 if (err < 0) 15570 return err; 15571 if (!spec->autocfg.line_outs) 15572 return 0; /* can't find valid BIOS pin config */ 15573 15574 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 15575 if (err < 0) 15576 return err; 15577 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 15578 if (err < 0) 15579 return err; 15580 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 15581 if (err < 0) 15582 return err; 15583 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 15584 if (err < 0) 15585 return err; 15586 15587 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 15588 15589 alc_auto_parse_digital(codec); 15590 15591 if (spec->kctls.list) 15592 add_mixer(spec, spec->kctls.list); 15593 15594 add_verb(spec, alc861_auto_init_verbs); 15595 15596 spec->num_mux_defs = 1; 15597 spec->input_mux = &spec->private_imux[0]; 15598 15599 spec->adc_nids = alc861_adc_nids; 15600 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15601 set_capture_mixer(codec); 15602 15603 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 15604 15605 return 1; 15606} 15607 15608/* additional initialization for auto-configuration model */ 15609static void alc861_auto_init(struct hda_codec *codec) 15610{ 15611 struct alc_spec *spec = codec->spec; 15612 alc861_auto_init_multi_out(codec); 15613 alc861_auto_init_hp_out(codec); 15614 alc861_auto_init_analog_input(codec); 15615 alc_auto_init_digital(codec); 15616 if (spec->unsol_event) 15617 alc_inithook(codec); 15618} 15619 15620#ifdef CONFIG_SND_HDA_POWER_SAVE 15621static struct hda_amp_list alc861_loopbacks[] = { 15622 { 0x15, HDA_INPUT, 0 }, 15623 { 0x15, HDA_INPUT, 1 }, 15624 { 0x15, HDA_INPUT, 2 }, 15625 { 0x15, HDA_INPUT, 3 }, 15626 { } /* end */ 15627}; 15628#endif 15629 15630 15631/* 15632 * configuration and preset 15633 */ 15634static const char *alc861_models[ALC861_MODEL_LAST] = { 15635 [ALC861_3ST] = "3stack", 15636 [ALC660_3ST] = "3stack-660", 15637 [ALC861_3ST_DIG] = "3stack-dig", 15638 [ALC861_6ST_DIG] = "6stack-dig", 15639 [ALC861_UNIWILL_M31] = "uniwill-m31", 15640 [ALC861_TOSHIBA] = "toshiba", 15641 [ALC861_ASUS] = "asus", 15642 [ALC861_ASUS_LAPTOP] = "asus-laptop", 15643 [ALC861_AUTO] = "auto", 15644}; 15645 15646static struct snd_pci_quirk alc861_cfg_tbl[] = { 15647 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 15648 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15649 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 15650 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 15651 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 15652 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 15653 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 15654 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 15655 * Any other models that need this preset? 15656 */ 15657 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 15658 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 15659 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 15660 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 15661 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 15662 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 15663 /* FIXME: the below seems conflict */ 15664 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 15665 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 15666 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 15667 {} 15668}; 15669 15670static struct alc_config_preset alc861_presets[] = { 15671 [ALC861_3ST] = { 15672 .mixers = { alc861_3ST_mixer }, 15673 .init_verbs = { alc861_threestack_init_verbs }, 15674 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15675 .dac_nids = alc861_dac_nids, 15676 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15677 .channel_mode = alc861_threestack_modes, 15678 .need_dac_fix = 1, 15679 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15680 .adc_nids = alc861_adc_nids, 15681 .input_mux = &alc861_capture_source, 15682 }, 15683 [ALC861_3ST_DIG] = { 15684 .mixers = { alc861_base_mixer }, 15685 .init_verbs = { alc861_threestack_init_verbs }, 15686 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15687 .dac_nids = alc861_dac_nids, 15688 .dig_out_nid = ALC861_DIGOUT_NID, 15689 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15690 .channel_mode = alc861_threestack_modes, 15691 .need_dac_fix = 1, 15692 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15693 .adc_nids = alc861_adc_nids, 15694 .input_mux = &alc861_capture_source, 15695 }, 15696 [ALC861_6ST_DIG] = { 15697 .mixers = { alc861_base_mixer }, 15698 .init_verbs = { alc861_base_init_verbs }, 15699 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15700 .dac_nids = alc861_dac_nids, 15701 .dig_out_nid = ALC861_DIGOUT_NID, 15702 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 15703 .channel_mode = alc861_8ch_modes, 15704 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15705 .adc_nids = alc861_adc_nids, 15706 .input_mux = &alc861_capture_source, 15707 }, 15708 [ALC660_3ST] = { 15709 .mixers = { alc861_3ST_mixer }, 15710 .init_verbs = { alc861_threestack_init_verbs }, 15711 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 15712 .dac_nids = alc660_dac_nids, 15713 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 15714 .channel_mode = alc861_threestack_modes, 15715 .need_dac_fix = 1, 15716 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15717 .adc_nids = alc861_adc_nids, 15718 .input_mux = &alc861_capture_source, 15719 }, 15720 [ALC861_UNIWILL_M31] = { 15721 .mixers = { alc861_uniwill_m31_mixer }, 15722 .init_verbs = { alc861_uniwill_m31_init_verbs }, 15723 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15724 .dac_nids = alc861_dac_nids, 15725 .dig_out_nid = ALC861_DIGOUT_NID, 15726 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 15727 .channel_mode = alc861_uniwill_m31_modes, 15728 .need_dac_fix = 1, 15729 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15730 .adc_nids = alc861_adc_nids, 15731 .input_mux = &alc861_capture_source, 15732 }, 15733 [ALC861_TOSHIBA] = { 15734 .mixers = { alc861_toshiba_mixer }, 15735 .init_verbs = { alc861_base_init_verbs, 15736 alc861_toshiba_init_verbs }, 15737 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15738 .dac_nids = alc861_dac_nids, 15739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15740 .channel_mode = alc883_3ST_2ch_modes, 15741 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15742 .adc_nids = alc861_adc_nids, 15743 .input_mux = &alc861_capture_source, 15744 .unsol_event = alc861_toshiba_unsol_event, 15745 .init_hook = alc861_toshiba_automute, 15746 }, 15747 [ALC861_ASUS] = { 15748 .mixers = { alc861_asus_mixer }, 15749 .init_verbs = { alc861_asus_init_verbs }, 15750 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15751 .dac_nids = alc861_dac_nids, 15752 .dig_out_nid = ALC861_DIGOUT_NID, 15753 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 15754 .channel_mode = alc861_asus_modes, 15755 .need_dac_fix = 1, 15756 .hp_nid = 0x06, 15757 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15758 .adc_nids = alc861_adc_nids, 15759 .input_mux = &alc861_capture_source, 15760 }, 15761 [ALC861_ASUS_LAPTOP] = { 15762 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 15763 .init_verbs = { alc861_asus_init_verbs, 15764 alc861_asus_laptop_init_verbs }, 15765 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 15766 .dac_nids = alc861_dac_nids, 15767 .dig_out_nid = ALC861_DIGOUT_NID, 15768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 15769 .channel_mode = alc883_3ST_2ch_modes, 15770 .need_dac_fix = 1, 15771 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 15772 .adc_nids = alc861_adc_nids, 15773 .input_mux = &alc861_capture_source, 15774 }, 15775}; 15776 15777/* Pin config fixes */ 15778enum { 15779 PINFIX_FSC_AMILO_PI1505, 15780}; 15781 15782static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = { 15783 { 0x0b, 0x0221101f }, /* HP */ 15784 { 0x0f, 0x90170310 }, /* speaker */ 15785 { } 15786}; 15787 15788static const struct alc_fixup alc861_fixups[] = { 15789 [PINFIX_FSC_AMILO_PI1505] = { 15790 .pins = alc861_fsc_amilo_pi1505_pinfix 15791 }, 15792}; 15793 15794static struct snd_pci_quirk alc861_fixup_tbl[] = { 15795 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 15796 {} 15797}; 15798 15799static int patch_alc861(struct hda_codec *codec) 15800{ 15801 struct alc_spec *spec; 15802 int board_config; 15803 int err; 15804 15805 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15806 if (spec == NULL) 15807 return -ENOMEM; 15808 15809 codec->spec = spec; 15810 15811 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 15812 alc861_models, 15813 alc861_cfg_tbl); 15814 15815 if (board_config < 0) { 15816 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15817 codec->chip_name); 15818 board_config = ALC861_AUTO; 15819 } 15820 15821 if (board_config == ALC861_AUTO) 15822 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 15823 15824 if (board_config == ALC861_AUTO) { 15825 /* automatic parse from the BIOS config */ 15826 err = alc861_parse_auto_config(codec); 15827 if (err < 0) { 15828 alc_free(codec); 15829 return err; 15830 } else if (!err) { 15831 printk(KERN_INFO 15832 "hda_codec: Cannot set up configuration " 15833 "from BIOS. Using base mode...\n"); 15834 board_config = ALC861_3ST_DIG; 15835 } 15836 } 15837 15838 err = snd_hda_attach_beep_device(codec, 0x23); 15839 if (err < 0) { 15840 alc_free(codec); 15841 return err; 15842 } 15843 15844 if (board_config != ALC861_AUTO) 15845 setup_preset(codec, &alc861_presets[board_config]); 15846 15847 spec->stream_analog_playback = &alc861_pcm_analog_playback; 15848 spec->stream_analog_capture = &alc861_pcm_analog_capture; 15849 15850 spec->stream_digital_playback = &alc861_pcm_digital_playback; 15851 spec->stream_digital_capture = &alc861_pcm_digital_capture; 15852 15853 if (!spec->cap_mixer) 15854 set_capture_mixer(codec); 15855 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 15856 15857 spec->vmaster_nid = 0x03; 15858 15859 if (board_config == ALC861_AUTO) 15860 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); 15861 15862 codec->patch_ops = alc_patch_ops; 15863 if (board_config == ALC861_AUTO) { 15864 spec->init_hook = alc861_auto_init; 15865#ifdef CONFIG_SND_HDA_POWER_SAVE 15866 spec->power_hook = alc_power_eapd; 15867#endif 15868 } 15869#ifdef CONFIG_SND_HDA_POWER_SAVE 15870 if (!spec->loopback.amplist) 15871 spec->loopback.amplist = alc861_loopbacks; 15872#endif 15873 15874 return 0; 15875} 15876 15877/* 15878 * ALC861-VD support 15879 * 15880 * Based on ALC882 15881 * 15882 * In addition, an independent DAC 15883 */ 15884#define ALC861VD_DIGOUT_NID 0x06 15885 15886static hda_nid_t alc861vd_dac_nids[4] = { 15887 /* front, surr, clfe, side surr */ 15888 0x02, 0x03, 0x04, 0x05 15889}; 15890 15891/* dac_nids for ALC660vd are in a different order - according to 15892 * Realtek's driver. 15893 * This should probably result in a different mixer for 6stack models 15894 * of ALC660vd codecs, but for now there is only 3stack mixer 15895 * - and it is the same as in 861vd. 15896 * adc_nids in ALC660vd are (is) the same as in 861vd 15897 */ 15898static hda_nid_t alc660vd_dac_nids[3] = { 15899 /* front, rear, clfe, rear_surr */ 15900 0x02, 0x04, 0x03 15901}; 15902 15903static hda_nid_t alc861vd_adc_nids[1] = { 15904 /* ADC0 */ 15905 0x09, 15906}; 15907 15908static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 15909 15910/* input MUX */ 15911/* FIXME: should be a matrix-type input source selection */ 15912static struct hda_input_mux alc861vd_capture_source = { 15913 .num_items = 4, 15914 .items = { 15915 { "Mic", 0x0 }, 15916 { "Front Mic", 0x1 }, 15917 { "Line", 0x2 }, 15918 { "CD", 0x4 }, 15919 }, 15920}; 15921 15922static struct hda_input_mux alc861vd_dallas_capture_source = { 15923 .num_items = 2, 15924 .items = { 15925 { "Ext Mic", 0x0 }, 15926 { "Int Mic", 0x1 }, 15927 }, 15928}; 15929 15930static struct hda_input_mux alc861vd_hp_capture_source = { 15931 .num_items = 2, 15932 .items = { 15933 { "Front Mic", 0x0 }, 15934 { "ATAPI Mic", 0x1 }, 15935 }, 15936}; 15937 15938/* 15939 * 2ch mode 15940 */ 15941static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 15942 { 2, NULL } 15943}; 15944 15945/* 15946 * 6ch mode 15947 */ 15948static struct hda_verb alc861vd_6stack_ch6_init[] = { 15949 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15950 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15951 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15952 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15953 { } /* end */ 15954}; 15955 15956/* 15957 * 8ch mode 15958 */ 15959static struct hda_verb alc861vd_6stack_ch8_init[] = { 15960 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15961 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15962 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15963 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 15964 { } /* end */ 15965}; 15966 15967static struct hda_channel_mode alc861vd_6stack_modes[2] = { 15968 { 6, alc861vd_6stack_ch6_init }, 15969 { 8, alc861vd_6stack_ch8_init }, 15970}; 15971 15972static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 15973 { 15974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15975 .name = "Channel Mode", 15976 .info = alc_ch_mode_info, 15977 .get = alc_ch_mode_get, 15978 .put = alc_ch_mode_put, 15979 }, 15980 { } /* end */ 15981}; 15982 15983/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 15984 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 15985 */ 15986static struct snd_kcontrol_new alc861vd_6st_mixer[] = { 15987 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 15988 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 15989 15990 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 15991 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 15992 15993 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 15994 HDA_OUTPUT), 15995 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 15996 HDA_OUTPUT), 15997 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 15998 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 15999 16000 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16001 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16002 16003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16004 16005 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16008 16009 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16010 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16011 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16012 16013 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16014 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16015 16016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16018 16019 { } /* end */ 16020}; 16021 16022static struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16023 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16024 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16025 16026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16027 16028 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16030 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16031 16032 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16033 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16035 16036 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16037 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16038 16039 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16040 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16041 16042 { } /* end */ 16043}; 16044 16045static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16046 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16047 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16048 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16049 16050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16051 16052 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16054 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16055 16056 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16057 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16059 16060 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16061 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16062 16063 { } /* end */ 16064}; 16065 16066/* Pin assignment: Speaker=0x14, HP = 0x15, 16067 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16068 */ 16069static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16070 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16071 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16072 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16073 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16074 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16075 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16076 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16077 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16078 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16079 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16080 { } /* end */ 16081}; 16082 16083/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16084 * Front Mic=0x18, ATAPI Mic = 0x19, 16085 */ 16086static struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16087 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16088 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16089 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16090 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16091 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16092 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16093 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16094 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16095 16096 { } /* end */ 16097}; 16098 16099/* 16100 * generic initialization of ADC, input mixers and output mixers 16101 */ 16102static struct hda_verb alc861vd_volume_init_verbs[] = { 16103 /* 16104 * Unmute ADC0 and set the default input to mic-in 16105 */ 16106 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16107 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16108 16109 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16110 * the analog-loopback mixer widget 16111 */ 16112 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16118 16119 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16124 16125 /* 16126 * Set up output mixers (0x02 - 0x05) 16127 */ 16128 /* set vol=0 to output mixers */ 16129 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16130 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16131 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16132 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16133 16134 /* set up input amps for analog loopback */ 16135 /* Amp Indices: DAC = 0, mixer = 1 */ 16136 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16138 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16139 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16140 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16142 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16143 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16144 16145 { } 16146}; 16147 16148/* 16149 * 3-stack pin configuration: 16150 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16151 */ 16152static struct hda_verb alc861vd_3stack_init_verbs[] = { 16153 /* 16154 * Set pin mode and muting 16155 */ 16156 /* set front pin widgets 0x14 for output */ 16157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16159 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16160 16161 /* Mic (rear) pin: input vref at 80% */ 16162 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16164 /* Front Mic pin: input vref at 80% */ 16165 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16166 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16167 /* Line In pin: input */ 16168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16169 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16170 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16171 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16172 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16173 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16174 /* CD pin widget for input */ 16175 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16176 16177 { } 16178}; 16179 16180/* 16181 * 6-stack pin configuration: 16182 */ 16183static struct hda_verb alc861vd_6stack_init_verbs[] = { 16184 /* 16185 * Set pin mode and muting 16186 */ 16187 /* set front pin widgets 0x14 for output */ 16188 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16189 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16190 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16191 16192 /* Rear Pin: output 1 (0x0d) */ 16193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16196 /* CLFE Pin: output 2 (0x0e) */ 16197 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16198 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16199 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16200 /* Side Pin: output 3 (0x0f) */ 16201 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16202 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16203 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16204 16205 /* Mic (rear) pin: input vref at 80% */ 16206 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16207 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16208 /* Front Mic pin: input vref at 80% */ 16209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16210 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16211 /* Line In pin: input */ 16212 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16213 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16214 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16216 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16217 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16218 /* CD pin widget for input */ 16219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16220 16221 { } 16222}; 16223 16224static struct hda_verb alc861vd_eapd_verbs[] = { 16225 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16226 { } 16227}; 16228 16229static struct hda_verb alc660vd_eapd_verbs[] = { 16230 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16231 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16232 { } 16233}; 16234 16235static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16238 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16239 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16240 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16241 {} 16242}; 16243 16244static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) 16245{ 16246 unsigned int present; 16247 unsigned char bits; 16248 16249 present = snd_hda_jack_detect(codec, 0x18); 16250 bits = present ? HDA_AMP_MUTE : 0; 16251 16252 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, 16253 HDA_AMP_MUTE, bits); 16254} 16255 16256static void alc861vd_lenovo_setup(struct hda_codec *codec) 16257{ 16258 struct alc_spec *spec = codec->spec; 16259 spec->autocfg.hp_pins[0] = 0x1b; 16260 spec->autocfg.speaker_pins[0] = 0x14; 16261} 16262 16263static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16264{ 16265 alc_automute_amp(codec); 16266 alc861vd_lenovo_mic_automute(codec); 16267} 16268 16269static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16270 unsigned int res) 16271{ 16272 switch (res >> 26) { 16273 case ALC880_MIC_EVENT: 16274 alc861vd_lenovo_mic_automute(codec); 16275 break; 16276 default: 16277 alc_automute_amp_unsol_event(codec, res); 16278 break; 16279 } 16280} 16281 16282static struct hda_verb alc861vd_dallas_verbs[] = { 16283 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16284 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16285 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16286 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16287 16288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16294 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16295 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16296 16297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16303 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16305 16306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16310 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16313 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16314 16315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16319 16320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16321 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16322 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16323 16324 { } /* end */ 16325}; 16326 16327/* toggle speaker-output according to the hp-jack state */ 16328static void alc861vd_dallas_setup(struct hda_codec *codec) 16329{ 16330 struct alc_spec *spec = codec->spec; 16331 16332 spec->autocfg.hp_pins[0] = 0x15; 16333 spec->autocfg.speaker_pins[0] = 0x14; 16334} 16335 16336#ifdef CONFIG_SND_HDA_POWER_SAVE 16337#define alc861vd_loopbacks alc880_loopbacks 16338#endif 16339 16340/* pcm configuration: identical with ALC880 */ 16341#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16342#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16343#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16344#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16345 16346/* 16347 * configuration and preset 16348 */ 16349static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16350 [ALC660VD_3ST] = "3stack-660", 16351 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16352 [ALC660VD_ASUS_V1S] = "asus-v1s", 16353 [ALC861VD_3ST] = "3stack", 16354 [ALC861VD_3ST_DIG] = "3stack-digout", 16355 [ALC861VD_6ST_DIG] = "6stack-digout", 16356 [ALC861VD_LENOVO] = "lenovo", 16357 [ALC861VD_DALLAS] = "dallas", 16358 [ALC861VD_HP] = "hp", 16359 [ALC861VD_AUTO] = "auto", 16360}; 16361 16362static struct snd_pci_quirk alc861vd_cfg_tbl[] = { 16363 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 16364 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 16365 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 16366 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 16367 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 16368 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 16369 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 16370 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 16371 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 16372 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 16373 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 16374 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 16375 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 16376 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 16377 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 16378 {} 16379}; 16380 16381static struct alc_config_preset alc861vd_presets[] = { 16382 [ALC660VD_3ST] = { 16383 .mixers = { alc861vd_3st_mixer }, 16384 .init_verbs = { alc861vd_volume_init_verbs, 16385 alc861vd_3stack_init_verbs }, 16386 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16387 .dac_nids = alc660vd_dac_nids, 16388 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16389 .channel_mode = alc861vd_3stack_2ch_modes, 16390 .input_mux = &alc861vd_capture_source, 16391 }, 16392 [ALC660VD_3ST_DIG] = { 16393 .mixers = { alc861vd_3st_mixer }, 16394 .init_verbs = { alc861vd_volume_init_verbs, 16395 alc861vd_3stack_init_verbs }, 16396 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16397 .dac_nids = alc660vd_dac_nids, 16398 .dig_out_nid = ALC861VD_DIGOUT_NID, 16399 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16400 .channel_mode = alc861vd_3stack_2ch_modes, 16401 .input_mux = &alc861vd_capture_source, 16402 }, 16403 [ALC861VD_3ST] = { 16404 .mixers = { alc861vd_3st_mixer }, 16405 .init_verbs = { alc861vd_volume_init_verbs, 16406 alc861vd_3stack_init_verbs }, 16407 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16408 .dac_nids = alc861vd_dac_nids, 16409 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16410 .channel_mode = alc861vd_3stack_2ch_modes, 16411 .input_mux = &alc861vd_capture_source, 16412 }, 16413 [ALC861VD_3ST_DIG] = { 16414 .mixers = { alc861vd_3st_mixer }, 16415 .init_verbs = { alc861vd_volume_init_verbs, 16416 alc861vd_3stack_init_verbs }, 16417 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16418 .dac_nids = alc861vd_dac_nids, 16419 .dig_out_nid = ALC861VD_DIGOUT_NID, 16420 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16421 .channel_mode = alc861vd_3stack_2ch_modes, 16422 .input_mux = &alc861vd_capture_source, 16423 }, 16424 [ALC861VD_6ST_DIG] = { 16425 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 16426 .init_verbs = { alc861vd_volume_init_verbs, 16427 alc861vd_6stack_init_verbs }, 16428 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16429 .dac_nids = alc861vd_dac_nids, 16430 .dig_out_nid = ALC861VD_DIGOUT_NID, 16431 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 16432 .channel_mode = alc861vd_6stack_modes, 16433 .input_mux = &alc861vd_capture_source, 16434 }, 16435 [ALC861VD_LENOVO] = { 16436 .mixers = { alc861vd_lenovo_mixer }, 16437 .init_verbs = { alc861vd_volume_init_verbs, 16438 alc861vd_3stack_init_verbs, 16439 alc861vd_eapd_verbs, 16440 alc861vd_lenovo_unsol_verbs }, 16441 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16442 .dac_nids = alc660vd_dac_nids, 16443 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16444 .channel_mode = alc861vd_3stack_2ch_modes, 16445 .input_mux = &alc861vd_capture_source, 16446 .unsol_event = alc861vd_lenovo_unsol_event, 16447 .setup = alc861vd_lenovo_setup, 16448 .init_hook = alc861vd_lenovo_init_hook, 16449 }, 16450 [ALC861VD_DALLAS] = { 16451 .mixers = { alc861vd_dallas_mixer }, 16452 .init_verbs = { alc861vd_dallas_verbs }, 16453 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16454 .dac_nids = alc861vd_dac_nids, 16455 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16456 .channel_mode = alc861vd_3stack_2ch_modes, 16457 .input_mux = &alc861vd_dallas_capture_source, 16458 .unsol_event = alc_automute_amp_unsol_event, 16459 .setup = alc861vd_dallas_setup, 16460 .init_hook = alc_automute_amp, 16461 }, 16462 [ALC861VD_HP] = { 16463 .mixers = { alc861vd_hp_mixer }, 16464 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 16465 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 16466 .dac_nids = alc861vd_dac_nids, 16467 .dig_out_nid = ALC861VD_DIGOUT_NID, 16468 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16469 .channel_mode = alc861vd_3stack_2ch_modes, 16470 .input_mux = &alc861vd_hp_capture_source, 16471 .unsol_event = alc_automute_amp_unsol_event, 16472 .setup = alc861vd_dallas_setup, 16473 .init_hook = alc_automute_amp, 16474 }, 16475 [ALC660VD_ASUS_V1S] = { 16476 .mixers = { alc861vd_lenovo_mixer }, 16477 .init_verbs = { alc861vd_volume_init_verbs, 16478 alc861vd_3stack_init_verbs, 16479 alc861vd_eapd_verbs, 16480 alc861vd_lenovo_unsol_verbs }, 16481 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 16482 .dac_nids = alc660vd_dac_nids, 16483 .dig_out_nid = ALC861VD_DIGOUT_NID, 16484 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 16485 .channel_mode = alc861vd_3stack_2ch_modes, 16486 .input_mux = &alc861vd_capture_source, 16487 .unsol_event = alc861vd_lenovo_unsol_event, 16488 .setup = alc861vd_lenovo_setup, 16489 .init_hook = alc861vd_lenovo_init_hook, 16490 }, 16491}; 16492 16493/* 16494 * BIOS auto configuration 16495 */ 16496static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 16497 const struct auto_pin_cfg *cfg) 16498{ 16499 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0); 16500} 16501 16502 16503static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 16504 hda_nid_t nid, int pin_type, int dac_idx) 16505{ 16506 alc_set_pin_output(codec, nid, pin_type); 16507} 16508 16509static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 16510{ 16511 struct alc_spec *spec = codec->spec; 16512 int i; 16513 16514 for (i = 0; i <= HDA_SIDE; i++) { 16515 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16516 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16517 if (nid) 16518 alc861vd_auto_set_output_and_unmute(codec, nid, 16519 pin_type, i); 16520 } 16521} 16522 16523 16524static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 16525{ 16526 struct alc_spec *spec = codec->spec; 16527 hda_nid_t pin; 16528 16529 pin = spec->autocfg.hp_pins[0]; 16530 if (pin) /* connect to front and use dac 0 */ 16531 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 16532 pin = spec->autocfg.speaker_pins[0]; 16533 if (pin) 16534 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 16535} 16536 16537#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 16538 16539static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 16540{ 16541 struct alc_spec *spec = codec->spec; 16542 int i; 16543 16544 for (i = 0; i < AUTO_PIN_LAST; i++) { 16545 hda_nid_t nid = spec->autocfg.input_pins[i]; 16546 if (alc_is_input_pin(codec, nid)) { 16547 alc_set_input_pin(codec, nid, i); 16548 if (nid != ALC861VD_PIN_CD_NID && 16549 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 16550 snd_hda_codec_write(codec, nid, 0, 16551 AC_VERB_SET_AMP_GAIN_MUTE, 16552 AMP_OUT_MUTE); 16553 } 16554 } 16555} 16556 16557#define alc861vd_auto_init_input_src alc882_auto_init_input_src 16558 16559#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 16560#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 16561 16562/* add playback controls from the parsed DAC table */ 16563/* Based on ALC880 version. But ALC861VD has separate, 16564 * different NIDs for mute/unmute switch and volume control */ 16565static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 16566 const struct auto_pin_cfg *cfg) 16567{ 16568 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 16569 hda_nid_t nid_v, nid_s; 16570 int i, err; 16571 16572 for (i = 0; i < cfg->line_outs; i++) { 16573 if (!spec->multiout.dac_nids[i]) 16574 continue; 16575 nid_v = alc861vd_idx_to_mixer_vol( 16576 alc880_dac_to_idx( 16577 spec->multiout.dac_nids[i])); 16578 nid_s = alc861vd_idx_to_mixer_switch( 16579 alc880_dac_to_idx( 16580 spec->multiout.dac_nids[i])); 16581 16582 if (i == 2) { 16583 /* Center/LFE */ 16584 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16585 "Center", 16586 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 16587 HDA_OUTPUT)); 16588 if (err < 0) 16589 return err; 16590 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 16591 "LFE", 16592 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 16593 HDA_OUTPUT)); 16594 if (err < 0) 16595 return err; 16596 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16597 "Center", 16598 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 16599 HDA_INPUT)); 16600 if (err < 0) 16601 return err; 16602 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 16603 "LFE", 16604 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 16605 HDA_INPUT)); 16606 if (err < 0) 16607 return err; 16608 } else { 16609 const char *pfx; 16610 if (cfg->line_outs == 1 && 16611 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 16612 if (!cfg->hp_pins) 16613 pfx = "Speaker"; 16614 else 16615 pfx = "PCM"; 16616 } else 16617 pfx = chname[i]; 16618 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16619 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 16620 HDA_OUTPUT)); 16621 if (err < 0) 16622 return err; 16623 if (cfg->line_outs == 1 && 16624 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 16625 pfx = "Speaker"; 16626 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16627 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 16628 HDA_INPUT)); 16629 if (err < 0) 16630 return err; 16631 } 16632 } 16633 return 0; 16634} 16635 16636/* add playback controls for speaker and HP outputs */ 16637/* Based on ALC880 version. But ALC861VD has separate, 16638 * different NIDs for mute/unmute switch and volume control */ 16639static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 16640 hda_nid_t pin, const char *pfx) 16641{ 16642 hda_nid_t nid_v, nid_s; 16643 int err; 16644 16645 if (!pin) 16646 return 0; 16647 16648 if (alc880_is_fixed_pin(pin)) { 16649 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 16650 /* specify the DAC as the extra output */ 16651 if (!spec->multiout.hp_nid) 16652 spec->multiout.hp_nid = nid_v; 16653 else 16654 spec->multiout.extra_out_nid[0] = nid_v; 16655 /* control HP volume/switch on the output mixer amp */ 16656 nid_v = alc861vd_idx_to_mixer_vol( 16657 alc880_fixed_pin_idx(pin)); 16658 nid_s = alc861vd_idx_to_mixer_switch( 16659 alc880_fixed_pin_idx(pin)); 16660 16661 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 16662 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 16663 if (err < 0) 16664 return err; 16665 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 16666 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 16667 if (err < 0) 16668 return err; 16669 } else if (alc880_is_multi_pin(pin)) { 16670 /* set manual connection */ 16671 /* we have only a switch on HP-out PIN */ 16672 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 16673 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 16674 if (err < 0) 16675 return err; 16676 } 16677 return 0; 16678} 16679 16680/* parse the BIOS configuration and set up the alc_spec 16681 * return 1 if successful, 0 if the proper config is not found, 16682 * or a negative error code 16683 * Based on ALC880 version - had to change it to override 16684 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 16685static int alc861vd_parse_auto_config(struct hda_codec *codec) 16686{ 16687 struct alc_spec *spec = codec->spec; 16688 int err; 16689 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 16690 16691 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16692 alc861vd_ignore); 16693 if (err < 0) 16694 return err; 16695 if (!spec->autocfg.line_outs) 16696 return 0; /* can't find valid BIOS pin config */ 16697 16698 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 16699 if (err < 0) 16700 return err; 16701 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 16702 if (err < 0) 16703 return err; 16704 err = alc861vd_auto_create_extra_out(spec, 16705 spec->autocfg.speaker_pins[0], 16706 "Speaker"); 16707 if (err < 0) 16708 return err; 16709 err = alc861vd_auto_create_extra_out(spec, 16710 spec->autocfg.hp_pins[0], 16711 "Headphone"); 16712 if (err < 0) 16713 return err; 16714 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 16715 if (err < 0) 16716 return err; 16717 16718 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16719 16720 alc_auto_parse_digital(codec); 16721 16722 if (spec->kctls.list) 16723 add_mixer(spec, spec->kctls.list); 16724 16725 add_verb(spec, alc861vd_volume_init_verbs); 16726 16727 spec->num_mux_defs = 1; 16728 spec->input_mux = &spec->private_imux[0]; 16729 16730 err = alc_auto_add_mic_boost(codec); 16731 if (err < 0) 16732 return err; 16733 16734 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 16735 16736 return 1; 16737} 16738 16739/* additional initialization for auto-configuration model */ 16740static void alc861vd_auto_init(struct hda_codec *codec) 16741{ 16742 struct alc_spec *spec = codec->spec; 16743 alc861vd_auto_init_multi_out(codec); 16744 alc861vd_auto_init_hp_out(codec); 16745 alc861vd_auto_init_analog_input(codec); 16746 alc861vd_auto_init_input_src(codec); 16747 alc_auto_init_digital(codec); 16748 if (spec->unsol_event) 16749 alc_inithook(codec); 16750} 16751 16752enum { 16753 ALC660VD_FIX_ASUS_GPIO1 16754}; 16755 16756/* reset GPIO1 */ 16757static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = { 16758 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 16759 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 16760 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 16761 { } 16762}; 16763 16764static const struct alc_fixup alc861vd_fixups[] = { 16765 [ALC660VD_FIX_ASUS_GPIO1] = { 16766 .verbs = alc660vd_fix_asus_gpio1_verbs, 16767 }, 16768}; 16769 16770static struct snd_pci_quirk alc861vd_fixup_tbl[] = { 16771 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 16772 {} 16773}; 16774 16775static int patch_alc861vd(struct hda_codec *codec) 16776{ 16777 struct alc_spec *spec; 16778 int err, board_config; 16779 16780 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16781 if (spec == NULL) 16782 return -ENOMEM; 16783 16784 codec->spec = spec; 16785 16786 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 16787 alc861vd_models, 16788 alc861vd_cfg_tbl); 16789 16790 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 16791 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16792 codec->chip_name); 16793 board_config = ALC861VD_AUTO; 16794 } 16795 16796 if (board_config == ALC861VD_AUTO) 16797 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 16798 16799 if (board_config == ALC861VD_AUTO) { 16800 /* automatic parse from the BIOS config */ 16801 err = alc861vd_parse_auto_config(codec); 16802 if (err < 0) { 16803 alc_free(codec); 16804 return err; 16805 } else if (!err) { 16806 printk(KERN_INFO 16807 "hda_codec: Cannot set up configuration " 16808 "from BIOS. Using base mode...\n"); 16809 board_config = ALC861VD_3ST; 16810 } 16811 } 16812 16813 err = snd_hda_attach_beep_device(codec, 0x23); 16814 if (err < 0) { 16815 alc_free(codec); 16816 return err; 16817 } 16818 16819 if (board_config != ALC861VD_AUTO) 16820 setup_preset(codec, &alc861vd_presets[board_config]); 16821 16822 if (codec->vendor_id == 0x10ec0660) { 16823 /* always turn on EAPD */ 16824 add_verb(spec, alc660vd_eapd_verbs); 16825 } 16826 16827 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 16828 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 16829 16830 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 16831 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 16832 16833 if (!spec->adc_nids) { 16834 spec->adc_nids = alc861vd_adc_nids; 16835 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 16836 } 16837 if (!spec->capsrc_nids) 16838 spec->capsrc_nids = alc861vd_capsrc_nids; 16839 16840 set_capture_mixer(codec); 16841 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 16842 16843 spec->vmaster_nid = 0x02; 16844 16845 if (board_config == ALC861VD_AUTO) 16846 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); 16847 16848 codec->patch_ops = alc_patch_ops; 16849 16850 if (board_config == ALC861VD_AUTO) 16851 spec->init_hook = alc861vd_auto_init; 16852#ifdef CONFIG_SND_HDA_POWER_SAVE 16853 if (!spec->loopback.amplist) 16854 spec->loopback.amplist = alc861vd_loopbacks; 16855#endif 16856 16857 return 0; 16858} 16859 16860/* 16861 * ALC662 support 16862 * 16863 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 16864 * configuration. Each pin widget can choose any input DACs and a mixer. 16865 * Each ADC is connected from a mixer of all inputs. This makes possible 16866 * 6-channel independent captures. 16867 * 16868 * In addition, an independent DAC for the multi-playback (not used in this 16869 * driver yet). 16870 */ 16871#define ALC662_DIGOUT_NID 0x06 16872#define ALC662_DIGIN_NID 0x0a 16873 16874static hda_nid_t alc662_dac_nids[4] = { 16875 /* front, rear, clfe, rear_surr */ 16876 0x02, 0x03, 0x04 16877}; 16878 16879static hda_nid_t alc272_dac_nids[2] = { 16880 0x02, 0x03 16881}; 16882 16883static hda_nid_t alc662_adc_nids[2] = { 16884 /* ADC1-2 */ 16885 0x09, 0x08 16886}; 16887 16888static hda_nid_t alc272_adc_nids[1] = { 16889 /* ADC1-2 */ 16890 0x08, 16891}; 16892 16893static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 16894static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 16895 16896 16897/* input MUX */ 16898/* FIXME: should be a matrix-type input source selection */ 16899static struct hda_input_mux alc662_capture_source = { 16900 .num_items = 4, 16901 .items = { 16902 { "Mic", 0x0 }, 16903 { "Front Mic", 0x1 }, 16904 { "Line", 0x2 }, 16905 { "CD", 0x4 }, 16906 }, 16907}; 16908 16909static struct hda_input_mux alc662_lenovo_101e_capture_source = { 16910 .num_items = 2, 16911 .items = { 16912 { "Mic", 0x1 }, 16913 { "Line", 0x2 }, 16914 }, 16915}; 16916 16917static struct hda_input_mux alc663_capture_source = { 16918 .num_items = 3, 16919 .items = { 16920 { "Mic", 0x0 }, 16921 { "Front Mic", 0x1 }, 16922 { "Line", 0x2 }, 16923 }, 16924}; 16925 16926#if 0 /* set to 1 for testing other input sources below */ 16927static struct hda_input_mux alc272_nc10_capture_source = { 16928 .num_items = 16, 16929 .items = { 16930 { "Autoselect Mic", 0x0 }, 16931 { "Internal Mic", 0x1 }, 16932 { "In-0x02", 0x2 }, 16933 { "In-0x03", 0x3 }, 16934 { "In-0x04", 0x4 }, 16935 { "In-0x05", 0x5 }, 16936 { "In-0x06", 0x6 }, 16937 { "In-0x07", 0x7 }, 16938 { "In-0x08", 0x8 }, 16939 { "In-0x09", 0x9 }, 16940 { "In-0x0a", 0x0a }, 16941 { "In-0x0b", 0x0b }, 16942 { "In-0x0c", 0x0c }, 16943 { "In-0x0d", 0x0d }, 16944 { "In-0x0e", 0x0e }, 16945 { "In-0x0f", 0x0f }, 16946 }, 16947}; 16948#endif 16949 16950/* 16951 * 2ch mode 16952 */ 16953static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 16954 { 2, NULL } 16955}; 16956 16957/* 16958 * 2ch mode 16959 */ 16960static struct hda_verb alc662_3ST_ch2_init[] = { 16961 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 16962 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16963 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 16964 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 16965 { } /* end */ 16966}; 16967 16968/* 16969 * 6ch mode 16970 */ 16971static struct hda_verb alc662_3ST_ch6_init[] = { 16972 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16973 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 16974 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 16975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 16977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 16978 { } /* end */ 16979}; 16980 16981static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 16982 { 2, alc662_3ST_ch2_init }, 16983 { 6, alc662_3ST_ch6_init }, 16984}; 16985 16986/* 16987 * 2ch mode 16988 */ 16989static struct hda_verb alc662_sixstack_ch6_init[] = { 16990 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16991 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16992 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16993 { } /* end */ 16994}; 16995 16996/* 16997 * 6ch mode 16998 */ 16999static struct hda_verb alc662_sixstack_ch8_init[] = { 17000 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17001 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17002 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17003 { } /* end */ 17004}; 17005 17006static struct hda_channel_mode alc662_5stack_modes[2] = { 17007 { 2, alc662_sixstack_ch6_init }, 17008 { 6, alc662_sixstack_ch8_init }, 17009}; 17010 17011/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17012 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17013 */ 17014 17015static struct snd_kcontrol_new alc662_base_mixer[] = { 17016 /* output mixer control */ 17017 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17018 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17019 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17020 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17021 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17022 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17023 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17024 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17026 17027 /*Input mixer control */ 17028 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17029 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17030 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17031 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17032 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17033 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17034 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17035 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17036 { } /* end */ 17037}; 17038 17039static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17040 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17041 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17042 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17043 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17044 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17049 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17050 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17051 { } /* end */ 17052}; 17053 17054static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17055 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17056 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17057 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17058 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17059 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17060 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17061 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17062 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17070 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17071 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17072 { } /* end */ 17073}; 17074 17075static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17076 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17077 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17078 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17079 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17085 { } /* end */ 17086}; 17087 17088static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17089 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17090 ALC262_HIPPO_MASTER_SWITCH, 17091 17092 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17093 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17094 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17095 17096 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17097 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17098 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17099 { } /* end */ 17100}; 17101 17102static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17103 ALC262_HIPPO_MASTER_SWITCH, 17104 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17105 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17106 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17107 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17108 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17113 { } /* end */ 17114}; 17115 17116static struct hda_bind_ctls alc663_asus_bind_master_vol = { 17117 .ops = &snd_hda_bind_vol, 17118 .values = { 17119 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17120 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17121 0 17122 }, 17123}; 17124 17125static struct hda_bind_ctls alc663_asus_one_bind_switch = { 17126 .ops = &snd_hda_bind_sw, 17127 .values = { 17128 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17129 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17130 0 17131 }, 17132}; 17133 17134static struct snd_kcontrol_new alc663_m51va_mixer[] = { 17135 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17136 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17138 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17139 { } /* end */ 17140}; 17141 17142static struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17143 .ops = &snd_hda_bind_sw, 17144 .values = { 17145 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17146 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17147 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17148 0 17149 }, 17150}; 17151 17152static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17153 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17154 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17157 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17158 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17159 17160 { } /* end */ 17161}; 17162 17163static struct hda_bind_ctls alc663_asus_four_bind_switch = { 17164 .ops = &snd_hda_bind_sw, 17165 .values = { 17166 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17167 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17168 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17169 0 17170 }, 17171}; 17172 17173static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17174 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17175 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17178 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17179 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17180 { } /* end */ 17181}; 17182 17183static struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17184 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17185 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17186 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17189 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17190 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17191 { } /* end */ 17192}; 17193 17194static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17195 .ops = &snd_hda_bind_vol, 17196 .values = { 17197 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17198 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17199 0 17200 }, 17201}; 17202 17203static struct hda_bind_ctls alc663_asus_two_bind_switch = { 17204 .ops = &snd_hda_bind_sw, 17205 .values = { 17206 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17207 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17208 0 17209 }, 17210}; 17211 17212static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17213 HDA_BIND_VOL("Master Playback Volume", 17214 &alc663_asus_two_bind_master_vol), 17215 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17216 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17217 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17220 { } /* end */ 17221}; 17222 17223static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17224 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17225 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17230 { } /* end */ 17231}; 17232 17233static struct snd_kcontrol_new alc663_g71v_mixer[] = { 17234 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17235 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17236 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17237 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17238 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17239 17240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17242 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17243 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17244 { } /* end */ 17245}; 17246 17247static struct snd_kcontrol_new alc663_g50v_mixer[] = { 17248 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17249 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17251 17252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17254 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17255 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17256 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17257 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17258 { } /* end */ 17259}; 17260 17261static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17262 .ops = &snd_hda_bind_sw, 17263 .values = { 17264 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17265 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17266 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17267 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17268 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17269 0 17270 }, 17271}; 17272 17273static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17274 .ops = &snd_hda_bind_sw, 17275 .values = { 17276 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17277 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17278 0 17279 }, 17280}; 17281 17282static struct snd_kcontrol_new alc663_mode7_mixer[] = { 17283 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17284 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17285 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17286 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17287 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17288 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17289 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17290 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17291 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17292 { } /* end */ 17293}; 17294 17295static struct snd_kcontrol_new alc663_mode8_mixer[] = { 17296 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17297 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17298 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17299 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17300 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17303 { } /* end */ 17304}; 17305 17306 17307static struct snd_kcontrol_new alc662_chmode_mixer[] = { 17308 { 17309 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17310 .name = "Channel Mode", 17311 .info = alc_ch_mode_info, 17312 .get = alc_ch_mode_get, 17313 .put = alc_ch_mode_put, 17314 }, 17315 { } /* end */ 17316}; 17317 17318static struct hda_verb alc662_init_verbs[] = { 17319 /* ADC: mute amp left and right */ 17320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17321 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17322 17323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17327 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17329 17330 /* Front Pin: output 0 (0x0c) */ 17331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17332 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17333 17334 /* Rear Pin: output 1 (0x0d) */ 17335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17336 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17337 17338 /* CLFE Pin: output 2 (0x0e) */ 17339 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17340 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17341 17342 /* Mic (rear) pin: input vref at 80% */ 17343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17345 /* Front Mic pin: input vref at 80% */ 17346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17348 /* Line In pin: input */ 17349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17351 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 17352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 17355 /* CD pin widget for input */ 17356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17357 17358 /* FIXME: use matrix-type input source selection */ 17359 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 17360 /* Input mixer */ 17361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17363 17364 /* always trun on EAPD */ 17365 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17366 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 17367 17368 { } 17369}; 17370 17371static struct hda_verb alc663_init_verbs[] = { 17372 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17373 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17374 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17378 { } 17379}; 17380 17381static struct hda_verb alc272_init_verbs[] = { 17382 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17383 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17384 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17385 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17386 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17387 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17390 { } 17391}; 17392 17393static struct hda_verb alc662_sue_init_verbs[] = { 17394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17395 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17396 {} 17397}; 17398 17399static struct hda_verb alc662_eeepc_sue_init_verbs[] = { 17400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17402 {} 17403}; 17404 17405/* Set Unsolicited Event*/ 17406static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 17407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17408 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17409 {} 17410}; 17411 17412static struct hda_verb alc663_m51va_init_verbs[] = { 17413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17415 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17416 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17417 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17420 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17421 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17422 {} 17423}; 17424 17425static struct hda_verb alc663_21jd_amic_init_verbs[] = { 17426 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17427 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17428 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17429 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17430 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17431 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17432 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17433 {} 17434}; 17435 17436static struct hda_verb alc662_1bjd_amic_init_verbs[] = { 17437 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17438 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17439 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17440 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17441 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17442 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17443 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17444 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17445 {} 17446}; 17447 17448static struct hda_verb alc663_15jd_amic_init_verbs[] = { 17449 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17451 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17454 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17456 {} 17457}; 17458 17459static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 17460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17461 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17462 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17463 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17465 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17466 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 17467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17469 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17470 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17472 {} 17473}; 17474 17475static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 17476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17477 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17478 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17479 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17487 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17488 {} 17489}; 17490 17491static struct hda_verb alc663_g71v_init_verbs[] = { 17492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17493 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 17494 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 17495 17496 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17497 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17498 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17499 17500 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 17501 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 17502 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 17503 {} 17504}; 17505 17506static struct hda_verb alc663_g50v_init_verbs[] = { 17507 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17508 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17509 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 17510 17511 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17512 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17513 {} 17514}; 17515 17516static struct hda_verb alc662_ecs_init_verbs[] = { 17517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 17518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17519 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17520 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17521 {} 17522}; 17523 17524static struct hda_verb alc272_dell_zm1_init_verbs[] = { 17525 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17526 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17527 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17529 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17530 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17531 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17534 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17535 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17536 {} 17537}; 17538 17539static struct hda_verb alc272_dell_init_verbs[] = { 17540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17541 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17544 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17545 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17546 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17547 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17549 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17550 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17551 {} 17552}; 17553 17554static struct hda_verb alc663_mode7_init_verbs[] = { 17555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17556 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17557 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17558 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17560 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17561 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 17562 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17563 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17564 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17565 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17567 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17568 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17569 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17570 {} 17571}; 17572 17573static struct hda_verb alc663_mode8_init_verbs[] = { 17574 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17577 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 17578 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17581 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 17582 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 17583 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17584 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 17585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 17587 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 17589 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 17590 {} 17591}; 17592 17593static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 17594 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 17595 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 17596 { } /* end */ 17597}; 17598 17599static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 17600 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 17601 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 17602 { } /* end */ 17603}; 17604 17605static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 17606{ 17607 unsigned int present; 17608 unsigned char bits; 17609 17610 present = snd_hda_jack_detect(codec, 0x14); 17611 bits = present ? HDA_AMP_MUTE : 0; 17612 17613 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17614 HDA_AMP_MUTE, bits); 17615} 17616 17617static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) 17618{ 17619 unsigned int present; 17620 unsigned char bits; 17621 17622 present = snd_hda_jack_detect(codec, 0x1b); 17623 bits = present ? HDA_AMP_MUTE : 0; 17624 17625 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 17626 HDA_AMP_MUTE, bits); 17627 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 17628 HDA_AMP_MUTE, bits); 17629} 17630 17631static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, 17632 unsigned int res) 17633{ 17634 if ((res >> 26) == ALC880_HP_EVENT) 17635 alc662_lenovo_101e_all_automute(codec); 17636 if ((res >> 26) == ALC880_FRONT_EVENT) 17637 alc662_lenovo_101e_ispeaker_automute(codec); 17638} 17639 17640/* unsolicited event for HP jack sensing */ 17641static void alc662_eeepc_unsol_event(struct hda_codec *codec, 17642 unsigned int res) 17643{ 17644 if ((res >> 26) == ALC880_MIC_EVENT) 17645 alc_mic_automute(codec); 17646 else 17647 alc262_hippo_unsol_event(codec, res); 17648} 17649 17650static void alc662_eeepc_setup(struct hda_codec *codec) 17651{ 17652 struct alc_spec *spec = codec->spec; 17653 17654 alc262_hippo1_setup(codec); 17655 spec->ext_mic.pin = 0x18; 17656 spec->ext_mic.mux_idx = 0; 17657 spec->int_mic.pin = 0x19; 17658 spec->int_mic.mux_idx = 1; 17659 spec->auto_mic = 1; 17660} 17661 17662static void alc662_eeepc_inithook(struct hda_codec *codec) 17663{ 17664 alc262_hippo_automute(codec); 17665 alc_mic_automute(codec); 17666} 17667 17668static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 17669{ 17670 struct alc_spec *spec = codec->spec; 17671 17672 spec->autocfg.hp_pins[0] = 0x14; 17673 spec->autocfg.speaker_pins[0] = 0x1b; 17674} 17675 17676#define alc662_eeepc_ep20_inithook alc262_hippo_master_update 17677 17678static void alc663_m51va_speaker_automute(struct hda_codec *codec) 17679{ 17680 unsigned int present; 17681 unsigned char bits; 17682 17683 present = snd_hda_jack_detect(codec, 0x21); 17684 bits = present ? HDA_AMP_MUTE : 0; 17685 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17686 HDA_AMP_MUTE, bits); 17687 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17688 HDA_AMP_MUTE, bits); 17689} 17690 17691static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) 17692{ 17693 unsigned int present; 17694 unsigned char bits; 17695 17696 present = snd_hda_jack_detect(codec, 0x21); 17697 bits = present ? HDA_AMP_MUTE : 0; 17698 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17699 HDA_AMP_MUTE, bits); 17700 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17701 HDA_AMP_MUTE, bits); 17702 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17703 HDA_AMP_MUTE, bits); 17704 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17705 HDA_AMP_MUTE, bits); 17706} 17707 17708static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) 17709{ 17710 unsigned int present; 17711 unsigned char bits; 17712 17713 present = snd_hda_jack_detect(codec, 0x15); 17714 bits = present ? HDA_AMP_MUTE : 0; 17715 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17716 HDA_AMP_MUTE, bits); 17717 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17718 HDA_AMP_MUTE, bits); 17719 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, 17720 HDA_AMP_MUTE, bits); 17721 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, 17722 HDA_AMP_MUTE, bits); 17723} 17724 17725static void alc662_f5z_speaker_automute(struct hda_codec *codec) 17726{ 17727 unsigned int present; 17728 unsigned char bits; 17729 17730 present = snd_hda_jack_detect(codec, 0x1b); 17731 bits = present ? 0 : PIN_OUT; 17732 snd_hda_codec_write(codec, 0x14, 0, 17733 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); 17734} 17735 17736static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) 17737{ 17738 unsigned int present1, present2; 17739 17740 present1 = snd_hda_jack_detect(codec, 0x21); 17741 present2 = snd_hda_jack_detect(codec, 0x15); 17742 17743 if (present1 || present2) { 17744 snd_hda_codec_write_cache(codec, 0x14, 0, 17745 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17746 } else { 17747 snd_hda_codec_write_cache(codec, 0x14, 0, 17748 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17749 } 17750} 17751 17752static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) 17753{ 17754 unsigned int present1, present2; 17755 17756 present1 = snd_hda_jack_detect(codec, 0x1b); 17757 present2 = snd_hda_jack_detect(codec, 0x15); 17758 17759 if (present1 || present2) { 17760 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17761 HDA_AMP_MUTE, HDA_AMP_MUTE); 17762 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17763 HDA_AMP_MUTE, HDA_AMP_MUTE); 17764 } else { 17765 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, 17766 HDA_AMP_MUTE, 0); 17767 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, 17768 HDA_AMP_MUTE, 0); 17769 } 17770} 17771 17772static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) 17773{ 17774 unsigned int present1, present2; 17775 17776 present1 = snd_hda_codec_read(codec, 0x1b, 0, 17777 AC_VERB_GET_PIN_SENSE, 0) 17778 & AC_PINSENSE_PRESENCE; 17779 present2 = snd_hda_codec_read(codec, 0x21, 0, 17780 AC_VERB_GET_PIN_SENSE, 0) 17781 & AC_PINSENSE_PRESENCE; 17782 17783 if (present1 || present2) { 17784 snd_hda_codec_write_cache(codec, 0x14, 0, 17785 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17786 snd_hda_codec_write_cache(codec, 0x17, 0, 17787 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17788 } else { 17789 snd_hda_codec_write_cache(codec, 0x14, 0, 17790 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17791 snd_hda_codec_write_cache(codec, 0x17, 0, 17792 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17793 } 17794} 17795 17796static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) 17797{ 17798 unsigned int present1, present2; 17799 17800 present1 = snd_hda_codec_read(codec, 0x21, 0, 17801 AC_VERB_GET_PIN_SENSE, 0) 17802 & AC_PINSENSE_PRESENCE; 17803 present2 = snd_hda_codec_read(codec, 0x15, 0, 17804 AC_VERB_GET_PIN_SENSE, 0) 17805 & AC_PINSENSE_PRESENCE; 17806 17807 if (present1 || present2) { 17808 snd_hda_codec_write_cache(codec, 0x14, 0, 17809 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17810 snd_hda_codec_write_cache(codec, 0x17, 0, 17811 AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 17812 } else { 17813 snd_hda_codec_write_cache(codec, 0x14, 0, 17814 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17815 snd_hda_codec_write_cache(codec, 0x17, 0, 17816 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 17817 } 17818} 17819 17820static void alc663_m51va_unsol_event(struct hda_codec *codec, 17821 unsigned int res) 17822{ 17823 switch (res >> 26) { 17824 case ALC880_HP_EVENT: 17825 alc663_m51va_speaker_automute(codec); 17826 break; 17827 case ALC880_MIC_EVENT: 17828 alc_mic_automute(codec); 17829 break; 17830 } 17831} 17832 17833static void alc663_m51va_setup(struct hda_codec *codec) 17834{ 17835 struct alc_spec *spec = codec->spec; 17836 spec->ext_mic.pin = 0x18; 17837 spec->ext_mic.mux_idx = 0; 17838 spec->int_mic.pin = 0x12; 17839 spec->int_mic.mux_idx = 9; 17840 spec->auto_mic = 1; 17841} 17842 17843static void alc663_m51va_inithook(struct hda_codec *codec) 17844{ 17845 alc663_m51va_speaker_automute(codec); 17846 alc_mic_automute(codec); 17847} 17848 17849/* ***************** Mode1 ******************************/ 17850#define alc663_mode1_unsol_event alc663_m51va_unsol_event 17851 17852static void alc663_mode1_setup(struct hda_codec *codec) 17853{ 17854 struct alc_spec *spec = codec->spec; 17855 spec->ext_mic.pin = 0x18; 17856 spec->ext_mic.mux_idx = 0; 17857 spec->int_mic.pin = 0x19; 17858 spec->int_mic.mux_idx = 1; 17859 spec->auto_mic = 1; 17860} 17861 17862#define alc663_mode1_inithook alc663_m51va_inithook 17863 17864/* ***************** Mode2 ******************************/ 17865static void alc662_mode2_unsol_event(struct hda_codec *codec, 17866 unsigned int res) 17867{ 17868 switch (res >> 26) { 17869 case ALC880_HP_EVENT: 17870 alc662_f5z_speaker_automute(codec); 17871 break; 17872 case ALC880_MIC_EVENT: 17873 alc_mic_automute(codec); 17874 break; 17875 } 17876} 17877 17878#define alc662_mode2_setup alc663_mode1_setup 17879 17880static void alc662_mode2_inithook(struct hda_codec *codec) 17881{ 17882 alc662_f5z_speaker_automute(codec); 17883 alc_mic_automute(codec); 17884} 17885/* ***************** Mode3 ******************************/ 17886static void alc663_mode3_unsol_event(struct hda_codec *codec, 17887 unsigned int res) 17888{ 17889 switch (res >> 26) { 17890 case ALC880_HP_EVENT: 17891 alc663_two_hp_m1_speaker_automute(codec); 17892 break; 17893 case ALC880_MIC_EVENT: 17894 alc_mic_automute(codec); 17895 break; 17896 } 17897} 17898 17899#define alc663_mode3_setup alc663_mode1_setup 17900 17901static void alc663_mode3_inithook(struct hda_codec *codec) 17902{ 17903 alc663_two_hp_m1_speaker_automute(codec); 17904 alc_mic_automute(codec); 17905} 17906/* ***************** Mode4 ******************************/ 17907static void alc663_mode4_unsol_event(struct hda_codec *codec, 17908 unsigned int res) 17909{ 17910 switch (res >> 26) { 17911 case ALC880_HP_EVENT: 17912 alc663_21jd_two_speaker_automute(codec); 17913 break; 17914 case ALC880_MIC_EVENT: 17915 alc_mic_automute(codec); 17916 break; 17917 } 17918} 17919 17920#define alc663_mode4_setup alc663_mode1_setup 17921 17922static void alc663_mode4_inithook(struct hda_codec *codec) 17923{ 17924 alc663_21jd_two_speaker_automute(codec); 17925 alc_mic_automute(codec); 17926} 17927/* ***************** Mode5 ******************************/ 17928static void alc663_mode5_unsol_event(struct hda_codec *codec, 17929 unsigned int res) 17930{ 17931 switch (res >> 26) { 17932 case ALC880_HP_EVENT: 17933 alc663_15jd_two_speaker_automute(codec); 17934 break; 17935 case ALC880_MIC_EVENT: 17936 alc_mic_automute(codec); 17937 break; 17938 } 17939} 17940 17941#define alc663_mode5_setup alc663_mode1_setup 17942 17943static void alc663_mode5_inithook(struct hda_codec *codec) 17944{ 17945 alc663_15jd_two_speaker_automute(codec); 17946 alc_mic_automute(codec); 17947} 17948/* ***************** Mode6 ******************************/ 17949static void alc663_mode6_unsol_event(struct hda_codec *codec, 17950 unsigned int res) 17951{ 17952 switch (res >> 26) { 17953 case ALC880_HP_EVENT: 17954 alc663_two_hp_m2_speaker_automute(codec); 17955 break; 17956 case ALC880_MIC_EVENT: 17957 alc_mic_automute(codec); 17958 break; 17959 } 17960} 17961 17962#define alc663_mode6_setup alc663_mode1_setup 17963 17964static void alc663_mode6_inithook(struct hda_codec *codec) 17965{ 17966 alc663_two_hp_m2_speaker_automute(codec); 17967 alc_mic_automute(codec); 17968} 17969 17970/* ***************** Mode7 ******************************/ 17971static void alc663_mode7_unsol_event(struct hda_codec *codec, 17972 unsigned int res) 17973{ 17974 switch (res >> 26) { 17975 case ALC880_HP_EVENT: 17976 alc663_two_hp_m7_speaker_automute(codec); 17977 break; 17978 case ALC880_MIC_EVENT: 17979 alc_mic_automute(codec); 17980 break; 17981 } 17982} 17983 17984#define alc663_mode7_setup alc663_mode1_setup 17985 17986static void alc663_mode7_inithook(struct hda_codec *codec) 17987{ 17988 alc663_two_hp_m7_speaker_automute(codec); 17989 alc_mic_automute(codec); 17990} 17991 17992/* ***************** Mode8 ******************************/ 17993static void alc663_mode8_unsol_event(struct hda_codec *codec, 17994 unsigned int res) 17995{ 17996 switch (res >> 26) { 17997 case ALC880_HP_EVENT: 17998 alc663_two_hp_m8_speaker_automute(codec); 17999 break; 18000 case ALC880_MIC_EVENT: 18001 alc_mic_automute(codec); 18002 break; 18003 } 18004} 18005 18006#define alc663_mode8_setup alc663_m51va_setup 18007 18008static void alc663_mode8_inithook(struct hda_codec *codec) 18009{ 18010 alc663_two_hp_m8_speaker_automute(codec); 18011 alc_mic_automute(codec); 18012} 18013 18014static void alc663_g71v_hp_automute(struct hda_codec *codec) 18015{ 18016 unsigned int present; 18017 unsigned char bits; 18018 18019 present = snd_hda_jack_detect(codec, 0x21); 18020 bits = present ? HDA_AMP_MUTE : 0; 18021 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 18022 HDA_AMP_MUTE, bits); 18023 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18024 HDA_AMP_MUTE, bits); 18025} 18026 18027static void alc663_g71v_front_automute(struct hda_codec *codec) 18028{ 18029 unsigned int present; 18030 unsigned char bits; 18031 18032 present = snd_hda_jack_detect(codec, 0x15); 18033 bits = present ? HDA_AMP_MUTE : 0; 18034 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 18035 HDA_AMP_MUTE, bits); 18036} 18037 18038static void alc663_g71v_unsol_event(struct hda_codec *codec, 18039 unsigned int res) 18040{ 18041 switch (res >> 26) { 18042 case ALC880_HP_EVENT: 18043 alc663_g71v_hp_automute(codec); 18044 break; 18045 case ALC880_FRONT_EVENT: 18046 alc663_g71v_front_automute(codec); 18047 break; 18048 case ALC880_MIC_EVENT: 18049 alc_mic_automute(codec); 18050 break; 18051 } 18052} 18053 18054#define alc663_g71v_setup alc663_m51va_setup 18055 18056static void alc663_g71v_inithook(struct hda_codec *codec) 18057{ 18058 alc663_g71v_front_automute(codec); 18059 alc663_g71v_hp_automute(codec); 18060 alc_mic_automute(codec); 18061} 18062 18063static void alc663_g50v_unsol_event(struct hda_codec *codec, 18064 unsigned int res) 18065{ 18066 switch (res >> 26) { 18067 case ALC880_HP_EVENT: 18068 alc663_m51va_speaker_automute(codec); 18069 break; 18070 case ALC880_MIC_EVENT: 18071 alc_mic_automute(codec); 18072 break; 18073 } 18074} 18075 18076#define alc663_g50v_setup alc663_m51va_setup 18077 18078static void alc663_g50v_inithook(struct hda_codec *codec) 18079{ 18080 alc663_m51va_speaker_automute(codec); 18081 alc_mic_automute(codec); 18082} 18083 18084static struct snd_kcontrol_new alc662_ecs_mixer[] = { 18085 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18086 ALC262_HIPPO_MASTER_SWITCH, 18087 18088 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18089 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18090 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18091 18092 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18093 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18094 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18095 { } /* end */ 18096}; 18097 18098static struct snd_kcontrol_new alc272_nc10_mixer[] = { 18099 /* Master Playback automatically created from Speaker and Headphone */ 18100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18101 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18102 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18103 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18104 18105 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18106 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18107 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18108 18109 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18110 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18111 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18112 { } /* end */ 18113}; 18114 18115#ifdef CONFIG_SND_HDA_POWER_SAVE 18116#define alc662_loopbacks alc880_loopbacks 18117#endif 18118 18119 18120/* pcm configuration: identical with ALC880 */ 18121#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18122#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18123#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18124#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18125 18126/* 18127 * configuration and preset 18128 */ 18129static const char *alc662_models[ALC662_MODEL_LAST] = { 18130 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18131 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18132 [ALC662_3ST_6ch] = "3stack-6ch", 18133 [ALC662_5ST_DIG] = "6stack-dig", 18134 [ALC662_LENOVO_101E] = "lenovo-101e", 18135 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18136 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18137 [ALC662_ECS] = "ecs", 18138 [ALC663_ASUS_M51VA] = "m51va", 18139 [ALC663_ASUS_G71V] = "g71v", 18140 [ALC663_ASUS_H13] = "h13", 18141 [ALC663_ASUS_G50V] = "g50v", 18142 [ALC663_ASUS_MODE1] = "asus-mode1", 18143 [ALC662_ASUS_MODE2] = "asus-mode2", 18144 [ALC663_ASUS_MODE3] = "asus-mode3", 18145 [ALC663_ASUS_MODE4] = "asus-mode4", 18146 [ALC663_ASUS_MODE5] = "asus-mode5", 18147 [ALC663_ASUS_MODE6] = "asus-mode6", 18148 [ALC663_ASUS_MODE7] = "asus-mode7", 18149 [ALC663_ASUS_MODE8] = "asus-mode8", 18150 [ALC272_DELL] = "dell", 18151 [ALC272_DELL_ZM1] = "dell-zm1", 18152 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18153 [ALC662_AUTO] = "auto", 18154}; 18155 18156static struct snd_pci_quirk alc662_cfg_tbl[] = { 18157 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18158 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18159 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18160 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18161 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18162 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18163 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18164 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18165 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18166 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18167 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18168 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18169 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18170 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18171 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18172 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18173 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18174 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18175 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18176 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18177 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18178 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18179 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18180 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18181 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18182 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18183 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18184 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18185 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18186 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18187 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18188 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18189 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18190 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18191 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18192 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18193 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18194 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18195 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18196 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18197 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18198 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18199 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18200 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18201 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18202 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18203 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18204 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18205 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18206 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18207 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18208 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18209 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18210 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18211 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18212 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18213 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18214 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18215 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18216 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18217 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18218 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18219 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18220 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18221 ALC662_3ST_6ch_DIG), 18222 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18223 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18224 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18225 ALC662_3ST_6ch_DIG), 18226 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18227 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18228 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18229 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18230 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18231 ALC662_3ST_6ch_DIG), 18232 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18233 ALC663_ASUS_H13), 18234 {} 18235}; 18236 18237static struct alc_config_preset alc662_presets[] = { 18238 [ALC662_3ST_2ch_DIG] = { 18239 .mixers = { alc662_3ST_2ch_mixer }, 18240 .init_verbs = { alc662_init_verbs }, 18241 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18242 .dac_nids = alc662_dac_nids, 18243 .dig_out_nid = ALC662_DIGOUT_NID, 18244 .dig_in_nid = ALC662_DIGIN_NID, 18245 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18246 .channel_mode = alc662_3ST_2ch_modes, 18247 .input_mux = &alc662_capture_source, 18248 }, 18249 [ALC662_3ST_6ch_DIG] = { 18250 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18251 .init_verbs = { alc662_init_verbs }, 18252 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18253 .dac_nids = alc662_dac_nids, 18254 .dig_out_nid = ALC662_DIGOUT_NID, 18255 .dig_in_nid = ALC662_DIGIN_NID, 18256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18257 .channel_mode = alc662_3ST_6ch_modes, 18258 .need_dac_fix = 1, 18259 .input_mux = &alc662_capture_source, 18260 }, 18261 [ALC662_3ST_6ch] = { 18262 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18263 .init_verbs = { alc662_init_verbs }, 18264 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18265 .dac_nids = alc662_dac_nids, 18266 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18267 .channel_mode = alc662_3ST_6ch_modes, 18268 .need_dac_fix = 1, 18269 .input_mux = &alc662_capture_source, 18270 }, 18271 [ALC662_5ST_DIG] = { 18272 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18273 .init_verbs = { alc662_init_verbs }, 18274 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18275 .dac_nids = alc662_dac_nids, 18276 .dig_out_nid = ALC662_DIGOUT_NID, 18277 .dig_in_nid = ALC662_DIGIN_NID, 18278 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18279 .channel_mode = alc662_5stack_modes, 18280 .input_mux = &alc662_capture_source, 18281 }, 18282 [ALC662_LENOVO_101E] = { 18283 .mixers = { alc662_lenovo_101e_mixer }, 18284 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 18285 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18286 .dac_nids = alc662_dac_nids, 18287 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18288 .channel_mode = alc662_3ST_2ch_modes, 18289 .input_mux = &alc662_lenovo_101e_capture_source, 18290 .unsol_event = alc662_lenovo_101e_unsol_event, 18291 .init_hook = alc662_lenovo_101e_all_automute, 18292 }, 18293 [ALC662_ASUS_EEEPC_P701] = { 18294 .mixers = { alc662_eeepc_p701_mixer }, 18295 .init_verbs = { alc662_init_verbs, 18296 alc662_eeepc_sue_init_verbs }, 18297 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18298 .dac_nids = alc662_dac_nids, 18299 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18300 .channel_mode = alc662_3ST_2ch_modes, 18301 .unsol_event = alc662_eeepc_unsol_event, 18302 .setup = alc662_eeepc_setup, 18303 .init_hook = alc662_eeepc_inithook, 18304 }, 18305 [ALC662_ASUS_EEEPC_EP20] = { 18306 .mixers = { alc662_eeepc_ep20_mixer, 18307 alc662_chmode_mixer }, 18308 .init_verbs = { alc662_init_verbs, 18309 alc662_eeepc_ep20_sue_init_verbs }, 18310 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18311 .dac_nids = alc662_dac_nids, 18312 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18313 .channel_mode = alc662_3ST_6ch_modes, 18314 .input_mux = &alc662_lenovo_101e_capture_source, 18315 .unsol_event = alc662_eeepc_unsol_event, 18316 .setup = alc662_eeepc_ep20_setup, 18317 .init_hook = alc662_eeepc_ep20_inithook, 18318 }, 18319 [ALC662_ECS] = { 18320 .mixers = { alc662_ecs_mixer }, 18321 .init_verbs = { alc662_init_verbs, 18322 alc662_ecs_init_verbs }, 18323 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18324 .dac_nids = alc662_dac_nids, 18325 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18326 .channel_mode = alc662_3ST_2ch_modes, 18327 .unsol_event = alc662_eeepc_unsol_event, 18328 .setup = alc662_eeepc_setup, 18329 .init_hook = alc662_eeepc_inithook, 18330 }, 18331 [ALC663_ASUS_M51VA] = { 18332 .mixers = { alc663_m51va_mixer }, 18333 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18334 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18335 .dac_nids = alc662_dac_nids, 18336 .dig_out_nid = ALC662_DIGOUT_NID, 18337 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18338 .channel_mode = alc662_3ST_2ch_modes, 18339 .unsol_event = alc663_m51va_unsol_event, 18340 .setup = alc663_m51va_setup, 18341 .init_hook = alc663_m51va_inithook, 18342 }, 18343 [ALC663_ASUS_G71V] = { 18344 .mixers = { alc663_g71v_mixer }, 18345 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 18346 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18347 .dac_nids = alc662_dac_nids, 18348 .dig_out_nid = ALC662_DIGOUT_NID, 18349 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18350 .channel_mode = alc662_3ST_2ch_modes, 18351 .unsol_event = alc663_g71v_unsol_event, 18352 .setup = alc663_g71v_setup, 18353 .init_hook = alc663_g71v_inithook, 18354 }, 18355 [ALC663_ASUS_H13] = { 18356 .mixers = { alc663_m51va_mixer }, 18357 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 18358 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18359 .dac_nids = alc662_dac_nids, 18360 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18361 .channel_mode = alc662_3ST_2ch_modes, 18362 .unsol_event = alc663_m51va_unsol_event, 18363 .init_hook = alc663_m51va_inithook, 18364 }, 18365 [ALC663_ASUS_G50V] = { 18366 .mixers = { alc663_g50v_mixer }, 18367 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 18368 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18369 .dac_nids = alc662_dac_nids, 18370 .dig_out_nid = ALC662_DIGOUT_NID, 18371 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18372 .channel_mode = alc662_3ST_6ch_modes, 18373 .input_mux = &alc663_capture_source, 18374 .unsol_event = alc663_g50v_unsol_event, 18375 .setup = alc663_g50v_setup, 18376 .init_hook = alc663_g50v_inithook, 18377 }, 18378 [ALC663_ASUS_MODE1] = { 18379 .mixers = { alc663_m51va_mixer }, 18380 .cap_mixer = alc662_auto_capture_mixer, 18381 .init_verbs = { alc662_init_verbs, 18382 alc663_21jd_amic_init_verbs }, 18383 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18384 .hp_nid = 0x03, 18385 .dac_nids = alc662_dac_nids, 18386 .dig_out_nid = ALC662_DIGOUT_NID, 18387 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18388 .channel_mode = alc662_3ST_2ch_modes, 18389 .unsol_event = alc663_mode1_unsol_event, 18390 .setup = alc663_mode1_setup, 18391 .init_hook = alc663_mode1_inithook, 18392 }, 18393 [ALC662_ASUS_MODE2] = { 18394 .mixers = { alc662_1bjd_mixer }, 18395 .cap_mixer = alc662_auto_capture_mixer, 18396 .init_verbs = { alc662_init_verbs, 18397 alc662_1bjd_amic_init_verbs }, 18398 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18399 .dac_nids = alc662_dac_nids, 18400 .dig_out_nid = ALC662_DIGOUT_NID, 18401 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18402 .channel_mode = alc662_3ST_2ch_modes, 18403 .unsol_event = alc662_mode2_unsol_event, 18404 .setup = alc662_mode2_setup, 18405 .init_hook = alc662_mode2_inithook, 18406 }, 18407 [ALC663_ASUS_MODE3] = { 18408 .mixers = { alc663_two_hp_m1_mixer }, 18409 .cap_mixer = alc662_auto_capture_mixer, 18410 .init_verbs = { alc662_init_verbs, 18411 alc663_two_hp_amic_m1_init_verbs }, 18412 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18413 .hp_nid = 0x03, 18414 .dac_nids = alc662_dac_nids, 18415 .dig_out_nid = ALC662_DIGOUT_NID, 18416 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18417 .channel_mode = alc662_3ST_2ch_modes, 18418 .unsol_event = alc663_mode3_unsol_event, 18419 .setup = alc663_mode3_setup, 18420 .init_hook = alc663_mode3_inithook, 18421 }, 18422 [ALC663_ASUS_MODE4] = { 18423 .mixers = { alc663_asus_21jd_clfe_mixer }, 18424 .cap_mixer = alc662_auto_capture_mixer, 18425 .init_verbs = { alc662_init_verbs, 18426 alc663_21jd_amic_init_verbs}, 18427 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18428 .hp_nid = 0x03, 18429 .dac_nids = alc662_dac_nids, 18430 .dig_out_nid = ALC662_DIGOUT_NID, 18431 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18432 .channel_mode = alc662_3ST_2ch_modes, 18433 .unsol_event = alc663_mode4_unsol_event, 18434 .setup = alc663_mode4_setup, 18435 .init_hook = alc663_mode4_inithook, 18436 }, 18437 [ALC663_ASUS_MODE5] = { 18438 .mixers = { alc663_asus_15jd_clfe_mixer }, 18439 .cap_mixer = alc662_auto_capture_mixer, 18440 .init_verbs = { alc662_init_verbs, 18441 alc663_15jd_amic_init_verbs }, 18442 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18443 .hp_nid = 0x03, 18444 .dac_nids = alc662_dac_nids, 18445 .dig_out_nid = ALC662_DIGOUT_NID, 18446 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18447 .channel_mode = alc662_3ST_2ch_modes, 18448 .unsol_event = alc663_mode5_unsol_event, 18449 .setup = alc663_mode5_setup, 18450 .init_hook = alc663_mode5_inithook, 18451 }, 18452 [ALC663_ASUS_MODE6] = { 18453 .mixers = { alc663_two_hp_m2_mixer }, 18454 .cap_mixer = alc662_auto_capture_mixer, 18455 .init_verbs = { alc662_init_verbs, 18456 alc663_two_hp_amic_m2_init_verbs }, 18457 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18458 .hp_nid = 0x03, 18459 .dac_nids = alc662_dac_nids, 18460 .dig_out_nid = ALC662_DIGOUT_NID, 18461 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18462 .channel_mode = alc662_3ST_2ch_modes, 18463 .unsol_event = alc663_mode6_unsol_event, 18464 .setup = alc663_mode6_setup, 18465 .init_hook = alc663_mode6_inithook, 18466 }, 18467 [ALC663_ASUS_MODE7] = { 18468 .mixers = { alc663_mode7_mixer }, 18469 .cap_mixer = alc662_auto_capture_mixer, 18470 .init_verbs = { alc662_init_verbs, 18471 alc663_mode7_init_verbs }, 18472 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18473 .hp_nid = 0x03, 18474 .dac_nids = alc662_dac_nids, 18475 .dig_out_nid = ALC662_DIGOUT_NID, 18476 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18477 .channel_mode = alc662_3ST_2ch_modes, 18478 .unsol_event = alc663_mode7_unsol_event, 18479 .setup = alc663_mode7_setup, 18480 .init_hook = alc663_mode7_inithook, 18481 }, 18482 [ALC663_ASUS_MODE8] = { 18483 .mixers = { alc663_mode8_mixer }, 18484 .cap_mixer = alc662_auto_capture_mixer, 18485 .init_verbs = { alc662_init_verbs, 18486 alc663_mode8_init_verbs }, 18487 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18488 .hp_nid = 0x03, 18489 .dac_nids = alc662_dac_nids, 18490 .dig_out_nid = ALC662_DIGOUT_NID, 18491 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18492 .channel_mode = alc662_3ST_2ch_modes, 18493 .unsol_event = alc663_mode8_unsol_event, 18494 .setup = alc663_mode8_setup, 18495 .init_hook = alc663_mode8_inithook, 18496 }, 18497 [ALC272_DELL] = { 18498 .mixers = { alc663_m51va_mixer }, 18499 .cap_mixer = alc272_auto_capture_mixer, 18500 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, 18501 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18502 .dac_nids = alc662_dac_nids, 18503 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18504 .adc_nids = alc272_adc_nids, 18505 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18506 .capsrc_nids = alc272_capsrc_nids, 18507 .channel_mode = alc662_3ST_2ch_modes, 18508 .unsol_event = alc663_m51va_unsol_event, 18509 .setup = alc663_m51va_setup, 18510 .init_hook = alc663_m51va_inithook, 18511 }, 18512 [ALC272_DELL_ZM1] = { 18513 .mixers = { alc663_m51va_mixer }, 18514 .cap_mixer = alc662_auto_capture_mixer, 18515 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, 18516 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18517 .dac_nids = alc662_dac_nids, 18518 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18519 .adc_nids = alc662_adc_nids, 18520 .num_adc_nids = 1, 18521 .capsrc_nids = alc662_capsrc_nids, 18522 .channel_mode = alc662_3ST_2ch_modes, 18523 .unsol_event = alc663_m51va_unsol_event, 18524 .setup = alc663_m51va_setup, 18525 .init_hook = alc663_m51va_inithook, 18526 }, 18527 [ALC272_SAMSUNG_NC10] = { 18528 .mixers = { alc272_nc10_mixer }, 18529 .init_verbs = { alc662_init_verbs, 18530 alc663_21jd_amic_init_verbs }, 18531 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18532 .dac_nids = alc272_dac_nids, 18533 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18534 .channel_mode = alc662_3ST_2ch_modes, 18535 /*.input_mux = &alc272_nc10_capture_source,*/ 18536 .unsol_event = alc663_mode4_unsol_event, 18537 .setup = alc663_mode4_setup, 18538 .init_hook = alc663_mode4_inithook, 18539 }, 18540}; 18541 18542 18543/* 18544 * BIOS auto configuration 18545 */ 18546 18547/* convert from MIX nid to DAC */ 18548static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) 18549{ 18550 if (nid == 0x0f) 18551 return 0x02; 18552 else if (nid >= 0x0c && nid <= 0x0e) 18553 return nid - 0x0c + 0x02; 18554 else 18555 return 0; 18556} 18557 18558/* get MIX nid connected to the given pin targeted to DAC */ 18559static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18560 hda_nid_t dac) 18561{ 18562 hda_nid_t mix[4]; 18563 int i, num; 18564 18565 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18566 for (i = 0; i < num; i++) { 18567 if (alc662_mix_to_dac(mix[i]) == dac) 18568 return mix[i]; 18569 } 18570 return 0; 18571} 18572 18573/* look for an empty DAC slot */ 18574static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18575{ 18576 struct alc_spec *spec = codec->spec; 18577 hda_nid_t srcs[5]; 18578 int i, j, num; 18579 18580 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 18581 if (num < 0) 18582 return 0; 18583 for (i = 0; i < num; i++) { 18584 hda_nid_t nid = alc662_mix_to_dac(srcs[i]); 18585 if (!nid) 18586 continue; 18587 for (j = 0; j < spec->multiout.num_dacs; j++) 18588 if (spec->multiout.dac_nids[j] == nid) 18589 break; 18590 if (j >= spec->multiout.num_dacs) 18591 return nid; 18592 } 18593 return 0; 18594} 18595 18596/* fill in the dac_nids table from the parsed pin configuration */ 18597static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 18598 const struct auto_pin_cfg *cfg) 18599{ 18600 struct alc_spec *spec = codec->spec; 18601 int i; 18602 hda_nid_t dac; 18603 18604 spec->multiout.dac_nids = spec->private_dac_nids; 18605 for (i = 0; i < cfg->line_outs; i++) { 18606 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); 18607 if (!dac) 18608 continue; 18609 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 18610 } 18611 return 0; 18612} 18613 18614static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 18615 hda_nid_t nid, unsigned int chs) 18616{ 18617 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 18618 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 18619} 18620 18621static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 18622 hda_nid_t nid, unsigned int chs) 18623{ 18624 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18625 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 18626} 18627 18628#define alc662_add_stereo_vol(spec, pfx, nid) \ 18629 alc662_add_vol_ctl(spec, pfx, nid, 3) 18630#define alc662_add_stereo_sw(spec, pfx, nid) \ 18631 alc662_add_sw_ctl(spec, pfx, nid, 3) 18632 18633/* add playback controls from the parsed DAC table */ 18634static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 18635 const struct auto_pin_cfg *cfg) 18636{ 18637 struct alc_spec *spec = codec->spec; 18638 static const char *chname[4] = { 18639 "Front", "Surround", NULL /*CLFE*/, "Side" 18640 }; 18641 hda_nid_t nid, mix; 18642 int i, err; 18643 18644 for (i = 0; i < cfg->line_outs; i++) { 18645 nid = spec->multiout.dac_nids[i]; 18646 if (!nid) 18647 continue; 18648 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 18649 if (!mix) 18650 continue; 18651 if (i == 2) { 18652 /* Center/LFE */ 18653 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 18654 if (err < 0) 18655 return err; 18656 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 18657 if (err < 0) 18658 return err; 18659 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 18660 if (err < 0) 18661 return err; 18662 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 18663 if (err < 0) 18664 return err; 18665 } else { 18666 const char *pfx; 18667 if (cfg->line_outs == 1 && 18668 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 18669 if (cfg->hp_outs) 18670 pfx = "Speaker"; 18671 else 18672 pfx = "PCM"; 18673 } else 18674 pfx = chname[i]; 18675 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18676 if (err < 0) 18677 return err; 18678 if (cfg->line_outs == 1 && 18679 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 18680 pfx = "Speaker"; 18681 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18682 if (err < 0) 18683 return err; 18684 } 18685 } 18686 return 0; 18687} 18688 18689/* add playback controls for speaker and HP outputs */ 18690/* return DAC nid if any new DAC is assigned */ 18691static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 18692 const char *pfx) 18693{ 18694 struct alc_spec *spec = codec->spec; 18695 hda_nid_t nid, mix; 18696 int err; 18697 18698 if (!pin) 18699 return 0; 18700 nid = alc662_look_for_dac(codec, pin); 18701 if (!nid) { 18702 /* the corresponding DAC is already occupied */ 18703 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 18704 return 0; /* no way */ 18705 /* create a switch only */ 18706 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 18707 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 18708 } 18709 18710 mix = alc662_dac_to_mix(codec, pin, nid); 18711 if (!mix) 18712 return 0; 18713 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 18714 if (err < 0) 18715 return err; 18716 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 18717 if (err < 0) 18718 return err; 18719 return nid; 18720} 18721 18722/* create playback/capture controls for input pins */ 18723#define alc662_auto_create_input_ctls \ 18724 alc882_auto_create_input_ctls 18725 18726static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 18727 hda_nid_t nid, int pin_type, 18728 hda_nid_t dac) 18729{ 18730 int i, num; 18731 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 18732 18733 alc_set_pin_output(codec, nid, pin_type); 18734 /* need the manual connection? */ 18735 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 18736 if (num <= 1) 18737 return; 18738 for (i = 0; i < num; i++) { 18739 if (alc662_mix_to_dac(srcs[i]) != dac) 18740 continue; 18741 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); 18742 return; 18743 } 18744} 18745 18746static void alc662_auto_init_multi_out(struct hda_codec *codec) 18747{ 18748 struct alc_spec *spec = codec->spec; 18749 int pin_type = get_pin_type(spec->autocfg.line_out_type); 18750 int i; 18751 18752 for (i = 0; i <= HDA_SIDE; i++) { 18753 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 18754 if (nid) 18755 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 18756 spec->multiout.dac_nids[i]); 18757 } 18758} 18759 18760static void alc662_auto_init_hp_out(struct hda_codec *codec) 18761{ 18762 struct alc_spec *spec = codec->spec; 18763 hda_nid_t pin; 18764 18765 pin = spec->autocfg.hp_pins[0]; 18766 if (pin) 18767 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 18768 spec->multiout.hp_nid); 18769 pin = spec->autocfg.speaker_pins[0]; 18770 if (pin) 18771 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 18772 spec->multiout.extra_out_nid[0]); 18773} 18774 18775#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 18776 18777static void alc662_auto_init_analog_input(struct hda_codec *codec) 18778{ 18779 struct alc_spec *spec = codec->spec; 18780 int i; 18781 18782 for (i = 0; i < AUTO_PIN_LAST; i++) { 18783 hda_nid_t nid = spec->autocfg.input_pins[i]; 18784 if (alc_is_input_pin(codec, nid)) { 18785 alc_set_input_pin(codec, nid, i); 18786 if (nid != ALC662_PIN_CD_NID && 18787 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 18788 snd_hda_codec_write(codec, nid, 0, 18789 AC_VERB_SET_AMP_GAIN_MUTE, 18790 AMP_OUT_MUTE); 18791 } 18792 } 18793} 18794 18795#define alc662_auto_init_input_src alc882_auto_init_input_src 18796 18797static int alc662_parse_auto_config(struct hda_codec *codec) 18798{ 18799 struct alc_spec *spec = codec->spec; 18800 int err; 18801 static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 18802 18803 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 18804 alc662_ignore); 18805 if (err < 0) 18806 return err; 18807 if (!spec->autocfg.line_outs) 18808 return 0; /* can't find valid BIOS pin config */ 18809 18810 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 18811 if (err < 0) 18812 return err; 18813 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 18814 if (err < 0) 18815 return err; 18816 err = alc662_auto_create_extra_out(codec, 18817 spec->autocfg.speaker_pins[0], 18818 "Speaker"); 18819 if (err < 0) 18820 return err; 18821 if (err) 18822 spec->multiout.extra_out_nid[0] = err; 18823 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 18824 "Headphone"); 18825 if (err < 0) 18826 return err; 18827 if (err) 18828 spec->multiout.hp_nid = err; 18829 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 18830 if (err < 0) 18831 return err; 18832 18833 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 18834 18835 alc_auto_parse_digital(codec); 18836 18837 if (spec->kctls.list) 18838 add_mixer(spec, spec->kctls.list); 18839 18840 spec->num_mux_defs = 1; 18841 spec->input_mux = &spec->private_imux[0]; 18842 18843 add_verb(spec, alc662_init_verbs); 18844 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18845 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18846 add_verb(spec, alc663_init_verbs); 18847 18848 if (codec->vendor_id == 0x10ec0272) 18849 add_verb(spec, alc272_init_verbs); 18850 18851 err = alc_auto_add_mic_boost(codec); 18852 if (err < 0) 18853 return err; 18854 18855 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 18856 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 18857 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 18858 else 18859 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 18860 18861 return 1; 18862} 18863 18864/* additional initialization for auto-configuration model */ 18865static void alc662_auto_init(struct hda_codec *codec) 18866{ 18867 struct alc_spec *spec = codec->spec; 18868 alc662_auto_init_multi_out(codec); 18869 alc662_auto_init_hp_out(codec); 18870 alc662_auto_init_analog_input(codec); 18871 alc662_auto_init_input_src(codec); 18872 alc_auto_init_digital(codec); 18873 if (spec->unsol_event) 18874 alc_inithook(codec); 18875} 18876 18877static int patch_alc662(struct hda_codec *codec) 18878{ 18879 struct alc_spec *spec; 18880 int err, board_config; 18881 18882 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 18883 if (!spec) 18884 return -ENOMEM; 18885 18886 codec->spec = spec; 18887 18888 alc_auto_parse_customize_define(codec); 18889 18890 alc_fix_pll_init(codec, 0x20, 0x04, 15); 18891 18892 if (alc_read_coef_idx(codec, 0) == 0x8020) 18893 alc_codec_rename(codec, "ALC661"); 18894 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) && 18895 codec->bus->pci->subsystem_vendor == 0x1025 && 18896 spec->cdefine.platform_type == 1) 18897 alc_codec_rename(codec, "ALC272X"); 18898 18899 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 18900 alc662_models, 18901 alc662_cfg_tbl); 18902 if (board_config < 0) { 18903 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 18904 codec->chip_name); 18905 board_config = ALC662_AUTO; 18906 } 18907 18908 if (board_config == ALC662_AUTO) { 18909 /* automatic parse from the BIOS config */ 18910 err = alc662_parse_auto_config(codec); 18911 if (err < 0) { 18912 alc_free(codec); 18913 return err; 18914 } else if (!err) { 18915 printk(KERN_INFO 18916 "hda_codec: Cannot set up configuration " 18917 "from BIOS. Using base mode...\n"); 18918 board_config = ALC662_3ST_2ch_DIG; 18919 } 18920 } 18921 18922 if (has_cdefine_beep(codec)) { 18923 err = snd_hda_attach_beep_device(codec, 0x1); 18924 if (err < 0) { 18925 alc_free(codec); 18926 return err; 18927 } 18928 } 18929 18930 if (board_config != ALC662_AUTO) 18931 setup_preset(codec, &alc662_presets[board_config]); 18932 18933 spec->stream_analog_playback = &alc662_pcm_analog_playback; 18934 spec->stream_analog_capture = &alc662_pcm_analog_capture; 18935 18936 spec->stream_digital_playback = &alc662_pcm_digital_playback; 18937 spec->stream_digital_capture = &alc662_pcm_digital_capture; 18938 18939 if (!spec->adc_nids) { 18940 spec->adc_nids = alc662_adc_nids; 18941 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 18942 } 18943 if (!spec->capsrc_nids) 18944 spec->capsrc_nids = alc662_capsrc_nids; 18945 18946 if (!spec->cap_mixer) 18947 set_capture_mixer(codec); 18948 18949 if (has_cdefine_beep(codec)) { 18950 switch (codec->vendor_id) { 18951 case 0x10ec0662: 18952 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18953 break; 18954 case 0x10ec0272: 18955 case 0x10ec0663: 18956 case 0x10ec0665: 18957 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18958 break; 18959 case 0x10ec0273: 18960 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 18961 break; 18962 } 18963 } 18964 spec->vmaster_nid = 0x02; 18965 18966 codec->patch_ops = alc_patch_ops; 18967 if (board_config == ALC662_AUTO) 18968 spec->init_hook = alc662_auto_init; 18969#ifdef CONFIG_SND_HDA_POWER_SAVE 18970 if (!spec->loopback.amplist) 18971 spec->loopback.amplist = alc662_loopbacks; 18972#endif 18973 18974 return 0; 18975} 18976 18977static int patch_alc888(struct hda_codec *codec) 18978{ 18979 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 18980 kfree(codec->chip_name); 18981 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 18982 if (!codec->chip_name) { 18983 alc_free(codec); 18984 return -ENOMEM; 18985 } 18986 return patch_alc662(codec); 18987 } 18988 return patch_alc882(codec); 18989} 18990 18991/* 18992 * ALC680 support 18993 */ 18994#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 18995#define alc680_modes alc260_modes 18996 18997static hda_nid_t alc680_dac_nids[3] = { 18998 /* Lout1, Lout2, hp */ 18999 0x02, 0x03, 0x04 19000}; 19001 19002static hda_nid_t alc680_adc_nids[3] = { 19003 /* ADC0-2 */ 19004 /* DMIC, MIC, Line-in*/ 19005 0x07, 0x08, 0x09 19006}; 19007 19008static struct snd_kcontrol_new alc680_base_mixer[] = { 19009 /* output mixer control */ 19010 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19011 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19012 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19015 { } 19016}; 19017 19018static struct snd_kcontrol_new alc680_capture_mixer[] = { 19019 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 19020 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 19021 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 19022 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 19023 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 19024 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT), 19025 { } /* end */ 19026}; 19027 19028/* 19029 * generic initialization of ADC, input mixers and output mixers 19030 */ 19031static struct hda_verb alc680_init_verbs[] = { 19032 /* Unmute DAC0-1 and set vol = 0 */ 19033 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 19034 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 19035 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 19036 19037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 19038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 19039 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 19040 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 19041 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 19042 19043 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19045 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19046 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19047 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19048 { } 19049}; 19050 19051/* create input playback/capture controls for the given pin */ 19052static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19053 const char *ctlname, int idx) 19054{ 19055 hda_nid_t dac; 19056 int err; 19057 19058 switch (nid) { 19059 case 0x14: 19060 dac = 0x02; 19061 break; 19062 case 0x15: 19063 dac = 0x03; 19064 break; 19065 case 0x16: 19066 dac = 0x04; 19067 break; 19068 default: 19069 return 0; 19070 } 19071 if (spec->multiout.dac_nids[0] != dac && 19072 spec->multiout.dac_nids[1] != dac) { 19073 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19074 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19075 HDA_OUTPUT)); 19076 if (err < 0) 19077 return err; 19078 19079 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19080 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19081 19082 if (err < 0) 19083 return err; 19084 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; 19085 } 19086 19087 return 0; 19088} 19089 19090/* add playback controls from the parsed DAC table */ 19091static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19092 const struct auto_pin_cfg *cfg) 19093{ 19094 hda_nid_t nid; 19095 int err; 19096 19097 spec->multiout.dac_nids = spec->private_dac_nids; 19098 19099 nid = cfg->line_out_pins[0]; 19100 if (nid) { 19101 const char *name; 19102 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19103 name = "Speaker"; 19104 else 19105 name = "Front"; 19106 err = alc680_new_analog_output(spec, nid, name, 0); 19107 if (err < 0) 19108 return err; 19109 } 19110 19111 nid = cfg->speaker_pins[0]; 19112 if (nid) { 19113 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19114 if (err < 0) 19115 return err; 19116 } 19117 nid = cfg->hp_pins[0]; 19118 if (nid) { 19119 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19120 if (err < 0) 19121 return err; 19122 } 19123 19124 return 0; 19125} 19126 19127static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19128 hda_nid_t nid, int pin_type) 19129{ 19130 alc_set_pin_output(codec, nid, pin_type); 19131} 19132 19133static void alc680_auto_init_multi_out(struct hda_codec *codec) 19134{ 19135 struct alc_spec *spec = codec->spec; 19136 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19137 if (nid) { 19138 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19139 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19140 } 19141} 19142 19143static void alc680_auto_init_hp_out(struct hda_codec *codec) 19144{ 19145 struct alc_spec *spec = codec->spec; 19146 hda_nid_t pin; 19147 19148 pin = spec->autocfg.hp_pins[0]; 19149 if (pin) 19150 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19151 pin = spec->autocfg.speaker_pins[0]; 19152 if (pin) 19153 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19154} 19155 19156/* pcm configuration: identical with ALC880 */ 19157#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19158#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19159#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19160#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19161 19162static struct hda_input_mux alc680_capture_source = { 19163 .num_items = 1, 19164 .items = { 19165 { "Mic", 0x0 }, 19166 }, 19167}; 19168 19169/* 19170 * BIOS auto configuration 19171 */ 19172static int alc680_parse_auto_config(struct hda_codec *codec) 19173{ 19174 struct alc_spec *spec = codec->spec; 19175 int err; 19176 static hda_nid_t alc680_ignore[] = { 0 }; 19177 19178 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19179 alc680_ignore); 19180 if (err < 0) 19181 return err; 19182 if (!spec->autocfg.line_outs) { 19183 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19184 spec->multiout.max_channels = 2; 19185 spec->no_analog = 1; 19186 goto dig_only; 19187 } 19188 return 0; /* can't find valid BIOS pin config */ 19189 } 19190 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19191 if (err < 0) 19192 return err; 19193 19194 spec->multiout.max_channels = 2; 19195 19196 dig_only: 19197 /* digital only support output */ 19198 alc_auto_parse_digital(codec); 19199 if (spec->kctls.list) 19200 add_mixer(spec, spec->kctls.list); 19201 19202 add_verb(spec, alc680_init_verbs); 19203 spec->num_mux_defs = 1; 19204 spec->input_mux = &alc680_capture_source; 19205 19206 err = alc_auto_add_mic_boost(codec); 19207 if (err < 0) 19208 return err; 19209 19210 return 1; 19211} 19212 19213#define alc680_auto_init_analog_input alc882_auto_init_analog_input 19214 19215/* init callback for auto-configuration model -- overriding the default init */ 19216static void alc680_auto_init(struct hda_codec *codec) 19217{ 19218 struct alc_spec *spec = codec->spec; 19219 alc680_auto_init_multi_out(codec); 19220 alc680_auto_init_hp_out(codec); 19221 alc680_auto_init_analog_input(codec); 19222 alc_auto_init_digital(codec); 19223 if (spec->unsol_event) 19224 alc_inithook(codec); 19225} 19226 19227/* 19228 * configuration and preset 19229 */ 19230static const char *alc680_models[ALC680_MODEL_LAST] = { 19231 [ALC680_BASE] = "base", 19232 [ALC680_AUTO] = "auto", 19233}; 19234 19235static struct snd_pci_quirk alc680_cfg_tbl[] = { 19236 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 19237 {} 19238}; 19239 19240static struct alc_config_preset alc680_presets[] = { 19241 [ALC680_BASE] = { 19242 .mixers = { alc680_base_mixer }, 19243 .cap_mixer = alc680_capture_mixer, 19244 .init_verbs = { alc680_init_verbs }, 19245 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 19246 .dac_nids = alc680_dac_nids, 19247 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids), 19248 .adc_nids = alc680_adc_nids, 19249 .hp_nid = 0x04, 19250 .dig_out_nid = ALC680_DIGOUT_NID, 19251 .num_channel_mode = ARRAY_SIZE(alc680_modes), 19252 .channel_mode = alc680_modes, 19253 .input_mux = &alc680_capture_source, 19254 }, 19255}; 19256 19257static int patch_alc680(struct hda_codec *codec) 19258{ 19259 struct alc_spec *spec; 19260 int board_config; 19261 int err; 19262 19263 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19264 if (spec == NULL) 19265 return -ENOMEM; 19266 19267 codec->spec = spec; 19268 19269 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 19270 alc680_models, 19271 alc680_cfg_tbl); 19272 19273 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 19274 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19275 codec->chip_name); 19276 board_config = ALC680_AUTO; 19277 } 19278 19279 if (board_config == ALC680_AUTO) { 19280 /* automatic parse from the BIOS config */ 19281 err = alc680_parse_auto_config(codec); 19282 if (err < 0) { 19283 alc_free(codec); 19284 return err; 19285 } else if (!err) { 19286 printk(KERN_INFO 19287 "hda_codec: Cannot set up configuration " 19288 "from BIOS. Using base mode...\n"); 19289 board_config = ALC680_BASE; 19290 } 19291 } 19292 19293 if (board_config != ALC680_AUTO) 19294 setup_preset(codec, &alc680_presets[board_config]); 19295 19296 spec->stream_analog_playback = &alc680_pcm_analog_playback; 19297 spec->stream_analog_capture = &alc680_pcm_analog_capture; 19298 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture; 19299 spec->stream_digital_playback = &alc680_pcm_digital_playback; 19300 19301 if (!spec->adc_nids) { 19302 spec->adc_nids = alc680_adc_nids; 19303 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 19304 } 19305 19306 if (!spec->cap_mixer) 19307 set_capture_mixer(codec); 19308 19309 spec->vmaster_nid = 0x02; 19310 19311 codec->patch_ops = alc_patch_ops; 19312 if (board_config == ALC680_AUTO) 19313 spec->init_hook = alc680_auto_init; 19314 19315 return 0; 19316} 19317 19318/* 19319 * patch entries 19320 */ 19321static struct hda_codec_preset snd_hda_preset_realtek[] = { 19322 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 19323 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 19324 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 19325 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 19326 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 19327 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 19328 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 19329 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 19330 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 19331 .patch = patch_alc861 }, 19332 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 19333 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 19334 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 19335 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 19336 .patch = patch_alc882 }, 19337 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 19338 .patch = patch_alc662 }, 19339 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 19340 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 19341 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 19342 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 19343 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 19344 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 19345 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 19346 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 19347 .patch = patch_alc882 }, 19348 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 19349 .patch = patch_alc882 }, 19350 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 19351 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, 19352 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 19353 .patch = patch_alc882 }, 19354 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 19355 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 19356 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 19357 {} /* terminator */ 19358}; 19359 19360MODULE_ALIAS("snd-hda-codec-id:10ec*"); 19361 19362MODULE_LICENSE("GPL"); 19363MODULE_DESCRIPTION("Realtek HD-audio codec"); 19364 19365static struct hda_codec_preset_list realtek_list = { 19366 .preset = snd_hda_preset_realtek, 19367 .owner = THIS_MODULE, 19368}; 19369 19370static int __init patch_realtek_init(void) 19371{ 19372 return snd_hda_add_codec_preset(&realtek_list); 19373} 19374 19375static void __exit patch_realtek_exit(void) 19376{ 19377 snd_hda_delete_codec_preset(&realtek_list); 19378} 19379 19380module_init(patch_realtek_init) 19381module_exit(patch_realtek_exit) 19382