patch_realtek.c revision 80f1aff93c34feff6ad229ff2a1307e82cb5b132
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 <sound/jack.h> 32#include "hda_codec.h" 33#include "hda_local.h" 34#include "hda_beep.h" 35 36#define ALC880_FRONT_EVENT 0x01 37#define ALC880_DCVOL_EVENT 0x02 38#define ALC880_HP_EVENT 0x04 39#define ALC880_MIC_EVENT 0x08 40 41/* ALC880 board config type */ 42enum { 43 ALC880_3ST, 44 ALC880_3ST_DIG, 45 ALC880_5ST, 46 ALC880_5ST_DIG, 47 ALC880_W810, 48 ALC880_Z71V, 49 ALC880_6ST, 50 ALC880_6ST_DIG, 51 ALC880_F1734, 52 ALC880_ASUS, 53 ALC880_ASUS_DIG, 54 ALC880_ASUS_W1V, 55 ALC880_ASUS_DIG2, 56 ALC880_FUJITSU, 57 ALC880_UNIWILL_DIG, 58 ALC880_UNIWILL, 59 ALC880_UNIWILL_P53, 60 ALC880_CLEVO, 61 ALC880_TCL_S700, 62 ALC880_LG, 63 ALC880_LG_LW, 64 ALC880_MEDION_RIM, 65#ifdef CONFIG_SND_DEBUG 66 ALC880_TEST, 67#endif 68 ALC880_AUTO, 69 ALC880_MODEL_LAST /* last tag */ 70}; 71 72/* ALC260 models */ 73enum { 74 ALC260_BASIC, 75 ALC260_HP, 76 ALC260_HP_DC7600, 77 ALC260_HP_3013, 78 ALC260_FUJITSU_S702X, 79 ALC260_ACER, 80 ALC260_WILL, 81 ALC260_REPLACER_672V, 82 ALC260_FAVORIT100, 83#ifdef CONFIG_SND_DEBUG 84 ALC260_TEST, 85#endif 86 ALC260_AUTO, 87 ALC260_MODEL_LAST /* last tag */ 88}; 89 90/* ALC262 models */ 91enum { 92 ALC262_BASIC, 93 ALC262_HIPPO, 94 ALC262_HIPPO_1, 95 ALC262_FUJITSU, 96 ALC262_HP_BPC, 97 ALC262_HP_BPC_D7000_WL, 98 ALC262_HP_BPC_D7000_WF, 99 ALC262_HP_TC_T5735, 100 ALC262_HP_RP5700, 101 ALC262_BENQ_ED8, 102 ALC262_SONY_ASSAMD, 103 ALC262_BENQ_T31, 104 ALC262_ULTRA, 105 ALC262_LENOVO_3000, 106 ALC262_NEC, 107 ALC262_TOSHIBA_S06, 108 ALC262_TOSHIBA_RX1, 109 ALC262_TYAN, 110 ALC262_AUTO, 111 ALC262_MODEL_LAST /* last tag */ 112}; 113 114/* ALC268 models */ 115enum { 116 ALC267_QUANTA_IL1, 117 ALC268_3ST, 118 ALC268_TOSHIBA, 119 ALC268_ACER, 120 ALC268_ACER_DMIC, 121 ALC268_ACER_ASPIRE_ONE, 122 ALC268_DELL, 123 ALC268_ZEPTO, 124#ifdef CONFIG_SND_DEBUG 125 ALC268_TEST, 126#endif 127 ALC268_AUTO, 128 ALC268_MODEL_LAST /* last tag */ 129}; 130 131/* ALC269 models */ 132enum { 133 ALC269_BASIC, 134 ALC269_QUANTA_FL1, 135 ALC269_AMIC, 136 ALC269_DMIC, 137 ALC269VB_AMIC, 138 ALC269VB_DMIC, 139 ALC269_FUJITSU, 140 ALC269_LIFEBOOK, 141 ALC271_ACER, 142 ALC269_AUTO, 143 ALC269_MODEL_LAST /* last tag */ 144}; 145 146/* ALC861 models */ 147enum { 148 ALC861_3ST, 149 ALC660_3ST, 150 ALC861_3ST_DIG, 151 ALC861_6ST_DIG, 152 ALC861_UNIWILL_M31, 153 ALC861_TOSHIBA, 154 ALC861_ASUS, 155 ALC861_ASUS_LAPTOP, 156 ALC861_AUTO, 157 ALC861_MODEL_LAST, 158}; 159 160/* ALC861-VD models */ 161enum { 162 ALC660VD_3ST, 163 ALC660VD_3ST_DIG, 164 ALC660VD_ASUS_V1S, 165 ALC861VD_3ST, 166 ALC861VD_3ST_DIG, 167 ALC861VD_6ST_DIG, 168 ALC861VD_LENOVO, 169 ALC861VD_DALLAS, 170 ALC861VD_HP, 171 ALC861VD_AUTO, 172 ALC861VD_MODEL_LAST, 173}; 174 175/* ALC662 models */ 176enum { 177 ALC662_3ST_2ch_DIG, 178 ALC662_3ST_6ch_DIG, 179 ALC662_3ST_6ch, 180 ALC662_5ST_DIG, 181 ALC662_LENOVO_101E, 182 ALC662_ASUS_EEEPC_P701, 183 ALC662_ASUS_EEEPC_EP20, 184 ALC663_ASUS_M51VA, 185 ALC663_ASUS_G71V, 186 ALC663_ASUS_H13, 187 ALC663_ASUS_G50V, 188 ALC662_ECS, 189 ALC663_ASUS_MODE1, 190 ALC662_ASUS_MODE2, 191 ALC663_ASUS_MODE3, 192 ALC663_ASUS_MODE4, 193 ALC663_ASUS_MODE5, 194 ALC663_ASUS_MODE6, 195 ALC663_ASUS_MODE7, 196 ALC663_ASUS_MODE8, 197 ALC272_DELL, 198 ALC272_DELL_ZM1, 199 ALC272_SAMSUNG_NC10, 200 ALC662_AUTO, 201 ALC662_MODEL_LAST, 202}; 203 204/* ALC882 models */ 205enum { 206 ALC882_3ST_DIG, 207 ALC882_6ST_DIG, 208 ALC882_ARIMA, 209 ALC882_W2JC, 210 ALC882_TARGA, 211 ALC882_ASUS_A7J, 212 ALC882_ASUS_A7M, 213 ALC885_MACPRO, 214 ALC885_MBA21, 215 ALC885_MBP3, 216 ALC885_MB5, 217 ALC885_MACMINI3, 218 ALC885_IMAC24, 219 ALC885_IMAC91, 220 ALC883_3ST_2ch_DIG, 221 ALC883_3ST_6ch_DIG, 222 ALC883_3ST_6ch, 223 ALC883_6ST_DIG, 224 ALC883_TARGA_DIG, 225 ALC883_TARGA_2ch_DIG, 226 ALC883_TARGA_8ch_DIG, 227 ALC883_ACER, 228 ALC883_ACER_ASPIRE, 229 ALC888_ACER_ASPIRE_4930G, 230 ALC888_ACER_ASPIRE_6530G, 231 ALC888_ACER_ASPIRE_8930G, 232 ALC888_ACER_ASPIRE_7730G, 233 ALC883_MEDION, 234 ALC883_MEDION_WIM2160, 235 ALC883_LAPTOP_EAPD, 236 ALC883_LENOVO_101E_2ch, 237 ALC883_LENOVO_NB0763, 238 ALC888_LENOVO_MS7195_DIG, 239 ALC888_LENOVO_SKY, 240 ALC883_HAIER_W66, 241 ALC888_3ST_HP, 242 ALC888_6ST_DELL, 243 ALC883_MITAC, 244 ALC883_CLEVO_M540R, 245 ALC883_CLEVO_M720, 246 ALC883_FUJITSU_PI2515, 247 ALC888_FUJITSU_XA3530, 248 ALC883_3ST_6ch_INTEL, 249 ALC889A_INTEL, 250 ALC889_INTEL, 251 ALC888_ASUS_M90V, 252 ALC888_ASUS_EEE1601, 253 ALC889A_MB31, 254 ALC1200_ASUS_P5Q, 255 ALC883_SONY_VAIO_TT, 256 ALC882_AUTO, 257 ALC882_MODEL_LAST, 258}; 259 260/* ALC680 models */ 261enum { 262 ALC680_BASE, 263 ALC680_AUTO, 264 ALC680_MODEL_LAST, 265}; 266 267/* for GPIO Poll */ 268#define GPIO_MASK 0x03 269 270/* extra amp-initialization sequence types */ 271enum { 272 ALC_INIT_NONE, 273 ALC_INIT_DEFAULT, 274 ALC_INIT_GPIO1, 275 ALC_INIT_GPIO2, 276 ALC_INIT_GPIO3, 277}; 278 279struct alc_mic_route { 280 hda_nid_t pin; 281 unsigned char mux_idx; 282 unsigned char amix_idx; 283}; 284 285#define MUX_IDX_UNDEF ((unsigned char)-1) 286 287struct alc_customize_define { 288 unsigned int sku_cfg; 289 unsigned char port_connectivity; 290 unsigned char check_sum; 291 unsigned char customization; 292 unsigned char external_amp; 293 unsigned int enable_pcbeep:1; 294 unsigned int platform_type:1; 295 unsigned int swap:1; 296 unsigned int override:1; 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ 298}; 299 300struct alc_fixup; 301 302struct alc_multi_io { 303 hda_nid_t pin; /* multi-io widget pin NID */ 304 hda_nid_t dac; /* DAC to be connected */ 305 unsigned int ctl_in; /* cached input-pin control value */ 306}; 307 308enum { 309 ALC_AUTOMUTE_PIN, /* change the pin control */ 310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */ 311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ 312}; 313 314struct alc_spec { 315 /* codec parameterization */ 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 317 unsigned int num_mixers; 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 320 321 const struct hda_verb *init_verbs[10]; /* initialization verbs 322 * don't forget NULL 323 * termination! 324 */ 325 unsigned int num_init_verbs; 326 327 char stream_name_analog[32]; /* analog PCM stream */ 328 const struct hda_pcm_stream *stream_analog_playback; 329 const struct hda_pcm_stream *stream_analog_capture; 330 const struct hda_pcm_stream *stream_analog_alt_playback; 331 const struct hda_pcm_stream *stream_analog_alt_capture; 332 333 char stream_name_digital[32]; /* digital PCM stream */ 334 const struct hda_pcm_stream *stream_digital_playback; 335 const struct hda_pcm_stream *stream_digital_capture; 336 337 /* playback */ 338 struct hda_multi_out multiout; /* playback set-up 339 * max_channels, dacs must be set 340 * dig_out_nid and hp_nid are optional 341 */ 342 hda_nid_t alt_dac_nid; 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */ 344 int dig_out_type; 345 346 /* capture */ 347 unsigned int num_adc_nids; 348 const hda_nid_t *adc_nids; 349 const hda_nid_t *capsrc_nids; 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 351 352 /* capture setup for dynamic dual-adc switch */ 353 unsigned int cur_adc_idx; 354 hda_nid_t cur_adc; 355 unsigned int cur_adc_stream_tag; 356 unsigned int cur_adc_format; 357 358 /* capture source */ 359 unsigned int num_mux_defs; 360 const struct hda_input_mux *input_mux; 361 unsigned int cur_mux[3]; 362 struct alc_mic_route ext_mic; 363 struct alc_mic_route dock_mic; 364 struct alc_mic_route int_mic; 365 366 /* channel model */ 367 const struct hda_channel_mode *channel_mode; 368 int num_channel_mode; 369 int need_dac_fix; 370 int const_channel_count; 371 int ext_channel_count; 372 373 /* PCM information */ 374 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 375 376 /* dynamic controls, init_verbs and input_mux */ 377 struct auto_pin_cfg autocfg; 378 struct alc_customize_define cdefine; 379 struct snd_array kctls; 380 struct hda_input_mux private_imux[3]; 381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 384 385 /* hooks */ 386 void (*init_hook)(struct hda_codec *codec); 387 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 388#ifdef CONFIG_SND_HDA_POWER_SAVE 389 void (*power_hook)(struct hda_codec *codec); 390#endif 391 void (*shutup)(struct hda_codec *codec); 392 393 /* for pin sensing */ 394 unsigned int jack_present: 1; 395 unsigned int line_jack_present:1; 396 unsigned int master_mute:1; 397 unsigned int auto_mic:1; 398 unsigned int automute:1; /* HP automute enabled */ 399 unsigned int detect_line:1; /* Line-out detection enabled */ 400 unsigned int automute_lines:1; /* automute line-out as well; NOP when automute_hp_lo isn't set */ 401 unsigned int automute_hp_lo:1; /* both HP and LO available */ 402 403 /* other flags */ 404 unsigned int no_analog :1; /* digital I/O only */ 405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 406 unsigned int single_input_src:1; 407 408 /* auto-mute control */ 409 int automute_mode; 410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; 411 412 int init_amp; 413 int codec_variant; /* flag for other variants */ 414 415 /* for virtual master */ 416 hda_nid_t vmaster_nid; 417#ifdef CONFIG_SND_HDA_POWER_SAVE 418 struct hda_loopback_check loopback; 419#endif 420 421 /* for PLL fix */ 422 hda_nid_t pll_nid; 423 unsigned int pll_coef_idx, pll_coef_bit; 424 425 /* fix-up list */ 426 int fixup_id; 427 const struct alc_fixup *fixup_list; 428 const char *fixup_name; 429 430 /* multi-io */ 431 int multi_ios; 432 struct alc_multi_io multi_io[4]; 433}; 434 435/* 436 * configuration template - to be copied to the spec instance 437 */ 438struct alc_config_preset { 439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size 440 * with spec 441 */ 442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 443 const struct hda_verb *init_verbs[5]; 444 unsigned int num_dacs; 445 const hda_nid_t *dac_nids; 446 hda_nid_t dig_out_nid; /* optional */ 447 hda_nid_t hp_nid; /* optional */ 448 const hda_nid_t *slave_dig_outs; 449 unsigned int num_adc_nids; 450 const hda_nid_t *adc_nids; 451 const hda_nid_t *capsrc_nids; 452 hda_nid_t dig_in_nid; 453 unsigned int num_channel_mode; 454 const struct hda_channel_mode *channel_mode; 455 int need_dac_fix; 456 int const_channel_count; 457 unsigned int num_mux_defs; 458 const struct hda_input_mux *input_mux; 459 void (*unsol_event)(struct hda_codec *, unsigned int); 460 void (*setup)(struct hda_codec *); 461 void (*init_hook)(struct hda_codec *); 462#ifdef CONFIG_SND_HDA_POWER_SAVE 463 const struct hda_amp_list *loopbacks; 464 void (*power_hook)(struct hda_codec *codec); 465#endif 466}; 467 468 469/* 470 * input MUX handling 471 */ 472static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, 473 struct snd_ctl_elem_info *uinfo) 474{ 475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 476 struct alc_spec *spec = codec->spec; 477 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); 478 if (mux_idx >= spec->num_mux_defs) 479 mux_idx = 0; 480 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) 481 mux_idx = 0; 482 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); 483} 484 485static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, 486 struct snd_ctl_elem_value *ucontrol) 487{ 488 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 489 struct alc_spec *spec = codec->spec; 490 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 491 492 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 493 return 0; 494} 495 496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 497 struct snd_ctl_elem_value *ucontrol) 498{ 499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 500 struct alc_spec *spec = codec->spec; 501 const struct hda_input_mux *imux; 502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 503 unsigned int mux_idx; 504 hda_nid_t nid = spec->capsrc_nids ? 505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 506 unsigned int type; 507 508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 509 imux = &spec->input_mux[mux_idx]; 510 if (!imux->num_items && mux_idx > 0) 511 imux = &spec->input_mux[0]; 512 if (!imux->num_items) 513 return 0; 514 515 type = get_wcaps_type(get_wcaps(codec, nid)); 516 if (type == AC_WID_AUD_MIX) { 517 /* Matrix-mixer style (e.g. ALC882) */ 518 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 519 unsigned int i, idx; 520 521 idx = ucontrol->value.enumerated.item[0]; 522 if (idx >= imux->num_items) 523 idx = imux->num_items - 1; 524 if (*cur_val == idx) 525 return 0; 526 for (i = 0; i < imux->num_items; i++) { 527 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 528 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 529 imux->items[i].index, 530 HDA_AMP_MUTE, v); 531 } 532 *cur_val = idx; 533 return 1; 534 } else { 535 /* MUX style (e.g. ALC880) */ 536 return snd_hda_input_mux_put(codec, imux, ucontrol, nid, 537 &spec->cur_mux[adc_idx]); 538 } 539} 540 541/* 542 * channel mode setting 543 */ 544static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, 545 struct snd_ctl_elem_info *uinfo) 546{ 547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 548 struct alc_spec *spec = codec->spec; 549 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, 550 spec->num_channel_mode); 551} 552 553static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, 554 struct snd_ctl_elem_value *ucontrol) 555{ 556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 557 struct alc_spec *spec = codec->spec; 558 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, 559 spec->num_channel_mode, 560 spec->ext_channel_count); 561} 562 563static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, 564 struct snd_ctl_elem_value *ucontrol) 565{ 566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 567 struct alc_spec *spec = codec->spec; 568 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, 569 spec->num_channel_mode, 570 &spec->ext_channel_count); 571 if (err >= 0 && !spec->const_channel_count) { 572 spec->multiout.max_channels = spec->ext_channel_count; 573 if (spec->need_dac_fix) 574 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 575 } 576 return err; 577} 578 579/* 580 * Control the mode of pin widget settings via the mixer. "pc" is used 581 * instead of "%" to avoid consequences of accidentally treating the % as 582 * being part of a format specifier. Maximum allowed length of a value is 583 * 63 characters plus NULL terminator. 584 * 585 * Note: some retasking pin complexes seem to ignore requests for input 586 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these 587 * are requested. Therefore order this list so that this behaviour will not 588 * cause problems when mixer clients move through the enum sequentially. 589 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of 590 * March 2006. 591 */ 592static const char * const alc_pin_mode_names[] = { 593 "Mic 50pc bias", "Mic 80pc bias", 594 "Line in", "Line out", "Headphone out", 595}; 596static const unsigned char alc_pin_mode_values[] = { 597 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, 598}; 599/* The control can present all 5 options, or it can limit the options based 600 * in the pin being assumed to be exclusively an input or an output pin. In 601 * addition, "input" pins may or may not process the mic bias option 602 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to 603 * accept requests for bias as of chip versions up to March 2006) and/or 604 * wiring in the computer. 605 */ 606#define ALC_PIN_DIR_IN 0x00 607#define ALC_PIN_DIR_OUT 0x01 608#define ALC_PIN_DIR_INOUT 0x02 609#define ALC_PIN_DIR_IN_NOMICBIAS 0x03 610#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 611 612/* Info about the pin modes supported by the different pin direction modes. 613 * For each direction the minimum and maximum values are given. 614 */ 615static const signed char alc_pin_mode_dir_info[5][2] = { 616 { 0, 2 }, /* ALC_PIN_DIR_IN */ 617 { 3, 4 }, /* ALC_PIN_DIR_OUT */ 618 { 0, 4 }, /* ALC_PIN_DIR_INOUT */ 619 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ 620 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ 621}; 622#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) 623#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) 624#define alc_pin_mode_n_items(_dir) \ 625 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) 626 627static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, 628 struct snd_ctl_elem_info *uinfo) 629{ 630 unsigned int item_num = uinfo->value.enumerated.item; 631 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 632 633 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 634 uinfo->count = 1; 635 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); 636 637 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) 638 item_num = alc_pin_mode_min(dir); 639 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); 640 return 0; 641} 642 643static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, 644 struct snd_ctl_elem_value *ucontrol) 645{ 646 unsigned int i; 647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 648 hda_nid_t nid = kcontrol->private_value & 0xffff; 649 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 650 long *valp = ucontrol->value.integer.value; 651 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 652 AC_VERB_GET_PIN_WIDGET_CONTROL, 653 0x00); 654 655 /* Find enumerated value for current pinctl setting */ 656 i = alc_pin_mode_min(dir); 657 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) 658 i++; 659 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); 660 return 0; 661} 662 663static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, 664 struct snd_ctl_elem_value *ucontrol) 665{ 666 signed int change; 667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 668 hda_nid_t nid = kcontrol->private_value & 0xffff; 669 unsigned char dir = (kcontrol->private_value >> 16) & 0xff; 670 long val = *ucontrol->value.integer.value; 671 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, 672 AC_VERB_GET_PIN_WIDGET_CONTROL, 673 0x00); 674 675 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) 676 val = alc_pin_mode_min(dir); 677 678 change = pinctl != alc_pin_mode_values[val]; 679 if (change) { 680 /* Set pin mode to that requested */ 681 snd_hda_codec_write_cache(codec, nid, 0, 682 AC_VERB_SET_PIN_WIDGET_CONTROL, 683 alc_pin_mode_values[val]); 684 685 /* Also enable the retasking pin's input/output as required 686 * for the requested pin mode. Enum values of 2 or less are 687 * input modes. 688 * 689 * Dynamically switching the input/output buffers probably 690 * reduces noise slightly (particularly on input) so we'll 691 * do it. However, having both input and output buffers 692 * enabled simultaneously doesn't seem to be problematic if 693 * this turns out to be necessary in the future. 694 */ 695 if (val <= 2) { 696 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 697 HDA_AMP_MUTE, HDA_AMP_MUTE); 698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 699 HDA_AMP_MUTE, 0); 700 } else { 701 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 702 HDA_AMP_MUTE, HDA_AMP_MUTE); 703 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 704 HDA_AMP_MUTE, 0); 705 } 706 } 707 return change; 708} 709 710#define ALC_PIN_MODE(xname, nid, dir) \ 711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 712 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 713 .info = alc_pin_mode_info, \ 714 .get = alc_pin_mode_get, \ 715 .put = alc_pin_mode_put, \ 716 .private_value = nid | (dir<<16) } 717 718/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged 719 * together using a mask with more than one bit set. This control is 720 * currently used only by the ALC260 test model. At this stage they are not 721 * needed for any "production" models. 722 */ 723#ifdef CONFIG_SND_DEBUG 724#define alc_gpio_data_info snd_ctl_boolean_mono_info 725 726static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, 727 struct snd_ctl_elem_value *ucontrol) 728{ 729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 730 hda_nid_t nid = kcontrol->private_value & 0xffff; 731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 732 long *valp = ucontrol->value.integer.value; 733 unsigned int val = snd_hda_codec_read(codec, nid, 0, 734 AC_VERB_GET_GPIO_DATA, 0x00); 735 736 *valp = (val & mask) != 0; 737 return 0; 738} 739static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, 740 struct snd_ctl_elem_value *ucontrol) 741{ 742 signed int change; 743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 744 hda_nid_t nid = kcontrol->private_value & 0xffff; 745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 746 long val = *ucontrol->value.integer.value; 747 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, 748 AC_VERB_GET_GPIO_DATA, 749 0x00); 750 751 /* Set/unset the masked GPIO bit(s) as needed */ 752 change = (val == 0 ? 0 : mask) != (gpio_data & mask); 753 if (val == 0) 754 gpio_data &= ~mask; 755 else 756 gpio_data |= mask; 757 snd_hda_codec_write_cache(codec, nid, 0, 758 AC_VERB_SET_GPIO_DATA, gpio_data); 759 760 return change; 761} 762#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ 763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 765 .info = alc_gpio_data_info, \ 766 .get = alc_gpio_data_get, \ 767 .put = alc_gpio_data_put, \ 768 .private_value = nid | (mask<<16) } 769#endif /* CONFIG_SND_DEBUG */ 770 771/* A switch control to allow the enabling of the digital IO pins on the 772 * ALC260. This is incredibly simplistic; the intention of this control is 773 * to provide something in the test model allowing digital outputs to be 774 * identified if present. If models are found which can utilise these 775 * outputs a more complete mixer control can be devised for those models if 776 * necessary. 777 */ 778#ifdef CONFIG_SND_DEBUG 779#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info 780 781static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, 782 struct snd_ctl_elem_value *ucontrol) 783{ 784 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 785 hda_nid_t nid = kcontrol->private_value & 0xffff; 786 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 787 long *valp = ucontrol->value.integer.value; 788 unsigned int val = snd_hda_codec_read(codec, nid, 0, 789 AC_VERB_GET_DIGI_CONVERT_1, 0x00); 790 791 *valp = (val & mask) != 0; 792 return 0; 793} 794static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, 795 struct snd_ctl_elem_value *ucontrol) 796{ 797 signed int change; 798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 799 hda_nid_t nid = kcontrol->private_value & 0xffff; 800 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 801 long val = *ucontrol->value.integer.value; 802 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 803 AC_VERB_GET_DIGI_CONVERT_1, 804 0x00); 805 806 /* Set/unset the masked control bit(s) as needed */ 807 change = (val == 0 ? 0 : mask) != (ctrl_data & mask); 808 if (val==0) 809 ctrl_data &= ~mask; 810 else 811 ctrl_data |= mask; 812 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, 813 ctrl_data); 814 815 return change; 816} 817#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ 818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 820 .info = alc_spdif_ctrl_info, \ 821 .get = alc_spdif_ctrl_get, \ 822 .put = alc_spdif_ctrl_put, \ 823 .private_value = nid | (mask<<16) } 824#endif /* CONFIG_SND_DEBUG */ 825 826/* A switch control to allow the enabling EAPD digital outputs on the ALC26x. 827 * Again, this is only used in the ALC26x test models to help identify when 828 * the EAPD line must be asserted for features to work. 829 */ 830#ifdef CONFIG_SND_DEBUG 831#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info 832 833static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, 834 struct snd_ctl_elem_value *ucontrol) 835{ 836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 837 hda_nid_t nid = kcontrol->private_value & 0xffff; 838 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 839 long *valp = ucontrol->value.integer.value; 840 unsigned int val = snd_hda_codec_read(codec, nid, 0, 841 AC_VERB_GET_EAPD_BTLENABLE, 0x00); 842 843 *valp = (val & mask) != 0; 844 return 0; 845} 846 847static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 848 struct snd_ctl_elem_value *ucontrol) 849{ 850 int change; 851 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 852 hda_nid_t nid = kcontrol->private_value & 0xffff; 853 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 854 long val = *ucontrol->value.integer.value; 855 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, 856 AC_VERB_GET_EAPD_BTLENABLE, 857 0x00); 858 859 /* Set/unset the masked control bit(s) as needed */ 860 change = (!val ? 0 : mask) != (ctrl_data & mask); 861 if (!val) 862 ctrl_data &= ~mask; 863 else 864 ctrl_data |= mask; 865 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 866 ctrl_data); 867 868 return change; 869} 870 871#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ 872 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ 873 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 874 .info = alc_eapd_ctrl_info, \ 875 .get = alc_eapd_ctrl_get, \ 876 .put = alc_eapd_ctrl_put, \ 877 .private_value = nid | (mask<<16) } 878#endif /* CONFIG_SND_DEBUG */ 879 880/* 881 * set up the input pin config (depending on the given auto-pin type) 882 */ 883static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 884 int auto_pin_type) 885{ 886 unsigned int val = PIN_IN; 887 888 if (auto_pin_type == AUTO_PIN_MIC) { 889 unsigned int pincap; 890 unsigned int oldval; 891 oldval = snd_hda_codec_read(codec, nid, 0, 892 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 893 pincap = snd_hda_query_pin_caps(codec, nid); 894 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 895 /* if the default pin setup is vref50, we give it priority */ 896 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50) 897 val = PIN_VREF80; 898 else if (pincap & AC_PINCAP_VREF_50) 899 val = PIN_VREF50; 900 else if (pincap & AC_PINCAP_VREF_100) 901 val = PIN_VREF100; 902 else if (pincap & AC_PINCAP_VREF_GRD) 903 val = PIN_VREFGRD; 904 } 905 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 906} 907 908static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) 909{ 910 struct alc_spec *spec = codec->spec; 911 struct auto_pin_cfg *cfg = &spec->autocfg; 912 913 if (!cfg->line_outs) { 914 while (cfg->line_outs < AUTO_CFG_MAX_OUTS && 915 cfg->line_out_pins[cfg->line_outs]) 916 cfg->line_outs++; 917 } 918 if (!cfg->speaker_outs) { 919 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && 920 cfg->speaker_pins[cfg->speaker_outs]) 921 cfg->speaker_outs++; 922 } 923 if (!cfg->hp_outs) { 924 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && 925 cfg->hp_pins[cfg->hp_outs]) 926 cfg->hp_outs++; 927 } 928} 929 930/* 931 */ 932static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 933{ 934 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) 935 return; 936 spec->mixers[spec->num_mixers++] = mix; 937} 938 939static void add_verb(struct alc_spec *spec, const struct hda_verb *verb) 940{ 941 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs))) 942 return; 943 spec->init_verbs[spec->num_init_verbs++] = verb; 944} 945 946/* 947 * set up from the preset table 948 */ 949static void setup_preset(struct hda_codec *codec, 950 const struct alc_config_preset *preset) 951{ 952 struct alc_spec *spec = codec->spec; 953 int i; 954 955 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 956 add_mixer(spec, preset->mixers[i]); 957 spec->cap_mixer = preset->cap_mixer; 958 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 959 i++) 960 add_verb(spec, preset->init_verbs[i]); 961 962 spec->channel_mode = preset->channel_mode; 963 spec->num_channel_mode = preset->num_channel_mode; 964 spec->need_dac_fix = preset->need_dac_fix; 965 spec->const_channel_count = preset->const_channel_count; 966 967 if (preset->const_channel_count) 968 spec->multiout.max_channels = preset->const_channel_count; 969 else 970 spec->multiout.max_channels = spec->channel_mode[0].channels; 971 spec->ext_channel_count = spec->channel_mode[0].channels; 972 973 spec->multiout.num_dacs = preset->num_dacs; 974 spec->multiout.dac_nids = preset->dac_nids; 975 spec->multiout.dig_out_nid = preset->dig_out_nid; 976 spec->multiout.slave_dig_outs = preset->slave_dig_outs; 977 spec->multiout.hp_nid = preset->hp_nid; 978 979 spec->num_mux_defs = preset->num_mux_defs; 980 if (!spec->num_mux_defs) 981 spec->num_mux_defs = 1; 982 spec->input_mux = preset->input_mux; 983 984 spec->num_adc_nids = preset->num_adc_nids; 985 spec->adc_nids = preset->adc_nids; 986 spec->capsrc_nids = preset->capsrc_nids; 987 spec->dig_in_nid = preset->dig_in_nid; 988 989 spec->unsol_event = preset->unsol_event; 990 spec->init_hook = preset->init_hook; 991#ifdef CONFIG_SND_HDA_POWER_SAVE 992 spec->power_hook = preset->power_hook; 993 spec->loopback.amplist = preset->loopbacks; 994#endif 995 996 if (preset->setup) 997 preset->setup(codec); 998 999 alc_fixup_autocfg_pin_nums(codec); 1000} 1001 1002/* Enable GPIO mask and set output */ 1003static const struct hda_verb alc_gpio1_init_verbs[] = { 1004 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 1005 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 1006 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 1007 { } 1008}; 1009 1010static const struct hda_verb alc_gpio2_init_verbs[] = { 1011 {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1012 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1013 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 1014 { } 1015}; 1016 1017static const struct hda_verb alc_gpio3_init_verbs[] = { 1018 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 1019 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, 1020 {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, 1021 { } 1022}; 1023 1024/* 1025 * Fix hardware PLL issue 1026 * On some codecs, the analog PLL gating control must be off while 1027 * the default value is 1. 1028 */ 1029static void alc_fix_pll(struct hda_codec *codec) 1030{ 1031 struct alc_spec *spec = codec->spec; 1032 unsigned int val; 1033 1034 if (!spec->pll_nid) 1035 return; 1036 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1037 spec->pll_coef_idx); 1038 val = snd_hda_codec_read(codec, spec->pll_nid, 0, 1039 AC_VERB_GET_PROC_COEF, 0); 1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, 1041 spec->pll_coef_idx); 1042 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, 1043 val & ~(1 << spec->pll_coef_bit)); 1044} 1045 1046static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, 1047 unsigned int coef_idx, unsigned int coef_bit) 1048{ 1049 struct alc_spec *spec = codec->spec; 1050 spec->pll_nid = nid; 1051 spec->pll_coef_idx = coef_idx; 1052 spec->pll_coef_bit = coef_bit; 1053 alc_fix_pll(codec); 1054} 1055 1056static int alc_init_jacks(struct hda_codec *codec) 1057{ 1058#ifdef CONFIG_SND_HDA_INPUT_JACK 1059 struct alc_spec *spec = codec->spec; 1060 int err; 1061 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 1062 unsigned int mic_nid = spec->ext_mic.pin; 1063 unsigned int dock_nid = spec->dock_mic.pin; 1064 1065 if (hp_nid) { 1066 err = snd_hda_input_jack_add(codec, hp_nid, 1067 SND_JACK_HEADPHONE, NULL); 1068 if (err < 0) 1069 return err; 1070 snd_hda_input_jack_report(codec, hp_nid); 1071 } 1072 1073 if (mic_nid) { 1074 err = snd_hda_input_jack_add(codec, mic_nid, 1075 SND_JACK_MICROPHONE, NULL); 1076 if (err < 0) 1077 return err; 1078 snd_hda_input_jack_report(codec, mic_nid); 1079 } 1080 if (dock_nid) { 1081 err = snd_hda_input_jack_add(codec, dock_nid, 1082 SND_JACK_MICROPHONE, NULL); 1083 if (err < 0) 1084 return err; 1085 snd_hda_input_jack_report(codec, dock_nid); 1086 } 1087#endif /* CONFIG_SND_HDA_INPUT_JACK */ 1088 return 0; 1089} 1090 1091static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 1092{ 1093 int i, present = 0; 1094 1095 for (i = 0; i < num_pins; i++) { 1096 hda_nid_t nid = pins[i]; 1097 if (!nid) 1098 break; 1099 snd_hda_input_jack_report(codec, nid); 1100 present |= snd_hda_jack_detect(codec, nid); 1101 } 1102 return present; 1103} 1104 1105static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 1106 bool mute, bool hp_out) 1107{ 1108 struct alc_spec *spec = codec->spec; 1109 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; 1110 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); 1111 int i; 1112 1113 for (i = 0; i < num_pins; i++) { 1114 hda_nid_t nid = pins[i]; 1115 if (!nid) 1116 break; 1117 switch (spec->automute_mode) { 1118 case ALC_AUTOMUTE_PIN: 1119 snd_hda_codec_write(codec, nid, 0, 1120 AC_VERB_SET_PIN_WIDGET_CONTROL, 1121 pin_bits); 1122 break; 1123 case ALC_AUTOMUTE_AMP: 1124 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 1125 HDA_AMP_MUTE, mute_bits); 1126 break; 1127 case ALC_AUTOMUTE_MIXER: 1128 nid = spec->automute_mixer_nid[i]; 1129 if (!nid) 1130 break; 1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, 1132 HDA_AMP_MUTE, mute_bits); 1133 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, 1134 HDA_AMP_MUTE, mute_bits); 1135 break; 1136 } 1137 } 1138} 1139 1140/* Toggle internal speakers muting */ 1141static void update_speakers(struct hda_codec *codec) 1142{ 1143 struct alc_spec *spec = codec->spec; 1144 int on; 1145 1146 /* Control HP pins/amps depending on master_mute state; 1147 * in general, HP pins/amps control should be enabled in all cases, 1148 * but currently set only for master_mute, just to be safe 1149 */ 1150 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 1151 spec->autocfg.hp_pins, spec->master_mute, true); 1152 1153 if (!spec->automute) 1154 on = 0; 1155 else 1156 on = spec->jack_present | spec->line_jack_present; 1157 on |= spec->master_mute; 1158 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), 1159 spec->autocfg.speaker_pins, on, false); 1160 1161 /* toggle line-out mutes if needed, too */ 1162 /* if LO is a copy of either HP or Speaker, don't need to handle it */ 1163 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || 1164 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) 1165 return; 1166 if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines)) 1167 on = 0; 1168 else 1169 on = spec->jack_present; 1170 on |= spec->master_mute; 1171 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 1172 spec->autocfg.line_out_pins, on, false); 1173} 1174 1175static void alc_hp_automute(struct hda_codec *codec) 1176{ 1177 struct alc_spec *spec = codec->spec; 1178 1179 if (!spec->automute) 1180 return; 1181 spec->jack_present = 1182 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 1183 spec->autocfg.hp_pins); 1184 update_speakers(codec); 1185} 1186 1187static void alc_line_automute(struct hda_codec *codec) 1188{ 1189 struct alc_spec *spec = codec->spec; 1190 1191 if (!spec->automute || !spec->detect_line) 1192 return; 1193 spec->line_jack_present = 1194 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 1195 spec->autocfg.line_out_pins); 1196 update_speakers(codec); 1197} 1198 1199static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1200 hda_nid_t nid) 1201{ 1202 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 1203 int i, nums; 1204 1205 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); 1206 for (i = 0; i < nums; i++) 1207 if (conn[i] == nid) 1208 return i; 1209 return -1; 1210} 1211 1212/* switch the current ADC according to the jack state */ 1213static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1214{ 1215 struct alc_spec *spec = codec->spec; 1216 unsigned int present; 1217 hda_nid_t new_adc; 1218 1219 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1220 if (present) 1221 spec->cur_adc_idx = 1; 1222 else 1223 spec->cur_adc_idx = 0; 1224 new_adc = spec->adc_nids[spec->cur_adc_idx]; 1225 if (spec->cur_adc && spec->cur_adc != new_adc) { 1226 /* stream is running, let's swap the current ADC */ 1227 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 1228 spec->cur_adc = new_adc; 1229 snd_hda_codec_setup_stream(codec, new_adc, 1230 spec->cur_adc_stream_tag, 0, 1231 spec->cur_adc_format); 1232 } 1233} 1234 1235static void alc_mic_automute(struct hda_codec *codec) 1236{ 1237 struct alc_spec *spec = codec->spec; 1238 struct alc_mic_route *dead1, *dead2, *alive; 1239 unsigned int present, type; 1240 hda_nid_t cap_nid; 1241 1242 if (!spec->auto_mic) 1243 return; 1244 if (!spec->int_mic.pin || !spec->ext_mic.pin) 1245 return; 1246 if (snd_BUG_ON(!spec->adc_nids)) 1247 return; 1248 1249 if (spec->dual_adc_switch) { 1250 alc_dual_mic_adc_auto_switch(codec); 1251 return; 1252 } 1253 1254 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 1255 1256 alive = &spec->int_mic; 1257 dead1 = &spec->ext_mic; 1258 dead2 = &spec->dock_mic; 1259 1260 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 1261 if (present) { 1262 alive = &spec->ext_mic; 1263 dead1 = &spec->int_mic; 1264 dead2 = &spec->dock_mic; 1265 } 1266 if (!present && spec->dock_mic.pin > 0) { 1267 present = snd_hda_jack_detect(codec, spec->dock_mic.pin); 1268 if (present) { 1269 alive = &spec->dock_mic; 1270 dead1 = &spec->int_mic; 1271 dead2 = &spec->ext_mic; 1272 } 1273 snd_hda_input_jack_report(codec, spec->dock_mic.pin); 1274 } 1275 1276 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 1277 if (type == AC_WID_AUD_MIX) { 1278 /* Matrix-mixer style (e.g. ALC882) */ 1279 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1280 alive->mux_idx, 1281 HDA_AMP_MUTE, 0); 1282 if (dead1->pin > 0) 1283 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1284 dead1->mux_idx, 1285 HDA_AMP_MUTE, HDA_AMP_MUTE); 1286 if (dead2->pin > 0) 1287 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 1288 dead2->mux_idx, 1289 HDA_AMP_MUTE, HDA_AMP_MUTE); 1290 } else { 1291 /* MUX style (e.g. ALC880) */ 1292 snd_hda_codec_write_cache(codec, cap_nid, 0, 1293 AC_VERB_SET_CONNECT_SEL, 1294 alive->mux_idx); 1295 } 1296 snd_hda_input_jack_report(codec, spec->ext_mic.pin); 1297 1298 /* FIXME: analog mixer */ 1299} 1300 1301/* unsolicited event for HP jack sensing */ 1302static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1303{ 1304 if (codec->vendor_id == 0x10ec0880) 1305 res >>= 28; 1306 else 1307 res >>= 26; 1308 switch (res) { 1309 case ALC880_HP_EVENT: 1310 alc_hp_automute(codec); 1311 break; 1312 case ALC880_FRONT_EVENT: 1313 alc_line_automute(codec); 1314 break; 1315 case ALC880_MIC_EVENT: 1316 alc_mic_automute(codec); 1317 break; 1318 } 1319} 1320 1321static void alc_inithook(struct hda_codec *codec) 1322{ 1323 alc_hp_automute(codec); 1324 alc_line_automute(codec); 1325 alc_mic_automute(codec); 1326} 1327 1328/* additional initialization for ALC888 variants */ 1329static void alc888_coef_init(struct hda_codec *codec) 1330{ 1331 unsigned int tmp; 1332 1333 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); 1334 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1335 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1336 if ((tmp & 0xf0) == 0x20) 1337 /* alc888S-VC */ 1338 snd_hda_codec_read(codec, 0x20, 0, 1339 AC_VERB_SET_PROC_COEF, 0x830); 1340 else 1341 /* alc888-VB */ 1342 snd_hda_codec_read(codec, 0x20, 0, 1343 AC_VERB_SET_PROC_COEF, 0x3030); 1344} 1345 1346static void alc889_coef_init(struct hda_codec *codec) 1347{ 1348 unsigned int tmp; 1349 1350 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1351 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 1352 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); 1353 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); 1354} 1355 1356/* turn on/off EAPD control (only if available) */ 1357static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) 1358{ 1359 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) 1360 return; 1361 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) 1362 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, 1363 on ? 2 : 0); 1364} 1365 1366/* turn on/off EAPD controls of the codec */ 1367static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 1368{ 1369 /* We currently only handle front, HP */ 1370 switch (codec->vendor_id) { 1371 case 0x10ec0260: 1372 set_eapd(codec, 0x0f, on); 1373 set_eapd(codec, 0x10, on); 1374 break; 1375 case 0x10ec0262: 1376 case 0x10ec0267: 1377 case 0x10ec0268: 1378 case 0x10ec0269: 1379 case 0x10ec0270: 1380 case 0x10ec0272: 1381 case 0x10ec0660: 1382 case 0x10ec0662: 1383 case 0x10ec0663: 1384 case 0x10ec0665: 1385 case 0x10ec0862: 1386 case 0x10ec0889: 1387 case 0x10ec0892: 1388 set_eapd(codec, 0x14, on); 1389 set_eapd(codec, 0x15, on); 1390 break; 1391 } 1392} 1393 1394/* generic shutup callback; 1395 * just turning off EPAD and a little pause for avoiding pop-noise 1396 */ 1397static void alc_eapd_shutup(struct hda_codec *codec) 1398{ 1399 alc_auto_setup_eapd(codec, false); 1400 msleep(200); 1401} 1402 1403static void alc_auto_init_amp(struct hda_codec *codec, int type) 1404{ 1405 unsigned int tmp; 1406 1407 switch (type) { 1408 case ALC_INIT_GPIO1: 1409 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1410 break; 1411 case ALC_INIT_GPIO2: 1412 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1413 break; 1414 case ALC_INIT_GPIO3: 1415 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1416 break; 1417 case ALC_INIT_DEFAULT: 1418 alc_auto_setup_eapd(codec, true); 1419 switch (codec->vendor_id) { 1420 case 0x10ec0260: 1421 snd_hda_codec_write(codec, 0x1a, 0, 1422 AC_VERB_SET_COEF_INDEX, 7); 1423 tmp = snd_hda_codec_read(codec, 0x1a, 0, 1424 AC_VERB_GET_PROC_COEF, 0); 1425 snd_hda_codec_write(codec, 0x1a, 0, 1426 AC_VERB_SET_COEF_INDEX, 7); 1427 snd_hda_codec_write(codec, 0x1a, 0, 1428 AC_VERB_SET_PROC_COEF, 1429 tmp | 0x2010); 1430 break; 1431 case 0x10ec0262: 1432 case 0x10ec0880: 1433 case 0x10ec0882: 1434 case 0x10ec0883: 1435 case 0x10ec0885: 1436 case 0x10ec0887: 1437 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ 1438 alc889_coef_init(codec); 1439 break; 1440 case 0x10ec0888: 1441 alc888_coef_init(codec); 1442 break; 1443#if 0 /* XXX: This may cause the silent output on speaker on some machines */ 1444 case 0x10ec0267: 1445 case 0x10ec0268: 1446 snd_hda_codec_write(codec, 0x20, 0, 1447 AC_VERB_SET_COEF_INDEX, 7); 1448 tmp = snd_hda_codec_read(codec, 0x20, 0, 1449 AC_VERB_GET_PROC_COEF, 0); 1450 snd_hda_codec_write(codec, 0x20, 0, 1451 AC_VERB_SET_COEF_INDEX, 7); 1452 snd_hda_codec_write(codec, 0x20, 0, 1453 AC_VERB_SET_PROC_COEF, 1454 tmp | 0x3000); 1455 break; 1456#endif /* XXX */ 1457 } 1458 break; 1459 } 1460} 1461 1462static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 1463 struct snd_ctl_elem_info *uinfo) 1464{ 1465 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1466 struct alc_spec *spec = codec->spec; 1467 static const char * const texts2[] = { 1468 "Disabled", "Enabled" 1469 }; 1470 static const char * const texts3[] = { 1471 "Disabled", "Speaker Only", "Line-Out+Speaker" 1472 }; 1473 const char * const *texts; 1474 1475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1476 uinfo->count = 1; 1477 if (spec->automute_hp_lo) { 1478 uinfo->value.enumerated.items = 3; 1479 texts = texts3; 1480 } else { 1481 uinfo->value.enumerated.items = 2; 1482 texts = texts2; 1483 } 1484 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1485 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 1486 strcpy(uinfo->value.enumerated.name, 1487 texts[uinfo->value.enumerated.item]); 1488 return 0; 1489} 1490 1491static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, 1492 struct snd_ctl_elem_value *ucontrol) 1493{ 1494 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1495 struct alc_spec *spec = codec->spec; 1496 unsigned int val; 1497 if (!spec->automute) 1498 val = 0; 1499 else if (!spec->automute_hp_lo || !spec->automute_lines) 1500 val = 1; 1501 else 1502 val = 2; 1503 ucontrol->value.enumerated.item[0] = val; 1504 return 0; 1505} 1506 1507static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, 1508 struct snd_ctl_elem_value *ucontrol) 1509{ 1510 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1511 struct alc_spec *spec = codec->spec; 1512 1513 switch (ucontrol->value.enumerated.item[0]) { 1514 case 0: 1515 if (!spec->automute) 1516 return 0; 1517 spec->automute = 0; 1518 break; 1519 case 1: 1520 if (spec->automute && 1521 (!spec->automute_hp_lo || !spec->automute_lines)) 1522 return 0; 1523 spec->automute = 1; 1524 spec->automute_lines = 0; 1525 break; 1526 case 2: 1527 if (!spec->automute_hp_lo) 1528 return -EINVAL; 1529 if (spec->automute && spec->automute_lines) 1530 return 0; 1531 spec->automute = 1; 1532 spec->automute_lines = 1; 1533 break; 1534 default: 1535 return -EINVAL; 1536 } 1537 update_speakers(codec); 1538 return 1; 1539} 1540 1541static const struct snd_kcontrol_new alc_automute_mode_enum = { 1542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1543 .name = "Auto-Mute Mode", 1544 .info = alc_automute_mode_info, 1545 .get = alc_automute_mode_get, 1546 .put = alc_automute_mode_put, 1547}; 1548 1549static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 1550 1551static int alc_add_automute_mode_enum(struct hda_codec *codec) 1552{ 1553 struct alc_spec *spec = codec->spec; 1554 struct snd_kcontrol_new *knew; 1555 1556 knew = alc_kcontrol_new(spec); 1557 if (!knew) 1558 return -ENOMEM; 1559 *knew = alc_automute_mode_enum; 1560 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL); 1561 if (!knew->name) 1562 return -ENOMEM; 1563 return 0; 1564} 1565 1566static void alc_init_auto_hp(struct hda_codec *codec) 1567{ 1568 struct alc_spec *spec = codec->spec; 1569 struct auto_pin_cfg *cfg = &spec->autocfg; 1570 int present = 0; 1571 int i; 1572 1573 if (cfg->hp_pins[0]) 1574 present++; 1575 if (cfg->line_out_pins[0]) 1576 present++; 1577 if (cfg->speaker_pins[0]) 1578 present++; 1579 if (present < 2) /* need two different output types */ 1580 return; 1581 if (present == 3) 1582 spec->automute_hp_lo = 1; /* both HP and LO automute */ 1583 1584 if (!cfg->speaker_pins[0] && 1585 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 1586 memcpy(cfg->speaker_pins, cfg->line_out_pins, 1587 sizeof(cfg->speaker_pins)); 1588 cfg->speaker_outs = cfg->line_outs; 1589 } 1590 1591 if (!cfg->hp_pins[0] && 1592 cfg->line_out_type == AUTO_PIN_HP_OUT) { 1593 memcpy(cfg->hp_pins, cfg->line_out_pins, 1594 sizeof(cfg->hp_pins)); 1595 cfg->hp_outs = cfg->line_outs; 1596 } 1597 1598 for (i = 0; i < cfg->hp_outs; i++) { 1599 hda_nid_t nid = cfg->hp_pins[i]; 1600 if (!is_jack_detectable(codec, nid)) 1601 continue; 1602 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", 1603 nid); 1604 snd_hda_codec_write_cache(codec, nid, 0, 1605 AC_VERB_SET_UNSOLICITED_ENABLE, 1606 AC_USRSP_EN | ALC880_HP_EVENT); 1607 spec->automute = 1; 1608 spec->automute_mode = ALC_AUTOMUTE_PIN; 1609 } 1610 if (spec->automute && cfg->line_out_pins[0] && 1611 cfg->speaker_pins[0] && 1612 cfg->line_out_pins[0] != cfg->hp_pins[0] && 1613 cfg->line_out_pins[0] != cfg->speaker_pins[0]) { 1614 for (i = 0; i < cfg->line_outs; i++) { 1615 hda_nid_t nid = cfg->line_out_pins[i]; 1616 if (!is_jack_detectable(codec, nid)) 1617 continue; 1618 snd_printdd("realtek: Enable Line-Out auto-muting " 1619 "on NID 0x%x\n", nid); 1620 snd_hda_codec_write_cache(codec, nid, 0, 1621 AC_VERB_SET_UNSOLICITED_ENABLE, 1622 AC_USRSP_EN | ALC880_FRONT_EVENT); 1623 spec->detect_line = 1; 1624 } 1625 spec->automute_lines = spec->detect_line; 1626 } 1627 1628 if (spec->automute) { 1629 /* create a control for automute mode */ 1630 alc_add_automute_mode_enum(codec); 1631 spec->unsol_event = alc_sku_unsol_event; 1632 } 1633} 1634 1635static void alc_init_auto_mic(struct hda_codec *codec) 1636{ 1637 struct alc_spec *spec = codec->spec; 1638 struct auto_pin_cfg *cfg = &spec->autocfg; 1639 hda_nid_t fixed, ext, dock; 1640 int i; 1641 1642 fixed = ext = dock = 0; 1643 for (i = 0; i < cfg->num_inputs; i++) { 1644 hda_nid_t nid = cfg->inputs[i].pin; 1645 unsigned int defcfg; 1646 defcfg = snd_hda_codec_get_pincfg(codec, nid); 1647 switch (snd_hda_get_input_pin_attr(defcfg)) { 1648 case INPUT_PIN_ATTR_INT: 1649 if (fixed) 1650 return; /* already occupied */ 1651 if (cfg->inputs[i].type != AUTO_PIN_MIC) 1652 return; /* invalid type */ 1653 fixed = nid; 1654 break; 1655 case INPUT_PIN_ATTR_UNUSED: 1656 return; /* invalid entry */ 1657 case INPUT_PIN_ATTR_DOCK: 1658 if (dock) 1659 return; /* already occupied */ 1660 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) 1661 return; /* invalid type */ 1662 dock = nid; 1663 break; 1664 default: 1665 if (ext) 1666 return; /* already occupied */ 1667 if (cfg->inputs[i].type != AUTO_PIN_MIC) 1668 return; /* invalid type */ 1669 ext = nid; 1670 break; 1671 } 1672 } 1673 if (!ext && dock) { 1674 ext = dock; 1675 dock = 0; 1676 } 1677 if (!ext || !fixed) 1678 return; 1679 if (!is_jack_detectable(codec, ext)) 1680 return; /* no unsol support */ 1681 if (dock && !is_jack_detectable(codec, dock)) 1682 return; /* no unsol support */ 1683 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1684 ext, fixed, dock); 1685 spec->ext_mic.pin = ext; 1686 spec->dock_mic.pin = dock; 1687 spec->int_mic.pin = fixed; 1688 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1689 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1690 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ 1691 spec->auto_mic = 1; 1692 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, 1693 AC_VERB_SET_UNSOLICITED_ENABLE, 1694 AC_USRSP_EN | ALC880_MIC_EVENT); 1695 spec->unsol_event = alc_sku_unsol_event; 1696} 1697 1698/* Could be any non-zero and even value. When used as fixup, tells 1699 * the driver to ignore any present sku defines. 1700 */ 1701#define ALC_FIXUP_SKU_IGNORE (2) 1702 1703static int alc_auto_parse_customize_define(struct hda_codec *codec) 1704{ 1705 unsigned int ass, tmp, i; 1706 unsigned nid = 0; 1707 struct alc_spec *spec = codec->spec; 1708 1709 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ 1710 1711 if (spec->cdefine.fixup) { 1712 ass = spec->cdefine.sku_cfg; 1713 if (ass == ALC_FIXUP_SKU_IGNORE) 1714 return -1; 1715 goto do_sku; 1716 } 1717 1718 ass = codec->subsystem_id & 0xffff; 1719 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1720 goto do_sku; 1721 1722 nid = 0x1d; 1723 if (codec->vendor_id == 0x10ec0260) 1724 nid = 0x17; 1725 ass = snd_hda_codec_get_pincfg(codec, nid); 1726 1727 if (!(ass & 1)) { 1728 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n", 1729 codec->chip_name, ass); 1730 return -1; 1731 } 1732 1733 /* check sum */ 1734 tmp = 0; 1735 for (i = 1; i < 16; i++) { 1736 if ((ass >> i) & 1) 1737 tmp++; 1738 } 1739 if (((ass >> 16) & 0xf) != tmp) 1740 return -1; 1741 1742 spec->cdefine.port_connectivity = ass >> 30; 1743 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; 1744 spec->cdefine.check_sum = (ass >> 16) & 0xf; 1745 spec->cdefine.customization = ass >> 8; 1746do_sku: 1747 spec->cdefine.sku_cfg = ass; 1748 spec->cdefine.external_amp = (ass & 0x38) >> 3; 1749 spec->cdefine.platform_type = (ass & 0x4) >> 2; 1750 spec->cdefine.swap = (ass & 0x2) >> 1; 1751 spec->cdefine.override = ass & 0x1; 1752 1753 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n", 1754 nid, spec->cdefine.sku_cfg); 1755 snd_printd("SKU: port_connectivity=0x%x\n", 1756 spec->cdefine.port_connectivity); 1757 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); 1758 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); 1759 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization); 1760 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp); 1761 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type); 1762 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap); 1763 snd_printd("SKU: override=0x%x\n", spec->cdefine.override); 1764 1765 return 0; 1766} 1767 1768/* check subsystem ID and set up device-specific initialization; 1769 * return 1 if initialized, 0 if invalid SSID 1770 */ 1771/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1772 * 31 ~ 16 : Manufacture ID 1773 * 15 ~ 8 : SKU ID 1774 * 7 ~ 0 : Assembly ID 1775 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 1776 */ 1777static int alc_subsystem_id(struct hda_codec *codec, 1778 hda_nid_t porta, hda_nid_t porte, 1779 hda_nid_t portd, hda_nid_t porti) 1780{ 1781 unsigned int ass, tmp, i; 1782 unsigned nid; 1783 struct alc_spec *spec = codec->spec; 1784 1785 if (spec->cdefine.fixup) { 1786 ass = spec->cdefine.sku_cfg; 1787 if (ass == ALC_FIXUP_SKU_IGNORE) 1788 return 0; 1789 goto do_sku; 1790 } 1791 1792 ass = codec->subsystem_id & 0xffff; 1793 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1794 goto do_sku; 1795 1796 /* invalid SSID, check the special NID pin defcfg instead */ 1797 /* 1798 * 31~30 : port connectivity 1799 * 29~21 : reserve 1800 * 20 : PCBEEP input 1801 * 19~16 : Check sum (15:1) 1802 * 15~1 : Custom 1803 * 0 : override 1804 */ 1805 nid = 0x1d; 1806 if (codec->vendor_id == 0x10ec0260) 1807 nid = 0x17; 1808 ass = snd_hda_codec_get_pincfg(codec, nid); 1809 snd_printd("realtek: No valid SSID, " 1810 "checking pincfg 0x%08x for NID 0x%x\n", 1811 ass, nid); 1812 if (!(ass & 1)) 1813 return 0; 1814 if ((ass >> 30) != 1) /* no physical connection */ 1815 return 0; 1816 1817 /* check sum */ 1818 tmp = 0; 1819 for (i = 1; i < 16; i++) { 1820 if ((ass >> i) & 1) 1821 tmp++; 1822 } 1823 if (((ass >> 16) & 0xf) != tmp) 1824 return 0; 1825do_sku: 1826 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", 1827 ass & 0xffff, codec->vendor_id); 1828 /* 1829 * 0 : override 1830 * 1 : Swap Jack 1831 * 2 : 0 --> Desktop, 1 --> Laptop 1832 * 3~5 : External Amplifier control 1833 * 7~6 : Reserved 1834 */ 1835 tmp = (ass & 0x38) >> 3; /* external Amp control */ 1836 switch (tmp) { 1837 case 1: 1838 spec->init_amp = ALC_INIT_GPIO1; 1839 break; 1840 case 3: 1841 spec->init_amp = ALC_INIT_GPIO2; 1842 break; 1843 case 7: 1844 spec->init_amp = ALC_INIT_GPIO3; 1845 break; 1846 case 5: 1847 default: 1848 spec->init_amp = ALC_INIT_DEFAULT; 1849 break; 1850 } 1851 1852 /* is laptop or Desktop and enable the function "Mute internal speaker 1853 * when the external headphone out jack is plugged" 1854 */ 1855 if (!(ass & 0x8000)) 1856 return 1; 1857 /* 1858 * 10~8 : Jack location 1859 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1860 * 14~13: Resvered 1861 * 15 : 1 --> enable the function "Mute internal speaker 1862 * when the external headphone out jack is plugged" 1863 */ 1864 if (!spec->autocfg.hp_pins[0] && 1865 !(spec->autocfg.line_out_pins[0] && 1866 spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) { 1867 hda_nid_t nid; 1868 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1869 if (tmp == 0) 1870 nid = porta; 1871 else if (tmp == 1) 1872 nid = porte; 1873 else if (tmp == 2) 1874 nid = portd; 1875 else if (tmp == 3) 1876 nid = porti; 1877 else 1878 return 1; 1879 for (i = 0; i < spec->autocfg.line_outs; i++) 1880 if (spec->autocfg.line_out_pins[i] == nid) 1881 return 1; 1882 spec->autocfg.hp_pins[0] = nid; 1883 } 1884 return 1; 1885} 1886 1887static void alc_ssid_check(struct hda_codec *codec, 1888 hda_nid_t porta, hda_nid_t porte, 1889 hda_nid_t portd, hda_nid_t porti) 1890{ 1891 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1892 struct alc_spec *spec = codec->spec; 1893 snd_printd("realtek: " 1894 "Enable default setup for auto mode as fallback\n"); 1895 spec->init_amp = ALC_INIT_DEFAULT; 1896 } 1897 1898 alc_init_auto_hp(codec); 1899 alc_init_auto_mic(codec); 1900} 1901 1902/* 1903 * Fix-up pin default configurations and add default verbs 1904 */ 1905 1906struct alc_pincfg { 1907 hda_nid_t nid; 1908 u32 val; 1909}; 1910 1911struct alc_model_fixup { 1912 const int id; 1913 const char *name; 1914}; 1915 1916struct alc_fixup { 1917 int type; 1918 bool chained; 1919 int chain_id; 1920 union { 1921 unsigned int sku; 1922 const struct alc_pincfg *pins; 1923 const struct hda_verb *verbs; 1924 void (*func)(struct hda_codec *codec, 1925 const struct alc_fixup *fix, 1926 int action); 1927 } v; 1928}; 1929 1930enum { 1931 ALC_FIXUP_INVALID, 1932 ALC_FIXUP_SKU, 1933 ALC_FIXUP_PINS, 1934 ALC_FIXUP_VERBS, 1935 ALC_FIXUP_FUNC, 1936}; 1937 1938enum { 1939 ALC_FIXUP_ACT_PRE_PROBE, 1940 ALC_FIXUP_ACT_PROBE, 1941 ALC_FIXUP_ACT_INIT, 1942}; 1943 1944static void alc_apply_fixup(struct hda_codec *codec, int action) 1945{ 1946 struct alc_spec *spec = codec->spec; 1947 int id = spec->fixup_id; 1948#ifdef CONFIG_SND_DEBUG_VERBOSE 1949 const char *modelname = spec->fixup_name; 1950#endif 1951 int depth = 0; 1952 1953 if (!spec->fixup_list) 1954 return; 1955 1956 while (id >= 0) { 1957 const struct alc_fixup *fix = spec->fixup_list + id; 1958 const struct alc_pincfg *cfg; 1959 1960 switch (fix->type) { 1961 case ALC_FIXUP_SKU: 1962 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) 1963 break;; 1964 snd_printdd(KERN_INFO "hda_codec: %s: " 1965 "Apply sku override for %s\n", 1966 codec->chip_name, modelname); 1967 spec->cdefine.sku_cfg = fix->v.sku; 1968 spec->cdefine.fixup = 1; 1969 break; 1970 case ALC_FIXUP_PINS: 1971 cfg = fix->v.pins; 1972 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) 1973 break; 1974 snd_printdd(KERN_INFO "hda_codec: %s: " 1975 "Apply pincfg for %s\n", 1976 codec->chip_name, modelname); 1977 for (; cfg->nid; cfg++) 1978 snd_hda_codec_set_pincfg(codec, cfg->nid, 1979 cfg->val); 1980 break; 1981 case ALC_FIXUP_VERBS: 1982 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) 1983 break; 1984 snd_printdd(KERN_INFO "hda_codec: %s: " 1985 "Apply fix-verbs for %s\n", 1986 codec->chip_name, modelname); 1987 add_verb(codec->spec, fix->v.verbs); 1988 break; 1989 case ALC_FIXUP_FUNC: 1990 if (!fix->v.func) 1991 break; 1992 snd_printdd(KERN_INFO "hda_codec: %s: " 1993 "Apply fix-func for %s\n", 1994 codec->chip_name, modelname); 1995 fix->v.func(codec, fix, action); 1996 break; 1997 default: 1998 snd_printk(KERN_ERR "hda_codec: %s: " 1999 "Invalid fixup type %d\n", 2000 codec->chip_name, fix->type); 2001 break; 2002 } 2003 if (!fix->chained) 2004 break; 2005 if (++depth > 10) 2006 break; 2007 id = fix->chain_id; 2008 } 2009} 2010 2011static void alc_pick_fixup(struct hda_codec *codec, 2012 const struct alc_model_fixup *models, 2013 const struct snd_pci_quirk *quirk, 2014 const struct alc_fixup *fixlist) 2015{ 2016 struct alc_spec *spec = codec->spec; 2017 int id = -1; 2018 const char *name = NULL; 2019 2020 if (codec->modelname && models) { 2021 while (models->name) { 2022 if (!strcmp(codec->modelname, models->name)) { 2023 id = models->id; 2024 name = models->name; 2025 break; 2026 } 2027 models++; 2028 } 2029 } 2030 if (id < 0) { 2031 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 2032 if (quirk) { 2033 id = quirk->value; 2034#ifdef CONFIG_SND_DEBUG_VERBOSE 2035 name = quirk->name; 2036#endif 2037 } 2038 } 2039 2040 spec->fixup_id = id; 2041 if (id >= 0) { 2042 spec->fixup_list = fixlist; 2043 spec->fixup_name = name; 2044 } 2045} 2046 2047static int alc_read_coef_idx(struct hda_codec *codec, 2048 unsigned int coef_idx) 2049{ 2050 unsigned int val; 2051 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 2052 coef_idx); 2053 val = snd_hda_codec_read(codec, 0x20, 0, 2054 AC_VERB_GET_PROC_COEF, 0); 2055 return val; 2056} 2057 2058static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, 2059 unsigned int coef_val) 2060{ 2061 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 2062 coef_idx); 2063 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, 2064 coef_val); 2065} 2066 2067/* set right pin controls for digital I/O */ 2068static void alc_auto_init_digital(struct hda_codec *codec) 2069{ 2070 struct alc_spec *spec = codec->spec; 2071 int i; 2072 hda_nid_t pin; 2073 2074 for (i = 0; i < spec->autocfg.dig_outs; i++) { 2075 pin = spec->autocfg.dig_out_pins[i]; 2076 if (pin) { 2077 snd_hda_codec_write(codec, pin, 0, 2078 AC_VERB_SET_PIN_WIDGET_CONTROL, 2079 PIN_OUT); 2080 } 2081 } 2082 pin = spec->autocfg.dig_in_pin; 2083 if (pin) 2084 snd_hda_codec_write(codec, pin, 0, 2085 AC_VERB_SET_PIN_WIDGET_CONTROL, 2086 PIN_IN); 2087} 2088 2089/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ 2090static void alc_auto_parse_digital(struct hda_codec *codec) 2091{ 2092 struct alc_spec *spec = codec->spec; 2093 int i, err, nums; 2094 hda_nid_t dig_nid; 2095 2096 /* support multiple SPDIFs; the secondary is set up as a slave */ 2097 nums = 0; 2098 for (i = 0; i < spec->autocfg.dig_outs; i++) { 2099 err = snd_hda_get_connections(codec, 2100 spec->autocfg.dig_out_pins[i], 2101 &dig_nid, 1); 2102 if (err <= 0) 2103 continue; 2104 if (!nums) { 2105 spec->multiout.dig_out_nid = dig_nid; 2106 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 2107 } else { 2108 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 2109 if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 2110 break; 2111 spec->slave_dig_outs[nums - 1] = dig_nid; 2112 } 2113 nums++; 2114 } 2115 2116 if (spec->autocfg.dig_in_pin) { 2117 dig_nid = codec->start_nid; 2118 for (i = 0; i < codec->num_nodes; i++, dig_nid++) { 2119 unsigned int wcaps = get_wcaps(codec, dig_nid); 2120 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN) 2121 continue; 2122 if (!(wcaps & AC_WCAP_DIGITAL)) 2123 continue; 2124 if (!(wcaps & AC_WCAP_CONN_LIST)) 2125 continue; 2126 err = get_connection_index(codec, dig_nid, 2127 spec->autocfg.dig_in_pin); 2128 if (err >= 0) { 2129 spec->dig_in_nid = dig_nid; 2130 break; 2131 } 2132 } 2133 } 2134} 2135 2136/* 2137 * ALC888 2138 */ 2139 2140/* 2141 * 2ch mode 2142 */ 2143static const struct hda_verb alc888_4ST_ch2_intel_init[] = { 2144/* Mic-in jack as mic in */ 2145 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2146 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2147/* Line-in jack as Line in */ 2148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2150/* Line-Out as Front */ 2151 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 2152 { } /* end */ 2153}; 2154 2155/* 2156 * 4ch mode 2157 */ 2158static const struct hda_verb alc888_4ST_ch4_intel_init[] = { 2159/* Mic-in jack as mic in */ 2160 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2161 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2162/* Line-in jack as Surround */ 2163 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2164 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2165/* Line-Out as Front */ 2166 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, 2167 { } /* end */ 2168}; 2169 2170/* 2171 * 6ch mode 2172 */ 2173static const struct hda_verb alc888_4ST_ch6_intel_init[] = { 2174/* Mic-in jack as CLFE */ 2175 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2176 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2177/* Line-in jack as Surround */ 2178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2180/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ 2181 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 2182 { } /* end */ 2183}; 2184 2185/* 2186 * 8ch mode 2187 */ 2188static const struct hda_verb alc888_4ST_ch8_intel_init[] = { 2189/* Mic-in jack as CLFE */ 2190 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2191 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2192/* Line-in jack as Surround */ 2193 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2194 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2195/* Line-Out as Side */ 2196 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 2197 { } /* end */ 2198}; 2199 2200static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { 2201 { 2, alc888_4ST_ch2_intel_init }, 2202 { 4, alc888_4ST_ch4_intel_init }, 2203 { 6, alc888_4ST_ch6_intel_init }, 2204 { 8, alc888_4ST_ch8_intel_init }, 2205}; 2206 2207/* 2208 * ALC888 Fujitsu Siemens Amillo xa3530 2209 */ 2210 2211static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = { 2212/* Front Mic: set to PIN_IN (empty by default) */ 2213 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2214/* Connect Internal HP to Front */ 2215 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2217 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2218/* Connect Bass HP to Front */ 2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2222/* Connect Line-Out side jack (SPDIF) to Side */ 2223 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2224 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2225 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 2226/* Connect Mic jack to CLFE */ 2227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2228 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2229 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 2230/* Connect Line-in jack to Surround */ 2231 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2232 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2233 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 2234/* Connect HP out jack to Front */ 2235 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2236 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2237 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 2238/* Enable unsolicited event for HP jack and Line-out jack */ 2239 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2240 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2241 {} 2242}; 2243 2244static void alc889_automute_setup(struct hda_codec *codec) 2245{ 2246 struct alc_spec *spec = codec->spec; 2247 2248 spec->autocfg.hp_pins[0] = 0x15; 2249 spec->autocfg.speaker_pins[0] = 0x14; 2250 spec->autocfg.speaker_pins[1] = 0x16; 2251 spec->autocfg.speaker_pins[2] = 0x17; 2252 spec->autocfg.speaker_pins[3] = 0x19; 2253 spec->autocfg.speaker_pins[4] = 0x1a; 2254 spec->automute = 1; 2255 spec->automute_mode = ALC_AUTOMUTE_AMP; 2256} 2257 2258static void alc889_intel_init_hook(struct hda_codec *codec) 2259{ 2260 alc889_coef_init(codec); 2261 alc_hp_automute(codec); 2262} 2263 2264static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) 2265{ 2266 struct alc_spec *spec = codec->spec; 2267 2268 spec->autocfg.hp_pins[0] = 0x17; /* line-out */ 2269 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 2270 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 2271 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 2272 spec->automute = 1; 2273 spec->automute_mode = ALC_AUTOMUTE_AMP; 2274} 2275 2276/* 2277 * ALC888 Acer Aspire 4930G model 2278 */ 2279 2280static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = { 2281/* Front Mic: set to PIN_IN (empty by default) */ 2282 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2283/* Unselect Front Mic by default in input mixer 3 */ 2284 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2285/* Enable unsolicited event for HP jack */ 2286 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2287/* Connect Internal HP to front */ 2288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2289 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2290 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2291/* Connect HP out to front */ 2292 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2293 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2294 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2295 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2296 { } 2297}; 2298 2299/* 2300 * ALC888 Acer Aspire 6530G model 2301 */ 2302 2303static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = { 2304/* Route to built-in subwoofer as well as speakers */ 2305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2307 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 2308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 2309/* Bias voltage on for external mic port */ 2310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2311/* Front Mic: set to PIN_IN (empty by default) */ 2312 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2313/* Unselect Front Mic by default in input mixer 3 */ 2314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2315/* Enable unsolicited event for HP jack */ 2316 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2317/* Enable speaker output */ 2318 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2319 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2320 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2321/* Enable headphone output */ 2322 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2323 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2325 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2326 { } 2327}; 2328 2329/* 2330 *ALC888 Acer Aspire 7730G model 2331 */ 2332 2333static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = { 2334/* Bias voltage on for external mic port */ 2335 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, 2336/* Front Mic: set to PIN_IN (empty by default) */ 2337 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2338/* Unselect Front Mic by default in input mixer 3 */ 2339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2340/* Enable unsolicited event for HP jack */ 2341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2342/* Enable speaker output */ 2343 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2344 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2345 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2346/* Enable headphone output */ 2347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2348 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2349 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2350 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2351/*Enable internal subwoofer */ 2352 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2353 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2354 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 2355 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2}, 2356 { } 2357}; 2358 2359/* 2360 * ALC889 Acer Aspire 8930G model 2361 */ 2362 2363static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = { 2364/* Front Mic: set to PIN_IN (empty by default) */ 2365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 2366/* Unselect Front Mic by default in input mixer 3 */ 2367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, 2368/* Enable unsolicited event for HP jack */ 2369 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 2370/* Connect Internal Front to Front */ 2371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2372 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2373 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 2374/* Connect Internal Rear to Rear */ 2375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2376 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2377 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 2378/* Connect Internal CLFE to CLFE */ 2379 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2380 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2381 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 2382/* Connect HP out to Front */ 2383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, 2384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2386/* Enable all DACs */ 2387/* DAC DISABLE/MUTE 1? */ 2388/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ 2389 {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, 2390 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2391/* DAC DISABLE/MUTE 2? */ 2392/* some bit here disables the other DACs. Init=0x4900 */ 2393 {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, 2394 {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, 2395/* DMIC fix 2396 * This laptop has a stereo digital microphone. The mics are only 1cm apart 2397 * which makes the stereo useless. However, either the mic or the ALC889 2398 * makes the signal become a difference/sum signal instead of standard 2399 * stereo, which is annoying. So instead we flip this bit which makes the 2400 * codec replicate the sum signal to both channels, turning it into a 2401 * normal mono mic. 2402 */ 2403/* DMIC_CONTROL? Init value = 0x0001 */ 2404 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 2405 {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, 2406 { } 2407}; 2408 2409static const struct hda_input_mux alc888_2_capture_sources[2] = { 2410 /* Front mic only available on one ADC */ 2411 { 2412 .num_items = 4, 2413 .items = { 2414 { "Mic", 0x0 }, 2415 { "Line", 0x2 }, 2416 { "CD", 0x4 }, 2417 { "Front Mic", 0xb }, 2418 }, 2419 }, 2420 { 2421 .num_items = 3, 2422 .items = { 2423 { "Mic", 0x0 }, 2424 { "Line", 0x2 }, 2425 { "CD", 0x4 }, 2426 }, 2427 } 2428}; 2429 2430static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { 2431 /* Interal mic only available on one ADC */ 2432 { 2433 .num_items = 5, 2434 .items = { 2435 { "Mic", 0x0 }, 2436 { "Line In", 0x2 }, 2437 { "CD", 0x4 }, 2438 { "Input Mix", 0xa }, 2439 { "Internal Mic", 0xb }, 2440 }, 2441 }, 2442 { 2443 .num_items = 4, 2444 .items = { 2445 { "Mic", 0x0 }, 2446 { "Line In", 0x2 }, 2447 { "CD", 0x4 }, 2448 { "Input Mix", 0xa }, 2449 }, 2450 } 2451}; 2452 2453static const struct hda_input_mux alc889_capture_sources[3] = { 2454 /* Digital mic only available on first "ADC" */ 2455 { 2456 .num_items = 5, 2457 .items = { 2458 { "Mic", 0x0 }, 2459 { "Line", 0x2 }, 2460 { "CD", 0x4 }, 2461 { "Front Mic", 0xb }, 2462 { "Input Mix", 0xa }, 2463 }, 2464 }, 2465 { 2466 .num_items = 4, 2467 .items = { 2468 { "Mic", 0x0 }, 2469 { "Line", 0x2 }, 2470 { "CD", 0x4 }, 2471 { "Input Mix", 0xa }, 2472 }, 2473 }, 2474 { 2475 .num_items = 4, 2476 .items = { 2477 { "Mic", 0x0 }, 2478 { "Line", 0x2 }, 2479 { "CD", 0x4 }, 2480 { "Input Mix", 0xa }, 2481 }, 2482 } 2483}; 2484 2485static const struct snd_kcontrol_new alc888_base_mixer[] = { 2486 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2487 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2488 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2489 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2490 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2491 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("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2496 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2497 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2498 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2499 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2500 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2503 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2504 { } /* end */ 2505}; 2506 2507static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { 2508 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2509 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2510 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2511 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2512 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2513 HDA_OUTPUT), 2514 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2515 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2516 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2517 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), 2518 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), 2519 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2520 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2521 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2522 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2524 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2525 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2526 { } /* end */ 2527}; 2528 2529static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { 2530 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2531 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2532 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2533 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2534 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 2535 HDA_OUTPUT), 2536 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2537 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2538 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2539 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2540 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2541 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2542 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 2543 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2544 { } /* end */ 2545}; 2546 2547 2548static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) 2549{ 2550 struct alc_spec *spec = codec->spec; 2551 2552 spec->autocfg.hp_pins[0] = 0x15; 2553 spec->autocfg.speaker_pins[0] = 0x14; 2554 spec->autocfg.speaker_pins[1] = 0x16; 2555 spec->autocfg.speaker_pins[2] = 0x17; 2556 spec->automute = 1; 2557 spec->automute_mode = ALC_AUTOMUTE_AMP; 2558} 2559 2560static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) 2561{ 2562 struct alc_spec *spec = codec->spec; 2563 2564 spec->autocfg.hp_pins[0] = 0x15; 2565 spec->autocfg.speaker_pins[0] = 0x14; 2566 spec->autocfg.speaker_pins[1] = 0x16; 2567 spec->autocfg.speaker_pins[2] = 0x17; 2568 spec->automute = 1; 2569 spec->automute_mode = ALC_AUTOMUTE_AMP; 2570} 2571 2572static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) 2573{ 2574 struct alc_spec *spec = codec->spec; 2575 2576 spec->autocfg.hp_pins[0] = 0x15; 2577 spec->autocfg.speaker_pins[0] = 0x14; 2578 spec->autocfg.speaker_pins[1] = 0x16; 2579 spec->autocfg.speaker_pins[2] = 0x17; 2580 spec->automute = 1; 2581 spec->automute_mode = ALC_AUTOMUTE_AMP; 2582} 2583 2584static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) 2585{ 2586 struct alc_spec *spec = codec->spec; 2587 2588 spec->autocfg.hp_pins[0] = 0x15; 2589 spec->autocfg.speaker_pins[0] = 0x14; 2590 spec->autocfg.speaker_pins[1] = 0x16; 2591 spec->autocfg.speaker_pins[2] = 0x1b; 2592 spec->automute = 1; 2593 spec->automute_mode = ALC_AUTOMUTE_AMP; 2594} 2595 2596/* 2597 * ALC880 3-stack model 2598 * 2599 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 2600 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, 2601 * F-Mic = 0x1b, HP = 0x19 2602 */ 2603 2604static const hda_nid_t alc880_dac_nids[4] = { 2605 /* front, rear, clfe, rear_surr */ 2606 0x02, 0x05, 0x04, 0x03 2607}; 2608 2609static const hda_nid_t alc880_adc_nids[3] = { 2610 /* ADC0-2 */ 2611 0x07, 0x08, 0x09, 2612}; 2613 2614/* The datasheet says the node 0x07 is connected from inputs, 2615 * but it shows zero connection in the real implementation on some devices. 2616 * Note: this is a 915GAV bug, fixed on 915GLV 2617 */ 2618static const hda_nid_t alc880_adc_nids_alt[2] = { 2619 /* ADC1-2 */ 2620 0x08, 0x09, 2621}; 2622 2623#define ALC880_DIGOUT_NID 0x06 2624#define ALC880_DIGIN_NID 0x0a 2625 2626static const struct hda_input_mux alc880_capture_source = { 2627 .num_items = 4, 2628 .items = { 2629 { "Mic", 0x0 }, 2630 { "Front Mic", 0x3 }, 2631 { "Line", 0x2 }, 2632 { "CD", 0x4 }, 2633 }, 2634}; 2635 2636/* channel source setting (2/6 channel selection for 3-stack) */ 2637/* 2ch mode */ 2638static const struct hda_verb alc880_threestack_ch2_init[] = { 2639 /* set line-in to input, mute it */ 2640 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2641 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2642 /* set mic-in to input vref 80%, mute it */ 2643 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 2644 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2645 { } /* end */ 2646}; 2647 2648/* 6ch mode */ 2649static const struct hda_verb alc880_threestack_ch6_init[] = { 2650 /* set line-in to output, unmute it */ 2651 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2652 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2653 /* set mic-in to output, unmute it */ 2654 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2655 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2656 { } /* end */ 2657}; 2658 2659static const struct hda_channel_mode alc880_threestack_modes[2] = { 2660 { 2, alc880_threestack_ch2_init }, 2661 { 6, alc880_threestack_ch6_init }, 2662}; 2663 2664static const struct snd_kcontrol_new alc880_three_stack_mixer[] = { 2665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2668 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 2669 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2671 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2672 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2679 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 2680 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 2681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), 2682 { 2683 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2684 .name = "Channel Mode", 2685 .info = alc_ch_mode_info, 2686 .get = alc_ch_mode_get, 2687 .put = alc_ch_mode_put, 2688 }, 2689 { } /* end */ 2690}; 2691 2692/* capture mixer elements */ 2693static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 2694 struct snd_ctl_elem_info *uinfo) 2695{ 2696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2697 struct alc_spec *spec = codec->spec; 2698 int err; 2699 2700 mutex_lock(&codec->control_mutex); 2701 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2702 HDA_INPUT); 2703 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 2704 mutex_unlock(&codec->control_mutex); 2705 return err; 2706} 2707 2708static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, 2709 unsigned int size, unsigned int __user *tlv) 2710{ 2711 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2712 struct alc_spec *spec = codec->spec; 2713 int err; 2714 2715 mutex_lock(&codec->control_mutex); 2716 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 2717 HDA_INPUT); 2718 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 2719 mutex_unlock(&codec->control_mutex); 2720 return err; 2721} 2722 2723typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, 2724 struct snd_ctl_elem_value *ucontrol); 2725 2726static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 2727 struct snd_ctl_elem_value *ucontrol, 2728 getput_call_t func, bool check_adc_switch) 2729{ 2730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2731 struct alc_spec *spec = codec->spec; 2732 int i, err = 0; 2733 2734 mutex_lock(&codec->control_mutex); 2735 if (check_adc_switch && spec->dual_adc_switch) { 2736 for (i = 0; i < spec->num_adc_nids; i++) { 2737 kcontrol->private_value = 2738 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 2739 3, 0, HDA_INPUT); 2740 err = func(kcontrol, ucontrol); 2741 if (err < 0) 2742 goto error; 2743 } 2744 } else { 2745 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 2746 kcontrol->private_value = 2747 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 2748 3, 0, HDA_INPUT); 2749 err = func(kcontrol, ucontrol); 2750 } 2751 error: 2752 mutex_unlock(&codec->control_mutex); 2753 return err; 2754} 2755 2756static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, 2757 struct snd_ctl_elem_value *ucontrol) 2758{ 2759 return alc_cap_getput_caller(kcontrol, ucontrol, 2760 snd_hda_mixer_amp_volume_get, false); 2761} 2762 2763static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, 2764 struct snd_ctl_elem_value *ucontrol) 2765{ 2766 return alc_cap_getput_caller(kcontrol, ucontrol, 2767 snd_hda_mixer_amp_volume_put, true); 2768} 2769 2770/* capture mixer elements */ 2771#define alc_cap_sw_info snd_ctl_boolean_stereo_info 2772 2773static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, 2774 struct snd_ctl_elem_value *ucontrol) 2775{ 2776 return alc_cap_getput_caller(kcontrol, ucontrol, 2777 snd_hda_mixer_amp_switch_get, false); 2778} 2779 2780static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, 2781 struct snd_ctl_elem_value *ucontrol) 2782{ 2783 return alc_cap_getput_caller(kcontrol, ucontrol, 2784 snd_hda_mixer_amp_switch_put, true); 2785} 2786 2787#define _DEFINE_CAPMIX(num) \ 2788 { \ 2789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2790 .name = "Capture Switch", \ 2791 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 2792 .count = num, \ 2793 .info = alc_cap_sw_info, \ 2794 .get = alc_cap_sw_get, \ 2795 .put = alc_cap_sw_put, \ 2796 }, \ 2797 { \ 2798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2799 .name = "Capture Volume", \ 2800 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \ 2801 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 2802 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \ 2803 .count = num, \ 2804 .info = alc_cap_vol_info, \ 2805 .get = alc_cap_vol_get, \ 2806 .put = alc_cap_vol_put, \ 2807 .tlv = { .c = alc_cap_vol_tlv }, \ 2808 } 2809 2810#define _DEFINE_CAPSRC(num) \ 2811 { \ 2812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2813 /* .name = "Capture Source", */ \ 2814 .name = "Input Source", \ 2815 .count = num, \ 2816 .info = alc_mux_enum_info, \ 2817 .get = alc_mux_enum_get, \ 2818 .put = alc_mux_enum_put, \ 2819 } 2820 2821#define DEFINE_CAPMIX(num) \ 2822static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ 2823 _DEFINE_CAPMIX(num), \ 2824 _DEFINE_CAPSRC(num), \ 2825 { } /* end */ \ 2826} 2827 2828#define DEFINE_CAPMIX_NOSRC(num) \ 2829static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ 2830 _DEFINE_CAPMIX(num), \ 2831 { } /* end */ \ 2832} 2833 2834/* up to three ADCs */ 2835DEFINE_CAPMIX(1); 2836DEFINE_CAPMIX(2); 2837DEFINE_CAPMIX(3); 2838DEFINE_CAPMIX_NOSRC(1); 2839DEFINE_CAPMIX_NOSRC(2); 2840DEFINE_CAPMIX_NOSRC(3); 2841 2842/* 2843 * ALC880 5-stack model 2844 * 2845 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), 2846 * Side = 0x02 (0xd) 2847 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 2848 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 2849 */ 2850 2851/* additional mixers to alc880_three_stack_mixer */ 2852static const struct snd_kcontrol_new alc880_five_stack_mixer[] = { 2853 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2854 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), 2855 { } /* end */ 2856}; 2857 2858/* channel source setting (6/8 channel selection for 5-stack) */ 2859/* 6ch mode */ 2860static const struct hda_verb alc880_fivestack_ch6_init[] = { 2861 /* set line-in to input, mute it */ 2862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 2863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 2864 { } /* end */ 2865}; 2866 2867/* 8ch mode */ 2868static const struct hda_verb alc880_fivestack_ch8_init[] = { 2869 /* set line-in to output, unmute it */ 2870 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 2871 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 2872 { } /* end */ 2873}; 2874 2875static const struct hda_channel_mode alc880_fivestack_modes[2] = { 2876 { 6, alc880_fivestack_ch6_init }, 2877 { 8, alc880_fivestack_ch8_init }, 2878}; 2879 2880 2881/* 2882 * ALC880 6-stack model 2883 * 2884 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), 2885 * Side = 0x05 (0x0f) 2886 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, 2887 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b 2888 */ 2889 2890static const hda_nid_t alc880_6st_dac_nids[4] = { 2891 /* front, rear, clfe, rear_surr */ 2892 0x02, 0x03, 0x04, 0x05 2893}; 2894 2895static const struct hda_input_mux alc880_6stack_capture_source = { 2896 .num_items = 4, 2897 .items = { 2898 { "Mic", 0x0 }, 2899 { "Front Mic", 0x1 }, 2900 { "Line", 0x2 }, 2901 { "CD", 0x4 }, 2902 }, 2903}; 2904 2905/* fixed 8-channels */ 2906static const struct hda_channel_mode alc880_sixstack_modes[1] = { 2907 { 8, NULL }, 2908}; 2909 2910static const struct snd_kcontrol_new alc880_six_stack_mixer[] = { 2911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2913 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2914 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2915 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2916 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2917 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2918 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2919 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 2920 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 2921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2923 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2924 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2927 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2928 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2929 { 2930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2931 .name = "Channel Mode", 2932 .info = alc_ch_mode_info, 2933 .get = alc_ch_mode_get, 2934 .put = alc_ch_mode_put, 2935 }, 2936 { } /* end */ 2937}; 2938 2939 2940/* 2941 * ALC880 W810 model 2942 * 2943 * W810 has rear IO for: 2944 * Front (DAC 02) 2945 * Surround (DAC 03) 2946 * Center/LFE (DAC 04) 2947 * Digital out (06) 2948 * 2949 * The system also has a pair of internal speakers, and a headphone jack. 2950 * These are both connected to Line2 on the codec, hence to DAC 02. 2951 * 2952 * There is a variable resistor to control the speaker or headphone 2953 * volume. This is a hardware-only device without a software API. 2954 * 2955 * Plugging headphones in will disable the internal speakers. This is 2956 * implemented in hardware, not via the driver using jack sense. In 2957 * a similar fashion, plugging into the rear socket marked "front" will 2958 * disable both the speakers and headphones. 2959 * 2960 * For input, there's a microphone jack, and an "audio in" jack. 2961 * These may not do anything useful with this driver yet, because I 2962 * haven't setup any initialization verbs for these yet... 2963 */ 2964 2965static const hda_nid_t alc880_w810_dac_nids[3] = { 2966 /* front, rear/surround, clfe */ 2967 0x02, 0x03, 0x04 2968}; 2969 2970/* fixed 6 channels */ 2971static const struct hda_channel_mode alc880_w810_modes[1] = { 2972 { 6, NULL } 2973}; 2974 2975/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ 2976static const struct snd_kcontrol_new alc880_w810_base_mixer[] = { 2977 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 2978 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 2979 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 2980 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 2981 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 2982 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 2983 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 2984 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 2985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 2986 { } /* end */ 2987}; 2988 2989 2990/* 2991 * Z710V model 2992 * 2993 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) 2994 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), 2995 * Line = 0x1a 2996 */ 2997 2998static const hda_nid_t alc880_z71v_dac_nids[1] = { 2999 0x02 3000}; 3001#define ALC880_Z71V_HP_DAC 0x03 3002 3003/* fixed 2 channels */ 3004static const struct hda_channel_mode alc880_2_jack_modes[1] = { 3005 { 2, NULL } 3006}; 3007 3008static const struct snd_kcontrol_new alc880_z71v_mixer[] = { 3009 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3010 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3012 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 3013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3017 { } /* end */ 3018}; 3019 3020 3021/* 3022 * ALC880 F1734 model 3023 * 3024 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) 3025 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 3026 */ 3027 3028static const hda_nid_t alc880_f1734_dac_nids[1] = { 3029 0x03 3030}; 3031#define ALC880_F1734_HP_DAC 0x02 3032 3033static const struct snd_kcontrol_new alc880_f1734_mixer[] = { 3034 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3035 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3036 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3037 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 3038 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3039 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3041 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3042 { } /* end */ 3043}; 3044 3045static const struct hda_input_mux alc880_f1734_capture_source = { 3046 .num_items = 2, 3047 .items = { 3048 { "Mic", 0x1 }, 3049 { "CD", 0x4 }, 3050 }, 3051}; 3052 3053 3054/* 3055 * ALC880 ASUS model 3056 * 3057 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 3058 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 3059 * Mic = 0x18, Line = 0x1a 3060 */ 3061 3062#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ 3063#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ 3064 3065static const struct snd_kcontrol_new alc880_asus_mixer[] = { 3066 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3067 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 3068 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3069 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 3070 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3071 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3072 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3073 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3074 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3075 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3076 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3077 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3078 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3079 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3080 { 3081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3082 .name = "Channel Mode", 3083 .info = alc_ch_mode_info, 3084 .get = alc_ch_mode_get, 3085 .put = alc_ch_mode_put, 3086 }, 3087 { } /* end */ 3088}; 3089 3090/* 3091 * ALC880 ASUS W1V model 3092 * 3093 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) 3094 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, 3095 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b 3096 */ 3097 3098/* additional mixers to alc880_asus_mixer */ 3099static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { 3100 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), 3101 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), 3102 { } /* end */ 3103}; 3104 3105/* TCL S700 */ 3106static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { 3107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3108 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 3109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 3110 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), 3111 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), 3112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), 3113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 3114 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 3115 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 3116 { } /* end */ 3117}; 3118 3119/* Uniwill */ 3120static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { 3121 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3122 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3123 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3124 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 3125 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 3126 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 3127 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 3128 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 3129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3131 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 3132 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 3133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3135 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3136 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3137 { 3138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3139 .name = "Channel Mode", 3140 .info = alc_ch_mode_info, 3141 .get = alc_ch_mode_get, 3142 .put = alc_ch_mode_put, 3143 }, 3144 { } /* end */ 3145}; 3146 3147static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = { 3148 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3149 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3150 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3151 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 3152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 3153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 3154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3156 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3157 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3158 { } /* end */ 3159}; 3160 3161static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { 3162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3163 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 3164 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 3165 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 3166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 3167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 3168 { } /* end */ 3169}; 3170 3171/* 3172 * virtual master controls 3173 */ 3174 3175/* 3176 * slave controls for virtual master 3177 */ 3178static const char * const alc_slave_vols[] = { 3179 "Front Playback Volume", 3180 "Surround Playback Volume", 3181 "Center Playback Volume", 3182 "LFE Playback Volume", 3183 "Side Playback Volume", 3184 "Headphone Playback Volume", 3185 "Speaker Playback Volume", 3186 "Mono Playback Volume", 3187 "Line-Out Playback Volume", 3188 NULL, 3189}; 3190 3191static const char * const alc_slave_sws[] = { 3192 "Front Playback Switch", 3193 "Surround Playback Switch", 3194 "Center Playback Switch", 3195 "LFE Playback Switch", 3196 "Side Playback Switch", 3197 "Headphone Playback Switch", 3198 "Speaker Playback Switch", 3199 "Mono Playback Switch", 3200 "IEC958 Playback Switch", 3201 "Line-Out Playback Switch", 3202 NULL, 3203}; 3204 3205/* 3206 * build control elements 3207 */ 3208 3209#define NID_MAPPING (-1) 3210 3211#define SUBDEV_SPEAKER_ (0 << 6) 3212#define SUBDEV_HP_ (1 << 6) 3213#define SUBDEV_LINE_ (2 << 6) 3214#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f)) 3215#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f)) 3216#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f)) 3217 3218static void alc_free_kctls(struct hda_codec *codec); 3219 3220#ifdef CONFIG_SND_HDA_INPUT_BEEP 3221/* additional beep mixers; the actual parameters are overwritten at build */ 3222static const struct snd_kcontrol_new alc_beep_mixer[] = { 3223 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), 3224 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), 3225 { } /* end */ 3226}; 3227#endif 3228 3229static int alc_build_controls(struct hda_codec *codec) 3230{ 3231 struct alc_spec *spec = codec->spec; 3232 struct snd_kcontrol *kctl = NULL; 3233 const struct snd_kcontrol_new *knew; 3234 int i, j, err; 3235 unsigned int u; 3236 hda_nid_t nid; 3237 3238 for (i = 0; i < spec->num_mixers; i++) { 3239 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 3240 if (err < 0) 3241 return err; 3242 } 3243 if (spec->cap_mixer) { 3244 err = snd_hda_add_new_ctls(codec, spec->cap_mixer); 3245 if (err < 0) 3246 return err; 3247 } 3248 if (spec->multiout.dig_out_nid) { 3249 err = snd_hda_create_spdif_out_ctls(codec, 3250 spec->multiout.dig_out_nid); 3251 if (err < 0) 3252 return err; 3253 if (!spec->no_analog) { 3254 err = snd_hda_create_spdif_share_sw(codec, 3255 &spec->multiout); 3256 if (err < 0) 3257 return err; 3258 spec->multiout.share_spdif = 1; 3259 } 3260 } 3261 if (spec->dig_in_nid) { 3262 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 3263 if (err < 0) 3264 return err; 3265 } 3266 3267#ifdef CONFIG_SND_HDA_INPUT_BEEP 3268 /* create beep controls if needed */ 3269 if (spec->beep_amp) { 3270 const struct snd_kcontrol_new *knew; 3271 for (knew = alc_beep_mixer; knew->name; knew++) { 3272 struct snd_kcontrol *kctl; 3273 kctl = snd_ctl_new1(knew, codec); 3274 if (!kctl) 3275 return -ENOMEM; 3276 kctl->private_value = spec->beep_amp; 3277 err = snd_hda_ctl_add(codec, 0, kctl); 3278 if (err < 0) 3279 return err; 3280 } 3281 } 3282#endif 3283 3284 /* if we have no master control, let's create it */ 3285 if (!spec->no_analog && 3286 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 3287 unsigned int vmaster_tlv[4]; 3288 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 3289 HDA_OUTPUT, vmaster_tlv); 3290 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 3291 vmaster_tlv, alc_slave_vols); 3292 if (err < 0) 3293 return err; 3294 } 3295 if (!spec->no_analog && 3296 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 3297 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 3298 NULL, alc_slave_sws); 3299 if (err < 0) 3300 return err; 3301 } 3302 3303 /* assign Capture Source enums to NID */ 3304 if (spec->capsrc_nids || spec->adc_nids) { 3305 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 3306 if (!kctl) 3307 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 3308 for (i = 0; kctl && i < kctl->count; i++) { 3309 const hda_nid_t *nids = spec->capsrc_nids; 3310 if (!nids) 3311 nids = spec->adc_nids; 3312 err = snd_hda_add_nid(codec, kctl, i, nids[i]); 3313 if (err < 0) 3314 return err; 3315 } 3316 } 3317 if (spec->cap_mixer) { 3318 const char *kname = kctl ? kctl->id.name : NULL; 3319 for (knew = spec->cap_mixer; knew->name; knew++) { 3320 if (kname && strcmp(knew->name, kname) == 0) 3321 continue; 3322 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3323 for (i = 0; kctl && i < kctl->count; i++) { 3324 err = snd_hda_add_nid(codec, kctl, i, 3325 spec->adc_nids[i]); 3326 if (err < 0) 3327 return err; 3328 } 3329 } 3330 } 3331 3332 /* other nid->control mapping */ 3333 for (i = 0; i < spec->num_mixers; i++) { 3334 for (knew = spec->mixers[i]; knew->name; knew++) { 3335 if (knew->iface != NID_MAPPING) 3336 continue; 3337 kctl = snd_hda_find_mixer_ctl(codec, knew->name); 3338 if (kctl == NULL) 3339 continue; 3340 u = knew->subdevice; 3341 for (j = 0; j < 4; j++, u >>= 8) { 3342 nid = u & 0x3f; 3343 if (nid == 0) 3344 continue; 3345 switch (u & 0xc0) { 3346 case SUBDEV_SPEAKER_: 3347 nid = spec->autocfg.speaker_pins[nid]; 3348 break; 3349 case SUBDEV_LINE_: 3350 nid = spec->autocfg.line_out_pins[nid]; 3351 break; 3352 case SUBDEV_HP_: 3353 nid = spec->autocfg.hp_pins[nid]; 3354 break; 3355 default: 3356 continue; 3357 } 3358 err = snd_hda_add_nid(codec, kctl, 0, nid); 3359 if (err < 0) 3360 return err; 3361 } 3362 u = knew->private_value; 3363 for (j = 0; j < 4; j++, u >>= 8) { 3364 nid = u & 0xff; 3365 if (nid == 0) 3366 continue; 3367 err = snd_hda_add_nid(codec, kctl, 0, nid); 3368 if (err < 0) 3369 return err; 3370 } 3371 } 3372 } 3373 3374 alc_free_kctls(codec); /* no longer needed */ 3375 3376 return 0; 3377} 3378 3379 3380/* 3381 * initialize the codec volumes, etc 3382 */ 3383 3384/* 3385 * generic initialization of ADC, input mixers and output mixers 3386 */ 3387static const struct hda_verb alc880_volume_init_verbs[] = { 3388 /* 3389 * Unmute ADC0-2 and set the default input to mic-in 3390 */ 3391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 3392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 3394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 3396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 3397 3398 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 3399 * mixer widget 3400 * Note: PASD motherboards uses the Line In 2 as the input for front 3401 * panel mic (mic 2) 3402 */ 3403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 3404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 3407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 3408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3411 3412 /* 3413 * Set up output mixers (0x0c - 0x0f) 3414 */ 3415 /* set vol=0 to output mixers */ 3416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3419 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 3420 /* set up input amps for analog loopback */ 3421 /* Amp Indices: DAC = 0, mixer = 1 */ 3422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 3430 3431 { } 3432}; 3433 3434/* 3435 * 3-stack pin configuration: 3436 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 3437 */ 3438static const struct hda_verb alc880_pin_3stack_init_verbs[] = { 3439 /* 3440 * preset connection lists of input pins 3441 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3442 */ 3443 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 3444 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3445 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 3446 3447 /* 3448 * Set pin mode and muting 3449 */ 3450 /* set front pin widgets 0x14 for output */ 3451 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3452 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3453 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3454 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3455 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3456 /* Mic2 (as headphone out) for HP output */ 3457 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3458 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3459 /* Line In pin widget for input */ 3460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3462 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3463 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3464 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3465 /* CD pin widget for input */ 3466 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3467 3468 { } 3469}; 3470 3471/* 3472 * 5-stack pin configuration: 3473 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, 3474 * line-in/side = 0x1a, f-mic = 0x1b 3475 */ 3476static const struct hda_verb alc880_pin_5stack_init_verbs[] = { 3477 /* 3478 * preset connection lists of input pins 3479 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround 3480 */ 3481 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3482 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ 3483 3484 /* 3485 * Set pin mode and muting 3486 */ 3487 /* set pin widgets 0x14-0x17 for output */ 3488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3489 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3490 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3492 /* unmute pins for output (no gain on this amp) */ 3493 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3495 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3496 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3497 3498 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3501 /* Mic2 (as headphone out) for HP output */ 3502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3503 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3504 /* Line In pin widget for input */ 3505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3507 /* Line2 (as front mic) pin widget for input and vref at 80% */ 3508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3510 /* CD pin widget for input */ 3511 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3512 3513 { } 3514}; 3515 3516/* 3517 * W810 pin configuration: 3518 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b 3519 */ 3520static const struct hda_verb alc880_pin_w810_init_verbs[] = { 3521 /* hphone/speaker input selector: front DAC */ 3522 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, 3523 3524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3529 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3530 3531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3532 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3533 3534 { } 3535}; 3536 3537/* 3538 * Z71V pin configuration: 3539 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) 3540 */ 3541static const struct hda_verb alc880_pin_z71v_init_verbs[] = { 3542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3543 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3546 3547 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3551 3552 { } 3553}; 3554 3555/* 3556 * 6-stack pin configuration: 3557 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, 3558 * f-mic = 0x19, line = 0x1a, HP = 0x1b 3559 */ 3560static const struct hda_verb alc880_pin_6stack_init_verbs[] = { 3561 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3562 3563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3569 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3571 3572 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3573 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3576 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3577 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3579 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3580 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3581 3582 { } 3583}; 3584 3585/* 3586 * Uniwill pin configuration: 3587 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, 3588 * line = 0x1a 3589 */ 3590static const struct hda_verb alc880_uniwill_init_verbs[] = { 3591 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3592 3593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3594 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3595 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3596 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3597 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3599 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3600 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3604 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3606 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3607 3608 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3610 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3611 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3612 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3613 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3614 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ 3615 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 3616 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3617 3618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3619 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 3620 3621 { } 3622}; 3623 3624/* 3625* Uniwill P53 3626* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 3627 */ 3628static const struct hda_verb alc880_uniwill_p53_init_verbs[] = { 3629 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 3630 3631 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3632 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3635 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3639 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 3642 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 3643 3644 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3645 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3646 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3647 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3648 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3649 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3650 3651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3652 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT}, 3653 3654 { } 3655}; 3656 3657static const struct hda_verb alc880_beep_init_verbs[] = { 3658 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, 3659 { } 3660}; 3661 3662/* auto-toggle front mic */ 3663static void alc88x_simple_mic_automute(struct hda_codec *codec) 3664{ 3665 unsigned int present; 3666 unsigned char bits; 3667 3668 present = snd_hda_jack_detect(codec, 0x18); 3669 bits = present ? HDA_AMP_MUTE : 0; 3670 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 3671} 3672 3673static void alc880_uniwill_setup(struct hda_codec *codec) 3674{ 3675 struct alc_spec *spec = codec->spec; 3676 3677 spec->autocfg.hp_pins[0] = 0x14; 3678 spec->autocfg.speaker_pins[0] = 0x15; 3679 spec->autocfg.speaker_pins[0] = 0x16; 3680 spec->automute = 1; 3681 spec->automute_mode = ALC_AUTOMUTE_AMP; 3682} 3683 3684static void alc880_uniwill_init_hook(struct hda_codec *codec) 3685{ 3686 alc_hp_automute(codec); 3687 alc88x_simple_mic_automute(codec); 3688} 3689 3690static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3691 unsigned int res) 3692{ 3693 /* Looks like the unsol event is incompatible with the standard 3694 * definition. 4bit tag is placed at 28 bit! 3695 */ 3696 switch (res >> 28) { 3697 case ALC880_MIC_EVENT: 3698 alc88x_simple_mic_automute(codec); 3699 break; 3700 default: 3701 alc_sku_unsol_event(codec, res); 3702 break; 3703 } 3704} 3705 3706static void alc880_uniwill_p53_setup(struct hda_codec *codec) 3707{ 3708 struct alc_spec *spec = codec->spec; 3709 3710 spec->autocfg.hp_pins[0] = 0x14; 3711 spec->autocfg.speaker_pins[0] = 0x15; 3712 spec->automute = 1; 3713 spec->automute_mode = ALC_AUTOMUTE_AMP; 3714} 3715 3716static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 3717{ 3718 unsigned int present; 3719 3720 present = snd_hda_codec_read(codec, 0x21, 0, 3721 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 3722 present &= HDA_AMP_VOLMASK; 3723 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, 3724 HDA_AMP_VOLMASK, present); 3725 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, 3726 HDA_AMP_VOLMASK, present); 3727} 3728 3729static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, 3730 unsigned int res) 3731{ 3732 /* Looks like the unsol event is incompatible with the standard 3733 * definition. 4bit tag is placed at 28 bit! 3734 */ 3735 if ((res >> 28) == ALC880_DCVOL_EVENT) 3736 alc880_uniwill_p53_dcvol_automute(codec); 3737 else 3738 alc_sku_unsol_event(codec, res); 3739} 3740 3741/* 3742 * F1734 pin configuration: 3743 * HP = 0x14, speaker-out = 0x15, mic = 0x18 3744 */ 3745static const struct hda_verb alc880_pin_f1734_init_verbs[] = { 3746 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, 3747 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3748 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3749 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3750 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3751 3752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3756 3757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3759 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3761 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3763 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3764 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3765 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3766 3767 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 3768 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT}, 3769 3770 { } 3771}; 3772 3773/* 3774 * ASUS pin configuration: 3775 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a 3776 */ 3777static const struct hda_verb alc880_pin_asus_init_verbs[] = { 3778 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, 3779 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, 3780 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, 3781 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, 3782 3783 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3784 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3785 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3787 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3788 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3789 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3791 3792 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3794 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3796 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 3798 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3800 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3801 3802 { } 3803}; 3804 3805/* Enable GPIO mask and set output */ 3806#define alc880_gpio1_init_verbs alc_gpio1_init_verbs 3807#define alc880_gpio2_init_verbs alc_gpio2_init_verbs 3808#define alc880_gpio3_init_verbs alc_gpio3_init_verbs 3809 3810/* Clevo m520g init */ 3811static const struct hda_verb alc880_pin_clevo_init_verbs[] = { 3812 /* headphone output */ 3813 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3814 /* line-out */ 3815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3817 /* Line-in */ 3818 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3820 /* CD */ 3821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3822 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3823 /* Mic1 (rear panel) */ 3824 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3825 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3826 /* Mic2 (front panel) */ 3827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3828 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3829 /* headphone */ 3830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3832 /* change to EAPD mode */ 3833 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3834 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3835 3836 { } 3837}; 3838 3839static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { 3840 /* change to EAPD mode */ 3841 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3842 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 3843 3844 /* Headphone output */ 3845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3846 /* Front output*/ 3847 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3848 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 3849 3850 /* Line In pin widget for input */ 3851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3852 /* CD pin widget for input */ 3853 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3854 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 3855 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3856 3857 /* change to EAPD mode */ 3858 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 3859 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 3860 3861 { } 3862}; 3863 3864/* 3865 * LG m1 express dual 3866 * 3867 * Pin assignment: 3868 * Rear Line-In/Out (blue): 0x14 3869 * Build-in Mic-In: 0x15 3870 * Speaker-out: 0x17 3871 * HP-Out (green): 0x1b 3872 * Mic-In/Out (red): 0x19 3873 * SPDIF-Out: 0x1e 3874 */ 3875 3876/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ 3877static const hda_nid_t alc880_lg_dac_nids[3] = { 3878 0x05, 0x02, 0x03 3879}; 3880 3881/* seems analog CD is not working */ 3882static const struct hda_input_mux alc880_lg_capture_source = { 3883 .num_items = 3, 3884 .items = { 3885 { "Mic", 0x1 }, 3886 { "Line", 0x5 }, 3887 { "Internal Mic", 0x6 }, 3888 }, 3889}; 3890 3891/* 2,4,6 channel modes */ 3892static const struct hda_verb alc880_lg_ch2_init[] = { 3893 /* set line-in and mic-in to input */ 3894 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 3895 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3896 { } 3897}; 3898 3899static const struct hda_verb alc880_lg_ch4_init[] = { 3900 /* set line-in to out and mic-in to input */ 3901 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3902 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 3903 { } 3904}; 3905 3906static const struct hda_verb alc880_lg_ch6_init[] = { 3907 /* set line-in and mic-in to output */ 3908 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3909 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 3910 { } 3911}; 3912 3913static const struct hda_channel_mode alc880_lg_ch_modes[3] = { 3914 { 2, alc880_lg_ch2_init }, 3915 { 4, alc880_lg_ch4_init }, 3916 { 6, alc880_lg_ch6_init }, 3917}; 3918 3919static const struct snd_kcontrol_new alc880_lg_mixer[] = { 3920 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 3921 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), 3922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 3923 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), 3924 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), 3925 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 3926 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 3927 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 3928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 3929 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 3930 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), 3931 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), 3932 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), 3933 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), 3934 { 3935 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3936 .name = "Channel Mode", 3937 .info = alc_ch_mode_info, 3938 .get = alc_ch_mode_get, 3939 .put = alc_ch_mode_put, 3940 }, 3941 { } /* end */ 3942}; 3943 3944static const struct hda_verb alc880_lg_init_verbs[] = { 3945 /* set capture source to mic-in */ 3946 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3947 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3948 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 3949 /* mute all amp mixer inputs */ 3950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, 3951 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 3952 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 3953 /* line-in to input */ 3954 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3955 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3956 /* built-in mic */ 3957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3958 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3959 /* speaker-out */ 3960 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3961 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3962 /* mic-in to input */ 3963 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, 3964 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3965 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3966 /* HP-out */ 3967 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, 3968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 3969 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3970 /* jack sense */ 3971 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 3972 { } 3973}; 3974 3975/* toggle speaker-output according to the hp-jack state */ 3976static void alc880_lg_setup(struct hda_codec *codec) 3977{ 3978 struct alc_spec *spec = codec->spec; 3979 3980 spec->autocfg.hp_pins[0] = 0x1b; 3981 spec->autocfg.speaker_pins[0] = 0x17; 3982 spec->automute = 1; 3983 spec->automute_mode = ALC_AUTOMUTE_AMP; 3984} 3985 3986/* 3987 * LG LW20 3988 * 3989 * Pin assignment: 3990 * Speaker-out: 0x14 3991 * Mic-In: 0x18 3992 * Built-in Mic-In: 0x19 3993 * Line-In: 0x1b 3994 * HP-Out: 0x1a 3995 * SPDIF-Out: 0x1e 3996 */ 3997 3998static const struct hda_input_mux alc880_lg_lw_capture_source = { 3999 .num_items = 3, 4000 .items = { 4001 { "Mic", 0x0 }, 4002 { "Internal Mic", 0x1 }, 4003 { "Line In", 0x2 }, 4004 }, 4005}; 4006 4007#define alc880_lg_lw_modes alc880_threestack_modes 4008 4009static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = { 4010 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4011 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4012 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4013 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), 4014 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 4015 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 4016 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 4017 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 4018 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4019 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4022 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 4023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 4024 { 4025 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4026 .name = "Channel Mode", 4027 .info = alc_ch_mode_info, 4028 .get = alc_ch_mode_get, 4029 .put = alc_ch_mode_put, 4030 }, 4031 { } /* end */ 4032}; 4033 4034static const struct hda_verb alc880_lg_lw_init_verbs[] = { 4035 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4036 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 4037 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ 4038 4039 /* set capture source to mic-in */ 4040 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4043 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 4044 /* speaker-out */ 4045 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4046 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4047 /* HP-out */ 4048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4050 /* mic-in to input */ 4051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4053 /* built-in mic */ 4054 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4055 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4056 /* jack sense */ 4057 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4058 { } 4059}; 4060 4061/* toggle speaker-output according to the hp-jack state */ 4062static void alc880_lg_lw_setup(struct hda_codec *codec) 4063{ 4064 struct alc_spec *spec = codec->spec; 4065 4066 spec->autocfg.hp_pins[0] = 0x1b; 4067 spec->autocfg.speaker_pins[0] = 0x14; 4068 spec->automute = 1; 4069 spec->automute_mode = ALC_AUTOMUTE_AMP; 4070} 4071 4072static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 4073 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4074 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 4075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4077 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4078 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), 4079 { } /* end */ 4080}; 4081 4082static const struct hda_input_mux alc880_medion_rim_capture_source = { 4083 .num_items = 2, 4084 .items = { 4085 { "Mic", 0x0 }, 4086 { "Internal Mic", 0x1 }, 4087 }, 4088}; 4089 4090static const struct hda_verb alc880_medion_rim_init_verbs[] = { 4091 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 4092 4093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4094 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4095 4096 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 4097 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4099 /* Mic2 (as headphone out) for HP output */ 4100 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 4101 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4102 /* Internal Speaker */ 4103 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4105 4106 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 4107 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 4108 4109 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 4110 { } 4111}; 4112 4113/* toggle speaker-output according to the hp-jack state */ 4114static void alc880_medion_rim_automute(struct hda_codec *codec) 4115{ 4116 struct alc_spec *spec = codec->spec; 4117 alc_hp_automute(codec); 4118 /* toggle EAPD */ 4119 if (spec->jack_present) 4120 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); 4121 else 4122 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); 4123} 4124 4125static void alc880_medion_rim_unsol_event(struct hda_codec *codec, 4126 unsigned int res) 4127{ 4128 /* Looks like the unsol event is incompatible with the standard 4129 * definition. 4bit tag is placed at 28 bit! 4130 */ 4131 if ((res >> 28) == ALC880_HP_EVENT) 4132 alc880_medion_rim_automute(codec); 4133} 4134 4135static void alc880_medion_rim_setup(struct hda_codec *codec) 4136{ 4137 struct alc_spec *spec = codec->spec; 4138 4139 spec->autocfg.hp_pins[0] = 0x14; 4140 spec->autocfg.speaker_pins[0] = 0x1b; 4141 spec->automute = 1; 4142 spec->automute_mode = ALC_AUTOMUTE_AMP; 4143} 4144 4145#ifdef CONFIG_SND_HDA_POWER_SAVE 4146static const struct hda_amp_list alc880_loopbacks[] = { 4147 { 0x0b, HDA_INPUT, 0 }, 4148 { 0x0b, HDA_INPUT, 1 }, 4149 { 0x0b, HDA_INPUT, 2 }, 4150 { 0x0b, HDA_INPUT, 3 }, 4151 { 0x0b, HDA_INPUT, 4 }, 4152 { } /* end */ 4153}; 4154 4155static const struct hda_amp_list alc880_lg_loopbacks[] = { 4156 { 0x0b, HDA_INPUT, 1 }, 4157 { 0x0b, HDA_INPUT, 6 }, 4158 { 0x0b, HDA_INPUT, 7 }, 4159 { } /* end */ 4160}; 4161#endif 4162 4163/* 4164 * Common callbacks 4165 */ 4166 4167static void alc_init_special_input_src(struct hda_codec *codec); 4168 4169static int alc_init(struct hda_codec *codec) 4170{ 4171 struct alc_spec *spec = codec->spec; 4172 unsigned int i; 4173 4174 alc_fix_pll(codec); 4175 alc_auto_init_amp(codec, spec->init_amp); 4176 4177 for (i = 0; i < spec->num_init_verbs; i++) 4178 snd_hda_sequence_write(codec, spec->init_verbs[i]); 4179 alc_init_special_input_src(codec); 4180 4181 if (spec->init_hook) 4182 spec->init_hook(codec); 4183 4184 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 4185 4186 hda_call_check_power_status(codec, 0x01); 4187 return 0; 4188} 4189 4190static void alc_unsol_event(struct hda_codec *codec, unsigned int res) 4191{ 4192 struct alc_spec *spec = codec->spec; 4193 4194 if (spec->unsol_event) 4195 spec->unsol_event(codec, res); 4196} 4197 4198#ifdef CONFIG_SND_HDA_POWER_SAVE 4199static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 4200{ 4201 struct alc_spec *spec = codec->spec; 4202 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 4203} 4204#endif 4205 4206/* 4207 * Analog playback callbacks 4208 */ 4209static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 4210 struct hda_codec *codec, 4211 struct snd_pcm_substream *substream) 4212{ 4213 struct alc_spec *spec = codec->spec; 4214 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 4215 hinfo); 4216} 4217 4218static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 4219 struct hda_codec *codec, 4220 unsigned int stream_tag, 4221 unsigned int format, 4222 struct snd_pcm_substream *substream) 4223{ 4224 struct alc_spec *spec = codec->spec; 4225 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, 4226 stream_tag, format, substream); 4227} 4228 4229static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 4230 struct hda_codec *codec, 4231 struct snd_pcm_substream *substream) 4232{ 4233 struct alc_spec *spec = codec->spec; 4234 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 4235} 4236 4237/* 4238 * Digital out 4239 */ 4240static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 4241 struct hda_codec *codec, 4242 struct snd_pcm_substream *substream) 4243{ 4244 struct alc_spec *spec = codec->spec; 4245 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 4246} 4247 4248static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 4249 struct hda_codec *codec, 4250 unsigned int stream_tag, 4251 unsigned int format, 4252 struct snd_pcm_substream *substream) 4253{ 4254 struct alc_spec *spec = codec->spec; 4255 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, 4256 stream_tag, format, substream); 4257} 4258 4259static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 4260 struct hda_codec *codec, 4261 struct snd_pcm_substream *substream) 4262{ 4263 struct alc_spec *spec = codec->spec; 4264 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 4265} 4266 4267static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 4268 struct hda_codec *codec, 4269 struct snd_pcm_substream *substream) 4270{ 4271 struct alc_spec *spec = codec->spec; 4272 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 4273} 4274 4275/* 4276 * Analog capture 4277 */ 4278static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 4279 struct hda_codec *codec, 4280 unsigned int stream_tag, 4281 unsigned int format, 4282 struct snd_pcm_substream *substream) 4283{ 4284 struct alc_spec *spec = codec->spec; 4285 4286 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], 4287 stream_tag, 0, format); 4288 return 0; 4289} 4290 4291static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 4292 struct hda_codec *codec, 4293 struct snd_pcm_substream *substream) 4294{ 4295 struct alc_spec *spec = codec->spec; 4296 4297 snd_hda_codec_cleanup_stream(codec, 4298 spec->adc_nids[substream->number + 1]); 4299 return 0; 4300} 4301 4302/* analog capture with dynamic dual-adc changes */ 4303static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 4304 struct hda_codec *codec, 4305 unsigned int stream_tag, 4306 unsigned int format, 4307 struct snd_pcm_substream *substream) 4308{ 4309 struct alc_spec *spec = codec->spec; 4310 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 4311 spec->cur_adc_stream_tag = stream_tag; 4312 spec->cur_adc_format = format; 4313 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 4314 return 0; 4315} 4316 4317static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 4318 struct hda_codec *codec, 4319 struct snd_pcm_substream *substream) 4320{ 4321 struct alc_spec *spec = codec->spec; 4322 snd_hda_codec_cleanup_stream(codec, spec->cur_adc); 4323 spec->cur_adc = 0; 4324 return 0; 4325} 4326 4327static const struct hda_pcm_stream dualmic_pcm_analog_capture = { 4328 .substreams = 1, 4329 .channels_min = 2, 4330 .channels_max = 2, 4331 .nid = 0, /* fill later */ 4332 .ops = { 4333 .prepare = dualmic_capture_pcm_prepare, 4334 .cleanup = dualmic_capture_pcm_cleanup 4335 }, 4336}; 4337 4338/* 4339 */ 4340static const struct hda_pcm_stream alc880_pcm_analog_playback = { 4341 .substreams = 1, 4342 .channels_min = 2, 4343 .channels_max = 8, 4344 /* NID is set in alc_build_pcms */ 4345 .ops = { 4346 .open = alc880_playback_pcm_open, 4347 .prepare = alc880_playback_pcm_prepare, 4348 .cleanup = alc880_playback_pcm_cleanup 4349 }, 4350}; 4351 4352static const struct hda_pcm_stream alc880_pcm_analog_capture = { 4353 .substreams = 1, 4354 .channels_min = 2, 4355 .channels_max = 2, 4356 /* NID is set in alc_build_pcms */ 4357}; 4358 4359static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 4360 .substreams = 1, 4361 .channels_min = 2, 4362 .channels_max = 2, 4363 /* NID is set in alc_build_pcms */ 4364}; 4365 4366static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 4367 .substreams = 2, /* can be overridden */ 4368 .channels_min = 2, 4369 .channels_max = 2, 4370 /* NID is set in alc_build_pcms */ 4371 .ops = { 4372 .prepare = alc880_alt_capture_pcm_prepare, 4373 .cleanup = alc880_alt_capture_pcm_cleanup 4374 }, 4375}; 4376 4377static const struct hda_pcm_stream alc880_pcm_digital_playback = { 4378 .substreams = 1, 4379 .channels_min = 2, 4380 .channels_max = 2, 4381 /* NID is set in alc_build_pcms */ 4382 .ops = { 4383 .open = alc880_dig_playback_pcm_open, 4384 .close = alc880_dig_playback_pcm_close, 4385 .prepare = alc880_dig_playback_pcm_prepare, 4386 .cleanup = alc880_dig_playback_pcm_cleanup 4387 }, 4388}; 4389 4390static const struct hda_pcm_stream alc880_pcm_digital_capture = { 4391 .substreams = 1, 4392 .channels_min = 2, 4393 .channels_max = 2, 4394 /* NID is set in alc_build_pcms */ 4395}; 4396 4397/* Used by alc_build_pcms to flag that a PCM has no playback stream */ 4398static const struct hda_pcm_stream alc_pcm_null_stream = { 4399 .substreams = 0, 4400 .channels_min = 0, 4401 .channels_max = 0, 4402}; 4403 4404static int alc_build_pcms(struct hda_codec *codec) 4405{ 4406 struct alc_spec *spec = codec->spec; 4407 struct hda_pcm *info = spec->pcm_rec; 4408 int i; 4409 4410 codec->num_pcms = 1; 4411 codec->pcm_info = info; 4412 4413 if (spec->no_analog) 4414 goto skip_analog; 4415 4416 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), 4417 "%s Analog", codec->chip_name); 4418 info->name = spec->stream_name_analog; 4419 4420 if (spec->stream_analog_playback) { 4421 if (snd_BUG_ON(!spec->multiout.dac_nids)) 4422 return -EINVAL; 4423 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 4424 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 4425 } 4426 if (spec->stream_analog_capture) { 4427 if (snd_BUG_ON(!spec->adc_nids)) 4428 return -EINVAL; 4429 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 4430 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 4431 } 4432 4433 if (spec->channel_mode) { 4434 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0; 4435 for (i = 0; i < spec->num_channel_mode; i++) { 4436 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) { 4437 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels; 4438 } 4439 } 4440 } 4441 4442 skip_analog: 4443 /* SPDIF for stream index #1 */ 4444 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 4445 snprintf(spec->stream_name_digital, 4446 sizeof(spec->stream_name_digital), 4447 "%s Digital", codec->chip_name); 4448 codec->num_pcms = 2; 4449 codec->slave_dig_outs = spec->multiout.slave_dig_outs; 4450 info = spec->pcm_rec + 1; 4451 info->name = spec->stream_name_digital; 4452 if (spec->dig_out_type) 4453 info->pcm_type = spec->dig_out_type; 4454 else 4455 info->pcm_type = HDA_PCM_TYPE_SPDIF; 4456 if (spec->multiout.dig_out_nid && 4457 spec->stream_digital_playback) { 4458 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 4459 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 4460 } 4461 if (spec->dig_in_nid && 4462 spec->stream_digital_capture) { 4463 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 4464 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 4465 } 4466 /* FIXME: do we need this for all Realtek codec models? */ 4467 codec->spdif_status_reset = 1; 4468 } 4469 4470 if (spec->no_analog) 4471 return 0; 4472 4473 /* If the use of more than one ADC is requested for the current 4474 * model, configure a second analog capture-only PCM. 4475 */ 4476 /* Additional Analaog capture for index #2 */ 4477 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 4478 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) { 4479 codec->num_pcms = 3; 4480 info = spec->pcm_rec + 2; 4481 info->name = spec->stream_name_analog; 4482 if (spec->alt_dac_nid) { 4483 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4484 *spec->stream_analog_alt_playback; 4485 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 4486 spec->alt_dac_nid; 4487 } else { 4488 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 4489 alc_pcm_null_stream; 4490 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 4491 } 4492 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { 4493 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4494 *spec->stream_analog_alt_capture; 4495 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 4496 spec->adc_nids[1]; 4497 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 4498 spec->num_adc_nids - 1; 4499 } else { 4500 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 4501 alc_pcm_null_stream; 4502 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0; 4503 } 4504 } 4505 4506 return 0; 4507} 4508 4509static inline void alc_shutup(struct hda_codec *codec) 4510{ 4511 struct alc_spec *spec = codec->spec; 4512 4513 if (spec && spec->shutup) 4514 spec->shutup(codec); 4515 snd_hda_shutup_pins(codec); 4516} 4517 4518static void alc_free_kctls(struct hda_codec *codec) 4519{ 4520 struct alc_spec *spec = codec->spec; 4521 4522 if (spec->kctls.list) { 4523 struct snd_kcontrol_new *kctl = spec->kctls.list; 4524 int i; 4525 for (i = 0; i < spec->kctls.used; i++) 4526 kfree(kctl[i].name); 4527 } 4528 snd_array_free(&spec->kctls); 4529} 4530 4531static void alc_free(struct hda_codec *codec) 4532{ 4533 struct alc_spec *spec = codec->spec; 4534 4535 if (!spec) 4536 return; 4537 4538 alc_shutup(codec); 4539 snd_hda_input_jack_free(codec); 4540 alc_free_kctls(codec); 4541 kfree(spec); 4542 snd_hda_detach_beep_device(codec); 4543} 4544 4545#ifdef CONFIG_SND_HDA_POWER_SAVE 4546static void alc_power_eapd(struct hda_codec *codec) 4547{ 4548 alc_auto_setup_eapd(codec, false); 4549} 4550 4551static int alc_suspend(struct hda_codec *codec, pm_message_t state) 4552{ 4553 struct alc_spec *spec = codec->spec; 4554 alc_shutup(codec); 4555 if (spec && spec->power_hook) 4556 spec->power_hook(codec); 4557 return 0; 4558} 4559#endif 4560 4561#ifdef SND_HDA_NEEDS_RESUME 4562static int alc_resume(struct hda_codec *codec) 4563{ 4564 msleep(150); /* to avoid pop noise */ 4565 codec->patch_ops.init(codec); 4566 snd_hda_codec_resume_amp(codec); 4567 snd_hda_codec_resume_cache(codec); 4568 hda_call_check_power_status(codec, 0x01); 4569 return 0; 4570} 4571#endif 4572 4573/* 4574 */ 4575static const struct hda_codec_ops alc_patch_ops = { 4576 .build_controls = alc_build_controls, 4577 .build_pcms = alc_build_pcms, 4578 .init = alc_init, 4579 .free = alc_free, 4580 .unsol_event = alc_unsol_event, 4581#ifdef SND_HDA_NEEDS_RESUME 4582 .resume = alc_resume, 4583#endif 4584#ifdef CONFIG_SND_HDA_POWER_SAVE 4585 .suspend = alc_suspend, 4586 .check_power_status = alc_check_power_status, 4587#endif 4588 .reboot_notify = alc_shutup, 4589}; 4590 4591/* replace the codec chip_name with the given string */ 4592static int alc_codec_rename(struct hda_codec *codec, const char *name) 4593{ 4594 kfree(codec->chip_name); 4595 codec->chip_name = kstrdup(name, GFP_KERNEL); 4596 if (!codec->chip_name) { 4597 alc_free(codec); 4598 return -ENOMEM; 4599 } 4600 return 0; 4601} 4602 4603/* 4604 * Test configuration for debugging 4605 * 4606 * Almost all inputs/outputs are enabled. I/O pins can be configured via 4607 * enum controls. 4608 */ 4609#ifdef CONFIG_SND_DEBUG 4610static const hda_nid_t alc880_test_dac_nids[4] = { 4611 0x02, 0x03, 0x04, 0x05 4612}; 4613 4614static const struct hda_input_mux alc880_test_capture_source = { 4615 .num_items = 7, 4616 .items = { 4617 { "In-1", 0x0 }, 4618 { "In-2", 0x1 }, 4619 { "In-3", 0x2 }, 4620 { "In-4", 0x3 }, 4621 { "CD", 0x4 }, 4622 { "Front", 0x5 }, 4623 { "Surround", 0x6 }, 4624 }, 4625}; 4626 4627static const struct hda_channel_mode alc880_test_modes[4] = { 4628 { 2, NULL }, 4629 { 4, NULL }, 4630 { 6, NULL }, 4631 { 8, NULL }, 4632}; 4633 4634static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, 4635 struct snd_ctl_elem_info *uinfo) 4636{ 4637 static const char * const texts[] = { 4638 "N/A", "Line Out", "HP Out", 4639 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" 4640 }; 4641 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4642 uinfo->count = 1; 4643 uinfo->value.enumerated.items = 8; 4644 if (uinfo->value.enumerated.item >= 8) 4645 uinfo->value.enumerated.item = 7; 4646 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4647 return 0; 4648} 4649 4650static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, 4651 struct snd_ctl_elem_value *ucontrol) 4652{ 4653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4654 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4655 unsigned int pin_ctl, item = 0; 4656 4657 pin_ctl = snd_hda_codec_read(codec, nid, 0, 4658 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4659 if (pin_ctl & AC_PINCTL_OUT_EN) { 4660 if (pin_ctl & AC_PINCTL_HP_EN) 4661 item = 2; 4662 else 4663 item = 1; 4664 } else if (pin_ctl & AC_PINCTL_IN_EN) { 4665 switch (pin_ctl & AC_PINCTL_VREFEN) { 4666 case AC_PINCTL_VREF_HIZ: item = 3; break; 4667 case AC_PINCTL_VREF_50: item = 4; break; 4668 case AC_PINCTL_VREF_GRD: item = 5; break; 4669 case AC_PINCTL_VREF_80: item = 6; break; 4670 case AC_PINCTL_VREF_100: item = 7; break; 4671 } 4672 } 4673 ucontrol->value.enumerated.item[0] = item; 4674 return 0; 4675} 4676 4677static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, 4678 struct snd_ctl_elem_value *ucontrol) 4679{ 4680 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4681 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4682 static const unsigned int ctls[] = { 4683 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, 4684 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, 4685 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, 4686 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, 4687 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, 4688 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, 4689 }; 4690 unsigned int old_ctl, new_ctl; 4691 4692 old_ctl = snd_hda_codec_read(codec, nid, 0, 4693 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 4694 new_ctl = ctls[ucontrol->value.enumerated.item[0]]; 4695 if (old_ctl != new_ctl) { 4696 int val; 4697 snd_hda_codec_write_cache(codec, nid, 0, 4698 AC_VERB_SET_PIN_WIDGET_CONTROL, 4699 new_ctl); 4700 val = ucontrol->value.enumerated.item[0] >= 3 ? 4701 HDA_AMP_MUTE : 0; 4702 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 4703 HDA_AMP_MUTE, val); 4704 return 1; 4705 } 4706 return 0; 4707} 4708 4709static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, 4710 struct snd_ctl_elem_info *uinfo) 4711{ 4712 static const char * const texts[] = { 4713 "Front", "Surround", "CLFE", "Side" 4714 }; 4715 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4716 uinfo->count = 1; 4717 uinfo->value.enumerated.items = 4; 4718 if (uinfo->value.enumerated.item >= 4) 4719 uinfo->value.enumerated.item = 3; 4720 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 4721 return 0; 4722} 4723 4724static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, 4725 struct snd_ctl_elem_value *ucontrol) 4726{ 4727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4728 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4729 unsigned int sel; 4730 4731 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); 4732 ucontrol->value.enumerated.item[0] = sel & 3; 4733 return 0; 4734} 4735 4736static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, 4737 struct snd_ctl_elem_value *ucontrol) 4738{ 4739 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 4740 hda_nid_t nid = (hda_nid_t)kcontrol->private_value; 4741 unsigned int sel; 4742 4743 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; 4744 if (ucontrol->value.enumerated.item[0] != sel) { 4745 sel = ucontrol->value.enumerated.item[0] & 3; 4746 snd_hda_codec_write_cache(codec, nid, 0, 4747 AC_VERB_SET_CONNECT_SEL, sel); 4748 return 1; 4749 } 4750 return 0; 4751} 4752 4753#define PIN_CTL_TEST(xname,nid) { \ 4754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4755 .name = xname, \ 4756 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4757 .info = alc_test_pin_ctl_info, \ 4758 .get = alc_test_pin_ctl_get, \ 4759 .put = alc_test_pin_ctl_put, \ 4760 .private_value = nid \ 4761 } 4762 4763#define PIN_SRC_TEST(xname,nid) { \ 4764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 4765 .name = xname, \ 4766 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ 4767 .info = alc_test_pin_src_info, \ 4768 .get = alc_test_pin_src_get, \ 4769 .put = alc_test_pin_src_put, \ 4770 .private_value = nid \ 4771 } 4772 4773static const struct snd_kcontrol_new alc880_test_mixer[] = { 4774 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 4775 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 4776 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 4777 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 4778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 4779 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 4780 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), 4781 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 4782 PIN_CTL_TEST("Front Pin Mode", 0x14), 4783 PIN_CTL_TEST("Surround Pin Mode", 0x15), 4784 PIN_CTL_TEST("CLFE Pin Mode", 0x16), 4785 PIN_CTL_TEST("Side Pin Mode", 0x17), 4786 PIN_CTL_TEST("In-1 Pin Mode", 0x18), 4787 PIN_CTL_TEST("In-2 Pin Mode", 0x19), 4788 PIN_CTL_TEST("In-3 Pin Mode", 0x1a), 4789 PIN_CTL_TEST("In-4 Pin Mode", 0x1b), 4790 PIN_SRC_TEST("In-1 Pin Source", 0x18), 4791 PIN_SRC_TEST("In-2 Pin Source", 0x19), 4792 PIN_SRC_TEST("In-3 Pin Source", 0x1a), 4793 PIN_SRC_TEST("In-4 Pin Source", 0x1b), 4794 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), 4795 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), 4796 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), 4797 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), 4798 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), 4799 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), 4800 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), 4801 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), 4802 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), 4803 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), 4804 { 4805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 4806 .name = "Channel Mode", 4807 .info = alc_ch_mode_info, 4808 .get = alc_ch_mode_get, 4809 .put = alc_ch_mode_put, 4810 }, 4811 { } /* end */ 4812}; 4813 4814static const struct hda_verb alc880_test_init_verbs[] = { 4815 /* Unmute inputs of 0x0c - 0x0f */ 4816 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4817 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4818 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4819 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4820 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4821 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4822 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4823 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 4824 /* Vol output for 0x0c-0x0f */ 4825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4826 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4827 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4828 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 4829 /* Set output pins 0x14-0x17 */ 4830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4832 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 4834 /* Unmute output pins 0x14-0x17 */ 4835 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4836 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4837 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4838 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 4839 /* Set input pins 0x18-0x1c */ 4840 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 4842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4843 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4844 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 4845 /* Mute input pins 0x18-0x1b */ 4846 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4847 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4849 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 4850 /* ADC set up */ 4851 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4852 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 4853 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4854 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 4855 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4856 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 4857 /* Analog input/passthru */ 4858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 4859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 4861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 4862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 4863 { } 4864}; 4865#endif 4866 4867/* 4868 */ 4869 4870static const char * const alc880_models[ALC880_MODEL_LAST] = { 4871 [ALC880_3ST] = "3stack", 4872 [ALC880_TCL_S700] = "tcl", 4873 [ALC880_3ST_DIG] = "3stack-digout", 4874 [ALC880_CLEVO] = "clevo", 4875 [ALC880_5ST] = "5stack", 4876 [ALC880_5ST_DIG] = "5stack-digout", 4877 [ALC880_W810] = "w810", 4878 [ALC880_Z71V] = "z71v", 4879 [ALC880_6ST] = "6stack", 4880 [ALC880_6ST_DIG] = "6stack-digout", 4881 [ALC880_ASUS] = "asus", 4882 [ALC880_ASUS_W1V] = "asus-w1v", 4883 [ALC880_ASUS_DIG] = "asus-dig", 4884 [ALC880_ASUS_DIG2] = "asus-dig2", 4885 [ALC880_UNIWILL_DIG] = "uniwill", 4886 [ALC880_UNIWILL_P53] = "uniwill-p53", 4887 [ALC880_FUJITSU] = "fujitsu", 4888 [ALC880_F1734] = "F1734", 4889 [ALC880_LG] = "lg", 4890 [ALC880_LG_LW] = "lg-lw", 4891 [ALC880_MEDION_RIM] = "medion", 4892#ifdef CONFIG_SND_DEBUG 4893 [ALC880_TEST] = "test", 4894#endif 4895 [ALC880_AUTO] = "auto", 4896}; 4897 4898static const struct snd_pci_quirk alc880_cfg_tbl[] = { 4899 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), 4900 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), 4901 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), 4902 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), 4903 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), 4904 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), 4905 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), 4906 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), 4907 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), 4908 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), 4909 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), 4910 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), 4911 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), 4912 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), 4913 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), 4914 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), 4915 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), 4916 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ 4917 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), 4918 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), 4919 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), 4920 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), 4921 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), 4922 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), 4923 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ 4924 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), 4925 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), 4926 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), 4927 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), 4928 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), 4929 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), 4930 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), 4931 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), 4932 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), 4933 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), 4934 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), 4935 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), 4936 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), 4937 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), 4938 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734), 4939 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), 4940 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), 4941 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), 4942 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), 4943 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), 4944 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), 4945 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), 4946 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), 4947 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), 4948 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4949 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4950 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4951 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), 4952 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4953 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4954 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4955 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ 4956 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), 4957 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), 4958 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), 4959 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), 4960 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), 4961 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), 4962 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), 4963 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), 4964 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), 4965 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), 4966 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), 4967 /* default Intel */ 4968 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), 4969 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), 4970 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), 4971 {} 4972}; 4973 4974/* 4975 * ALC880 codec presets 4976 */ 4977static const struct alc_config_preset alc880_presets[] = { 4978 [ALC880_3ST] = { 4979 .mixers = { alc880_three_stack_mixer }, 4980 .init_verbs = { alc880_volume_init_verbs, 4981 alc880_pin_3stack_init_verbs }, 4982 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4983 .dac_nids = alc880_dac_nids, 4984 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4985 .channel_mode = alc880_threestack_modes, 4986 .need_dac_fix = 1, 4987 .input_mux = &alc880_capture_source, 4988 }, 4989 [ALC880_3ST_DIG] = { 4990 .mixers = { alc880_three_stack_mixer }, 4991 .init_verbs = { alc880_volume_init_verbs, 4992 alc880_pin_3stack_init_verbs }, 4993 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 4994 .dac_nids = alc880_dac_nids, 4995 .dig_out_nid = ALC880_DIGOUT_NID, 4996 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 4997 .channel_mode = alc880_threestack_modes, 4998 .need_dac_fix = 1, 4999 .input_mux = &alc880_capture_source, 5000 }, 5001 [ALC880_TCL_S700] = { 5002 .mixers = { alc880_tcl_s700_mixer }, 5003 .init_verbs = { alc880_volume_init_verbs, 5004 alc880_pin_tcl_S700_init_verbs, 5005 alc880_gpio2_init_verbs }, 5006 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5007 .dac_nids = alc880_dac_nids, 5008 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ 5009 .num_adc_nids = 1, /* single ADC */ 5010 .hp_nid = 0x03, 5011 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5012 .channel_mode = alc880_2_jack_modes, 5013 .input_mux = &alc880_capture_source, 5014 }, 5015 [ALC880_5ST] = { 5016 .mixers = { alc880_three_stack_mixer, 5017 alc880_five_stack_mixer}, 5018 .init_verbs = { alc880_volume_init_verbs, 5019 alc880_pin_5stack_init_verbs }, 5020 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5021 .dac_nids = alc880_dac_nids, 5022 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 5023 .channel_mode = alc880_fivestack_modes, 5024 .input_mux = &alc880_capture_source, 5025 }, 5026 [ALC880_5ST_DIG] = { 5027 .mixers = { alc880_three_stack_mixer, 5028 alc880_five_stack_mixer }, 5029 .init_verbs = { alc880_volume_init_verbs, 5030 alc880_pin_5stack_init_verbs }, 5031 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5032 .dac_nids = alc880_dac_nids, 5033 .dig_out_nid = ALC880_DIGOUT_NID, 5034 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), 5035 .channel_mode = alc880_fivestack_modes, 5036 .input_mux = &alc880_capture_source, 5037 }, 5038 [ALC880_6ST] = { 5039 .mixers = { alc880_six_stack_mixer }, 5040 .init_verbs = { alc880_volume_init_verbs, 5041 alc880_pin_6stack_init_verbs }, 5042 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 5043 .dac_nids = alc880_6st_dac_nids, 5044 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 5045 .channel_mode = alc880_sixstack_modes, 5046 .input_mux = &alc880_6stack_capture_source, 5047 }, 5048 [ALC880_6ST_DIG] = { 5049 .mixers = { alc880_six_stack_mixer }, 5050 .init_verbs = { alc880_volume_init_verbs, 5051 alc880_pin_6stack_init_verbs }, 5052 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), 5053 .dac_nids = alc880_6st_dac_nids, 5054 .dig_out_nid = ALC880_DIGOUT_NID, 5055 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), 5056 .channel_mode = alc880_sixstack_modes, 5057 .input_mux = &alc880_6stack_capture_source, 5058 }, 5059 [ALC880_W810] = { 5060 .mixers = { alc880_w810_base_mixer }, 5061 .init_verbs = { alc880_volume_init_verbs, 5062 alc880_pin_w810_init_verbs, 5063 alc880_gpio2_init_verbs }, 5064 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), 5065 .dac_nids = alc880_w810_dac_nids, 5066 .dig_out_nid = ALC880_DIGOUT_NID, 5067 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 5068 .channel_mode = alc880_w810_modes, 5069 .input_mux = &alc880_capture_source, 5070 }, 5071 [ALC880_Z71V] = { 5072 .mixers = { alc880_z71v_mixer }, 5073 .init_verbs = { alc880_volume_init_verbs, 5074 alc880_pin_z71v_init_verbs }, 5075 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), 5076 .dac_nids = alc880_z71v_dac_nids, 5077 .dig_out_nid = ALC880_DIGOUT_NID, 5078 .hp_nid = 0x03, 5079 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5080 .channel_mode = alc880_2_jack_modes, 5081 .input_mux = &alc880_capture_source, 5082 }, 5083 [ALC880_F1734] = { 5084 .mixers = { alc880_f1734_mixer }, 5085 .init_verbs = { alc880_volume_init_verbs, 5086 alc880_pin_f1734_init_verbs }, 5087 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), 5088 .dac_nids = alc880_f1734_dac_nids, 5089 .hp_nid = 0x02, 5090 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5091 .channel_mode = alc880_2_jack_modes, 5092 .input_mux = &alc880_f1734_capture_source, 5093 .unsol_event = alc880_uniwill_p53_unsol_event, 5094 .setup = alc880_uniwill_p53_setup, 5095 .init_hook = alc_hp_automute, 5096 }, 5097 [ALC880_ASUS] = { 5098 .mixers = { alc880_asus_mixer }, 5099 .init_verbs = { alc880_volume_init_verbs, 5100 alc880_pin_asus_init_verbs, 5101 alc880_gpio1_init_verbs }, 5102 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5103 .dac_nids = alc880_asus_dac_nids, 5104 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 5105 .channel_mode = alc880_asus_modes, 5106 .need_dac_fix = 1, 5107 .input_mux = &alc880_capture_source, 5108 }, 5109 [ALC880_ASUS_DIG] = { 5110 .mixers = { alc880_asus_mixer }, 5111 .init_verbs = { alc880_volume_init_verbs, 5112 alc880_pin_asus_init_verbs, 5113 alc880_gpio1_init_verbs }, 5114 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5115 .dac_nids = alc880_asus_dac_nids, 5116 .dig_out_nid = ALC880_DIGOUT_NID, 5117 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 5118 .channel_mode = alc880_asus_modes, 5119 .need_dac_fix = 1, 5120 .input_mux = &alc880_capture_source, 5121 }, 5122 [ALC880_ASUS_DIG2] = { 5123 .mixers = { alc880_asus_mixer }, 5124 .init_verbs = { alc880_volume_init_verbs, 5125 alc880_pin_asus_init_verbs, 5126 alc880_gpio2_init_verbs }, /* use GPIO2 */ 5127 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5128 .dac_nids = alc880_asus_dac_nids, 5129 .dig_out_nid = ALC880_DIGOUT_NID, 5130 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 5131 .channel_mode = alc880_asus_modes, 5132 .need_dac_fix = 1, 5133 .input_mux = &alc880_capture_source, 5134 }, 5135 [ALC880_ASUS_W1V] = { 5136 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, 5137 .init_verbs = { alc880_volume_init_verbs, 5138 alc880_pin_asus_init_verbs, 5139 alc880_gpio1_init_verbs }, 5140 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5141 .dac_nids = alc880_asus_dac_nids, 5142 .dig_out_nid = ALC880_DIGOUT_NID, 5143 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 5144 .channel_mode = alc880_asus_modes, 5145 .need_dac_fix = 1, 5146 .input_mux = &alc880_capture_source, 5147 }, 5148 [ALC880_UNIWILL_DIG] = { 5149 .mixers = { alc880_asus_mixer }, 5150 .init_verbs = { alc880_volume_init_verbs, 5151 alc880_pin_asus_init_verbs }, 5152 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5153 .dac_nids = alc880_asus_dac_nids, 5154 .dig_out_nid = ALC880_DIGOUT_NID, 5155 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), 5156 .channel_mode = alc880_asus_modes, 5157 .need_dac_fix = 1, 5158 .input_mux = &alc880_capture_source, 5159 }, 5160 [ALC880_UNIWILL] = { 5161 .mixers = { alc880_uniwill_mixer }, 5162 .init_verbs = { alc880_volume_init_verbs, 5163 alc880_uniwill_init_verbs }, 5164 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5165 .dac_nids = alc880_asus_dac_nids, 5166 .dig_out_nid = ALC880_DIGOUT_NID, 5167 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5168 .channel_mode = alc880_threestack_modes, 5169 .need_dac_fix = 1, 5170 .input_mux = &alc880_capture_source, 5171 .unsol_event = alc880_uniwill_unsol_event, 5172 .setup = alc880_uniwill_setup, 5173 .init_hook = alc880_uniwill_init_hook, 5174 }, 5175 [ALC880_UNIWILL_P53] = { 5176 .mixers = { alc880_uniwill_p53_mixer }, 5177 .init_verbs = { alc880_volume_init_verbs, 5178 alc880_uniwill_p53_init_verbs }, 5179 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 5180 .dac_nids = alc880_asus_dac_nids, 5181 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), 5182 .channel_mode = alc880_threestack_modes, 5183 .input_mux = &alc880_capture_source, 5184 .unsol_event = alc880_uniwill_p53_unsol_event, 5185 .setup = alc880_uniwill_p53_setup, 5186 .init_hook = alc_hp_automute, 5187 }, 5188 [ALC880_FUJITSU] = { 5189 .mixers = { alc880_fujitsu_mixer }, 5190 .init_verbs = { alc880_volume_init_verbs, 5191 alc880_uniwill_p53_init_verbs, 5192 alc880_beep_init_verbs }, 5193 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5194 .dac_nids = alc880_dac_nids, 5195 .dig_out_nid = ALC880_DIGOUT_NID, 5196 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5197 .channel_mode = alc880_2_jack_modes, 5198 .input_mux = &alc880_capture_source, 5199 .unsol_event = alc880_uniwill_p53_unsol_event, 5200 .setup = alc880_uniwill_p53_setup, 5201 .init_hook = alc_hp_automute, 5202 }, 5203 [ALC880_CLEVO] = { 5204 .mixers = { alc880_three_stack_mixer }, 5205 .init_verbs = { alc880_volume_init_verbs, 5206 alc880_pin_clevo_init_verbs }, 5207 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5208 .dac_nids = alc880_dac_nids, 5209 .hp_nid = 0x03, 5210 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 5211 .channel_mode = alc880_threestack_modes, 5212 .need_dac_fix = 1, 5213 .input_mux = &alc880_capture_source, 5214 }, 5215 [ALC880_LG] = { 5216 .mixers = { alc880_lg_mixer }, 5217 .init_verbs = { alc880_volume_init_verbs, 5218 alc880_lg_init_verbs }, 5219 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), 5220 .dac_nids = alc880_lg_dac_nids, 5221 .dig_out_nid = ALC880_DIGOUT_NID, 5222 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), 5223 .channel_mode = alc880_lg_ch_modes, 5224 .need_dac_fix = 1, 5225 .input_mux = &alc880_lg_capture_source, 5226 .unsol_event = alc_sku_unsol_event, 5227 .setup = alc880_lg_setup, 5228 .init_hook = alc_hp_automute, 5229#ifdef CONFIG_SND_HDA_POWER_SAVE 5230 .loopbacks = alc880_lg_loopbacks, 5231#endif 5232 }, 5233 [ALC880_LG_LW] = { 5234 .mixers = { alc880_lg_lw_mixer }, 5235 .init_verbs = { alc880_volume_init_verbs, 5236 alc880_lg_lw_init_verbs }, 5237 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5238 .dac_nids = alc880_dac_nids, 5239 .dig_out_nid = ALC880_DIGOUT_NID, 5240 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), 5241 .channel_mode = alc880_lg_lw_modes, 5242 .input_mux = &alc880_lg_lw_capture_source, 5243 .unsol_event = alc_sku_unsol_event, 5244 .setup = alc880_lg_lw_setup, 5245 .init_hook = alc_hp_automute, 5246 }, 5247 [ALC880_MEDION_RIM] = { 5248 .mixers = { alc880_medion_rim_mixer }, 5249 .init_verbs = { alc880_volume_init_verbs, 5250 alc880_medion_rim_init_verbs, 5251 alc_gpio2_init_verbs }, 5252 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 5253 .dac_nids = alc880_dac_nids, 5254 .dig_out_nid = ALC880_DIGOUT_NID, 5255 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 5256 .channel_mode = alc880_2_jack_modes, 5257 .input_mux = &alc880_medion_rim_capture_source, 5258 .unsol_event = alc880_medion_rim_unsol_event, 5259 .setup = alc880_medion_rim_setup, 5260 .init_hook = alc880_medion_rim_automute, 5261 }, 5262#ifdef CONFIG_SND_DEBUG 5263 [ALC880_TEST] = { 5264 .mixers = { alc880_test_mixer }, 5265 .init_verbs = { alc880_test_init_verbs }, 5266 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), 5267 .dac_nids = alc880_test_dac_nids, 5268 .dig_out_nid = ALC880_DIGOUT_NID, 5269 .num_channel_mode = ARRAY_SIZE(alc880_test_modes), 5270 .channel_mode = alc880_test_modes, 5271 .input_mux = &alc880_test_capture_source, 5272 }, 5273#endif 5274}; 5275 5276/* 5277 * Automatic parse of I/O pins from the BIOS configuration 5278 */ 5279 5280enum { 5281 ALC_CTL_WIDGET_VOL, 5282 ALC_CTL_WIDGET_MUTE, 5283 ALC_CTL_BIND_MUTE, 5284}; 5285static const struct snd_kcontrol_new alc880_control_templates[] = { 5286 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 5287 HDA_CODEC_MUTE(NULL, 0, 0, 0), 5288 HDA_BIND_MUTE(NULL, 0, 0, 0), 5289}; 5290 5291static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec) 5292{ 5293 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); 5294 return snd_array_new(&spec->kctls); 5295} 5296 5297/* add dynamic controls */ 5298static int add_control(struct alc_spec *spec, int type, const char *name, 5299 int cidx, unsigned long val) 5300{ 5301 struct snd_kcontrol_new *knew; 5302 5303 knew = alc_kcontrol_new(spec); 5304 if (!knew) 5305 return -ENOMEM; 5306 *knew = alc880_control_templates[type]; 5307 knew->name = kstrdup(name, GFP_KERNEL); 5308 if (!knew->name) 5309 return -ENOMEM; 5310 knew->index = cidx; 5311 if (get_amp_nid_(val)) 5312 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 5313 knew->private_value = val; 5314 return 0; 5315} 5316 5317static int add_control_with_pfx(struct alc_spec *spec, int type, 5318 const char *pfx, const char *dir, 5319 const char *sfx, int cidx, unsigned long val) 5320{ 5321 char name[32]; 5322 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx); 5323 return add_control(spec, type, name, cidx, val); 5324} 5325 5326#define add_pb_vol_ctrl(spec, type, pfx, val) \ 5327 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val) 5328#define add_pb_sw_ctrl(spec, type, pfx, val) \ 5329 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val) 5330#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \ 5331 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val) 5332#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 5333 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 5334 5335#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 5336#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 5337#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 5338#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 5339#define alc880_idx_to_dac(nid) ((nid) + 0x02) 5340#define alc880_dac_to_idx(nid) ((nid) - 0x02) 5341#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 5342#define alc880_idx_to_selector(nid) ((nid) + 0x10) 5343#define ALC880_PIN_CD_NID 0x1c 5344 5345/* fill in the dac_nids table from the parsed pin configuration */ 5346static int alc880_auto_fill_dac_nids(struct alc_spec *spec, 5347 const struct auto_pin_cfg *cfg) 5348{ 5349 hda_nid_t nid; 5350 int assigned[4]; 5351 int i, j; 5352 5353 memset(assigned, 0, sizeof(assigned)); 5354 spec->multiout.dac_nids = spec->private_dac_nids; 5355 5356 /* check the pins hardwired to audio widget */ 5357 for (i = 0; i < cfg->line_outs; i++) { 5358 nid = cfg->line_out_pins[i]; 5359 if (alc880_is_fixed_pin(nid)) { 5360 int idx = alc880_fixed_pin_idx(nid); 5361 spec->private_dac_nids[i] = alc880_idx_to_dac(idx); 5362 assigned[idx] = 1; 5363 } 5364 } 5365 /* left pins can be connect to any audio widget */ 5366 for (i = 0; i < cfg->line_outs; i++) { 5367 nid = cfg->line_out_pins[i]; 5368 if (alc880_is_fixed_pin(nid)) 5369 continue; 5370 /* search for an empty channel */ 5371 for (j = 0; j < cfg->line_outs; j++) { 5372 if (!assigned[j]) { 5373 spec->private_dac_nids[i] = 5374 alc880_idx_to_dac(j); 5375 assigned[j] = 1; 5376 break; 5377 } 5378 } 5379 } 5380 spec->multiout.num_dacs = cfg->line_outs; 5381 return 0; 5382} 5383 5384static const char *alc_get_line_out_pfx(struct alc_spec *spec, 5385 bool can_be_master) 5386{ 5387 struct auto_pin_cfg *cfg = &spec->autocfg; 5388 5389 if (cfg->line_outs == 1 && !spec->multi_ios && 5390 !cfg->hp_outs && !cfg->speaker_outs && can_be_master) 5391 return "Master"; 5392 5393 switch (cfg->line_out_type) { 5394 case AUTO_PIN_SPEAKER_OUT: 5395 if (cfg->line_outs == 1) 5396 return "Speaker"; 5397 break; 5398 case AUTO_PIN_HP_OUT: 5399 return "Headphone"; 5400 default: 5401 if (cfg->line_outs == 1 && !spec->multi_ios) 5402 return "PCM"; 5403 break; 5404 } 5405 return NULL; 5406} 5407 5408/* add playback controls from the parsed DAC table */ 5409static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5410 const struct auto_pin_cfg *cfg) 5411{ 5412 static const char * const chname[4] = { 5413 "Front", "Surround", NULL /*CLFE*/, "Side" 5414 }; 5415 const char *pfx = alc_get_line_out_pfx(spec, false); 5416 hda_nid_t nid; 5417 int i, err, noutputs; 5418 5419 noutputs = cfg->line_outs; 5420 if (spec->multi_ios > 0) 5421 noutputs += spec->multi_ios; 5422 5423 for (i = 0; i < noutputs; i++) { 5424 if (!spec->multiout.dac_nids[i]) 5425 continue; 5426 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5427 if (!pfx && i == 2) { 5428 /* Center/LFE */ 5429 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5430 "Center", 5431 HDA_COMPOSE_AMP_VAL(nid, 1, 0, 5432 HDA_OUTPUT)); 5433 if (err < 0) 5434 return err; 5435 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5436 "LFE", 5437 HDA_COMPOSE_AMP_VAL(nid, 2, 0, 5438 HDA_OUTPUT)); 5439 if (err < 0) 5440 return err; 5441 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5442 "Center", 5443 HDA_COMPOSE_AMP_VAL(nid, 1, 2, 5444 HDA_INPUT)); 5445 if (err < 0) 5446 return err; 5447 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5448 "LFE", 5449 HDA_COMPOSE_AMP_VAL(nid, 2, 2, 5450 HDA_INPUT)); 5451 if (err < 0) 5452 return err; 5453 } else { 5454 const char *name = pfx; 5455 int index = i; 5456 if (!name) { 5457 name = chname[i]; 5458 index = 0; 5459 } 5460 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5461 name, index, 5462 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5463 HDA_OUTPUT)); 5464 if (err < 0) 5465 return err; 5466 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 5467 name, index, 5468 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5469 HDA_INPUT)); 5470 if (err < 0) 5471 return err; 5472 } 5473 } 5474 return 0; 5475} 5476 5477/* add playback controls for speaker and HP outputs */ 5478static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 5479 const char *pfx) 5480{ 5481 hda_nid_t nid; 5482 int err; 5483 5484 if (!pin) 5485 return 0; 5486 5487 if (alc880_is_fixed_pin(pin)) { 5488 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5489 /* specify the DAC as the extra output */ 5490 if (!spec->multiout.hp_nid) 5491 spec->multiout.hp_nid = nid; 5492 else 5493 spec->multiout.extra_out_nid[0] = nid; 5494 /* control HP volume/switch on the output mixer amp */ 5495 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); 5496 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5497 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 5498 if (err < 0) 5499 return err; 5500 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5501 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); 5502 if (err < 0) 5503 return err; 5504 } else if (alc880_is_multi_pin(pin)) { 5505 /* set manual connection */ 5506 /* we have only a switch on HP-out PIN */ 5507 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5508 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 5509 if (err < 0) 5510 return err; 5511 } 5512 return 0; 5513} 5514 5515/* create input playback/capture controls for the given pin */ 5516static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 5517 const char *ctlname, int ctlidx, 5518 int idx, hda_nid_t mix_nid) 5519{ 5520 int err; 5521 5522 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx, 5523 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5524 if (err < 0) 5525 return err; 5526 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx, 5527 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 5528 if (err < 0) 5529 return err; 5530 return 0; 5531} 5532 5533static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid) 5534{ 5535 unsigned int pincap = snd_hda_query_pin_caps(codec, nid); 5536 return (pincap & AC_PINCAP_IN) != 0; 5537} 5538 5539/* create playback/capture controls for input pins */ 5540static int alc_auto_create_input_ctls(struct hda_codec *codec, 5541 const struct auto_pin_cfg *cfg, 5542 hda_nid_t mixer, 5543 hda_nid_t cap1, hda_nid_t cap2) 5544{ 5545 struct alc_spec *spec = codec->spec; 5546 struct hda_input_mux *imux = &spec->private_imux[0]; 5547 int i, err, idx, type_idx = 0; 5548 const char *prev_label = NULL; 5549 5550 for (i = 0; i < cfg->num_inputs; i++) { 5551 hda_nid_t pin; 5552 const char *label; 5553 5554 pin = cfg->inputs[i].pin; 5555 if (!alc_is_input_pin(codec, pin)) 5556 continue; 5557 5558 label = hda_get_autocfg_input_label(codec, cfg, i); 5559 if (prev_label && !strcmp(label, prev_label)) 5560 type_idx++; 5561 else 5562 type_idx = 0; 5563 prev_label = label; 5564 5565 if (mixer) { 5566 idx = get_connection_index(codec, mixer, pin); 5567 if (idx >= 0) { 5568 err = new_analog_input(spec, pin, 5569 label, type_idx, 5570 idx, mixer); 5571 if (err < 0) 5572 return err; 5573 } 5574 } 5575 5576 if (!cap1) 5577 continue; 5578 idx = get_connection_index(codec, cap1, pin); 5579 if (idx < 0 && cap2) 5580 idx = get_connection_index(codec, cap2, pin); 5581 if (idx >= 0) 5582 snd_hda_add_imux_item(imux, label, idx, NULL); 5583 } 5584 return 0; 5585} 5586 5587static int alc880_auto_create_input_ctls(struct hda_codec *codec, 5588 const struct auto_pin_cfg *cfg) 5589{ 5590 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 5591} 5592 5593static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 5594 unsigned int pin_type) 5595{ 5596 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 5597 pin_type); 5598 /* unmute pin */ 5599 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 5600 AMP_OUT_UNMUTE); 5601} 5602 5603static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, 5604 hda_nid_t nid, int pin_type, 5605 int dac_idx) 5606{ 5607 alc_set_pin_output(codec, nid, pin_type); 5608 /* need the manual connection? */ 5609 if (alc880_is_multi_pin(nid)) { 5610 struct alc_spec *spec = codec->spec; 5611 int idx = alc880_multi_pin_idx(nid); 5612 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 5613 AC_VERB_SET_CONNECT_SEL, 5614 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 5615 } 5616} 5617 5618static int get_pin_type(int line_out_type) 5619{ 5620 if (line_out_type == AUTO_PIN_HP_OUT) 5621 return PIN_HP; 5622 else 5623 return PIN_OUT; 5624} 5625 5626static void alc880_auto_init_multi_out(struct hda_codec *codec) 5627{ 5628 struct alc_spec *spec = codec->spec; 5629 int i; 5630 5631 for (i = 0; i < spec->autocfg.line_outs; i++) { 5632 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 5633 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5634 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 5635 } 5636} 5637 5638static void alc880_auto_init_extra_out(struct hda_codec *codec) 5639{ 5640 struct alc_spec *spec = codec->spec; 5641 hda_nid_t pin; 5642 5643 pin = spec->autocfg.speaker_pins[0]; 5644 if (pin) /* connect to front */ 5645 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 5646 pin = spec->autocfg.hp_pins[0]; 5647 if (pin) /* connect to front */ 5648 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 5649} 5650 5651static void alc880_auto_init_analog_input(struct hda_codec *codec) 5652{ 5653 struct alc_spec *spec = codec->spec; 5654 struct auto_pin_cfg *cfg = &spec->autocfg; 5655 int i; 5656 5657 for (i = 0; i < cfg->num_inputs; i++) { 5658 hda_nid_t nid = cfg->inputs[i].pin; 5659 if (alc_is_input_pin(codec, nid)) { 5660 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 5661 if (nid != ALC880_PIN_CD_NID && 5662 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 5663 snd_hda_codec_write(codec, nid, 0, 5664 AC_VERB_SET_AMP_GAIN_MUTE, 5665 AMP_OUT_MUTE); 5666 } 5667 } 5668} 5669 5670static void alc880_auto_init_input_src(struct hda_codec *codec) 5671{ 5672 struct alc_spec *spec = codec->spec; 5673 int c; 5674 5675 for (c = 0; c < spec->num_adc_nids; c++) { 5676 unsigned int mux_idx; 5677 const struct hda_input_mux *imux; 5678 mux_idx = c >= spec->num_mux_defs ? 0 : c; 5679 imux = &spec->input_mux[mux_idx]; 5680 if (!imux->num_items && mux_idx > 0) 5681 imux = &spec->input_mux[0]; 5682 if (imux) 5683 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 5684 AC_VERB_SET_CONNECT_SEL, 5685 imux->items[0].index); 5686 } 5687} 5688 5689static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); 5690 5691/* parse the BIOS configuration and set up the alc_spec */ 5692/* return 1 if successful, 0 if the proper config is not found, 5693 * or a negative error code 5694 */ 5695static int alc880_parse_auto_config(struct hda_codec *codec) 5696{ 5697 struct alc_spec *spec = codec->spec; 5698 int err; 5699 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; 5700 5701 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5702 alc880_ignore); 5703 if (err < 0) 5704 return err; 5705 if (!spec->autocfg.line_outs) 5706 return 0; /* can't find valid BIOS pin config */ 5707 5708 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 5709 if (err < 0) 5710 return err; 5711 err = alc_auto_add_multi_channel_mode(codec); 5712 if (err < 0) 5713 return err; 5714 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 5715 if (err < 0) 5716 return err; 5717 err = alc880_auto_create_extra_out(spec, 5718 spec->autocfg.speaker_pins[0], 5719 "Speaker"); 5720 if (err < 0) 5721 return err; 5722 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 5723 "Headphone"); 5724 if (err < 0) 5725 return err; 5726 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 5727 if (err < 0) 5728 return err; 5729 5730 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 5731 5732 alc_auto_parse_digital(codec); 5733 5734 if (spec->kctls.list) 5735 add_mixer(spec, spec->kctls.list); 5736 5737 add_verb(spec, alc880_volume_init_verbs); 5738 5739 spec->num_mux_defs = 1; 5740 spec->input_mux = &spec->private_imux[0]; 5741 5742 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5743 5744 return 1; 5745} 5746 5747/* additional initialization for auto-configuration model */ 5748static void alc880_auto_init(struct hda_codec *codec) 5749{ 5750 struct alc_spec *spec = codec->spec; 5751 alc880_auto_init_multi_out(codec); 5752 alc880_auto_init_extra_out(codec); 5753 alc880_auto_init_analog_input(codec); 5754 alc880_auto_init_input_src(codec); 5755 alc_auto_init_digital(codec); 5756 if (spec->unsol_event) 5757 alc_inithook(codec); 5758} 5759 5760/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 5761 * one of two digital mic pins, e.g. on ALC272 5762 */ 5763static void fixup_automic_adc(struct hda_codec *codec) 5764{ 5765 struct alc_spec *spec = codec->spec; 5766 int i; 5767 5768 for (i = 0; i < spec->num_adc_nids; i++) { 5769 hda_nid_t cap = spec->capsrc_nids ? 5770 spec->capsrc_nids[i] : spec->adc_nids[i]; 5771 int iidx, eidx; 5772 5773 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 5774 if (iidx < 0) 5775 continue; 5776 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 5777 if (eidx < 0) 5778 continue; 5779 spec->int_mic.mux_idx = iidx; 5780 spec->ext_mic.mux_idx = eidx; 5781 if (spec->capsrc_nids) 5782 spec->capsrc_nids += i; 5783 spec->adc_nids += i; 5784 spec->num_adc_nids = 1; 5785 /* optional dock-mic */ 5786 eidx = get_connection_index(codec, cap, spec->dock_mic.pin); 5787 if (eidx < 0) 5788 spec->dock_mic.pin = 0; 5789 else 5790 spec->dock_mic.mux_idx = eidx; 5791 return; 5792 } 5793 snd_printd(KERN_INFO "hda_codec: %s: " 5794 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 5795 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 5796 spec->auto_mic = 0; /* disable auto-mic to be sure */ 5797} 5798 5799/* select or unmute the given capsrc route */ 5800static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap, 5801 int idx) 5802{ 5803 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 5804 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 5805 HDA_AMP_MUTE, 0); 5806 } else { 5807 snd_hda_codec_write_cache(codec, cap, 0, 5808 AC_VERB_SET_CONNECT_SEL, idx); 5809 } 5810} 5811 5812/* set the default connection to that pin */ 5813static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) 5814{ 5815 struct alc_spec *spec = codec->spec; 5816 int i; 5817 5818 if (!pin) 5819 return 0; 5820 for (i = 0; i < spec->num_adc_nids; i++) { 5821 hda_nid_t cap = spec->capsrc_nids ? 5822 spec->capsrc_nids[i] : spec->adc_nids[i]; 5823 int idx; 5824 5825 idx = get_connection_index(codec, cap, pin); 5826 if (idx < 0) 5827 continue; 5828 select_or_unmute_capsrc(codec, cap, idx); 5829 return i; /* return the found index */ 5830 } 5831 return -1; /* not found */ 5832} 5833 5834/* choose the ADC/MUX containing the input pin and initialize the setup */ 5835static void fixup_single_adc(struct hda_codec *codec) 5836{ 5837 struct alc_spec *spec = codec->spec; 5838 struct auto_pin_cfg *cfg = &spec->autocfg; 5839 int i; 5840 5841 /* search for the input pin; there must be only one */ 5842 if (cfg->num_inputs != 1) 5843 return; 5844 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin); 5845 if (i >= 0) { 5846 /* use only this ADC */ 5847 if (spec->capsrc_nids) 5848 spec->capsrc_nids += i; 5849 spec->adc_nids += i; 5850 spec->num_adc_nids = 1; 5851 spec->single_input_src = 1; 5852 } 5853} 5854 5855/* initialize dual adcs */ 5856static void fixup_dual_adc_switch(struct hda_codec *codec) 5857{ 5858 struct alc_spec *spec = codec->spec; 5859 init_capsrc_for_pin(codec, spec->ext_mic.pin); 5860 init_capsrc_for_pin(codec, spec->dock_mic.pin); 5861 init_capsrc_for_pin(codec, spec->int_mic.pin); 5862} 5863 5864/* initialize some special cases for input sources */ 5865static void alc_init_special_input_src(struct hda_codec *codec) 5866{ 5867 struct alc_spec *spec = codec->spec; 5868 if (spec->dual_adc_switch) 5869 fixup_dual_adc_switch(codec); 5870 else if (spec->single_input_src) 5871 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); 5872} 5873 5874static void set_capture_mixer(struct hda_codec *codec) 5875{ 5876 struct alc_spec *spec = codec->spec; 5877 static const struct snd_kcontrol_new *caps[2][3] = { 5878 { alc_capture_mixer_nosrc1, 5879 alc_capture_mixer_nosrc2, 5880 alc_capture_mixer_nosrc3 }, 5881 { alc_capture_mixer1, 5882 alc_capture_mixer2, 5883 alc_capture_mixer3 }, 5884 }; 5885 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 5886 int mux = 0; 5887 int num_adcs = spec->num_adc_nids; 5888 if (spec->dual_adc_switch) 5889 num_adcs = 1; 5890 else if (spec->auto_mic) 5891 fixup_automic_adc(codec); 5892 else if (spec->input_mux) { 5893 if (spec->input_mux->num_items > 1) 5894 mux = 1; 5895 else if (spec->input_mux->num_items == 1) 5896 fixup_single_adc(codec); 5897 } 5898 spec->cap_mixer = caps[mux][num_adcs - 1]; 5899 } 5900} 5901 5902/* fill adc_nids (and capsrc_nids) containing all active input pins */ 5903static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, 5904 int num_nids) 5905{ 5906 struct alc_spec *spec = codec->spec; 5907 struct auto_pin_cfg *cfg = &spec->autocfg; 5908 int n; 5909 hda_nid_t fallback_adc = 0, fallback_cap = 0; 5910 5911 for (n = 0; n < num_nids; n++) { 5912 hda_nid_t adc, cap; 5913 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 5914 int nconns, i, j; 5915 5916 adc = nids[n]; 5917 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) 5918 continue; 5919 cap = adc; 5920 nconns = snd_hda_get_connections(codec, cap, conn, 5921 ARRAY_SIZE(conn)); 5922 if (nconns == 1) { 5923 cap = conn[0]; 5924 nconns = snd_hda_get_connections(codec, cap, conn, 5925 ARRAY_SIZE(conn)); 5926 } 5927 if (nconns <= 0) 5928 continue; 5929 if (!fallback_adc) { 5930 fallback_adc = adc; 5931 fallback_cap = cap; 5932 } 5933 for (i = 0; i < cfg->num_inputs; i++) { 5934 hda_nid_t nid = cfg->inputs[i].pin; 5935 for (j = 0; j < nconns; j++) { 5936 if (conn[j] == nid) 5937 break; 5938 } 5939 if (j >= nconns) 5940 break; 5941 } 5942 if (i >= cfg->num_inputs) { 5943 int num_adcs = spec->num_adc_nids; 5944 spec->private_adc_nids[num_adcs] = adc; 5945 spec->private_capsrc_nids[num_adcs] = cap; 5946 spec->num_adc_nids++; 5947 spec->adc_nids = spec->private_adc_nids; 5948 if (adc != cap) 5949 spec->capsrc_nids = spec->private_capsrc_nids; 5950 } 5951 } 5952 if (!spec->num_adc_nids) { 5953 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" 5954 " using fallback 0x%x\n", 5955 codec->chip_name, fallback_adc); 5956 spec->private_adc_nids[0] = fallback_adc; 5957 spec->adc_nids = spec->private_adc_nids; 5958 if (fallback_adc != fallback_cap) { 5959 spec->private_capsrc_nids[0] = fallback_cap; 5960 spec->capsrc_nids = spec->private_adc_nids; 5961 } 5962 } 5963} 5964 5965#ifdef CONFIG_SND_HDA_INPUT_BEEP 5966#define set_beep_amp(spec, nid, idx, dir) \ 5967 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 5968 5969static const struct snd_pci_quirk beep_white_list[] = { 5970 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), 5971 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 5972 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 5973 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 5974 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 5975 {} 5976}; 5977 5978static inline int has_cdefine_beep(struct hda_codec *codec) 5979{ 5980 struct alc_spec *spec = codec->spec; 5981 const struct snd_pci_quirk *q; 5982 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); 5983 if (q) 5984 return q->value; 5985 return spec->cdefine.enable_pcbeep; 5986} 5987#else 5988#define set_beep_amp(spec, nid, idx, dir) /* NOP */ 5989#define has_cdefine_beep(codec) 0 5990#endif 5991 5992/* 5993 * OK, here we have finally the patch for ALC880 5994 */ 5995 5996static int patch_alc880(struct hda_codec *codec) 5997{ 5998 struct alc_spec *spec; 5999 int board_config; 6000 int err; 6001 6002 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 6003 if (spec == NULL) 6004 return -ENOMEM; 6005 6006 codec->spec = spec; 6007 6008 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 6009 alc880_models, 6010 alc880_cfg_tbl); 6011 if (board_config < 0) { 6012 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6013 codec->chip_name); 6014 board_config = ALC880_AUTO; 6015 } 6016 6017 if (board_config == ALC880_AUTO) { 6018 /* automatic parse from the BIOS config */ 6019 err = alc880_parse_auto_config(codec); 6020 if (err < 0) { 6021 alc_free(codec); 6022 return err; 6023 } else if (!err) { 6024 printk(KERN_INFO 6025 "hda_codec: Cannot set up configuration " 6026 "from BIOS. Using 3-stack mode...\n"); 6027 board_config = ALC880_3ST; 6028 } 6029 } 6030 6031 err = snd_hda_attach_beep_device(codec, 0x1); 6032 if (err < 0) { 6033 alc_free(codec); 6034 return err; 6035 } 6036 6037 if (board_config != ALC880_AUTO) 6038 setup_preset(codec, &alc880_presets[board_config]); 6039 6040 spec->stream_analog_playback = &alc880_pcm_analog_playback; 6041 spec->stream_analog_capture = &alc880_pcm_analog_capture; 6042 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 6043 6044 spec->stream_digital_playback = &alc880_pcm_digital_playback; 6045 spec->stream_digital_capture = &alc880_pcm_digital_capture; 6046 6047 if (!spec->adc_nids && spec->input_mux) { 6048 /* check whether NID 0x07 is valid */ 6049 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 6050 /* get type */ 6051 wcap = get_wcaps_type(wcap); 6052 if (wcap != AC_WID_AUD_IN) { 6053 spec->adc_nids = alc880_adc_nids_alt; 6054 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 6055 } else { 6056 spec->adc_nids = alc880_adc_nids; 6057 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 6058 } 6059 } 6060 set_capture_mixer(codec); 6061 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 6062 6063 spec->vmaster_nid = 0x0c; 6064 6065 codec->patch_ops = alc_patch_ops; 6066 if (board_config == ALC880_AUTO) 6067 spec->init_hook = alc880_auto_init; 6068#ifdef CONFIG_SND_HDA_POWER_SAVE 6069 if (!spec->loopback.amplist) 6070 spec->loopback.amplist = alc880_loopbacks; 6071#endif 6072 6073 return 0; 6074} 6075 6076 6077/* 6078 * ALC260 support 6079 */ 6080 6081static const hda_nid_t alc260_dac_nids[1] = { 6082 /* front */ 6083 0x02, 6084}; 6085 6086static const hda_nid_t alc260_adc_nids[1] = { 6087 /* ADC0 */ 6088 0x04, 6089}; 6090 6091static const hda_nid_t alc260_adc_nids_alt[1] = { 6092 /* ADC1 */ 6093 0x05, 6094}; 6095 6096/* NIDs used when simultaneous access to both ADCs makes sense. Note that 6097 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 6098 */ 6099static const hda_nid_t alc260_dual_adc_nids[2] = { 6100 /* ADC0, ADC1 */ 6101 0x04, 0x05 6102}; 6103 6104#define ALC260_DIGOUT_NID 0x03 6105#define ALC260_DIGIN_NID 0x06 6106 6107static const struct hda_input_mux alc260_capture_source = { 6108 .num_items = 4, 6109 .items = { 6110 { "Mic", 0x0 }, 6111 { "Front Mic", 0x1 }, 6112 { "Line", 0x2 }, 6113 { "CD", 0x4 }, 6114 }, 6115}; 6116 6117/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, 6118 * headphone jack and the internal CD lines since these are the only pins at 6119 * which audio can appear. For flexibility, also allow the option of 6120 * recording the mixer output on the second ADC (ADC0 doesn't have a 6121 * connection to the mixer output). 6122 */ 6123static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = { 6124 { 6125 .num_items = 3, 6126 .items = { 6127 { "Mic/Line", 0x0 }, 6128 { "CD", 0x4 }, 6129 { "Headphone", 0x2 }, 6130 }, 6131 }, 6132 { 6133 .num_items = 4, 6134 .items = { 6135 { "Mic/Line", 0x0 }, 6136 { "CD", 0x4 }, 6137 { "Headphone", 0x2 }, 6138 { "Mixer", 0x5 }, 6139 }, 6140 }, 6141 6142}; 6143 6144/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to 6145 * the Fujitsu S702x, but jacks are marked differently. 6146 */ 6147static const struct hda_input_mux alc260_acer_capture_sources[2] = { 6148 { 6149 .num_items = 4, 6150 .items = { 6151 { "Mic", 0x0 }, 6152 { "Line", 0x2 }, 6153 { "CD", 0x4 }, 6154 { "Headphone", 0x5 }, 6155 }, 6156 }, 6157 { 6158 .num_items = 5, 6159 .items = { 6160 { "Mic", 0x0 }, 6161 { "Line", 0x2 }, 6162 { "CD", 0x4 }, 6163 { "Headphone", 0x6 }, 6164 { "Mixer", 0x5 }, 6165 }, 6166 }, 6167}; 6168 6169/* Maxdata Favorit 100XS */ 6170static const struct hda_input_mux alc260_favorit100_capture_sources[2] = { 6171 { 6172 .num_items = 2, 6173 .items = { 6174 { "Line/Mic", 0x0 }, 6175 { "CD", 0x4 }, 6176 }, 6177 }, 6178 { 6179 .num_items = 3, 6180 .items = { 6181 { "Line/Mic", 0x0 }, 6182 { "CD", 0x4 }, 6183 { "Mixer", 0x5 }, 6184 }, 6185 }, 6186}; 6187 6188/* 6189 * This is just place-holder, so there's something for alc_build_pcms to look 6190 * at when it calculates the maximum number of channels. ALC260 has no mixer 6191 * element which allows changing the channel mode, so the verb list is 6192 * never used. 6193 */ 6194static const struct hda_channel_mode alc260_modes[1] = { 6195 { 2, NULL }, 6196}; 6197 6198 6199/* Mixer combinations 6200 * 6201 * basic: base_output + input + pc_beep + capture 6202 * HP: base_output + input + capture_alt 6203 * HP_3013: hp_3013 + input + capture 6204 * fujitsu: fujitsu + capture 6205 * acer: acer + capture 6206 */ 6207 6208static const struct snd_kcontrol_new alc260_base_output_mixer[] = { 6209 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6210 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6211 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6212 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 6213 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6214 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6215 { } /* end */ 6216}; 6217 6218static const struct snd_kcontrol_new alc260_input_mixer[] = { 6219 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6220 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6221 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6222 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6224 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6225 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), 6226 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), 6227 { } /* end */ 6228}; 6229 6230/* update HP, line and mono out pins according to the master switch */ 6231static void alc260_hp_master_update(struct hda_codec *codec) 6232{ 6233 update_speakers(codec); 6234} 6235 6236static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 6237 struct snd_ctl_elem_value *ucontrol) 6238{ 6239 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6240 struct alc_spec *spec = codec->spec; 6241 *ucontrol->value.integer.value = !spec->master_mute; 6242 return 0; 6243} 6244 6245static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 6246 struct snd_ctl_elem_value *ucontrol) 6247{ 6248 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 6249 struct alc_spec *spec = codec->spec; 6250 int val = !*ucontrol->value.integer.value; 6251 6252 if (val == spec->master_mute) 6253 return 0; 6254 spec->master_mute = val; 6255 alc260_hp_master_update(codec); 6256 return 1; 6257} 6258 6259static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { 6260 { 6261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6262 .name = "Master Playback Switch", 6263 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 6264 .info = snd_ctl_boolean_mono_info, 6265 .get = alc260_hp_master_sw_get, 6266 .put = alc260_hp_master_sw_put, 6267 }, 6268 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6269 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), 6270 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6271 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), 6272 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 6273 HDA_OUTPUT), 6274 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), 6275 { } /* end */ 6276}; 6277 6278static const struct hda_verb alc260_hp_unsol_verbs[] = { 6279 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6280 {}, 6281}; 6282 6283static void alc260_hp_setup(struct hda_codec *codec) 6284{ 6285 struct alc_spec *spec = codec->spec; 6286 6287 spec->autocfg.hp_pins[0] = 0x0f; 6288 spec->autocfg.speaker_pins[0] = 0x10; 6289 spec->autocfg.speaker_pins[1] = 0x11; 6290 spec->automute = 1; 6291 spec->automute_mode = ALC_AUTOMUTE_PIN; 6292} 6293 6294static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = { 6295 { 6296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 6297 .name = "Master Playback Switch", 6298 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, 6299 .info = snd_ctl_boolean_mono_info, 6300 .get = alc260_hp_master_sw_get, 6301 .put = alc260_hp_master_sw_put, 6302 }, 6303 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6304 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6305 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), 6306 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), 6307 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 6309 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 6310 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), 6311 { } /* end */ 6312}; 6313 6314static void alc260_hp_3013_setup(struct hda_codec *codec) 6315{ 6316 struct alc_spec *spec = codec->spec; 6317 6318 spec->autocfg.hp_pins[0] = 0x15; 6319 spec->autocfg.speaker_pins[0] = 0x10; 6320 spec->autocfg.speaker_pins[1] = 0x11; 6321 spec->automute = 1; 6322 spec->automute_mode = ALC_AUTOMUTE_PIN; 6323} 6324 6325static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = { 6326 .ops = &snd_hda_bind_vol, 6327 .values = { 6328 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), 6329 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), 6330 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), 6331 0 6332 }, 6333}; 6334 6335static const struct hda_bind_ctls alc260_dc7600_bind_switch = { 6336 .ops = &snd_hda_bind_sw, 6337 .values = { 6338 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), 6339 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 6340 0 6341 }, 6342}; 6343 6344static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { 6345 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), 6346 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), 6347 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), 6348 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), 6349 { } /* end */ 6350}; 6351 6352static const struct hda_verb alc260_hp_3013_unsol_verbs[] = { 6353 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6354 {}, 6355}; 6356 6357static void alc260_hp_3012_setup(struct hda_codec *codec) 6358{ 6359 struct alc_spec *spec = codec->spec; 6360 6361 spec->autocfg.hp_pins[0] = 0x10; 6362 spec->autocfg.speaker_pins[0] = 0x0f; 6363 spec->autocfg.speaker_pins[1] = 0x11; 6364 spec->autocfg.speaker_pins[2] = 0x15; 6365 spec->automute = 1; 6366 spec->automute_mode = ALC_AUTOMUTE_PIN; 6367} 6368 6369/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 6370 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 6371 */ 6372static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 6373 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6374 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 6375 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6376 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6377 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6378 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), 6379 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), 6380 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), 6381 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), 6382 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), 6383 { } /* end */ 6384}; 6385 6386/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current 6387 * versions of the ALC260 don't act on requests to enable mic bias from NID 6388 * 0x0f (used to drive the headphone jack in these laptops). The ALC260 6389 * datasheet doesn't mention this restriction. At this stage it's not clear 6390 * whether this behaviour is intentional or is a hardware bug in chip 6391 * revisions available in early 2006. Therefore for now allow the 6392 * "Headphone Jack Mode" control to span all choices, but if it turns out 6393 * that the lack of mic bias for this NID is intentional we could change the 6394 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 6395 * 6396 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 6397 * don't appear to make the mic bias available from the "line" jack, even 6398 * though the NID used for this jack (0x14) can supply it. The theory is 6399 * that perhaps Acer have included blocking capacitors between the ALC260 6400 * and the output jack. If this turns out to be the case for all such 6401 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 6402 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 6403 * 6404 * The C20x Tablet series have a mono internal speaker which is controlled 6405 * via the chip's Mono sum widget and pin complex, so include the necessary 6406 * controls for such models. On models without a "mono speaker" the control 6407 * won't do anything. 6408 */ 6409static const struct snd_kcontrol_new alc260_acer_mixer[] = { 6410 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6411 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6412 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6413 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, 6414 HDA_OUTPUT), 6415 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, 6416 HDA_INPUT), 6417 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6418 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6420 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6421 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6422 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6423 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6424 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6425 { } /* end */ 6426}; 6427 6428/* Maxdata Favorit 100XS: one output and one input (0x12) jack 6429 */ 6430static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { 6431 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6432 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 6433 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 6434 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6435 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6436 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6437 { } /* end */ 6438}; 6439 6440/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, 6441 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. 6442 */ 6443static const struct snd_kcontrol_new alc260_will_mixer[] = { 6444 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6445 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6447 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6448 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6449 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6450 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6451 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6452 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 6453 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 6454 { } /* end */ 6455}; 6456 6457/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, 6458 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. 6459 */ 6460static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { 6461 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 6462 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), 6463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 6464 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), 6465 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), 6466 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), 6467 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), 6468 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), 6469 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), 6470 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 6471 { } /* end */ 6472}; 6473 6474/* 6475 * initialization verbs 6476 */ 6477static const struct hda_verb alc260_init_verbs[] = { 6478 /* Line In pin widget for input */ 6479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6480 /* CD pin widget for input */ 6481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6482 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6483 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6484 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6485 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6486 /* LINE-2 is used for line-out in rear */ 6487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6488 /* select line-out */ 6489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 6490 /* LINE-OUT pin */ 6491 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6492 /* enable HP */ 6493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6494 /* enable Mono */ 6495 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6496 /* mute capture amp left and right */ 6497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6498 /* set connection select to line in (default select for this ADC) */ 6499 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6500 /* mute capture amp left and right */ 6501 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6502 /* set connection select to line in (default select for this ADC) */ 6503 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, 6504 /* set vol=0 Line-Out mixer amp left and right */ 6505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6506 /* unmute pin widget amp left and right (no gain on this amp) */ 6507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6508 /* set vol=0 HP mixer amp left and right */ 6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6510 /* unmute pin widget amp left and right (no gain on this amp) */ 6511 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6512 /* set vol=0 Mono mixer amp left and right */ 6513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6514 /* unmute pin widget amp left and right (no gain on this amp) */ 6515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6516 /* unmute LINE-2 out pin */ 6517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6518 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6519 * Line In 2 = 0x03 6520 */ 6521 /* mute analog inputs */ 6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6527 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6528 /* mute Front out path */ 6529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6531 /* mute Headphone out path */ 6532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6534 /* mute Mono out path */ 6535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6537 { } 6538}; 6539 6540#if 0 /* should be identical with alc260_init_verbs? */ 6541static const struct hda_verb alc260_hp_init_verbs[] = { 6542 /* Headphone and output */ 6543 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6544 /* mono output */ 6545 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6546 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6547 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6548 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6549 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6550 /* Line In pin widget for input */ 6551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6552 /* Line-2 pin widget for output */ 6553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6554 /* CD pin widget for input */ 6555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6556 /* unmute amp left and right */ 6557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6558 /* set connection select to line in (default select for this ADC) */ 6559 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6560 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6562 /* mute pin widget amp left and right (no gain on this amp) */ 6563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6564 /* unmute HP mixer amp left and right (volume = 0) */ 6565 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6566 /* mute pin widget amp left and right (no gain on this amp) */ 6567 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6568 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6569 * Line In 2 = 0x03 6570 */ 6571 /* mute analog inputs */ 6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6577 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6578 /* Unmute Front out path */ 6579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6581 /* Unmute Headphone out path */ 6582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6584 /* Unmute Mono out path */ 6585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6587 { } 6588}; 6589#endif 6590 6591static const struct hda_verb alc260_hp_3013_init_verbs[] = { 6592 /* Line out and output */ 6593 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6594 /* mono output */ 6595 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 6596 /* Mic1 (rear panel) pin widget for input and vref at 80% */ 6597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6598 /* Mic2 (front panel) pin widget for input and vref at 80% */ 6599 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 6600 /* Line In pin widget for input */ 6601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6602 /* Headphone pin widget for output */ 6603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 6604 /* CD pin widget for input */ 6605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 6606 /* unmute amp left and right */ 6607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, 6608 /* set connection select to line in (default select for this ADC) */ 6609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, 6610 /* unmute Line-Out mixer amp left and right (volume = 0) */ 6611 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6612 /* mute pin widget amp left and right (no gain on this amp) */ 6613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6614 /* unmute HP mixer amp left and right (volume = 0) */ 6615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 6616 /* mute pin widget amp left and right (no gain on this amp) */ 6617 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 6618 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & 6619 * Line In 2 = 0x03 6620 */ 6621 /* mute analog inputs */ 6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 6625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 6626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 6627 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ 6628 /* Unmute Front out path */ 6629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6631 /* Unmute Headphone out path */ 6632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6634 /* Unmute Mono out path */ 6635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 6636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 6637 { } 6638}; 6639 6640/* Initialisation sequence for ALC260 as configured in Fujitsu S702x 6641 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD 6642 * audio = 0x16, internal speaker = 0x10. 6643 */ 6644static const struct hda_verb alc260_fujitsu_init_verbs[] = { 6645 /* Disable all GPIOs */ 6646 {0x01, AC_VERB_SET_GPIO_MASK, 0}, 6647 /* Internal speaker is connected to headphone pin */ 6648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6649 /* Headphone/Line-out jack connects to Line1 pin; make it an output */ 6650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6651 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ 6652 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6653 /* Ensure all other unused pins are disabled and muted. */ 6654 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6656 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6657 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6662 6663 /* Disable digital (SPDIF) pins */ 6664 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6665 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6666 6667 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 6668 * when acting as an output. 6669 */ 6670 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6671 6672 /* Start with output sum widgets muted and their output gains at min */ 6673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6680 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6681 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6682 6683 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ 6684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6685 /* Unmute Line1 pin widget output buffer since it starts as an output. 6686 * If the pin mode is changed by the user the pin mode control will 6687 * take care of enabling the pin's input/output buffers as needed. 6688 * Therefore there's no need to enable the input buffer at this 6689 * stage. 6690 */ 6691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6692 /* Unmute input buffer of pin widget used for Line-in (no equiv 6693 * mixer ctrl) 6694 */ 6695 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6696 6697 /* Mute capture amp left and right */ 6698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6699 /* Set ADC connection select to match default mixer setting - line 6700 * in (on mic1 pin) 6701 */ 6702 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6703 6704 /* Do the same for the second ADC: mute capture input amp and 6705 * set ADC connection to line in (on mic1 pin) 6706 */ 6707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6708 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6709 6710 /* Mute all inputs to mixer widget (even unconnected ones) */ 6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6719 6720 { } 6721}; 6722 6723/* Initialisation sequence for ALC260 as configured in Acer TravelMate and 6724 * similar laptops (adapted from Fujitsu init verbs). 6725 */ 6726static const struct hda_verb alc260_acer_init_verbs[] = { 6727 /* On TravelMate laptops, GPIO 0 enables the internal speaker and 6728 * the headphone jack. Turn this on and rely on the standard mute 6729 * methods whenever the user wants to turn these outputs off. 6730 */ 6731 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6732 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6733 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6734 /* Internal speaker/Headphone jack is connected to Line-out pin */ 6735 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6736 /* Internal microphone/Mic jack is connected to Mic1 pin */ 6737 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6738 /* Line In jack is connected to Line1 pin */ 6739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 6740 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ 6741 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6742 /* Ensure all other unused pins are disabled and muted. */ 6743 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6744 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6745 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6746 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6749 /* Disable digital (SPDIF) pins */ 6750 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6751 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6752 6753 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6754 * bus when acting as outputs. 6755 */ 6756 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6757 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6758 6759 /* Start with output sum widgets muted and their output gains at min */ 6760 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6762 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6763 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6764 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6765 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6766 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6767 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6768 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6769 6770 /* Unmute Line-out pin widget amp left and right 6771 * (no equiv mixer ctrl) 6772 */ 6773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6774 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ 6775 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6776 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6777 * inputs. If the pin mode is changed by the user the pin mode control 6778 * will take care of enabling the pin's input/output buffers as needed. 6779 * Therefore there's no need to enable the input buffer at this 6780 * stage. 6781 */ 6782 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6784 6785 /* Mute capture amp left and right */ 6786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6787 /* Set ADC connection select to match default mixer setting - mic 6788 * (on mic1 pin) 6789 */ 6790 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6791 6792 /* Do similar with the second ADC: mute capture input amp and 6793 * set ADC connection to mic to match ALSA's default state. 6794 */ 6795 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6796 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6797 6798 /* Mute all inputs to mixer widget (even unconnected ones) */ 6799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6802 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6805 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6807 6808 { } 6809}; 6810 6811/* Initialisation sequence for Maxdata Favorit 100XS 6812 * (adapted from Acer init verbs). 6813 */ 6814static const struct hda_verb alc260_favorit100_init_verbs[] = { 6815 /* GPIO 0 enables the output jack. 6816 * Turn this on and rely on the standard mute 6817 * methods whenever the user wants to turn these outputs off. 6818 */ 6819 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6820 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6821 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 6822 /* Line/Mic input jack is connected to Mic1 pin */ 6823 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 6824 /* Ensure all other unused pins are disabled and muted. */ 6825 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6826 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6827 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6828 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6829 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6830 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6831 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6832 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 6834 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6835 /* Disable digital (SPDIF) pins */ 6836 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6837 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 6838 6839 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 6840 * bus when acting as outputs. 6841 */ 6842 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 6843 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 6844 6845 /* Start with output sum widgets muted and their output gains at min */ 6846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6847 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6848 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6849 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6850 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6851 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6852 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6853 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 6854 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 6855 6856 /* Unmute Line-out pin widget amp left and right 6857 * (no equiv mixer ctrl) 6858 */ 6859 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6860 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 6861 * inputs. If the pin mode is changed by the user the pin mode control 6862 * will take care of enabling the pin's input/output buffers as needed. 6863 * Therefore there's no need to enable the input buffer at this 6864 * stage. 6865 */ 6866 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 6867 6868 /* Mute capture amp left and right */ 6869 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6870 /* Set ADC connection select to match default mixer setting - mic 6871 * (on mic1 pin) 6872 */ 6873 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 6874 6875 /* Do similar with the second ADC: mute capture input amp and 6876 * set ADC connection to mic to match ALSA's default state. 6877 */ 6878 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 6879 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 6880 6881 /* Mute all inputs to mixer widget (even unconnected ones) */ 6882 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 6883 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 6884 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 6885 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 6886 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 6887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 6888 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 6889 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 6890 6891 { } 6892}; 6893 6894static const struct hda_verb alc260_will_verbs[] = { 6895 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6896 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, 6897 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 6898 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6899 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6900 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, 6901 {} 6902}; 6903 6904static const struct hda_verb alc260_replacer_672v_verbs[] = { 6905 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 6906 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, 6907 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, 6908 6909 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 6910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 6911 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 6912 6913 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6914 {} 6915}; 6916 6917/* toggle speaker-output according to the hp-jack state */ 6918static void alc260_replacer_672v_automute(struct hda_codec *codec) 6919{ 6920 unsigned int present; 6921 6922 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ 6923 present = snd_hda_jack_detect(codec, 0x0f); 6924 if (present) { 6925 snd_hda_codec_write_cache(codec, 0x01, 0, 6926 AC_VERB_SET_GPIO_DATA, 1); 6927 snd_hda_codec_write_cache(codec, 0x0f, 0, 6928 AC_VERB_SET_PIN_WIDGET_CONTROL, 6929 PIN_HP); 6930 } else { 6931 snd_hda_codec_write_cache(codec, 0x01, 0, 6932 AC_VERB_SET_GPIO_DATA, 0); 6933 snd_hda_codec_write_cache(codec, 0x0f, 0, 6934 AC_VERB_SET_PIN_WIDGET_CONTROL, 6935 PIN_OUT); 6936 } 6937} 6938 6939static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, 6940 unsigned int res) 6941{ 6942 if ((res >> 26) == ALC880_HP_EVENT) 6943 alc260_replacer_672v_automute(codec); 6944} 6945 6946static const struct hda_verb alc260_hp_dc7600_verbs[] = { 6947 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 6948 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 6949 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6950 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 6951 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6952 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 6953 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 6954 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6955 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6956 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 6957 {} 6958}; 6959 6960/* Test configuration for debugging, modelled after the ALC880 test 6961 * configuration. 6962 */ 6963#ifdef CONFIG_SND_DEBUG 6964static const hda_nid_t alc260_test_dac_nids[1] = { 6965 0x02, 6966}; 6967static const hda_nid_t alc260_test_adc_nids[2] = { 6968 0x04, 0x05, 6969}; 6970/* For testing the ALC260, each input MUX needs its own definition since 6971 * the signal assignments are different. This assumes that the first ADC 6972 * is NID 0x04. 6973 */ 6974static const struct hda_input_mux alc260_test_capture_sources[2] = { 6975 { 6976 .num_items = 7, 6977 .items = { 6978 { "MIC1 pin", 0x0 }, 6979 { "MIC2 pin", 0x1 }, 6980 { "LINE1 pin", 0x2 }, 6981 { "LINE2 pin", 0x3 }, 6982 { "CD pin", 0x4 }, 6983 { "LINE-OUT pin", 0x5 }, 6984 { "HP-OUT pin", 0x6 }, 6985 }, 6986 }, 6987 { 6988 .num_items = 8, 6989 .items = { 6990 { "MIC1 pin", 0x0 }, 6991 { "MIC2 pin", 0x1 }, 6992 { "LINE1 pin", 0x2 }, 6993 { "LINE2 pin", 0x3 }, 6994 { "CD pin", 0x4 }, 6995 { "Mixer", 0x5 }, 6996 { "LINE-OUT pin", 0x6 }, 6997 { "HP-OUT pin", 0x7 }, 6998 }, 6999 }, 7000}; 7001static const struct snd_kcontrol_new alc260_test_mixer[] = { 7002 /* Output driver widgets */ 7003 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 7004 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), 7005 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), 7006 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), 7007 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), 7008 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), 7009 7010 /* Modes for retasking pin widgets 7011 * Note: the ALC260 doesn't seem to act on requests to enable mic 7012 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't 7013 * mention this restriction. At this stage it's not clear whether 7014 * this behaviour is intentional or is a hardware bug in chip 7015 * revisions available at least up until early 2006. Therefore for 7016 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all 7017 * choices, but if it turns out that the lack of mic bias for these 7018 * NIDs is intentional we could change their modes from 7019 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. 7020 */ 7021 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), 7022 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), 7023 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), 7024 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), 7025 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), 7026 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), 7027 7028 /* Loopback mixer controls */ 7029 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), 7030 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), 7031 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), 7032 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), 7033 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), 7034 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), 7035 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), 7036 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), 7037 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 7038 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 7039 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), 7040 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), 7041 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), 7042 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), 7043 7044 /* Controls for GPIO pins, assuming they are configured as outputs */ 7045 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 7046 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 7047 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 7048 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 7049 7050 /* Switches to allow the digital IO pins to be enabled. The datasheet 7051 * is ambigious as to which NID is which; testing on laptops which 7052 * make this output available should provide clarification. 7053 */ 7054 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), 7055 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), 7056 7057 /* A switch allowing EAPD to be enabled. Some laptops seem to use 7058 * this output to turn on an external amplifier. 7059 */ 7060 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 7061 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 7062 7063 { } /* end */ 7064}; 7065static const struct hda_verb alc260_test_init_verbs[] = { 7066 /* Enable all GPIOs as outputs with an initial value of 0 */ 7067 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, 7068 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 7069 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, 7070 7071 /* Enable retasking pins as output, initially without power amp */ 7072 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7073 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7076 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7078 7079 /* Disable digital (SPDIF) pins initially, but users can enable 7080 * them via a mixer switch. In the case of SPDIF-out, this initverb 7081 * payload also sets the generation to 0, output to be in "consumer" 7082 * PCM format, copyright asserted, no pre-emphasis and no validity 7083 * control. 7084 */ 7085 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, 7086 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, 7087 7088 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 7089 * OUT1 sum bus when acting as an output. 7090 */ 7091 {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, 7092 {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, 7093 {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, 7094 {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, 7095 7096 /* Start with output sum widgets muted and their output gains at min */ 7097 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7098 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7099 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7100 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7101 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7103 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7104 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7105 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7106 7107 /* Unmute retasking pin widget output buffers since the default 7108 * state appears to be output. As the pin mode is changed by the 7109 * user the pin mode control will take care of enabling the pin's 7110 * input/output buffers as needed. 7111 */ 7112 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7113 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7114 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7115 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7116 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7117 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7118 /* Also unmute the mono-out pin widget */ 7119 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7120 7121 /* Mute capture amp left and right */ 7122 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7123 /* Set ADC connection select to match default mixer setting (mic1 7124 * pin) 7125 */ 7126 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 7127 7128 /* Do the same for the second ADC: mute capture input amp and 7129 * set ADC connection to mic1 pin 7130 */ 7131 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7132 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 7133 7134 /* Mute all inputs to mixer widget (even unconnected ones) */ 7135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ 7136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ 7137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ 7138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ 7139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ 7140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ 7141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ 7142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ 7143 7144 { } 7145}; 7146#endif 7147 7148#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback 7149#define alc260_pcm_analog_capture alc880_pcm_analog_capture 7150 7151#define alc260_pcm_digital_playback alc880_pcm_digital_playback 7152#define alc260_pcm_digital_capture alc880_pcm_digital_capture 7153 7154/* 7155 * for BIOS auto-configuration 7156 */ 7157 7158static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 7159 const char *pfx, int *vol_bits) 7160{ 7161 hda_nid_t nid_vol; 7162 unsigned long vol_val, sw_val; 7163 int err; 7164 7165 if (nid >= 0x0f && nid < 0x11) { 7166 nid_vol = nid - 0x7; 7167 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 7168 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 7169 } else if (nid == 0x11) { 7170 nid_vol = nid - 0x7; 7171 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT); 7172 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 7173 } else if (nid >= 0x12 && nid <= 0x15) { 7174 nid_vol = 0x08; 7175 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 7176 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 7177 } else 7178 return 0; /* N/A */ 7179 7180 if (!(*vol_bits & (1 << nid_vol))) { 7181 /* first control for the volume widget */ 7182 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val); 7183 if (err < 0) 7184 return err; 7185 *vol_bits |= (1 << nid_vol); 7186 } 7187 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val); 7188 if (err < 0) 7189 return err; 7190 return 1; 7191} 7192 7193/* add playback controls from the parsed DAC table */ 7194static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, 7195 const struct auto_pin_cfg *cfg) 7196{ 7197 hda_nid_t nid; 7198 int err; 7199 int vols = 0; 7200 7201 spec->multiout.num_dacs = 1; 7202 spec->multiout.dac_nids = spec->private_dac_nids; 7203 spec->private_dac_nids[0] = 0x02; 7204 7205 nid = cfg->line_out_pins[0]; 7206 if (nid) { 7207 const char *pfx; 7208 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 7209 pfx = "Master"; 7210 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 7211 pfx = "Speaker"; 7212 else 7213 pfx = "Front"; 7214 err = alc260_add_playback_controls(spec, nid, pfx, &vols); 7215 if (err < 0) 7216 return err; 7217 } 7218 7219 nid = cfg->speaker_pins[0]; 7220 if (nid) { 7221 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 7222 if (err < 0) 7223 return err; 7224 } 7225 7226 nid = cfg->hp_pins[0]; 7227 if (nid) { 7228 err = alc260_add_playback_controls(spec, nid, "Headphone", 7229 &vols); 7230 if (err < 0) 7231 return err; 7232 } 7233 return 0; 7234} 7235 7236/* create playback/capture controls for input pins */ 7237static int alc260_auto_create_input_ctls(struct hda_codec *codec, 7238 const struct auto_pin_cfg *cfg) 7239{ 7240 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05); 7241} 7242 7243static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 7244 hda_nid_t nid, int pin_type, 7245 int sel_idx) 7246{ 7247 alc_set_pin_output(codec, nid, pin_type); 7248 /* need the manual connection? */ 7249 if (nid >= 0x12) { 7250 int idx = nid - 0x12; 7251 snd_hda_codec_write(codec, idx + 0x0b, 0, 7252 AC_VERB_SET_CONNECT_SEL, sel_idx); 7253 } 7254} 7255 7256static void alc260_auto_init_multi_out(struct hda_codec *codec) 7257{ 7258 struct alc_spec *spec = codec->spec; 7259 hda_nid_t nid; 7260 7261 nid = spec->autocfg.line_out_pins[0]; 7262 if (nid) { 7263 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7264 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 7265 } 7266 7267 nid = spec->autocfg.speaker_pins[0]; 7268 if (nid) 7269 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); 7270 7271 nid = spec->autocfg.hp_pins[0]; 7272 if (nid) 7273 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); 7274} 7275 7276#define ALC260_PIN_CD_NID 0x16 7277static void alc260_auto_init_analog_input(struct hda_codec *codec) 7278{ 7279 struct alc_spec *spec = codec->spec; 7280 struct auto_pin_cfg *cfg = &spec->autocfg; 7281 int i; 7282 7283 for (i = 0; i < cfg->num_inputs; i++) { 7284 hda_nid_t nid = cfg->inputs[i].pin; 7285 if (nid >= 0x12) { 7286 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 7287 if (nid != ALC260_PIN_CD_NID && 7288 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 7289 snd_hda_codec_write(codec, nid, 0, 7290 AC_VERB_SET_AMP_GAIN_MUTE, 7291 AMP_OUT_MUTE); 7292 } 7293 } 7294} 7295 7296#define alc260_auto_init_input_src alc880_auto_init_input_src 7297 7298/* 7299 * generic initialization of ADC, input mixers and output mixers 7300 */ 7301static const struct hda_verb alc260_volume_init_verbs[] = { 7302 /* 7303 * Unmute ADC0-1 and set the default input to mic-in 7304 */ 7305 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, 7306 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7307 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, 7308 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7309 7310 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 7311 * mixer widget 7312 * Note: PASD motherboards uses the Line In 2 as the input for 7313 * front panel mic (mic 2) 7314 */ 7315 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 7316 /* mute analog inputs */ 7317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7322 7323 /* 7324 * Set up output mixers (0x08 - 0x0a) 7325 */ 7326 /* set vol=0 to output mixers */ 7327 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7329 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7330 /* set up input amps for analog loopback */ 7331 /* Amp Indices: DAC = 0, mixer = 1 */ 7332 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7333 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7334 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7335 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7336 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7337 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 7338 7339 { } 7340}; 7341 7342static int alc260_parse_auto_config(struct hda_codec *codec) 7343{ 7344 struct alc_spec *spec = codec->spec; 7345 int err; 7346 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 7347 7348 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 7349 alc260_ignore); 7350 if (err < 0) 7351 return err; 7352 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 7353 if (err < 0) 7354 return err; 7355 if (!spec->kctls.list) 7356 return 0; /* can't find valid BIOS pin config */ 7357 err = alc260_auto_create_input_ctls(codec, &spec->autocfg); 7358 if (err < 0) 7359 return err; 7360 7361 spec->multiout.max_channels = 2; 7362 7363 if (spec->autocfg.dig_outs) 7364 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 7365 if (spec->kctls.list) 7366 add_mixer(spec, spec->kctls.list); 7367 7368 add_verb(spec, alc260_volume_init_verbs); 7369 7370 spec->num_mux_defs = 1; 7371 spec->input_mux = &spec->private_imux[0]; 7372 7373 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0); 7374 7375 return 1; 7376} 7377 7378/* additional initialization for auto-configuration model */ 7379static void alc260_auto_init(struct hda_codec *codec) 7380{ 7381 struct alc_spec *spec = codec->spec; 7382 alc260_auto_init_multi_out(codec); 7383 alc260_auto_init_analog_input(codec); 7384 alc260_auto_init_input_src(codec); 7385 alc_auto_init_digital(codec); 7386 if (spec->unsol_event) 7387 alc_inithook(codec); 7388} 7389 7390#ifdef CONFIG_SND_HDA_POWER_SAVE 7391static const struct hda_amp_list alc260_loopbacks[] = { 7392 { 0x07, HDA_INPUT, 0 }, 7393 { 0x07, HDA_INPUT, 1 }, 7394 { 0x07, HDA_INPUT, 2 }, 7395 { 0x07, HDA_INPUT, 3 }, 7396 { 0x07, HDA_INPUT, 4 }, 7397 { } /* end */ 7398}; 7399#endif 7400 7401/* 7402 * Pin config fixes 7403 */ 7404enum { 7405 PINFIX_HP_DC5750, 7406}; 7407 7408static const struct alc_fixup alc260_fixups[] = { 7409 [PINFIX_HP_DC5750] = { 7410 .type = ALC_FIXUP_PINS, 7411 .v.pins = (const struct alc_pincfg[]) { 7412 { 0x11, 0x90130110 }, /* speaker */ 7413 { } 7414 } 7415 }, 7416}; 7417 7418static const struct snd_pci_quirk alc260_fixup_tbl[] = { 7419 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 7420 {} 7421}; 7422 7423/* 7424 * ALC260 configurations 7425 */ 7426static const char * const alc260_models[ALC260_MODEL_LAST] = { 7427 [ALC260_BASIC] = "basic", 7428 [ALC260_HP] = "hp", 7429 [ALC260_HP_3013] = "hp-3013", 7430 [ALC260_HP_DC7600] = "hp-dc7600", 7431 [ALC260_FUJITSU_S702X] = "fujitsu", 7432 [ALC260_ACER] = "acer", 7433 [ALC260_WILL] = "will", 7434 [ALC260_REPLACER_672V] = "replacer", 7435 [ALC260_FAVORIT100] = "favorit100", 7436#ifdef CONFIG_SND_DEBUG 7437 [ALC260_TEST] = "test", 7438#endif 7439 [ALC260_AUTO] = "auto", 7440}; 7441 7442static const struct snd_pci_quirk alc260_cfg_tbl[] = { 7443 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), 7444 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), 7445 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), 7446 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), 7447 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), 7448 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ 7449 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), 7450 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), 7451 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), 7452 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), 7453 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), 7454 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), 7455 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), 7456 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), 7457 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), 7458 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 7459 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 7460 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 7461 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), 7462 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), 7463 {} 7464}; 7465 7466static const struct alc_config_preset alc260_presets[] = { 7467 [ALC260_BASIC] = { 7468 .mixers = { alc260_base_output_mixer, 7469 alc260_input_mixer }, 7470 .init_verbs = { alc260_init_verbs }, 7471 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7472 .dac_nids = alc260_dac_nids, 7473 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7474 .adc_nids = alc260_dual_adc_nids, 7475 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7476 .channel_mode = alc260_modes, 7477 .input_mux = &alc260_capture_source, 7478 }, 7479 [ALC260_HP] = { 7480 .mixers = { alc260_hp_output_mixer, 7481 alc260_input_mixer }, 7482 .init_verbs = { alc260_init_verbs, 7483 alc260_hp_unsol_verbs }, 7484 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7485 .dac_nids = alc260_dac_nids, 7486 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7487 .adc_nids = alc260_adc_nids_alt, 7488 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7489 .channel_mode = alc260_modes, 7490 .input_mux = &alc260_capture_source, 7491 .unsol_event = alc_sku_unsol_event, 7492 .setup = alc260_hp_setup, 7493 .init_hook = alc_inithook, 7494 }, 7495 [ALC260_HP_DC7600] = { 7496 .mixers = { alc260_hp_dc7600_mixer, 7497 alc260_input_mixer }, 7498 .init_verbs = { alc260_init_verbs, 7499 alc260_hp_dc7600_verbs }, 7500 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7501 .dac_nids = alc260_dac_nids, 7502 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7503 .adc_nids = alc260_adc_nids_alt, 7504 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7505 .channel_mode = alc260_modes, 7506 .input_mux = &alc260_capture_source, 7507 .unsol_event = alc_sku_unsol_event, 7508 .setup = alc260_hp_3012_setup, 7509 .init_hook = alc_inithook, 7510 }, 7511 [ALC260_HP_3013] = { 7512 .mixers = { alc260_hp_3013_mixer, 7513 alc260_input_mixer }, 7514 .init_verbs = { alc260_hp_3013_init_verbs, 7515 alc260_hp_3013_unsol_verbs }, 7516 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7517 .dac_nids = alc260_dac_nids, 7518 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), 7519 .adc_nids = alc260_adc_nids_alt, 7520 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7521 .channel_mode = alc260_modes, 7522 .input_mux = &alc260_capture_source, 7523 .unsol_event = alc_sku_unsol_event, 7524 .setup = alc260_hp_3013_setup, 7525 .init_hook = alc_inithook, 7526 }, 7527 [ALC260_FUJITSU_S702X] = { 7528 .mixers = { alc260_fujitsu_mixer }, 7529 .init_verbs = { alc260_fujitsu_init_verbs }, 7530 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7531 .dac_nids = alc260_dac_nids, 7532 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7533 .adc_nids = alc260_dual_adc_nids, 7534 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7535 .channel_mode = alc260_modes, 7536 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), 7537 .input_mux = alc260_fujitsu_capture_sources, 7538 }, 7539 [ALC260_ACER] = { 7540 .mixers = { alc260_acer_mixer }, 7541 .init_verbs = { alc260_acer_init_verbs }, 7542 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7543 .dac_nids = alc260_dac_nids, 7544 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7545 .adc_nids = alc260_dual_adc_nids, 7546 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7547 .channel_mode = alc260_modes, 7548 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), 7549 .input_mux = alc260_acer_capture_sources, 7550 }, 7551 [ALC260_FAVORIT100] = { 7552 .mixers = { alc260_favorit100_mixer }, 7553 .init_verbs = { alc260_favorit100_init_verbs }, 7554 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7555 .dac_nids = alc260_dac_nids, 7556 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), 7557 .adc_nids = alc260_dual_adc_nids, 7558 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7559 .channel_mode = alc260_modes, 7560 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 7561 .input_mux = alc260_favorit100_capture_sources, 7562 }, 7563 [ALC260_WILL] = { 7564 .mixers = { alc260_will_mixer }, 7565 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 7566 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7567 .dac_nids = alc260_dac_nids, 7568 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7569 .adc_nids = alc260_adc_nids, 7570 .dig_out_nid = ALC260_DIGOUT_NID, 7571 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7572 .channel_mode = alc260_modes, 7573 .input_mux = &alc260_capture_source, 7574 }, 7575 [ALC260_REPLACER_672V] = { 7576 .mixers = { alc260_replacer_672v_mixer }, 7577 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 7578 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 7579 .dac_nids = alc260_dac_nids, 7580 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 7581 .adc_nids = alc260_adc_nids, 7582 .dig_out_nid = ALC260_DIGOUT_NID, 7583 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7584 .channel_mode = alc260_modes, 7585 .input_mux = &alc260_capture_source, 7586 .unsol_event = alc260_replacer_672v_unsol_event, 7587 .init_hook = alc260_replacer_672v_automute, 7588 }, 7589#ifdef CONFIG_SND_DEBUG 7590 [ALC260_TEST] = { 7591 .mixers = { alc260_test_mixer }, 7592 .init_verbs = { alc260_test_init_verbs }, 7593 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 7594 .dac_nids = alc260_test_dac_nids, 7595 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), 7596 .adc_nids = alc260_test_adc_nids, 7597 .num_channel_mode = ARRAY_SIZE(alc260_modes), 7598 .channel_mode = alc260_modes, 7599 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), 7600 .input_mux = alc260_test_capture_sources, 7601 }, 7602#endif 7603}; 7604 7605static int patch_alc260(struct hda_codec *codec) 7606{ 7607 struct alc_spec *spec; 7608 int err, board_config; 7609 7610 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 7611 if (spec == NULL) 7612 return -ENOMEM; 7613 7614 codec->spec = spec; 7615 7616 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 7617 alc260_models, 7618 alc260_cfg_tbl); 7619 if (board_config < 0) { 7620 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 7621 codec->chip_name); 7622 board_config = ALC260_AUTO; 7623 } 7624 7625 if (board_config == ALC260_AUTO) { 7626 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 7627 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 7628 } 7629 7630 if (board_config == ALC260_AUTO) { 7631 /* automatic parse from the BIOS config */ 7632 err = alc260_parse_auto_config(codec); 7633 if (err < 0) { 7634 alc_free(codec); 7635 return err; 7636 } else if (!err) { 7637 printk(KERN_INFO 7638 "hda_codec: Cannot set up configuration " 7639 "from BIOS. Using base mode...\n"); 7640 board_config = ALC260_BASIC; 7641 } 7642 } 7643 7644 err = snd_hda_attach_beep_device(codec, 0x1); 7645 if (err < 0) { 7646 alc_free(codec); 7647 return err; 7648 } 7649 7650 if (board_config != ALC260_AUTO) 7651 setup_preset(codec, &alc260_presets[board_config]); 7652 7653 spec->stream_analog_playback = &alc260_pcm_analog_playback; 7654 spec->stream_analog_capture = &alc260_pcm_analog_capture; 7655 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 7656 7657 spec->stream_digital_playback = &alc260_pcm_digital_playback; 7658 spec->stream_digital_capture = &alc260_pcm_digital_capture; 7659 7660 if (!spec->adc_nids && spec->input_mux) { 7661 /* check whether NID 0x04 is valid */ 7662 unsigned int wcap = get_wcaps(codec, 0x04); 7663 wcap = get_wcaps_type(wcap); 7664 /* get type */ 7665 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 7666 spec->adc_nids = alc260_adc_nids_alt; 7667 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt); 7668 } else { 7669 spec->adc_nids = alc260_adc_nids; 7670 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 7671 } 7672 } 7673 set_capture_mixer(codec); 7674 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7675 7676 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 7677 7678 spec->vmaster_nid = 0x08; 7679 7680 codec->patch_ops = alc_patch_ops; 7681 if (board_config == ALC260_AUTO) 7682 spec->init_hook = alc260_auto_init; 7683 spec->shutup = alc_eapd_shutup; 7684#ifdef CONFIG_SND_HDA_POWER_SAVE 7685 if (!spec->loopback.amplist) 7686 spec->loopback.amplist = alc260_loopbacks; 7687#endif 7688 7689 return 0; 7690} 7691 7692 7693/* 7694 * ALC882/883/885/888/889 support 7695 * 7696 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 7697 * configuration. Each pin widget can choose any input DACs and a mixer. 7698 * Each ADC is connected from a mixer of all inputs. This makes possible 7699 * 6-channel independent captures. 7700 * 7701 * In addition, an independent DAC for the multi-playback (not used in this 7702 * driver yet). 7703 */ 7704#define ALC882_DIGOUT_NID 0x06 7705#define ALC882_DIGIN_NID 0x0a 7706#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID 7707#define ALC883_DIGIN_NID ALC882_DIGIN_NID 7708#define ALC1200_DIGOUT_NID 0x10 7709 7710 7711static const struct hda_channel_mode alc882_ch_modes[1] = { 7712 { 8, NULL } 7713}; 7714 7715/* DACs */ 7716static const hda_nid_t alc882_dac_nids[4] = { 7717 /* front, rear, clfe, rear_surr */ 7718 0x02, 0x03, 0x04, 0x05 7719}; 7720#define alc883_dac_nids alc882_dac_nids 7721 7722/* ADCs */ 7723#define alc882_adc_nids alc880_adc_nids 7724#define alc882_adc_nids_alt alc880_adc_nids_alt 7725#define alc883_adc_nids alc882_adc_nids_alt 7726static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; 7727static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; 7728#define alc889_adc_nids alc880_adc_nids 7729 7730static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 7731static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 7732#define alc883_capsrc_nids alc882_capsrc_nids_alt 7733static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; 7734#define alc889_capsrc_nids alc882_capsrc_nids 7735 7736/* input MUX */ 7737/* FIXME: should be a matrix-type input source selection */ 7738 7739static const struct hda_input_mux alc882_capture_source = { 7740 .num_items = 4, 7741 .items = { 7742 { "Mic", 0x0 }, 7743 { "Front Mic", 0x1 }, 7744 { "Line", 0x2 }, 7745 { "CD", 0x4 }, 7746 }, 7747}; 7748 7749#define alc883_capture_source alc882_capture_source 7750 7751static const struct hda_input_mux alc889_capture_source = { 7752 .num_items = 3, 7753 .items = { 7754 { "Front Mic", 0x0 }, 7755 { "Mic", 0x3 }, 7756 { "Line", 0x2 }, 7757 }, 7758}; 7759 7760static const struct hda_input_mux mb5_capture_source = { 7761 .num_items = 3, 7762 .items = { 7763 { "Mic", 0x1 }, 7764 { "Line", 0x7 }, 7765 { "CD", 0x4 }, 7766 }, 7767}; 7768 7769static const struct hda_input_mux macmini3_capture_source = { 7770 .num_items = 2, 7771 .items = { 7772 { "Line", 0x2 }, 7773 { "CD", 0x4 }, 7774 }, 7775}; 7776 7777static const struct hda_input_mux alc883_3stack_6ch_intel = { 7778 .num_items = 4, 7779 .items = { 7780 { "Mic", 0x1 }, 7781 { "Front Mic", 0x0 }, 7782 { "Line", 0x2 }, 7783 { "CD", 0x4 }, 7784 }, 7785}; 7786 7787static const struct hda_input_mux alc883_lenovo_101e_capture_source = { 7788 .num_items = 2, 7789 .items = { 7790 { "Mic", 0x1 }, 7791 { "Line", 0x2 }, 7792 }, 7793}; 7794 7795static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = { 7796 .num_items = 4, 7797 .items = { 7798 { "Mic", 0x0 }, 7799 { "Internal Mic", 0x1 }, 7800 { "Line", 0x2 }, 7801 { "CD", 0x4 }, 7802 }, 7803}; 7804 7805static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { 7806 .num_items = 2, 7807 .items = { 7808 { "Mic", 0x0 }, 7809 { "Internal Mic", 0x1 }, 7810 }, 7811}; 7812 7813static const struct hda_input_mux alc883_lenovo_sky_capture_source = { 7814 .num_items = 3, 7815 .items = { 7816 { "Mic", 0x0 }, 7817 { "Front Mic", 0x1 }, 7818 { "Line", 0x4 }, 7819 }, 7820}; 7821 7822static const struct hda_input_mux alc883_asus_eee1601_capture_source = { 7823 .num_items = 2, 7824 .items = { 7825 { "Mic", 0x0 }, 7826 { "Line", 0x2 }, 7827 }, 7828}; 7829 7830static const struct hda_input_mux alc889A_mb31_capture_source = { 7831 .num_items = 2, 7832 .items = { 7833 { "Mic", 0x0 }, 7834 /* Front Mic (0x01) unused */ 7835 { "Line", 0x2 }, 7836 /* Line 2 (0x03) unused */ 7837 /* CD (0x04) unused? */ 7838 }, 7839}; 7840 7841static const struct hda_input_mux alc889A_imac91_capture_source = { 7842 .num_items = 2, 7843 .items = { 7844 { "Mic", 0x01 }, 7845 { "Line", 0x2 }, /* Not sure! */ 7846 }, 7847}; 7848 7849/* 7850 * 2ch mode 7851 */ 7852static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = { 7853 { 2, NULL } 7854}; 7855 7856/* 7857 * 2ch mode 7858 */ 7859static const struct hda_verb alc882_3ST_ch2_init[] = { 7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7864 { } /* end */ 7865}; 7866 7867/* 7868 * 4ch mode 7869 */ 7870static const struct hda_verb alc882_3ST_ch4_init[] = { 7871 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7872 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7873 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7874 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7875 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7876 { } /* end */ 7877}; 7878 7879/* 7880 * 6ch mode 7881 */ 7882static const struct hda_verb alc882_3ST_ch6_init[] = { 7883 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7884 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7885 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7886 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7887 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7888 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7889 { } /* end */ 7890}; 7891 7892static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = { 7893 { 2, alc882_3ST_ch2_init }, 7894 { 4, alc882_3ST_ch4_init }, 7895 { 6, alc882_3ST_ch6_init }, 7896}; 7897 7898#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes 7899 7900/* 7901 * 2ch mode 7902 */ 7903static const struct hda_verb alc883_3ST_ch2_clevo_init[] = { 7904 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, 7905 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7906 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7907 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7908 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7909 { } /* end */ 7910}; 7911 7912/* 7913 * 4ch mode 7914 */ 7915static const struct hda_verb alc883_3ST_ch4_clevo_init[] = { 7916 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7917 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 7918 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 7919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7921 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7922 { } /* end */ 7923}; 7924 7925/* 7926 * 6ch mode 7927 */ 7928static const struct hda_verb alc883_3ST_ch6_clevo_init[] = { 7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7930 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7931 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7932 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 7933 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7934 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 7935 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7936 { } /* end */ 7937}; 7938 7939static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { 7940 { 2, alc883_3ST_ch2_clevo_init }, 7941 { 4, alc883_3ST_ch4_clevo_init }, 7942 { 6, alc883_3ST_ch6_clevo_init }, 7943}; 7944 7945 7946/* 7947 * 6ch mode 7948 */ 7949static const struct hda_verb alc882_sixstack_ch6_init[] = { 7950 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 7951 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7952 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7953 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7954 { } /* end */ 7955}; 7956 7957/* 7958 * 8ch mode 7959 */ 7960static const struct hda_verb alc882_sixstack_ch8_init[] = { 7961 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7962 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7963 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7964 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7965 { } /* end */ 7966}; 7967 7968static const struct hda_channel_mode alc882_sixstack_modes[2] = { 7969 { 6, alc882_sixstack_ch6_init }, 7970 { 8, alc882_sixstack_ch8_init }, 7971}; 7972 7973 7974/* Macbook Air 2,1 */ 7975 7976static const struct hda_channel_mode alc885_mba21_ch_modes[1] = { 7977 { 2, NULL }, 7978}; 7979 7980/* 7981 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 7982 */ 7983 7984/* 7985 * 2ch mode 7986 */ 7987static const struct hda_verb alc885_mbp_ch2_init[] = { 7988 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 7989 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7990 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7991 { } /* end */ 7992}; 7993 7994/* 7995 * 4ch mode 7996 */ 7997static const struct hda_verb alc885_mbp_ch4_init[] = { 7998 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 7999 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8000 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8001 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8002 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8003 { } /* end */ 8004}; 8005 8006static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = { 8007 { 2, alc885_mbp_ch2_init }, 8008 { 4, alc885_mbp_ch4_init }, 8009}; 8010 8011/* 8012 * 2ch 8013 * Speakers/Woofer/HP = Front 8014 * LineIn = Input 8015 */ 8016static const struct hda_verb alc885_mb5_ch2_init[] = { 8017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8019 { } /* end */ 8020}; 8021 8022/* 8023 * 6ch mode 8024 * Speakers/HP = Front 8025 * Woofer = LFE 8026 * LineIn = Surround 8027 */ 8028static const struct hda_verb alc885_mb5_ch6_init[] = { 8029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8031 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8032 { } /* end */ 8033}; 8034 8035static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = { 8036 { 2, alc885_mb5_ch2_init }, 8037 { 6, alc885_mb5_ch6_init }, 8038}; 8039 8040#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes 8041 8042/* 8043 * 2ch mode 8044 */ 8045static const struct hda_verb alc883_4ST_ch2_init[] = { 8046 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8047 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8048 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8049 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8050 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8051 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8052 { } /* end */ 8053}; 8054 8055/* 8056 * 4ch mode 8057 */ 8058static const struct hda_verb alc883_4ST_ch4_init[] = { 8059 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8060 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8061 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8062 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8063 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8064 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8065 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8066 { } /* end */ 8067}; 8068 8069/* 8070 * 6ch mode 8071 */ 8072static const struct hda_verb alc883_4ST_ch6_init[] = { 8073 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8074 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8075 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8076 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8077 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8078 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8079 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8080 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8081 { } /* end */ 8082}; 8083 8084/* 8085 * 8ch mode 8086 */ 8087static const struct hda_verb alc883_4ST_ch8_init[] = { 8088 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8089 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8090 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8091 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8092 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8093 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8094 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8095 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8096 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8097 { } /* end */ 8098}; 8099 8100static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = { 8101 { 2, alc883_4ST_ch2_init }, 8102 { 4, alc883_4ST_ch4_init }, 8103 { 6, alc883_4ST_ch6_init }, 8104 { 8, alc883_4ST_ch8_init }, 8105}; 8106 8107 8108/* 8109 * 2ch mode 8110 */ 8111static const struct hda_verb alc883_3ST_ch2_intel_init[] = { 8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8114 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8115 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8116 { } /* end */ 8117}; 8118 8119/* 8120 * 4ch mode 8121 */ 8122static const struct hda_verb alc883_3ST_ch4_intel_init[] = { 8123 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 8124 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8125 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8126 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8127 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8128 { } /* end */ 8129}; 8130 8131/* 8132 * 6ch mode 8133 */ 8134static const struct hda_verb alc883_3ST_ch6_intel_init[] = { 8135 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8136 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8137 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8138 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8139 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8140 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8141 { } /* end */ 8142}; 8143 8144static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { 8145 { 2, alc883_3ST_ch2_intel_init }, 8146 { 4, alc883_3ST_ch4_intel_init }, 8147 { 6, alc883_3ST_ch6_intel_init }, 8148}; 8149 8150/* 8151 * 2ch mode 8152 */ 8153static const struct hda_verb alc889_ch2_intel_init[] = { 8154 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8155 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8156 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8157 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8158 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8159 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8160 { } /* end */ 8161}; 8162 8163/* 8164 * 6ch mode 8165 */ 8166static const struct hda_verb alc889_ch6_intel_init[] = { 8167 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8168 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8169 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8170 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8171 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 8172 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 8173 { } /* end */ 8174}; 8175 8176/* 8177 * 8ch mode 8178 */ 8179static const struct hda_verb alc889_ch8_intel_init[] = { 8180 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, 8181 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, 8182 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, 8183 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8184 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, 8185 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8186 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 8187 { } /* end */ 8188}; 8189 8190static const struct hda_channel_mode alc889_8ch_intel_modes[3] = { 8191 { 2, alc889_ch2_intel_init }, 8192 { 6, alc889_ch6_intel_init }, 8193 { 8, alc889_ch8_intel_init }, 8194}; 8195 8196/* 8197 * 6ch mode 8198 */ 8199static const struct hda_verb alc883_sixstack_ch6_init[] = { 8200 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 8201 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8202 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8203 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8204 { } /* end */ 8205}; 8206 8207/* 8208 * 8ch mode 8209 */ 8210static const struct hda_verb alc883_sixstack_ch8_init[] = { 8211 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8212 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8213 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8214 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 8215 { } /* end */ 8216}; 8217 8218static const struct hda_channel_mode alc883_sixstack_modes[2] = { 8219 { 6, alc883_sixstack_ch6_init }, 8220 { 8, alc883_sixstack_ch8_init }, 8221}; 8222 8223 8224/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 8225 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 8226 */ 8227static const struct snd_kcontrol_new alc882_base_mixer[] = { 8228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8229 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8230 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8231 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 8232 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 8233 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 8234 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 8235 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8236 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 8237 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 8238 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8239 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8240 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8241 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8242 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8244 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8246 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8247 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8248 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8249 { } /* end */ 8250}; 8251 8252/* Macbook Air 2,1 same control for HP and internal Speaker */ 8253 8254static const struct snd_kcontrol_new alc885_mba21_mixer[] = { 8255 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8256 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), 8257 { } 8258}; 8259 8260 8261static const struct snd_kcontrol_new alc885_mbp3_mixer[] = { 8262 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8263 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8264 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8265 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), 8266 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8267 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8268 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8269 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8270 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8271 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 8272 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 8273 { } /* end */ 8274}; 8275 8276static const struct snd_kcontrol_new alc885_mb5_mixer[] = { 8277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 8283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 8284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8288 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8289 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 8290 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT), 8291 { } /* end */ 8292}; 8293 8294static const struct snd_kcontrol_new alc885_macmini3_mixer[] = { 8295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8296 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 8297 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 8298 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 8299 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), 8300 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), 8301 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), 8302 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8304 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8305 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), 8306 { } /* end */ 8307}; 8308 8309static const struct snd_kcontrol_new alc885_imac91_mixer[] = { 8310 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8311 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 8312 { } /* end */ 8313}; 8314 8315 8316static const struct snd_kcontrol_new alc882_w2jc_mixer[] = { 8317 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8318 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8319 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8320 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8321 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8322 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8324 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8326 { } /* end */ 8327}; 8328 8329static const struct snd_kcontrol_new alc882_targa_mixer[] = { 8330 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8331 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 8333 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8334 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8335 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8336 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8340 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8341 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8342 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 8343 { } /* end */ 8344}; 8345 8346/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? 8347 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c 8348 */ 8349static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { 8350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8351 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 8352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8353 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), 8354 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8355 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8356 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8357 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8358 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), 8359 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8362 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8363 { } /* end */ 8364}; 8365 8366static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { 8367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8368 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8369 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 8371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 8372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8375 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 8376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8377 { } /* end */ 8378}; 8379 8380static const struct snd_kcontrol_new alc882_chmode_mixer[] = { 8381 { 8382 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 8383 .name = "Channel Mode", 8384 .info = alc_ch_mode_info, 8385 .get = alc_ch_mode_get, 8386 .put = alc_ch_mode_put, 8387 }, 8388 { } /* end */ 8389}; 8390 8391static const struct hda_verb alc882_base_init_verbs[] = { 8392 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8395 /* Rear mixer */ 8396 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8398 /* CLFE mixer */ 8399 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8400 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8401 /* Side mixer */ 8402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8403 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8404 8405 /* Front Pin: output 0 (0x0c) */ 8406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8407 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8408 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8409 /* Rear Pin: output 1 (0x0d) */ 8410 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8411 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 8413 /* CLFE Pin: output 2 (0x0e) */ 8414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8415 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8416 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8417 /* Side Pin: output 3 (0x0f) */ 8418 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8419 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8420 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8421 /* Mic (rear) pin: input vref at 80% */ 8422 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8423 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8424 /* Front Mic pin: input vref at 80% */ 8425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8426 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8427 /* Line In pin: input */ 8428 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8429 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8430 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 8431 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8432 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8433 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 8434 /* CD pin widget for input */ 8435 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8436 8437 /* FIXME: use matrix-type input source selection */ 8438 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8439 /* Input mixer2 */ 8440 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8441 /* Input mixer3 */ 8442 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8443 /* ADC2: mute amp left and right */ 8444 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8445 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8446 /* ADC3: mute amp left and right */ 8447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8448 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8449 8450 { } 8451}; 8452 8453static const struct hda_verb alc882_adc1_init_verbs[] = { 8454 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8459 /* ADC1: mute amp left and right */ 8460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8461 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8462 { } 8463}; 8464 8465static const struct hda_verb alc882_eapd_verbs[] = { 8466 /* change to EAPD mode */ 8467 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 8468 {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, 8469 { } 8470}; 8471 8472static const struct hda_verb alc889_eapd_verbs[] = { 8473 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8474 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 8475 { } 8476}; 8477 8478static const struct hda_verb alc_hp15_unsol_verbs[] = { 8479 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 8480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8481 {} 8482}; 8483 8484static const struct hda_verb alc885_init_verbs[] = { 8485 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8488 /* Rear mixer */ 8489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8491 /* CLFE mixer */ 8492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8493 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8494 /* Side mixer */ 8495 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8496 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8497 8498 /* Front HP Pin: output 0 (0x0c) */ 8499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8501 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8502 /* Front Pin: output 0 (0x0c) */ 8503 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8505 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8506 /* Rear Pin: output 1 (0x0d) */ 8507 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8508 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8509 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, 8510 /* CLFE Pin: output 2 (0x0e) */ 8511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8512 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8513 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 8514 /* Side Pin: output 3 (0x0f) */ 8515 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8516 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8517 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 8518 /* Mic (rear) pin: input vref at 80% */ 8519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8520 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8521 /* Front Mic pin: input vref at 80% */ 8522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8524 /* Line In pin: input */ 8525 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8526 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8527 8528 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 8529 /* Input mixer1 */ 8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8531 /* Input mixer2 */ 8532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8533 /* Input mixer3 */ 8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8535 /* ADC2: mute amp left and right */ 8536 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8537 /* ADC3: mute amp left and right */ 8538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8539 8540 { } 8541}; 8542 8543static const struct hda_verb alc885_init_input_verbs[] = { 8544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 8546 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 8547 { } 8548}; 8549 8550 8551/* Unmute Selector 24h and set the default input to front mic */ 8552static const struct hda_verb alc889_init_input_verbs[] = { 8553 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 8554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8555 { } 8556}; 8557 8558 8559#define alc883_init_verbs alc882_base_init_verbs 8560 8561/* Mac Pro test */ 8562static const struct snd_kcontrol_new alc882_macpro_mixer[] = { 8563 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 8564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 8565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), 8566 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 8567 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 8568 /* FIXME: this looks suspicious... 8569 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), 8570 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), 8571 */ 8572 { } /* end */ 8573}; 8574 8575static const struct hda_verb alc882_macpro_init_verbs[] = { 8576 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8580 /* Front Pin: output 0 (0x0c) */ 8581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8584 /* Front Mic pin: input vref at 80% */ 8585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8587 /* Speaker: output */ 8588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8590 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, 8591 /* Headphone output (output 0 - 0x0c) */ 8592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8594 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8595 8596 /* FIXME: use matrix-type input source selection */ 8597 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8598 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8603 /* Input mixer2 */ 8604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8606 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8608 /* Input mixer3 */ 8609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8613 /* ADC1: mute amp left and right */ 8614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8615 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8616 /* ADC2: mute amp left and right */ 8617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8618 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8619 /* ADC3: mute amp left and right */ 8620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8622 8623 { } 8624}; 8625 8626/* Macbook 5,1 */ 8627static const struct hda_verb alc885_mb5_init_verbs[] = { 8628 /* DACs */ 8629 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8630 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8631 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8632 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8633 /* Front mixer */ 8634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8637 /* Surround mixer */ 8638 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8639 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8641 /* LFE mixer */ 8642 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8643 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8645 /* HP mixer */ 8646 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8647 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8649 /* Front Pin (0x0c) */ 8650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8652 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8653 /* LFE Pin (0x0e) */ 8654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8656 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8657 /* HP Pin (0x0f) */ 8658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8659 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8660 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8661 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8662 /* Front Mic pin: input vref at 80% */ 8663 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8664 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8665 /* Line In pin */ 8666 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8668 8669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, 8670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, 8671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, 8672 { } 8673}; 8674 8675/* Macmini 3,1 */ 8676static const struct hda_verb alc885_macmini3_init_verbs[] = { 8677 /* DACs */ 8678 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8679 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8681 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8682 /* Front mixer */ 8683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8686 /* Surround mixer */ 8687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8688 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8689 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8690 /* LFE mixer */ 8691 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8692 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8693 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8694 /* HP mixer */ 8695 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8698 /* Front Pin (0x0c) */ 8699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8702 /* LFE Pin (0x0e) */ 8703 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, 8704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8705 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, 8706 /* HP Pin (0x0f) */ 8707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8709 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, 8710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8711 /* Line In pin */ 8712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8713 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8714 8715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8717 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8718 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8719 { } 8720}; 8721 8722 8723static const struct hda_verb alc885_mba21_init_verbs[] = { 8724 /*Internal and HP Speaker Mixer*/ 8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8728 /*Internal Speaker Pin (0x0c)*/ 8729 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8730 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8731 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8732 /* HP Pin: output 0 (0x0e) */ 8733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8735 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8736 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8737 /* Line in (is hp when jack connected)*/ 8738 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8740 8741 { } 8742 }; 8743 8744 8745/* Macbook Pro rev3 */ 8746static const struct hda_verb alc885_mbp3_init_verbs[] = { 8747 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 8748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8751 /* Rear mixer */ 8752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8755 /* HP mixer */ 8756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8759 /* Front Pin: output 0 (0x0c) */ 8760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8762 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8763 /* HP Pin: output 0 (0x0e) */ 8764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 8765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, 8767 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8768 /* Mic (rear) pin: input vref at 80% */ 8769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8771 /* Front Mic pin: input vref at 80% */ 8772 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8774 /* Line In pin: use output 1 when in LineOut mode */ 8775 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 8776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8777 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 8778 8779 /* FIXME: use matrix-type input source selection */ 8780 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8781 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 8782 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8783 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8784 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8785 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8786 /* Input mixer2 */ 8787 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8788 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8789 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8790 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8791 /* Input mixer3 */ 8792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8795 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8796 /* ADC1: mute amp left and right */ 8797 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8798 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8799 /* ADC2: mute amp left and right */ 8800 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8801 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8802 /* ADC3: mute amp left and right */ 8803 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8804 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8805 8806 { } 8807}; 8808 8809/* iMac 9,1 */ 8810static const struct hda_verb alc885_imac91_init_verbs[] = { 8811 /* Internal Speaker Pin (0x0c) */ 8812 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8814 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, 8816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8817 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8818 /* HP Pin: Rear */ 8819 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8820 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8821 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8822 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)}, 8823 /* Line in Rear */ 8824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, 8825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8826 /* Front Mic pin: input vref at 80% */ 8827 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8828 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8829 /* Rear mixer */ 8830 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8831 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8832 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8833 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ 8834 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 8835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 8837 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8840 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8841 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8842 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8845 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8846 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8847 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ 8848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 8850 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 8851 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 8852 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8854 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 8855 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8856 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8857 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 8858 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ 8859 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8860 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8861 { } 8862}; 8863 8864/* iMac 24 mixer. */ 8865static const struct snd_kcontrol_new alc885_imac24_mixer[] = { 8866 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 8867 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), 8868 { } /* end */ 8869}; 8870 8871/* iMac 24 init verbs. */ 8872static const struct hda_verb alc885_imac24_init_verbs[] = { 8873 /* Internal speakers: output 0 (0x0c) */ 8874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8876 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, 8877 /* Internal speakers: output 0 (0x0c) */ 8878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8880 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 8881 /* Headphone: output 0 (0x0c) */ 8882 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 8884 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 8885 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8886 /* Front Mic: input vref at 80% */ 8887 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 8888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 8889 { } 8890}; 8891 8892/* Toggle speaker-output according to the hp-jack state */ 8893static void alc885_imac24_setup(struct hda_codec *codec) 8894{ 8895 struct alc_spec *spec = codec->spec; 8896 8897 spec->autocfg.hp_pins[0] = 0x14; 8898 spec->autocfg.speaker_pins[0] = 0x18; 8899 spec->autocfg.speaker_pins[1] = 0x1a; 8900 spec->automute = 1; 8901 spec->automute_mode = ALC_AUTOMUTE_AMP; 8902} 8903 8904#define alc885_mb5_setup alc885_imac24_setup 8905#define alc885_macmini3_setup alc885_imac24_setup 8906 8907/* Macbook Air 2,1 */ 8908static void alc885_mba21_setup(struct hda_codec *codec) 8909{ 8910 struct alc_spec *spec = codec->spec; 8911 8912 spec->autocfg.hp_pins[0] = 0x14; 8913 spec->autocfg.speaker_pins[0] = 0x18; 8914 spec->automute = 1; 8915 spec->automute_mode = ALC_AUTOMUTE_AMP; 8916} 8917 8918 8919 8920static void alc885_mbp3_setup(struct hda_codec *codec) 8921{ 8922 struct alc_spec *spec = codec->spec; 8923 8924 spec->autocfg.hp_pins[0] = 0x15; 8925 spec->autocfg.speaker_pins[0] = 0x14; 8926 spec->automute = 1; 8927 spec->automute_mode = ALC_AUTOMUTE_AMP; 8928} 8929 8930static void alc885_imac91_setup(struct hda_codec *codec) 8931{ 8932 struct alc_spec *spec = codec->spec; 8933 8934 spec->autocfg.hp_pins[0] = 0x14; 8935 spec->autocfg.speaker_pins[0] = 0x18; 8936 spec->autocfg.speaker_pins[1] = 0x1a; 8937 spec->automute = 1; 8938 spec->automute_mode = ALC_AUTOMUTE_AMP; 8939} 8940 8941static const struct hda_verb alc882_targa_verbs[] = { 8942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8944 8945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8946 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8947 8948 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8949 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8950 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8951 8952 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 8953 { } /* end */ 8954}; 8955 8956/* toggle speaker-output according to the hp-jack state */ 8957static void alc882_targa_automute(struct hda_codec *codec) 8958{ 8959 struct alc_spec *spec = codec->spec; 8960 alc_hp_automute(codec); 8961 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, 8962 spec->jack_present ? 1 : 3); 8963} 8964 8965static void alc882_targa_setup(struct hda_codec *codec) 8966{ 8967 struct alc_spec *spec = codec->spec; 8968 8969 spec->autocfg.hp_pins[0] = 0x14; 8970 spec->autocfg.speaker_pins[0] = 0x1b; 8971 spec->automute = 1; 8972 spec->automute_mode = ALC_AUTOMUTE_AMP; 8973} 8974 8975static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 8976{ 8977 if ((res >> 26) == ALC880_HP_EVENT) 8978 alc882_targa_automute(codec); 8979} 8980 8981static const struct hda_verb alc882_asus_a7j_verbs[] = { 8982 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 8984 8985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 8986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 8988 8989 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8991 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 8992 8993 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 8994 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 8995 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 8996 { } /* end */ 8997}; 8998 8999static const struct hda_verb alc882_asus_a7m_verbs[] = { 9000 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9002 9003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9006 9007 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 9008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 9009 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ 9010 9011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ 9012 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ 9013 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ 9014 { } /* end */ 9015}; 9016 9017static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) 9018{ 9019 unsigned int gpiostate, gpiomask, gpiodir; 9020 9021 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 9022 AC_VERB_GET_GPIO_DATA, 0); 9023 9024 if (!muted) 9025 gpiostate |= (1 << pin); 9026 else 9027 gpiostate &= ~(1 << pin); 9028 9029 gpiomask = snd_hda_codec_read(codec, codec->afg, 0, 9030 AC_VERB_GET_GPIO_MASK, 0); 9031 gpiomask |= (1 << pin); 9032 9033 gpiodir = snd_hda_codec_read(codec, codec->afg, 0, 9034 AC_VERB_GET_GPIO_DIRECTION, 0); 9035 gpiodir |= (1 << pin); 9036 9037 9038 snd_hda_codec_write(codec, codec->afg, 0, 9039 AC_VERB_SET_GPIO_MASK, gpiomask); 9040 snd_hda_codec_write(codec, codec->afg, 0, 9041 AC_VERB_SET_GPIO_DIRECTION, gpiodir); 9042 9043 msleep(1); 9044 9045 snd_hda_codec_write(codec, codec->afg, 0, 9046 AC_VERB_SET_GPIO_DATA, gpiostate); 9047} 9048 9049/* set up GPIO at initialization */ 9050static void alc885_macpro_init_hook(struct hda_codec *codec) 9051{ 9052 alc882_gpio_mute(codec, 0, 0); 9053 alc882_gpio_mute(codec, 1, 0); 9054} 9055 9056/* set up GPIO and update auto-muting at initialization */ 9057static void alc885_imac24_init_hook(struct hda_codec *codec) 9058{ 9059 alc885_macpro_init_hook(codec); 9060 alc_hp_automute(codec); 9061} 9062 9063/* 9064 * generic initialization of ADC, input mixers and output mixers 9065 */ 9066static const struct hda_verb alc883_auto_init_verbs[] = { 9067 /* 9068 * Unmute ADC0-2 and set the default input to mic-in 9069 */ 9070 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 9071 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9072 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 9073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9074 9075 /* 9076 * Set up output mixers (0x0c - 0x0f) 9077 */ 9078 /* set vol=0 to output mixers */ 9079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 9083 /* set up input amps for analog loopback */ 9084 /* Amp Indices: DAC = 0, mixer = 1 */ 9085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9088 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9090 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9093 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9094 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9095 9096 /* FIXME: use matrix-type input source selection */ 9097 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 9098 /* Input mixer2 */ 9099 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9100 /* Input mixer3 */ 9101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9102 { } 9103}; 9104 9105/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 9106static const struct hda_verb alc889A_mb31_ch2_init[] = { 9107 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9108 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9109 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9110 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 9111 { } /* end */ 9112}; 9113 9114/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ 9115static const struct hda_verb alc889A_mb31_ch4_init[] = { 9116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 9117 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9119 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 9120 { } /* end */ 9121}; 9122 9123/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ 9124static const struct hda_verb alc889A_mb31_ch5_init[] = { 9125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ 9126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ 9127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ 9128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ 9129 { } /* end */ 9130}; 9131 9132/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ 9133static const struct hda_verb alc889A_mb31_ch6_init[] = { 9134 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ 9135 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ 9136 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ 9137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ 9138 { } /* end */ 9139}; 9140 9141static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { 9142 { 2, alc889A_mb31_ch2_init }, 9143 { 4, alc889A_mb31_ch4_init }, 9144 { 5, alc889A_mb31_ch5_init }, 9145 { 6, alc889A_mb31_ch6_init }, 9146}; 9147 9148static const struct hda_verb alc883_medion_eapd_verbs[] = { 9149 /* eanable EAPD on medion laptop */ 9150 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9151 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 9152 { } 9153}; 9154 9155#define alc883_base_mixer alc882_base_mixer 9156 9157static const struct snd_kcontrol_new alc883_mitac_mixer[] = { 9158 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9159 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9160 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9161 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9162 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9163 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9164 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9166 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9168 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9170 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9171 { } /* end */ 9172}; 9173 9174static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { 9175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9176 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9177 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9178 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9180 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9182 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9183 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9184 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9185 { } /* end */ 9186}; 9187 9188static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { 9189 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9190 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), 9191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9192 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9193 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9194 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9196 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9197 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9198 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9199 { } /* end */ 9200}; 9201 9202static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 9203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9214 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9216 { } /* end */ 9217}; 9218 9219static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9239 { } /* end */ 9240}; 9241 9242static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { 9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 9248 HDA_OUTPUT), 9249 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9250 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9251 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9252 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9253 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9254 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9255 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9256 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 9259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9260 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9261 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 9262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9263 { } /* end */ 9264}; 9265 9266static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { 9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, 9272 HDA_OUTPUT), 9273 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9274 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9275 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9276 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9277 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), 9278 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9280 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 9282 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT), 9283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 9284 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9285 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), 9286 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9287 { } /* end */ 9288}; 9289 9290static const struct snd_kcontrol_new alc883_fivestack_mixer[] = { 9291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9293 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9294 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9295 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9296 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9297 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9298 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9307 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9308 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9309 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9310 { } /* end */ 9311}; 9312 9313static const struct snd_kcontrol_new alc883_targa_mixer[] = { 9314 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9315 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9316 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9317 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9318 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9319 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 9320 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 9321 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 9322 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 9323 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 9324 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9325 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9326 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9327 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9331 { } /* end */ 9332}; 9333 9334static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { 9335 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9336 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9337 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9338 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9339 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9340 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9342 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9344 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9345 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9346 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9347 { } /* end */ 9348}; 9349 9350static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9351 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9352 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9353 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9354 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 9355 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9356 { } /* end */ 9357}; 9358 9359static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { 9360 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9361 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 9363 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9365 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9366 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9368 { } /* end */ 9369}; 9370 9371static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { 9372 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9373 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 9374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9375 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9376 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9379 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9380 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9381 { } /* end */ 9382}; 9383 9384static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { 9385 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9386 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9387 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9388 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 9389 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), 9390 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), 9391 { } /* end */ 9392}; 9393 9394static const struct hda_verb alc883_medion_wim2160_verbs[] = { 9395 /* Unmute front mixer */ 9396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9397 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9398 9399 /* Set speaker pin to front mixer */ 9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9401 9402 /* Init headphone pin */ 9403 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9404 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9405 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9406 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9407 9408 { } /* end */ 9409}; 9410 9411/* toggle speaker-output according to the hp-jack state */ 9412static void alc883_medion_wim2160_setup(struct hda_codec *codec) 9413{ 9414 struct alc_spec *spec = codec->spec; 9415 9416 spec->autocfg.hp_pins[0] = 0x1a; 9417 spec->autocfg.speaker_pins[0] = 0x15; 9418 spec->automute = 1; 9419 spec->automute_mode = ALC_AUTOMUTE_AMP; 9420} 9421 9422static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 9423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9424 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9426 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9427 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9429 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9431 { } /* end */ 9432}; 9433 9434static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { 9435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9436 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9442 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9443 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9444 { } /* end */ 9445}; 9446 9447static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 9448 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9449 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9450 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 9451 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), 9452 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 9453 0x0d, 1, 0x0, HDA_OUTPUT), 9454 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), 9455 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), 9456 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), 9457 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9458 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9466 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9467 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 9468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9469 { } /* end */ 9470}; 9471 9472static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { 9473 /* Output mixers */ 9474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 9475 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 9476 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 9477 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), 9478 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, 9479 HDA_OUTPUT), 9480 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), 9481 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), 9482 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), 9483 /* Output switches */ 9484 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), 9485 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9486 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9487 /* Boost mixers */ 9488 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), 9489 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), 9490 /* Input mixers */ 9491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9493 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9494 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9495 { } /* end */ 9496}; 9497 9498static const struct snd_kcontrol_new alc883_vaiott_mixer[] = { 9499 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9500 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9501 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9503 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 9504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9505 { } /* end */ 9506}; 9507 9508static const struct hda_bind_ctls alc883_bind_cap_vol = { 9509 .ops = &snd_hda_bind_vol, 9510 .values = { 9511 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9512 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9513 0 9514 }, 9515}; 9516 9517static const struct hda_bind_ctls alc883_bind_cap_switch = { 9518 .ops = &snd_hda_bind_sw, 9519 .values = { 9520 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 9521 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 9522 0 9523 }, 9524}; 9525 9526static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 9527 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 9528 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9529 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), 9530 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9531 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9532 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9533 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 9534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9535 { } /* end */ 9536}; 9537 9538static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { 9539 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 9540 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 9541 { 9542 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9543 /* .name = "Capture Source", */ 9544 .name = "Input Source", 9545 .count = 1, 9546 .info = alc_mux_enum_info, 9547 .get = alc_mux_enum_get, 9548 .put = alc_mux_enum_put, 9549 }, 9550 { } /* end */ 9551}; 9552 9553static const struct snd_kcontrol_new alc883_chmode_mixer[] = { 9554 { 9555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 9556 .name = "Channel Mode", 9557 .info = alc_ch_mode_info, 9558 .get = alc_ch_mode_get, 9559 .put = alc_ch_mode_put, 9560 }, 9561 { } /* end */ 9562}; 9563 9564/* toggle speaker-output according to the hp-jack state */ 9565static void alc883_mitac_setup(struct hda_codec *codec) 9566{ 9567 struct alc_spec *spec = codec->spec; 9568 9569 spec->autocfg.hp_pins[0] = 0x15; 9570 spec->autocfg.speaker_pins[0] = 0x14; 9571 spec->autocfg.speaker_pins[1] = 0x17; 9572 spec->automute = 1; 9573 spec->automute_mode = ALC_AUTOMUTE_AMP; 9574} 9575 9576static const struct hda_verb alc883_mitac_verbs[] = { 9577 /* HP */ 9578 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9580 /* Subwoofer */ 9581 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, 9582 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9583 9584 /* enable unsolicited event */ 9585 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9586 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */ 9587 9588 { } /* end */ 9589}; 9590 9591static const struct hda_verb alc883_clevo_m540r_verbs[] = { 9592 /* HP */ 9593 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9595 /* Int speaker */ 9596 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ 9597 9598 /* enable unsolicited event */ 9599 /* 9600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9601 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9602 */ 9603 9604 { } /* end */ 9605}; 9606 9607static const struct hda_verb alc883_clevo_m720_verbs[] = { 9608 /* HP */ 9609 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9610 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9611 /* Int speaker */ 9612 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 9613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9614 9615 /* enable unsolicited event */ 9616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9617 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9618 9619 { } /* end */ 9620}; 9621 9622static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { 9623 /* HP */ 9624 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9626 /* Subwoofer */ 9627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 9628 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9629 9630 /* enable unsolicited event */ 9631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9632 9633 { } /* end */ 9634}; 9635 9636static const struct hda_verb alc883_targa_verbs[] = { 9637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9639 9640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9641 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9642 9643/* Connect Line-Out side jack (SPDIF) to Side */ 9644 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9646 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 9647/* Connect Mic jack to CLFE */ 9648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9650 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, 9651/* Connect Line-in jack to Surround */ 9652 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9653 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9654 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 9655/* Connect HP out jack to Front */ 9656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9658 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9659 9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9661 9662 { } /* end */ 9663}; 9664 9665static const struct hda_verb alc883_lenovo_101e_verbs[] = { 9666 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, 9668 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, 9669 { } /* end */ 9670}; 9671 9672static const struct hda_verb alc883_lenovo_nb0763_verbs[] = { 9673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9675 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9677 { } /* end */ 9678}; 9679 9680static const struct hda_verb alc888_lenovo_ms7195_verbs[] = { 9681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9684 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN}, 9685 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9686 { } /* end */ 9687}; 9688 9689static const struct hda_verb alc883_haier_w66_verbs[] = { 9690 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9691 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9692 9693 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9694 9695 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 9696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9697 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9699 { } /* end */ 9700}; 9701 9702static const struct hda_verb alc888_lenovo_sky_verbs[] = { 9703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9708 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9709 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, 9710 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9711 { } /* end */ 9712}; 9713 9714static const struct hda_verb alc888_6st_dell_verbs[] = { 9715 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9716 { } 9717}; 9718 9719static const struct hda_verb alc883_vaiott_verbs[] = { 9720 /* HP */ 9721 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9723 9724 /* enable unsolicited event */ 9725 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9726 9727 { } /* end */ 9728}; 9729 9730static void alc888_3st_hp_setup(struct hda_codec *codec) 9731{ 9732 struct alc_spec *spec = codec->spec; 9733 9734 spec->autocfg.hp_pins[0] = 0x1b; 9735 spec->autocfg.speaker_pins[0] = 0x14; 9736 spec->autocfg.speaker_pins[1] = 0x16; 9737 spec->autocfg.speaker_pins[2] = 0x18; 9738 spec->automute = 1; 9739 spec->automute_mode = ALC_AUTOMUTE_AMP; 9740} 9741 9742static const struct hda_verb alc888_3st_hp_verbs[] = { 9743 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ 9744 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ 9745 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ 9746 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9747 { } /* end */ 9748}; 9749 9750/* 9751 * 2ch mode 9752 */ 9753static const struct hda_verb alc888_3st_hp_2ch_init[] = { 9754 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9755 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9756 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 9757 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9758 { } /* end */ 9759}; 9760 9761/* 9762 * 4ch mode 9763 */ 9764static const struct hda_verb alc888_3st_hp_4ch_init[] = { 9765 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 9766 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 9767 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9768 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9769 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9770 { } /* end */ 9771}; 9772 9773/* 9774 * 6ch mode 9775 */ 9776static const struct hda_verb alc888_3st_hp_6ch_init[] = { 9777 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9778 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9779 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 9780 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 9781 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 9782 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, 9783 { } /* end */ 9784}; 9785 9786static const struct hda_channel_mode alc888_3st_hp_modes[3] = { 9787 { 2, alc888_3st_hp_2ch_init }, 9788 { 4, alc888_3st_hp_4ch_init }, 9789 { 6, alc888_3st_hp_6ch_init }, 9790}; 9791 9792static void alc888_lenovo_ms7195_setup(struct hda_codec *codec) 9793{ 9794 struct alc_spec *spec = codec->spec; 9795 9796 spec->autocfg.hp_pins[0] = 0x1b; 9797 spec->autocfg.line_out_pins[0] = 0x14; 9798 spec->autocfg.speaker_pins[0] = 0x15; 9799 spec->automute = 1; 9800 spec->automute_mode = ALC_AUTOMUTE_AMP; 9801} 9802 9803/* toggle speaker-output according to the hp-jack state */ 9804static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) 9805{ 9806 struct alc_spec *spec = codec->spec; 9807 9808 spec->autocfg.hp_pins[0] = 0x14; 9809 spec->autocfg.speaker_pins[0] = 0x15; 9810 spec->automute = 1; 9811 spec->automute_mode = ALC_AUTOMUTE_AMP; 9812} 9813 9814/* toggle speaker-output according to the hp-jack state */ 9815#define alc883_targa_init_hook alc882_targa_init_hook 9816#define alc883_targa_unsol_event alc882_targa_unsol_event 9817 9818static void alc883_clevo_m720_setup(struct hda_codec *codec) 9819{ 9820 struct alc_spec *spec = codec->spec; 9821 9822 spec->autocfg.hp_pins[0] = 0x15; 9823 spec->autocfg.speaker_pins[0] = 0x14; 9824 spec->automute = 1; 9825 spec->automute_mode = ALC_AUTOMUTE_AMP; 9826} 9827 9828static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9829{ 9830 alc_hp_automute(codec); 9831 alc88x_simple_mic_automute(codec); 9832} 9833 9834static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9835 unsigned int res) 9836{ 9837 switch (res >> 26) { 9838 case ALC880_MIC_EVENT: 9839 alc88x_simple_mic_automute(codec); 9840 break; 9841 default: 9842 alc_sku_unsol_event(codec, res); 9843 break; 9844 } 9845} 9846 9847/* toggle speaker-output according to the hp-jack state */ 9848static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) 9849{ 9850 struct alc_spec *spec = codec->spec; 9851 9852 spec->autocfg.hp_pins[0] = 0x14; 9853 spec->autocfg.speaker_pins[0] = 0x15; 9854 spec->automute = 1; 9855 spec->automute_mode = ALC_AUTOMUTE_AMP; 9856} 9857 9858static void alc883_haier_w66_setup(struct hda_codec *codec) 9859{ 9860 struct alc_spec *spec = codec->spec; 9861 9862 spec->autocfg.hp_pins[0] = 0x1b; 9863 spec->autocfg.speaker_pins[0] = 0x14; 9864 spec->automute = 1; 9865 spec->automute_mode = ALC_AUTOMUTE_AMP; 9866} 9867 9868static void alc883_lenovo_101e_setup(struct hda_codec *codec) 9869{ 9870 struct alc_spec *spec = codec->spec; 9871 9872 spec->autocfg.hp_pins[0] = 0x1b; 9873 spec->autocfg.line_out_pins[0] = 0x14; 9874 spec->autocfg.speaker_pins[0] = 0x15; 9875 spec->automute = 1; 9876 spec->detect_line = 1; 9877 spec->automute_lines = 1; 9878 spec->automute_mode = ALC_AUTOMUTE_AMP; 9879} 9880 9881/* toggle speaker-output according to the hp-jack state */ 9882static void alc883_acer_aspire_setup(struct hda_codec *codec) 9883{ 9884 struct alc_spec *spec = codec->spec; 9885 9886 spec->autocfg.hp_pins[0] = 0x14; 9887 spec->autocfg.speaker_pins[0] = 0x15; 9888 spec->autocfg.speaker_pins[1] = 0x16; 9889 spec->automute = 1; 9890 spec->automute_mode = ALC_AUTOMUTE_AMP; 9891} 9892 9893static const struct hda_verb alc883_acer_eapd_verbs[] = { 9894 /* HP Pin: output 0 (0x0c) */ 9895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 9897 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 9898 /* Front Pin: output 0 (0x0c) */ 9899 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9900 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9901 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9902 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 9903 /* eanable EAPD on medion laptop */ 9904 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 9905 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 9906 /* enable unsolicited event */ 9907 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9908 { } 9909}; 9910 9911static void alc888_6st_dell_setup(struct hda_codec *codec) 9912{ 9913 struct alc_spec *spec = codec->spec; 9914 9915 spec->autocfg.hp_pins[0] = 0x1b; 9916 spec->autocfg.speaker_pins[0] = 0x14; 9917 spec->autocfg.speaker_pins[1] = 0x15; 9918 spec->autocfg.speaker_pins[2] = 0x16; 9919 spec->autocfg.speaker_pins[3] = 0x17; 9920 spec->automute = 1; 9921 spec->automute_mode = ALC_AUTOMUTE_AMP; 9922} 9923 9924static void alc888_lenovo_sky_setup(struct hda_codec *codec) 9925{ 9926 struct alc_spec *spec = codec->spec; 9927 9928 spec->autocfg.hp_pins[0] = 0x1b; 9929 spec->autocfg.speaker_pins[0] = 0x14; 9930 spec->autocfg.speaker_pins[1] = 0x15; 9931 spec->autocfg.speaker_pins[2] = 0x16; 9932 spec->autocfg.speaker_pins[3] = 0x17; 9933 spec->autocfg.speaker_pins[4] = 0x1a; 9934 spec->automute = 1; 9935 spec->automute_mode = ALC_AUTOMUTE_AMP; 9936} 9937 9938static void alc883_vaiott_setup(struct hda_codec *codec) 9939{ 9940 struct alc_spec *spec = codec->spec; 9941 9942 spec->autocfg.hp_pins[0] = 0x15; 9943 spec->autocfg.speaker_pins[0] = 0x14; 9944 spec->autocfg.speaker_pins[1] = 0x17; 9945 spec->automute = 1; 9946 spec->automute_mode = ALC_AUTOMUTE_AMP; 9947} 9948 9949static const struct hda_verb alc888_asus_m90v_verbs[] = { 9950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9951 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9952 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 9953 /* enable unsolicited event */ 9954 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 9956 { } /* end */ 9957}; 9958 9959static void alc883_mode2_setup(struct hda_codec *codec) 9960{ 9961 struct alc_spec *spec = codec->spec; 9962 9963 spec->autocfg.hp_pins[0] = 0x1b; 9964 spec->autocfg.speaker_pins[0] = 0x14; 9965 spec->autocfg.speaker_pins[1] = 0x15; 9966 spec->autocfg.speaker_pins[2] = 0x16; 9967 spec->ext_mic.pin = 0x18; 9968 spec->int_mic.pin = 0x19; 9969 spec->ext_mic.mux_idx = 0; 9970 spec->int_mic.mux_idx = 1; 9971 spec->auto_mic = 1; 9972 spec->automute = 1; 9973 spec->automute_mode = ALC_AUTOMUTE_AMP; 9974} 9975 9976static const struct hda_verb alc888_asus_eee1601_verbs[] = { 9977 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 9978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 9979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 9980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 9981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 9982 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, 9983 {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, 9984 /* enable unsolicited event */ 9985 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 9986 { } /* end */ 9987}; 9988 9989static void alc883_eee1601_inithook(struct hda_codec *codec) 9990{ 9991 struct alc_spec *spec = codec->spec; 9992 9993 spec->autocfg.hp_pins[0] = 0x14; 9994 spec->autocfg.speaker_pins[0] = 0x1b; 9995 alc_hp_automute(codec); 9996} 9997 9998static const struct hda_verb alc889A_mb31_verbs[] = { 9999 /* Init rear pin (used as headphone output) */ 10000 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ 10001 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ 10002 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 10003 /* Init line pin (used as output in 4ch and 6ch mode) */ 10004 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ 10005 /* Init line 2 pin (used as headphone out by default) */ 10006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ 10007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ 10008 { } /* end */ 10009}; 10010 10011/* Mute speakers according to the headphone jack state */ 10012static void alc889A_mb31_automute(struct hda_codec *codec) 10013{ 10014 unsigned int present; 10015 10016 /* Mute only in 2ch or 4ch mode */ 10017 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) 10018 == 0x00) { 10019 present = snd_hda_jack_detect(codec, 0x15); 10020 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 10021 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10022 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 10023 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 10024 } 10025} 10026 10027static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) 10028{ 10029 if ((res >> 26) == ALC880_HP_EVENT) 10030 alc889A_mb31_automute(codec); 10031} 10032 10033 10034#ifdef CONFIG_SND_HDA_POWER_SAVE 10035#define alc882_loopbacks alc880_loopbacks 10036#endif 10037 10038/* pcm configuration: identical with ALC880 */ 10039#define alc882_pcm_analog_playback alc880_pcm_analog_playback 10040#define alc882_pcm_analog_capture alc880_pcm_analog_capture 10041#define alc882_pcm_digital_playback alc880_pcm_digital_playback 10042#define alc882_pcm_digital_capture alc880_pcm_digital_capture 10043 10044static const hda_nid_t alc883_slave_dig_outs[] = { 10045 ALC1200_DIGOUT_NID, 0, 10046}; 10047 10048static const hda_nid_t alc1200_slave_dig_outs[] = { 10049 ALC883_DIGOUT_NID, 0, 10050}; 10051 10052/* 10053 * configuration and preset 10054 */ 10055static const char * const alc882_models[ALC882_MODEL_LAST] = { 10056 [ALC882_3ST_DIG] = "3stack-dig", 10057 [ALC882_6ST_DIG] = "6stack-dig", 10058 [ALC882_ARIMA] = "arima", 10059 [ALC882_W2JC] = "w2jc", 10060 [ALC882_TARGA] = "targa", 10061 [ALC882_ASUS_A7J] = "asus-a7j", 10062 [ALC882_ASUS_A7M] = "asus-a7m", 10063 [ALC885_MACPRO] = "macpro", 10064 [ALC885_MB5] = "mb5", 10065 [ALC885_MACMINI3] = "macmini3", 10066 [ALC885_MBA21] = "mba21", 10067 [ALC885_MBP3] = "mbp3", 10068 [ALC885_IMAC24] = "imac24", 10069 [ALC885_IMAC91] = "imac91", 10070 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", 10071 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 10072 [ALC883_3ST_6ch] = "3stack-6ch", 10073 [ALC883_6ST_DIG] = "alc883-6stack-dig", 10074 [ALC883_TARGA_DIG] = "targa-dig", 10075 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 10076 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 10077 [ALC883_ACER] = "acer", 10078 [ALC883_ACER_ASPIRE] = "acer-aspire", 10079 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 10080 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 10081 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 10082 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 10083 [ALC883_MEDION] = "medion", 10084 [ALC883_MEDION_WIM2160] = "medion-wim2160", 10085 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 10086 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 10087 [ALC883_LENOVO_NB0763] = "lenovo-nb0763", 10088 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", 10089 [ALC888_LENOVO_SKY] = "lenovo-sky", 10090 [ALC883_HAIER_W66] = "haier-w66", 10091 [ALC888_3ST_HP] = "3stack-hp", 10092 [ALC888_6ST_DELL] = "6stack-dell", 10093 [ALC883_MITAC] = "mitac", 10094 [ALC883_CLEVO_M540R] = "clevo-m540r", 10095 [ALC883_CLEVO_M720] = "clevo-m720", 10096 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 10097 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 10098 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 10099 [ALC889A_INTEL] = "intel-alc889a", 10100 [ALC889_INTEL] = "intel-x58", 10101 [ALC1200_ASUS_P5Q] = "asus-p5q", 10102 [ALC889A_MB31] = "mb31", 10103 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 10104 [ALC882_AUTO] = "auto", 10105}; 10106 10107static const struct snd_pci_quirk alc882_cfg_tbl[] = { 10108 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), 10109 10110 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 10111 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 10112 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 10113 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 10114 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 10115 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 10116 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 10117 ALC888_ACER_ASPIRE_4930G), 10118 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", 10119 ALC888_ACER_ASPIRE_4930G), 10120 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", 10121 ALC888_ACER_ASPIRE_8930G), 10122 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 10123 ALC888_ACER_ASPIRE_8930G), 10124 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), 10125 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), 10126 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 10127 ALC888_ACER_ASPIRE_6530G), 10128 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 10129 ALC888_ACER_ASPIRE_6530G), 10130 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", 10131 ALC888_ACER_ASPIRE_7730G), 10132 /* default Acer -- disabled as it causes more problems. 10133 * model=auto should work fine now 10134 */ 10135 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 10136 10137 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 10138 10139 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG), 10140 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 10141 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 10142 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 10143 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 10144 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 10145 10146 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), 10147 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), 10148 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), 10149 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 10150 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), 10151 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), 10152 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), 10153 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 10154 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 10155 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 10156 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 10157 10158 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), 10159 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 10160 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), 10161 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 10162 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 10163 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 10164 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 10165 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 10166 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), 10167 10168 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 10169 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 10170 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 10171 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ 10172 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), 10173 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), 10174 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 10175 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 10176 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 10177 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), 10178 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), 10179 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 10180 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 10181 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 10182 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), 10183 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 10184 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 10185 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 10186 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), 10187 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), 10188 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 10189 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 10190 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 10191 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), 10192 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 10193 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 10194 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 10195 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 10196 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), 10197 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 10198 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), 10199 10200 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 10201 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), 10202 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 10203 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 10204 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), 10205 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 10206 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 10207 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ 10208 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 10209 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 10210 ALC883_FUJITSU_PI2515), 10211 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", 10212 ALC888_FUJITSU_XA3530), 10213 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 10214 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 10215 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 10216 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), 10217 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), 10218 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 10219 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 10220 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 10221 10222 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 10223 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 10224 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 10225 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), 10226 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), 10227 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), 10228 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), 10229 10230 {} 10231}; 10232 10233/* codec SSID table for Intel Mac */ 10234static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { 10235 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), 10236 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), 10237 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), 10238 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), 10239 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), 10240 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), 10241 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), 10242 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), 10243 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), 10244 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), 10245 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), 10246 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), 10247 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), 10248 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), 10249 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), 10250 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), 10251 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), 10252 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, 10253 * so apparently no perfect solution yet 10254 */ 10255 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 10256 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 10257 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), 10258 {} /* terminator */ 10259}; 10260 10261static const struct alc_config_preset alc882_presets[] = { 10262 [ALC882_3ST_DIG] = { 10263 .mixers = { alc882_base_mixer }, 10264 .init_verbs = { alc882_base_init_verbs, 10265 alc882_adc1_init_verbs }, 10266 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10267 .dac_nids = alc882_dac_nids, 10268 .dig_out_nid = ALC882_DIGOUT_NID, 10269 .dig_in_nid = ALC882_DIGIN_NID, 10270 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10271 .channel_mode = alc882_ch_modes, 10272 .need_dac_fix = 1, 10273 .input_mux = &alc882_capture_source, 10274 }, 10275 [ALC882_6ST_DIG] = { 10276 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 10277 .init_verbs = { alc882_base_init_verbs, 10278 alc882_adc1_init_verbs }, 10279 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10280 .dac_nids = alc882_dac_nids, 10281 .dig_out_nid = ALC882_DIGOUT_NID, 10282 .dig_in_nid = ALC882_DIGIN_NID, 10283 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 10284 .channel_mode = alc882_sixstack_modes, 10285 .input_mux = &alc882_capture_source, 10286 }, 10287 [ALC882_ARIMA] = { 10288 .mixers = { alc882_base_mixer, alc882_chmode_mixer }, 10289 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10290 alc882_eapd_verbs }, 10291 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10292 .dac_nids = alc882_dac_nids, 10293 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), 10294 .channel_mode = alc882_sixstack_modes, 10295 .input_mux = &alc882_capture_source, 10296 }, 10297 [ALC882_W2JC] = { 10298 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, 10299 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10300 alc882_eapd_verbs, alc880_gpio1_init_verbs }, 10301 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10302 .dac_nids = alc882_dac_nids, 10303 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10304 .channel_mode = alc880_threestack_modes, 10305 .need_dac_fix = 1, 10306 .input_mux = &alc882_capture_source, 10307 .dig_out_nid = ALC882_DIGOUT_NID, 10308 }, 10309 [ALC885_MBA21] = { 10310 .mixers = { alc885_mba21_mixer }, 10311 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, 10312 .num_dacs = 2, 10313 .dac_nids = alc882_dac_nids, 10314 .channel_mode = alc885_mba21_ch_modes, 10315 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10316 .input_mux = &alc882_capture_source, 10317 .unsol_event = alc_sku_unsol_event, 10318 .setup = alc885_mba21_setup, 10319 .init_hook = alc_hp_automute, 10320 }, 10321 [ALC885_MBP3] = { 10322 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 10323 .init_verbs = { alc885_mbp3_init_verbs, 10324 alc880_gpio1_init_verbs }, 10325 .num_dacs = 2, 10326 .dac_nids = alc882_dac_nids, 10327 .hp_nid = 0x04, 10328 .channel_mode = alc885_mbp_4ch_modes, 10329 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), 10330 .input_mux = &alc882_capture_source, 10331 .dig_out_nid = ALC882_DIGOUT_NID, 10332 .dig_in_nid = ALC882_DIGIN_NID, 10333 .unsol_event = alc_sku_unsol_event, 10334 .setup = alc885_mbp3_setup, 10335 .init_hook = alc_hp_automute, 10336 }, 10337 [ALC885_MB5] = { 10338 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, 10339 .init_verbs = { alc885_mb5_init_verbs, 10340 alc880_gpio1_init_verbs }, 10341 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10342 .dac_nids = alc882_dac_nids, 10343 .channel_mode = alc885_mb5_6ch_modes, 10344 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), 10345 .input_mux = &mb5_capture_source, 10346 .dig_out_nid = ALC882_DIGOUT_NID, 10347 .dig_in_nid = ALC882_DIGIN_NID, 10348 .unsol_event = alc_sku_unsol_event, 10349 .setup = alc885_mb5_setup, 10350 .init_hook = alc_hp_automute, 10351 }, 10352 [ALC885_MACMINI3] = { 10353 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, 10354 .init_verbs = { alc885_macmini3_init_verbs, 10355 alc880_gpio1_init_verbs }, 10356 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10357 .dac_nids = alc882_dac_nids, 10358 .channel_mode = alc885_macmini3_6ch_modes, 10359 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), 10360 .input_mux = &macmini3_capture_source, 10361 .dig_out_nid = ALC882_DIGOUT_NID, 10362 .dig_in_nid = ALC882_DIGIN_NID, 10363 .unsol_event = alc_sku_unsol_event, 10364 .setup = alc885_macmini3_setup, 10365 .init_hook = alc_hp_automute, 10366 }, 10367 [ALC885_MACPRO] = { 10368 .mixers = { alc882_macpro_mixer }, 10369 .init_verbs = { alc882_macpro_init_verbs }, 10370 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10371 .dac_nids = alc882_dac_nids, 10372 .dig_out_nid = ALC882_DIGOUT_NID, 10373 .dig_in_nid = ALC882_DIGIN_NID, 10374 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10375 .channel_mode = alc882_ch_modes, 10376 .input_mux = &alc882_capture_source, 10377 .init_hook = alc885_macpro_init_hook, 10378 }, 10379 [ALC885_IMAC24] = { 10380 .mixers = { alc885_imac24_mixer }, 10381 .init_verbs = { alc885_imac24_init_verbs }, 10382 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10383 .dac_nids = alc882_dac_nids, 10384 .dig_out_nid = ALC882_DIGOUT_NID, 10385 .dig_in_nid = ALC882_DIGIN_NID, 10386 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), 10387 .channel_mode = alc882_ch_modes, 10388 .input_mux = &alc882_capture_source, 10389 .unsol_event = alc_sku_unsol_event, 10390 .setup = alc885_imac24_setup, 10391 .init_hook = alc885_imac24_init_hook, 10392 }, 10393 [ALC885_IMAC91] = { 10394 .mixers = {alc885_imac91_mixer}, 10395 .init_verbs = { alc885_imac91_init_verbs, 10396 alc880_gpio1_init_verbs }, 10397 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10398 .dac_nids = alc882_dac_nids, 10399 .channel_mode = alc885_mba21_ch_modes, 10400 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), 10401 .input_mux = &alc889A_imac91_capture_source, 10402 .dig_out_nid = ALC882_DIGOUT_NID, 10403 .dig_in_nid = ALC882_DIGIN_NID, 10404 .unsol_event = alc_sku_unsol_event, 10405 .setup = alc885_imac91_setup, 10406 .init_hook = alc_hp_automute, 10407 }, 10408 [ALC882_TARGA] = { 10409 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 10410 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10411 alc880_gpio3_init_verbs, alc882_targa_verbs}, 10412 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10413 .dac_nids = alc882_dac_nids, 10414 .dig_out_nid = ALC882_DIGOUT_NID, 10415 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10416 .adc_nids = alc882_adc_nids, 10417 .capsrc_nids = alc882_capsrc_nids, 10418 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10419 .channel_mode = alc882_3ST_6ch_modes, 10420 .need_dac_fix = 1, 10421 .input_mux = &alc882_capture_source, 10422 .unsol_event = alc_sku_unsol_event, 10423 .setup = alc882_targa_setup, 10424 .init_hook = alc882_targa_automute, 10425 }, 10426 [ALC882_ASUS_A7J] = { 10427 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, 10428 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10429 alc882_asus_a7j_verbs}, 10430 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10431 .dac_nids = alc882_dac_nids, 10432 .dig_out_nid = ALC882_DIGOUT_NID, 10433 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), 10434 .adc_nids = alc882_adc_nids, 10435 .capsrc_nids = alc882_capsrc_nids, 10436 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), 10437 .channel_mode = alc882_3ST_6ch_modes, 10438 .need_dac_fix = 1, 10439 .input_mux = &alc882_capture_source, 10440 }, 10441 [ALC882_ASUS_A7M] = { 10442 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, 10443 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, 10444 alc882_eapd_verbs, alc880_gpio1_init_verbs, 10445 alc882_asus_a7m_verbs }, 10446 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 10447 .dac_nids = alc882_dac_nids, 10448 .dig_out_nid = ALC882_DIGOUT_NID, 10449 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), 10450 .channel_mode = alc880_threestack_modes, 10451 .need_dac_fix = 1, 10452 .input_mux = &alc882_capture_source, 10453 }, 10454 [ALC883_3ST_2ch_DIG] = { 10455 .mixers = { alc883_3ST_2ch_mixer }, 10456 .init_verbs = { alc883_init_verbs }, 10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10458 .dac_nids = alc883_dac_nids, 10459 .dig_out_nid = ALC883_DIGOUT_NID, 10460 .dig_in_nid = ALC883_DIGIN_NID, 10461 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10462 .channel_mode = alc883_3ST_2ch_modes, 10463 .input_mux = &alc883_capture_source, 10464 }, 10465 [ALC883_3ST_6ch_DIG] = { 10466 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10467 .init_verbs = { alc883_init_verbs }, 10468 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10469 .dac_nids = alc883_dac_nids, 10470 .dig_out_nid = ALC883_DIGOUT_NID, 10471 .dig_in_nid = ALC883_DIGIN_NID, 10472 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10473 .channel_mode = alc883_3ST_6ch_modes, 10474 .need_dac_fix = 1, 10475 .input_mux = &alc883_capture_source, 10476 }, 10477 [ALC883_3ST_6ch] = { 10478 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10479 .init_verbs = { alc883_init_verbs }, 10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10481 .dac_nids = alc883_dac_nids, 10482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10483 .channel_mode = alc883_3ST_6ch_modes, 10484 .need_dac_fix = 1, 10485 .input_mux = &alc883_capture_source, 10486 }, 10487 [ALC883_3ST_6ch_INTEL] = { 10488 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, 10489 .init_verbs = { alc883_init_verbs }, 10490 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10491 .dac_nids = alc883_dac_nids, 10492 .dig_out_nid = ALC883_DIGOUT_NID, 10493 .dig_in_nid = ALC883_DIGIN_NID, 10494 .slave_dig_outs = alc883_slave_dig_outs, 10495 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), 10496 .channel_mode = alc883_3ST_6ch_intel_modes, 10497 .need_dac_fix = 1, 10498 .input_mux = &alc883_3stack_6ch_intel, 10499 }, 10500 [ALC889A_INTEL] = { 10501 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10502 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, 10503 alc_hp15_unsol_verbs }, 10504 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10505 .dac_nids = alc883_dac_nids, 10506 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10507 .adc_nids = alc889_adc_nids, 10508 .dig_out_nid = ALC883_DIGOUT_NID, 10509 .dig_in_nid = ALC883_DIGIN_NID, 10510 .slave_dig_outs = alc883_slave_dig_outs, 10511 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10512 .channel_mode = alc889_8ch_intel_modes, 10513 .capsrc_nids = alc889_capsrc_nids, 10514 .input_mux = &alc889_capture_source, 10515 .setup = alc889_automute_setup, 10516 .init_hook = alc_hp_automute, 10517 .unsol_event = alc_sku_unsol_event, 10518 .need_dac_fix = 1, 10519 }, 10520 [ALC889_INTEL] = { 10521 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, 10522 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, 10523 alc889_eapd_verbs, alc_hp15_unsol_verbs}, 10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10525 .dac_nids = alc883_dac_nids, 10526 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10527 .adc_nids = alc889_adc_nids, 10528 .dig_out_nid = ALC883_DIGOUT_NID, 10529 .dig_in_nid = ALC883_DIGIN_NID, 10530 .slave_dig_outs = alc883_slave_dig_outs, 10531 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), 10532 .channel_mode = alc889_8ch_intel_modes, 10533 .capsrc_nids = alc889_capsrc_nids, 10534 .input_mux = &alc889_capture_source, 10535 .setup = alc889_automute_setup, 10536 .init_hook = alc889_intel_init_hook, 10537 .unsol_event = alc_sku_unsol_event, 10538 .need_dac_fix = 1, 10539 }, 10540 [ALC883_6ST_DIG] = { 10541 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10542 .init_verbs = { alc883_init_verbs }, 10543 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10544 .dac_nids = alc883_dac_nids, 10545 .dig_out_nid = ALC883_DIGOUT_NID, 10546 .dig_in_nid = ALC883_DIGIN_NID, 10547 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10548 .channel_mode = alc883_sixstack_modes, 10549 .input_mux = &alc883_capture_source, 10550 }, 10551 [ALC883_TARGA_DIG] = { 10552 .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, 10553 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10554 alc883_targa_verbs}, 10555 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10556 .dac_nids = alc883_dac_nids, 10557 .dig_out_nid = ALC883_DIGOUT_NID, 10558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10559 .channel_mode = alc883_3ST_6ch_modes, 10560 .need_dac_fix = 1, 10561 .input_mux = &alc883_capture_source, 10562 .unsol_event = alc883_targa_unsol_event, 10563 .setup = alc882_targa_setup, 10564 .init_hook = alc882_targa_automute, 10565 }, 10566 [ALC883_TARGA_2ch_DIG] = { 10567 .mixers = { alc883_targa_2ch_mixer}, 10568 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10569 alc883_targa_verbs}, 10570 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10571 .dac_nids = alc883_dac_nids, 10572 .adc_nids = alc883_adc_nids_alt, 10573 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10574 .capsrc_nids = alc883_capsrc_nids, 10575 .dig_out_nid = ALC883_DIGOUT_NID, 10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10577 .channel_mode = alc883_3ST_2ch_modes, 10578 .input_mux = &alc883_capture_source, 10579 .unsol_event = alc883_targa_unsol_event, 10580 .setup = alc882_targa_setup, 10581 .init_hook = alc882_targa_automute, 10582 }, 10583 [ALC883_TARGA_8ch_DIG] = { 10584 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, 10585 alc883_chmode_mixer }, 10586 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, 10587 alc883_targa_verbs }, 10588 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10589 .dac_nids = alc883_dac_nids, 10590 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10591 .adc_nids = alc883_adc_nids_rev, 10592 .capsrc_nids = alc883_capsrc_nids_rev, 10593 .dig_out_nid = ALC883_DIGOUT_NID, 10594 .dig_in_nid = ALC883_DIGIN_NID, 10595 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), 10596 .channel_mode = alc883_4ST_8ch_modes, 10597 .need_dac_fix = 1, 10598 .input_mux = &alc883_capture_source, 10599 .unsol_event = alc883_targa_unsol_event, 10600 .setup = alc882_targa_setup, 10601 .init_hook = alc882_targa_automute, 10602 }, 10603 [ALC883_ACER] = { 10604 .mixers = { alc883_base_mixer }, 10605 /* On TravelMate laptops, GPIO 0 enables the internal speaker 10606 * and the headphone jack. Turn this on and rely on the 10607 * standard mute methods whenever the user wants to turn 10608 * these outputs off. 10609 */ 10610 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, 10611 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10612 .dac_nids = alc883_dac_nids, 10613 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10614 .channel_mode = alc883_3ST_2ch_modes, 10615 .input_mux = &alc883_capture_source, 10616 }, 10617 [ALC883_ACER_ASPIRE] = { 10618 .mixers = { alc883_acer_aspire_mixer }, 10619 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, 10620 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10621 .dac_nids = alc883_dac_nids, 10622 .dig_out_nid = ALC883_DIGOUT_NID, 10623 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10624 .channel_mode = alc883_3ST_2ch_modes, 10625 .input_mux = &alc883_capture_source, 10626 .unsol_event = alc_sku_unsol_event, 10627 .setup = alc883_acer_aspire_setup, 10628 .init_hook = alc_hp_automute, 10629 }, 10630 [ALC888_ACER_ASPIRE_4930G] = { 10631 .mixers = { alc888_acer_aspire_4930g_mixer, 10632 alc883_chmode_mixer }, 10633 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10634 alc888_acer_aspire_4930g_verbs }, 10635 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10636 .dac_nids = alc883_dac_nids, 10637 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10638 .adc_nids = alc883_adc_nids_rev, 10639 .capsrc_nids = alc883_capsrc_nids_rev, 10640 .dig_out_nid = ALC883_DIGOUT_NID, 10641 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10642 .channel_mode = alc883_3ST_6ch_modes, 10643 .need_dac_fix = 1, 10644 .const_channel_count = 6, 10645 .num_mux_defs = 10646 ARRAY_SIZE(alc888_2_capture_sources), 10647 .input_mux = alc888_2_capture_sources, 10648 .unsol_event = alc_sku_unsol_event, 10649 .setup = alc888_acer_aspire_4930g_setup, 10650 .init_hook = alc_hp_automute, 10651 }, 10652 [ALC888_ACER_ASPIRE_6530G] = { 10653 .mixers = { alc888_acer_aspire_6530_mixer }, 10654 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10655 alc888_acer_aspire_6530g_verbs }, 10656 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10657 .dac_nids = alc883_dac_nids, 10658 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10659 .adc_nids = alc883_adc_nids_rev, 10660 .capsrc_nids = alc883_capsrc_nids_rev, 10661 .dig_out_nid = ALC883_DIGOUT_NID, 10662 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10663 .channel_mode = alc883_3ST_2ch_modes, 10664 .num_mux_defs = 10665 ARRAY_SIZE(alc888_2_capture_sources), 10666 .input_mux = alc888_acer_aspire_6530_sources, 10667 .unsol_event = alc_sku_unsol_event, 10668 .setup = alc888_acer_aspire_6530g_setup, 10669 .init_hook = alc_hp_automute, 10670 }, 10671 [ALC888_ACER_ASPIRE_8930G] = { 10672 .mixers = { alc889_acer_aspire_8930g_mixer, 10673 alc883_chmode_mixer }, 10674 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10675 alc889_acer_aspire_8930g_verbs, 10676 alc889_eapd_verbs}, 10677 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10678 .dac_nids = alc883_dac_nids, 10679 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 10680 .adc_nids = alc889_adc_nids, 10681 .capsrc_nids = alc889_capsrc_nids, 10682 .dig_out_nid = ALC883_DIGOUT_NID, 10683 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10684 .channel_mode = alc883_3ST_6ch_modes, 10685 .need_dac_fix = 1, 10686 .const_channel_count = 6, 10687 .num_mux_defs = 10688 ARRAY_SIZE(alc889_capture_sources), 10689 .input_mux = alc889_capture_sources, 10690 .unsol_event = alc_sku_unsol_event, 10691 .setup = alc889_acer_aspire_8930g_setup, 10692 .init_hook = alc_hp_automute, 10693#ifdef CONFIG_SND_HDA_POWER_SAVE 10694 .power_hook = alc_power_eapd, 10695#endif 10696 }, 10697 [ALC888_ACER_ASPIRE_7730G] = { 10698 .mixers = { alc883_3ST_6ch_mixer, 10699 alc883_chmode_mixer }, 10700 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, 10701 alc888_acer_aspire_7730G_verbs }, 10702 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10703 .dac_nids = alc883_dac_nids, 10704 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10705 .adc_nids = alc883_adc_nids_rev, 10706 .capsrc_nids = alc883_capsrc_nids_rev, 10707 .dig_out_nid = ALC883_DIGOUT_NID, 10708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10709 .channel_mode = alc883_3ST_6ch_modes, 10710 .need_dac_fix = 1, 10711 .const_channel_count = 6, 10712 .input_mux = &alc883_capture_source, 10713 .unsol_event = alc_sku_unsol_event, 10714 .setup = alc888_acer_aspire_7730g_setup, 10715 .init_hook = alc_hp_automute, 10716 }, 10717 [ALC883_MEDION] = { 10718 .mixers = { alc883_fivestack_mixer, 10719 alc883_chmode_mixer }, 10720 .init_verbs = { alc883_init_verbs, 10721 alc883_medion_eapd_verbs }, 10722 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10723 .dac_nids = alc883_dac_nids, 10724 .adc_nids = alc883_adc_nids_alt, 10725 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10726 .capsrc_nids = alc883_capsrc_nids, 10727 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10728 .channel_mode = alc883_sixstack_modes, 10729 .input_mux = &alc883_capture_source, 10730 }, 10731 [ALC883_MEDION_WIM2160] = { 10732 .mixers = { alc883_medion_wim2160_mixer }, 10733 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10735 .dac_nids = alc883_dac_nids, 10736 .dig_out_nid = ALC883_DIGOUT_NID, 10737 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10738 .adc_nids = alc883_adc_nids, 10739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10740 .channel_mode = alc883_3ST_2ch_modes, 10741 .input_mux = &alc883_capture_source, 10742 .unsol_event = alc_sku_unsol_event, 10743 .setup = alc883_medion_wim2160_setup, 10744 .init_hook = alc_hp_automute, 10745 }, 10746 [ALC883_LAPTOP_EAPD] = { 10747 .mixers = { alc883_base_mixer }, 10748 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, 10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10750 .dac_nids = alc883_dac_nids, 10751 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10752 .channel_mode = alc883_3ST_2ch_modes, 10753 .input_mux = &alc883_capture_source, 10754 }, 10755 [ALC883_CLEVO_M540R] = { 10756 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10757 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, 10758 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10759 .dac_nids = alc883_dac_nids, 10760 .dig_out_nid = ALC883_DIGOUT_NID, 10761 .dig_in_nid = ALC883_DIGIN_NID, 10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), 10763 .channel_mode = alc883_3ST_6ch_clevo_modes, 10764 .need_dac_fix = 1, 10765 .input_mux = &alc883_capture_source, 10766 /* This machine has the hardware HP auto-muting, thus 10767 * we need no software mute via unsol event 10768 */ 10769 }, 10770 [ALC883_CLEVO_M720] = { 10771 .mixers = { alc883_clevo_m720_mixer }, 10772 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 10773 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10774 .dac_nids = alc883_dac_nids, 10775 .dig_out_nid = ALC883_DIGOUT_NID, 10776 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10777 .channel_mode = alc883_3ST_2ch_modes, 10778 .input_mux = &alc883_capture_source, 10779 .unsol_event = alc883_clevo_m720_unsol_event, 10780 .setup = alc883_clevo_m720_setup, 10781 .init_hook = alc883_clevo_m720_init_hook, 10782 }, 10783 [ALC883_LENOVO_101E_2ch] = { 10784 .mixers = { alc883_lenovo_101e_2ch_mixer}, 10785 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 10786 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10787 .dac_nids = alc883_dac_nids, 10788 .adc_nids = alc883_adc_nids_alt, 10789 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), 10790 .capsrc_nids = alc883_capsrc_nids, 10791 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10792 .channel_mode = alc883_3ST_2ch_modes, 10793 .input_mux = &alc883_lenovo_101e_capture_source, 10794 .setup = alc883_lenovo_101e_setup, 10795 .unsol_event = alc_sku_unsol_event, 10796 .init_hook = alc_inithook, 10797 }, 10798 [ALC883_LENOVO_NB0763] = { 10799 .mixers = { alc883_lenovo_nb0763_mixer }, 10800 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, 10801 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10802 .dac_nids = alc883_dac_nids, 10803 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10804 .channel_mode = alc883_3ST_2ch_modes, 10805 .need_dac_fix = 1, 10806 .input_mux = &alc883_lenovo_nb0763_capture_source, 10807 .unsol_event = alc_sku_unsol_event, 10808 .setup = alc883_lenovo_nb0763_setup, 10809 .init_hook = alc_hp_automute, 10810 }, 10811 [ALC888_LENOVO_MS7195_DIG] = { 10812 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10813 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, 10814 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10815 .dac_nids = alc883_dac_nids, 10816 .dig_out_nid = ALC883_DIGOUT_NID, 10817 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10818 .channel_mode = alc883_3ST_6ch_modes, 10819 .need_dac_fix = 1, 10820 .input_mux = &alc883_capture_source, 10821 .unsol_event = alc_sku_unsol_event, 10822 .setup = alc888_lenovo_ms7195_setup, 10823 .init_hook = alc_inithook, 10824 }, 10825 [ALC883_HAIER_W66] = { 10826 .mixers = { alc883_targa_2ch_mixer}, 10827 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, 10828 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10829 .dac_nids = alc883_dac_nids, 10830 .dig_out_nid = ALC883_DIGOUT_NID, 10831 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10832 .channel_mode = alc883_3ST_2ch_modes, 10833 .input_mux = &alc883_capture_source, 10834 .unsol_event = alc_sku_unsol_event, 10835 .setup = alc883_haier_w66_setup, 10836 .init_hook = alc_hp_automute, 10837 }, 10838 [ALC888_3ST_HP] = { 10839 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10840 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, 10841 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10842 .dac_nids = alc883_dac_nids, 10843 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), 10844 .channel_mode = alc888_3st_hp_modes, 10845 .need_dac_fix = 1, 10846 .input_mux = &alc883_capture_source, 10847 .unsol_event = alc_sku_unsol_event, 10848 .setup = alc888_3st_hp_setup, 10849 .init_hook = alc_hp_automute, 10850 }, 10851 [ALC888_6ST_DELL] = { 10852 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10853 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, 10854 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10855 .dac_nids = alc883_dac_nids, 10856 .dig_out_nid = ALC883_DIGOUT_NID, 10857 .dig_in_nid = ALC883_DIGIN_NID, 10858 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10859 .channel_mode = alc883_sixstack_modes, 10860 .input_mux = &alc883_capture_source, 10861 .unsol_event = alc_sku_unsol_event, 10862 .setup = alc888_6st_dell_setup, 10863 .init_hook = alc_hp_automute, 10864 }, 10865 [ALC883_MITAC] = { 10866 .mixers = { alc883_mitac_mixer }, 10867 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, 10868 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10869 .dac_nids = alc883_dac_nids, 10870 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10871 .channel_mode = alc883_3ST_2ch_modes, 10872 .input_mux = &alc883_capture_source, 10873 .unsol_event = alc_sku_unsol_event, 10874 .setup = alc883_mitac_setup, 10875 .init_hook = alc_hp_automute, 10876 }, 10877 [ALC883_FUJITSU_PI2515] = { 10878 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 10879 .init_verbs = { alc883_init_verbs, 10880 alc883_2ch_fujitsu_pi2515_verbs}, 10881 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10882 .dac_nids = alc883_dac_nids, 10883 .dig_out_nid = ALC883_DIGOUT_NID, 10884 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10885 .channel_mode = alc883_3ST_2ch_modes, 10886 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10887 .unsol_event = alc_sku_unsol_event, 10888 .setup = alc883_2ch_fujitsu_pi2515_setup, 10889 .init_hook = alc_hp_automute, 10890 }, 10891 [ALC888_FUJITSU_XA3530] = { 10892 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 10893 .init_verbs = { alc883_init_verbs, 10894 alc888_fujitsu_xa3530_verbs }, 10895 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10896 .dac_nids = alc883_dac_nids, 10897 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), 10898 .adc_nids = alc883_adc_nids_rev, 10899 .capsrc_nids = alc883_capsrc_nids_rev, 10900 .dig_out_nid = ALC883_DIGOUT_NID, 10901 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), 10902 .channel_mode = alc888_4ST_8ch_intel_modes, 10903 .num_mux_defs = 10904 ARRAY_SIZE(alc888_2_capture_sources), 10905 .input_mux = alc888_2_capture_sources, 10906 .unsol_event = alc_sku_unsol_event, 10907 .setup = alc888_fujitsu_xa3530_setup, 10908 .init_hook = alc_hp_automute, 10909 }, 10910 [ALC888_LENOVO_SKY] = { 10911 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 10912 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 10913 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10914 .dac_nids = alc883_dac_nids, 10915 .dig_out_nid = ALC883_DIGOUT_NID, 10916 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10917 .channel_mode = alc883_sixstack_modes, 10918 .need_dac_fix = 1, 10919 .input_mux = &alc883_lenovo_sky_capture_source, 10920 .unsol_event = alc_sku_unsol_event, 10921 .setup = alc888_lenovo_sky_setup, 10922 .init_hook = alc_hp_automute, 10923 }, 10924 [ALC888_ASUS_M90V] = { 10925 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 10926 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, 10927 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10928 .dac_nids = alc883_dac_nids, 10929 .dig_out_nid = ALC883_DIGOUT_NID, 10930 .dig_in_nid = ALC883_DIGIN_NID, 10931 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), 10932 .channel_mode = alc883_3ST_6ch_modes, 10933 .need_dac_fix = 1, 10934 .input_mux = &alc883_fujitsu_pi2515_capture_source, 10935 .unsol_event = alc_sku_unsol_event, 10936 .setup = alc883_mode2_setup, 10937 .init_hook = alc_inithook, 10938 }, 10939 [ALC888_ASUS_EEE1601] = { 10940 .mixers = { alc883_asus_eee1601_mixer }, 10941 .cap_mixer = alc883_asus_eee1601_cap_mixer, 10942 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 10943 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10944 .dac_nids = alc883_dac_nids, 10945 .dig_out_nid = ALC883_DIGOUT_NID, 10946 .dig_in_nid = ALC883_DIGIN_NID, 10947 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10948 .channel_mode = alc883_3ST_2ch_modes, 10949 .need_dac_fix = 1, 10950 .input_mux = &alc883_asus_eee1601_capture_source, 10951 .unsol_event = alc_sku_unsol_event, 10952 .init_hook = alc883_eee1601_inithook, 10953 }, 10954 [ALC1200_ASUS_P5Q] = { 10955 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 10956 .init_verbs = { alc883_init_verbs }, 10957 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10958 .dac_nids = alc883_dac_nids, 10959 .dig_out_nid = ALC1200_DIGOUT_NID, 10960 .dig_in_nid = ALC883_DIGIN_NID, 10961 .slave_dig_outs = alc1200_slave_dig_outs, 10962 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 10963 .channel_mode = alc883_sixstack_modes, 10964 .input_mux = &alc883_capture_source, 10965 }, 10966 [ALC889A_MB31] = { 10967 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, 10968 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, 10969 alc880_gpio1_init_verbs }, 10970 .adc_nids = alc883_adc_nids, 10971 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), 10972 .capsrc_nids = alc883_capsrc_nids, 10973 .dac_nids = alc883_dac_nids, 10974 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10975 .channel_mode = alc889A_mb31_6ch_modes, 10976 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), 10977 .input_mux = &alc889A_mb31_capture_source, 10978 .dig_out_nid = ALC883_DIGOUT_NID, 10979 .unsol_event = alc889A_mb31_unsol_event, 10980 .init_hook = alc889A_mb31_automute, 10981 }, 10982 [ALC883_SONY_VAIO_TT] = { 10983 .mixers = { alc883_vaiott_mixer }, 10984 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, 10985 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 10986 .dac_nids = alc883_dac_nids, 10987 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 10988 .channel_mode = alc883_3ST_2ch_modes, 10989 .input_mux = &alc883_capture_source, 10990 .unsol_event = alc_sku_unsol_event, 10991 .setup = alc883_vaiott_setup, 10992 .init_hook = alc_hp_automute, 10993 }, 10994}; 10995 10996 10997/* 10998 * Pin config fixes 10999 */ 11000enum { 11001 PINFIX_ABIT_AW9D_MAX, 11002 PINFIX_LENOVO_Y530, 11003 PINFIX_PB_M5210, 11004 PINFIX_ACER_ASPIRE_7736, 11005}; 11006 11007static const struct alc_fixup alc882_fixups[] = { 11008 [PINFIX_ABIT_AW9D_MAX] = { 11009 .type = ALC_FIXUP_PINS, 11010 .v.pins = (const struct alc_pincfg[]) { 11011 { 0x15, 0x01080104 }, /* side */ 11012 { 0x16, 0x01011012 }, /* rear */ 11013 { 0x17, 0x01016011 }, /* clfe */ 11014 { } 11015 } 11016 }, 11017 [PINFIX_LENOVO_Y530] = { 11018 .type = ALC_FIXUP_PINS, 11019 .v.pins = (const struct alc_pincfg[]) { 11020 { 0x15, 0x99130112 }, /* rear int speakers */ 11021 { 0x16, 0x99130111 }, /* subwoofer */ 11022 { } 11023 } 11024 }, 11025 [PINFIX_PB_M5210] = { 11026 .type = ALC_FIXUP_VERBS, 11027 .v.verbs = (const struct hda_verb[]) { 11028 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 11029 {} 11030 } 11031 }, 11032 [PINFIX_ACER_ASPIRE_7736] = { 11033 .type = ALC_FIXUP_SKU, 11034 .v.sku = ALC_FIXUP_SKU_IGNORE, 11035 }, 11036}; 11037 11038static const struct snd_pci_quirk alc882_fixup_tbl[] = { 11039 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), 11040 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), 11041 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 11042 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), 11043 {} 11044}; 11045 11046/* 11047 * BIOS auto configuration 11048 */ 11049static int alc882_auto_create_input_ctls(struct hda_codec *codec, 11050 const struct auto_pin_cfg *cfg) 11051{ 11052 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); 11053} 11054 11055static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, 11056 hda_nid_t nid, int pin_type, 11057 hda_nid_t dac) 11058{ 11059 int idx; 11060 11061 /* set as output */ 11062 alc_set_pin_output(codec, nid, pin_type); 11063 11064 if (dac == 0x25) 11065 idx = 4; 11066 else if (dac >= 0x02 && dac <= 0x05) 11067 idx = dac - 2; 11068 else 11069 return; 11070 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 11071} 11072 11073static void alc882_auto_init_multi_out(struct hda_codec *codec) 11074{ 11075 struct alc_spec *spec = codec->spec; 11076 int i; 11077 11078 for (i = 0; i <= HDA_SIDE; i++) { 11079 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 11080 int pin_type = get_pin_type(spec->autocfg.line_out_type); 11081 if (nid) 11082 alc882_auto_set_output_and_unmute(codec, nid, pin_type, 11083 spec->multiout.dac_nids[i]); 11084 } 11085} 11086 11087static void alc882_auto_init_hp_out(struct hda_codec *codec) 11088{ 11089 struct alc_spec *spec = codec->spec; 11090 hda_nid_t pin, dac; 11091 int i; 11092 11093 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { 11094 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { 11095 pin = spec->autocfg.hp_pins[i]; 11096 if (!pin) 11097 break; 11098 dac = spec->multiout.hp_nid; 11099 if (!dac) 11100 dac = spec->multiout.dac_nids[0]; /* to front */ 11101 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); 11102 } 11103 } 11104 11105 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { 11106 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { 11107 pin = spec->autocfg.speaker_pins[i]; 11108 if (!pin) 11109 break; 11110 dac = spec->multiout.extra_out_nid[0]; 11111 if (!dac) 11112 dac = spec->multiout.dac_nids[0]; /* to front */ 11113 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); 11114 } 11115 } 11116} 11117 11118static void alc882_auto_init_analog_input(struct hda_codec *codec) 11119{ 11120 struct alc_spec *spec = codec->spec; 11121 struct auto_pin_cfg *cfg = &spec->autocfg; 11122 int i; 11123 11124 for (i = 0; i < cfg->num_inputs; i++) { 11125 hda_nid_t nid = cfg->inputs[i].pin; 11126 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 11127 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 11128 snd_hda_codec_write(codec, nid, 0, 11129 AC_VERB_SET_AMP_GAIN_MUTE, 11130 AMP_OUT_MUTE); 11131 } 11132} 11133 11134static void alc882_auto_init_input_src(struct hda_codec *codec) 11135{ 11136 struct alc_spec *spec = codec->spec; 11137 int c; 11138 11139 for (c = 0; c < spec->num_adc_nids; c++) { 11140 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS]; 11141 hda_nid_t nid = spec->capsrc_nids[c]; 11142 unsigned int mux_idx; 11143 const struct hda_input_mux *imux; 11144 int conns, mute, idx, item; 11145 11146 /* mute ADC */ 11147 snd_hda_codec_write(codec, spec->adc_nids[c], 0, 11148 AC_VERB_SET_AMP_GAIN_MUTE, 11149 AMP_IN_MUTE(0)); 11150 11151 conns = snd_hda_get_connections(codec, nid, conn_list, 11152 ARRAY_SIZE(conn_list)); 11153 if (conns < 0) 11154 continue; 11155 mux_idx = c >= spec->num_mux_defs ? 0 : c; 11156 imux = &spec->input_mux[mux_idx]; 11157 if (!imux->num_items && mux_idx > 0) 11158 imux = &spec->input_mux[0]; 11159 for (idx = 0; idx < conns; idx++) { 11160 /* if the current connection is the selected one, 11161 * unmute it as default - otherwise mute it 11162 */ 11163 mute = AMP_IN_MUTE(idx); 11164 for (item = 0; item < imux->num_items; item++) { 11165 if (imux->items[item].index == idx) { 11166 if (spec->cur_mux[c] == item) 11167 mute = AMP_IN_UNMUTE(idx); 11168 break; 11169 } 11170 } 11171 /* check if we have a selector or mixer 11172 * we could check for the widget type instead, but 11173 * just check for Amp-In presence (in case of mixer 11174 * without amp-in there is something wrong, this 11175 * function shouldn't be used or capsrc nid is wrong) 11176 */ 11177 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) 11178 snd_hda_codec_write(codec, nid, 0, 11179 AC_VERB_SET_AMP_GAIN_MUTE, 11180 mute); 11181 else if (mute != AMP_IN_MUTE(idx)) 11182 snd_hda_codec_write(codec, nid, 0, 11183 AC_VERB_SET_CONNECT_SEL, 11184 idx); 11185 } 11186 } 11187} 11188 11189/* add mic boosts if needed */ 11190static int alc_auto_add_mic_boost(struct hda_codec *codec) 11191{ 11192 struct alc_spec *spec = codec->spec; 11193 struct auto_pin_cfg *cfg = &spec->autocfg; 11194 int i, err; 11195 int type_idx = 0; 11196 hda_nid_t nid; 11197 const char *prev_label = NULL; 11198 11199 for (i = 0; i < cfg->num_inputs; i++) { 11200 if (cfg->inputs[i].type > AUTO_PIN_MIC) 11201 break; 11202 nid = cfg->inputs[i].pin; 11203 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 11204 const char *label; 11205 char boost_label[32]; 11206 11207 label = hda_get_autocfg_input_label(codec, cfg, i); 11208 if (prev_label && !strcmp(label, prev_label)) 11209 type_idx++; 11210 else 11211 type_idx = 0; 11212 prev_label = label; 11213 11214 snprintf(boost_label, sizeof(boost_label), 11215 "%s Boost Volume", label); 11216 err = add_control(spec, ALC_CTL_WIDGET_VOL, 11217 boost_label, type_idx, 11218 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 11219 if (err < 0) 11220 return err; 11221 } 11222 } 11223 return 0; 11224} 11225 11226/* almost identical with ALC880 parser... */ 11227static int alc882_parse_auto_config(struct hda_codec *codec) 11228{ 11229 struct alc_spec *spec = codec->spec; 11230 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 11231 int err; 11232 11233 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 11234 alc882_ignore); 11235 if (err < 0) 11236 return err; 11237 if (!spec->autocfg.line_outs) 11238 return 0; /* can't find valid BIOS pin config */ 11239 11240 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 11241 if (err < 0) 11242 return err; 11243 err = alc_auto_add_multi_channel_mode(codec); 11244 if (err < 0) 11245 return err; 11246 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 11247 if (err < 0) 11248 return err; 11249 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 11250 "Headphone"); 11251 if (err < 0) 11252 return err; 11253 err = alc880_auto_create_extra_out(spec, 11254 spec->autocfg.speaker_pins[0], 11255 "Speaker"); 11256 if (err < 0) 11257 return err; 11258 err = alc882_auto_create_input_ctls(codec, &spec->autocfg); 11259 if (err < 0) 11260 return err; 11261 11262 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 11263 11264 alc_auto_parse_digital(codec); 11265 11266 if (spec->kctls.list) 11267 add_mixer(spec, spec->kctls.list); 11268 11269 add_verb(spec, alc883_auto_init_verbs); 11270 /* if ADC 0x07 is available, initialize it, too */ 11271 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) 11272 add_verb(spec, alc882_adc1_init_verbs); 11273 11274 spec->num_mux_defs = 1; 11275 spec->input_mux = &spec->private_imux[0]; 11276 11277 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 11278 11279 err = alc_auto_add_mic_boost(codec); 11280 if (err < 0) 11281 return err; 11282 11283 return 1; /* config found */ 11284} 11285 11286/* additional initialization for auto-configuration model */ 11287static void alc882_auto_init(struct hda_codec *codec) 11288{ 11289 struct alc_spec *spec = codec->spec; 11290 alc882_auto_init_multi_out(codec); 11291 alc882_auto_init_hp_out(codec); 11292 alc882_auto_init_analog_input(codec); 11293 alc882_auto_init_input_src(codec); 11294 alc_auto_init_digital(codec); 11295 if (spec->unsol_event) 11296 alc_inithook(codec); 11297} 11298 11299static int patch_alc882(struct hda_codec *codec) 11300{ 11301 struct alc_spec *spec; 11302 int err, board_config; 11303 11304 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 11305 if (spec == NULL) 11306 return -ENOMEM; 11307 11308 codec->spec = spec; 11309 11310 switch (codec->vendor_id) { 11311 case 0x10ec0882: 11312 case 0x10ec0885: 11313 break; 11314 default: 11315 /* ALC883 and variants */ 11316 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 11317 break; 11318 } 11319 11320 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 11321 alc882_models, 11322 alc882_cfg_tbl); 11323 11324 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 11325 board_config = snd_hda_check_board_codec_sid_config(codec, 11326 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 11327 11328 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 11329 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 11330 codec->chip_name); 11331 board_config = ALC882_AUTO; 11332 } 11333 11334 if (board_config == ALC882_AUTO) { 11335 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 11336 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 11337 } 11338 11339 alc_auto_parse_customize_define(codec); 11340 11341 if (board_config == ALC882_AUTO) { 11342 /* automatic parse from the BIOS config */ 11343 err = alc882_parse_auto_config(codec); 11344 if (err < 0) { 11345 alc_free(codec); 11346 return err; 11347 } else if (!err) { 11348 printk(KERN_INFO 11349 "hda_codec: Cannot set up configuration " 11350 "from BIOS. Using base mode...\n"); 11351 board_config = ALC882_3ST_DIG; 11352 } 11353 } 11354 11355 if (has_cdefine_beep(codec)) { 11356 err = snd_hda_attach_beep_device(codec, 0x1); 11357 if (err < 0) { 11358 alc_free(codec); 11359 return err; 11360 } 11361 } 11362 11363 if (board_config != ALC882_AUTO) 11364 setup_preset(codec, &alc882_presets[board_config]); 11365 11366 spec->stream_analog_playback = &alc882_pcm_analog_playback; 11367 spec->stream_analog_capture = &alc882_pcm_analog_capture; 11368 /* FIXME: setup DAC5 */ 11369 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 11370 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture; 11371 11372 spec->stream_digital_playback = &alc882_pcm_digital_playback; 11373 spec->stream_digital_capture = &alc882_pcm_digital_capture; 11374 11375 if (!spec->adc_nids && spec->input_mux) { 11376 int i, j; 11377 spec->num_adc_nids = 0; 11378 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) { 11379 const struct hda_input_mux *imux = spec->input_mux; 11380 hda_nid_t cap; 11381 hda_nid_t items[16]; 11382 hda_nid_t nid = alc882_adc_nids[i]; 11383 unsigned int wcap = get_wcaps(codec, nid); 11384 /* get type */ 11385 wcap = get_wcaps_type(wcap); 11386 if (wcap != AC_WID_AUD_IN) 11387 continue; 11388 spec->private_adc_nids[spec->num_adc_nids] = nid; 11389 err = snd_hda_get_connections(codec, nid, &cap, 1); 11390 if (err < 0) 11391 continue; 11392 err = snd_hda_get_connections(codec, cap, items, 11393 ARRAY_SIZE(items)); 11394 if (err < 0) 11395 continue; 11396 for (j = 0; j < imux->num_items; j++) 11397 if (imux->items[j].index >= err) 11398 break; 11399 if (j < imux->num_items) 11400 continue; 11401 spec->private_capsrc_nids[spec->num_adc_nids] = cap; 11402 spec->num_adc_nids++; 11403 } 11404 spec->adc_nids = spec->private_adc_nids; 11405 spec->capsrc_nids = spec->private_capsrc_nids; 11406 } 11407 11408 set_capture_mixer(codec); 11409 11410 if (has_cdefine_beep(codec)) 11411 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11412 11413 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 11414 11415 spec->vmaster_nid = 0x0c; 11416 11417 codec->patch_ops = alc_patch_ops; 11418 if (board_config == ALC882_AUTO) 11419 spec->init_hook = alc882_auto_init; 11420 11421 alc_init_jacks(codec); 11422#ifdef CONFIG_SND_HDA_POWER_SAVE 11423 if (!spec->loopback.amplist) 11424 spec->loopback.amplist = alc882_loopbacks; 11425#endif 11426 11427 return 0; 11428} 11429 11430 11431/* 11432 * ALC262 support 11433 */ 11434 11435#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID 11436#define ALC262_DIGIN_NID ALC880_DIGIN_NID 11437 11438#define alc262_dac_nids alc260_dac_nids 11439#define alc262_adc_nids alc882_adc_nids 11440#define alc262_adc_nids_alt alc882_adc_nids_alt 11441#define alc262_capsrc_nids alc882_capsrc_nids 11442#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt 11443 11444#define alc262_modes alc260_modes 11445#define alc262_capture_source alc882_capture_source 11446 11447static const hda_nid_t alc262_dmic_adc_nids[1] = { 11448 /* ADC0 */ 11449 0x09 11450}; 11451 11452static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; 11453 11454static const struct snd_kcontrol_new alc262_base_mixer[] = { 11455 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11456 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11457 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11458 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11463 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11466 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11467 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11469 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11470 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 11471 { } /* end */ 11472}; 11473 11474/* update HP, line and mono-out pins according to the master switch */ 11475#define alc262_hp_master_update alc260_hp_master_update 11476 11477static void alc262_hp_bpc_setup(struct hda_codec *codec) 11478{ 11479 struct alc_spec *spec = codec->spec; 11480 11481 spec->autocfg.hp_pins[0] = 0x1b; 11482 spec->autocfg.speaker_pins[0] = 0x16; 11483 spec->automute = 1; 11484 spec->automute_mode = ALC_AUTOMUTE_PIN; 11485} 11486 11487static void alc262_hp_wildwest_setup(struct hda_codec *codec) 11488{ 11489 struct alc_spec *spec = codec->spec; 11490 11491 spec->autocfg.hp_pins[0] = 0x15; 11492 spec->autocfg.speaker_pins[0] = 0x16; 11493 spec->automute = 1; 11494 spec->automute_mode = ALC_AUTOMUTE_PIN; 11495} 11496 11497#define alc262_hp_master_sw_get alc260_hp_master_sw_get 11498#define alc262_hp_master_sw_put alc260_hp_master_sw_put 11499 11500#define ALC262_HP_MASTER_SWITCH \ 11501 { \ 11502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11503 .name = "Master Playback Switch", \ 11504 .info = snd_ctl_boolean_mono_info, \ 11505 .get = alc262_hp_master_sw_get, \ 11506 .put = alc262_hp_master_sw_put, \ 11507 }, \ 11508 { \ 11509 .iface = NID_MAPPING, \ 11510 .name = "Master Playback Switch", \ 11511 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ 11512 } 11513 11514 11515static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 11516 ALC262_HP_MASTER_SWITCH, 11517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11518 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11520 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11521 HDA_OUTPUT), 11522 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11523 HDA_OUTPUT), 11524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11525 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11526 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11527 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11528 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11529 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11530 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11531 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11532 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11533 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11534 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), 11535 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), 11536 { } /* end */ 11537}; 11538 11539static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { 11540 ALC262_HP_MASTER_SWITCH, 11541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11542 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11543 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11544 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11545 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, 11546 HDA_OUTPUT), 11547 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, 11548 HDA_OUTPUT), 11549 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11550 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11551 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT), 11552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11554 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11555 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11556 { } /* end */ 11557}; 11558 11559static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11560 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11561 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11562 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), 11563 { } /* end */ 11564}; 11565 11566/* mute/unmute internal speaker according to the hp jack and mute state */ 11567static void alc262_hp_t5735_setup(struct hda_codec *codec) 11568{ 11569 struct alc_spec *spec = codec->spec; 11570 11571 spec->autocfg.hp_pins[0] = 0x15; 11572 spec->autocfg.speaker_pins[0] = 0x14; 11573 spec->automute = 1; 11574 spec->automute_mode = ALC_AUTOMUTE_PIN; 11575} 11576 11577static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 11578 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11579 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11584 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11585 { } /* end */ 11586}; 11587 11588static const struct hda_verb alc262_hp_t5735_verbs[] = { 11589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11591 11592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 11593 { } 11594}; 11595 11596static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { 11597 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 11599 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), 11600 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), 11601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11603 { } /* end */ 11604}; 11605 11606static const struct hda_verb alc262_hp_rp5700_verbs[] = { 11607 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11610 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11611 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11612 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 11615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11616 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, 11617 {} 11618}; 11619 11620static const struct hda_input_mux alc262_hp_rp5700_capture_source = { 11621 .num_items = 1, 11622 .items = { 11623 { "Line", 0x1 }, 11624 }, 11625}; 11626 11627/* bind hp and internal speaker mute (with plug check) as master switch */ 11628#define alc262_hippo_master_update alc262_hp_master_update 11629#define alc262_hippo_master_sw_get alc262_hp_master_sw_get 11630#define alc262_hippo_master_sw_put alc262_hp_master_sw_put 11631 11632#define ALC262_HIPPO_MASTER_SWITCH \ 11633 { \ 11634 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 11635 .name = "Master Playback Switch", \ 11636 .info = snd_ctl_boolean_mono_info, \ 11637 .get = alc262_hippo_master_sw_get, \ 11638 .put = alc262_hippo_master_sw_put, \ 11639 }, \ 11640 { \ 11641 .iface = NID_MAPPING, \ 11642 .name = "Master Playback Switch", \ 11643 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ 11644 (SUBDEV_SPEAKER(0) << 16), \ 11645 } 11646 11647static const struct snd_kcontrol_new alc262_hippo_mixer[] = { 11648 ALC262_HIPPO_MASTER_SWITCH, 11649 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11651 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11652 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11653 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11656 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11659 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11660 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11661 { } /* end */ 11662}; 11663 11664static const struct snd_kcontrol_new alc262_hippo1_mixer[] = { 11665 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11666 ALC262_HIPPO_MASTER_SWITCH, 11667 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11668 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11669 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11670 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11673 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11674 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11675 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11676 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11677 { } /* end */ 11678}; 11679 11680/* mute/unmute internal speaker according to the hp jack and mute state */ 11681static void alc262_hippo_setup(struct hda_codec *codec) 11682{ 11683 struct alc_spec *spec = codec->spec; 11684 11685 spec->autocfg.hp_pins[0] = 0x15; 11686 spec->autocfg.speaker_pins[0] = 0x14; 11687 spec->automute = 1; 11688 spec->automute_mode = ALC_AUTOMUTE_AMP; 11689} 11690 11691static void alc262_hippo1_setup(struct hda_codec *codec) 11692{ 11693 struct alc_spec *spec = codec->spec; 11694 11695 spec->autocfg.hp_pins[0] = 0x1b; 11696 spec->autocfg.speaker_pins[0] = 0x14; 11697 spec->automute = 1; 11698 spec->automute_mode = ALC_AUTOMUTE_AMP; 11699} 11700 11701 11702static const struct snd_kcontrol_new alc262_sony_mixer[] = { 11703 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11704 ALC262_HIPPO_MASTER_SWITCH, 11705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11707 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11708 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11709 { } /* end */ 11710}; 11711 11712static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = { 11713 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11714 ALC262_HIPPO_MASTER_SWITCH, 11715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11716 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11717 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11718 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11719 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11720 { } /* end */ 11721}; 11722 11723static const struct snd_kcontrol_new alc262_tyan_mixer[] = { 11724 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11725 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11726 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), 11727 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), 11728 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11729 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11732 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11733 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11734 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11735 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 11736 { } /* end */ 11737}; 11738 11739static const struct hda_verb alc262_tyan_verbs[] = { 11740 /* Headphone automute */ 11741 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11742 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11744 11745 /* P11 AUX_IN, white 4-pin connector */ 11746 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11747 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, 11748 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, 11749 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, 11750 11751 {} 11752}; 11753 11754/* unsolicited event for HP jack sensing */ 11755static void alc262_tyan_setup(struct hda_codec *codec) 11756{ 11757 struct alc_spec *spec = codec->spec; 11758 11759 spec->autocfg.hp_pins[0] = 0x1b; 11760 spec->autocfg.speaker_pins[0] = 0x15; 11761 spec->automute = 1; 11762 spec->automute_mode = ALC_AUTOMUTE_AMP; 11763} 11764 11765 11766#define alc262_capture_mixer alc882_capture_mixer 11767#define alc262_capture_alt_mixer alc882_capture_alt_mixer 11768 11769/* 11770 * generic initialization of ADC, input mixers and output mixers 11771 */ 11772static const struct hda_verb alc262_init_verbs[] = { 11773 /* 11774 * Unmute ADC0-2 and set the default input to mic-in 11775 */ 11776 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 11777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 11779 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 11781 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11782 11783 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 11784 * mixer widget 11785 * Note: PASD motherboards uses the Line In 2 as the input for 11786 * front panel mic (mic 2) 11787 */ 11788 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 11789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 11790 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 11791 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 11792 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 11793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 11794 11795 /* 11796 * Set up output mixers (0x0c - 0x0e) 11797 */ 11798 /* set vol=0 to output mixers */ 11799 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11801 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 11802 /* set up input amps for analog loopback */ 11803 /* Amp Indices: DAC = 0, mixer = 1 */ 11804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 11809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11810 11811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11813 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 11814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11816 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 11817 11818 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11819 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11820 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11823 11824 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 11825 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 11826 11827 /* FIXME: use matrix-type input source selection */ 11828 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 11829 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 11830 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11831 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11832 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11833 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11834 /* Input mixer2 */ 11835 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11836 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11837 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11838 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11839 /* Input mixer3 */ 11840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 11841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 11842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 11843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 11844 11845 { } 11846}; 11847 11848static const struct hda_verb alc262_eapd_verbs[] = { 11849 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11850 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 11851 { } 11852}; 11853 11854static const struct hda_verb alc262_hippo1_unsol_verbs[] = { 11855 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11856 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 11857 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, 11858 11859 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11861 {} 11862}; 11863 11864static const struct hda_verb alc262_sony_unsol_verbs[] = { 11865 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 11866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11867 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic 11868 11869 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11871 {} 11872}; 11873 11874static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 11875 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 11876 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 11877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11880 { } /* end */ 11881}; 11882 11883static const struct hda_verb alc262_toshiba_s06_verbs[] = { 11884 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11887 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 11888 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, 11889 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 11890 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 11891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11892 {} 11893}; 11894 11895static void alc262_toshiba_s06_setup(struct hda_codec *codec) 11896{ 11897 struct alc_spec *spec = codec->spec; 11898 11899 spec->autocfg.hp_pins[0] = 0x15; 11900 spec->autocfg.speaker_pins[0] = 0x14; 11901 spec->ext_mic.pin = 0x18; 11902 spec->ext_mic.mux_idx = 0; 11903 spec->int_mic.pin = 0x12; 11904 spec->int_mic.mux_idx = 9; 11905 spec->auto_mic = 1; 11906 spec->automute = 1; 11907 spec->automute_mode = ALC_AUTOMUTE_PIN; 11908} 11909 11910/* 11911 * nec model 11912 * 0x15 = headphone 11913 * 0x16 = internal speaker 11914 * 0x18 = external mic 11915 */ 11916 11917static const struct snd_kcontrol_new alc262_nec_mixer[] = { 11918 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), 11919 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), 11920 11921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11923 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 11924 11925 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11926 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11927 { } /* end */ 11928}; 11929 11930static const struct hda_verb alc262_nec_verbs[] = { 11931 /* Unmute Speaker */ 11932 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 11933 11934 /* Headphone */ 11935 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 11936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 11937 11938 /* External mic to headphone */ 11939 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11940 /* External mic to speaker */ 11941 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 11942 {} 11943}; 11944 11945/* 11946 * fujitsu model 11947 * 0x14 = headphone/spdif-out, 0x15 = internal speaker, 11948 * 0x1b = port replicator headphone out 11949 */ 11950 11951#define ALC_HP_EVENT ALC880_HP_EVENT 11952 11953static const struct hda_verb alc262_fujitsu_unsol_verbs[] = { 11954 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11956 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11957 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11958 {} 11959}; 11960 11961static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { 11962 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, 11963 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11964 {} 11965}; 11966 11967static const struct hda_verb alc262_lenovo_3000_init_verbs[] = { 11968 /* Front Mic pin: input vref at 50% */ 11969 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 11970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 11971 {} 11972}; 11973 11974static const struct hda_input_mux alc262_fujitsu_capture_source = { 11975 .num_items = 3, 11976 .items = { 11977 { "Mic", 0x0 }, 11978 { "Internal Mic", 0x1 }, 11979 { "CD", 0x4 }, 11980 }, 11981}; 11982 11983static const struct hda_input_mux alc262_HP_capture_source = { 11984 .num_items = 5, 11985 .items = { 11986 { "Mic", 0x0 }, 11987 { "Front Mic", 0x1 }, 11988 { "Line", 0x2 }, 11989 { "CD", 0x4 }, 11990 { "AUX IN", 0x6 }, 11991 }, 11992}; 11993 11994static const struct hda_input_mux alc262_HP_D7000_capture_source = { 11995 .num_items = 4, 11996 .items = { 11997 { "Mic", 0x0 }, 11998 { "Front Mic", 0x2 }, 11999 { "Line", 0x1 }, 12000 { "CD", 0x4 }, 12001 }, 12002}; 12003 12004static void alc262_fujitsu_setup(struct hda_codec *codec) 12005{ 12006 struct alc_spec *spec = codec->spec; 12007 12008 spec->autocfg.hp_pins[0] = 0x14; 12009 spec->autocfg.hp_pins[1] = 0x1b; 12010 spec->autocfg.speaker_pins[0] = 0x15; 12011 spec->automute = 1; 12012 spec->automute_mode = ALC_AUTOMUTE_AMP; 12013} 12014 12015/* bind volumes of both NID 0x0c and 0x0d */ 12016static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { 12017 .ops = &snd_hda_bind_vol, 12018 .values = { 12019 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), 12020 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), 12021 0 12022 }, 12023}; 12024 12025static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = { 12026 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12027 { 12028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12029 .name = "Master Playback Switch", 12030 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, 12031 .info = snd_ctl_boolean_mono_info, 12032 .get = alc262_hp_master_sw_get, 12033 .put = alc262_hp_master_sw_put, 12034 }, 12035 { 12036 .iface = NID_MAPPING, 12037 .name = "Master Playback Switch", 12038 .private_value = 0x1b, 12039 }, 12040 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 12041 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 12042 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 12043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12045 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 12046 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 12047 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 12048 { } /* end */ 12049}; 12050 12051static void alc262_lenovo_3000_setup(struct hda_codec *codec) 12052{ 12053 struct alc_spec *spec = codec->spec; 12054 12055 spec->autocfg.hp_pins[0] = 0x1b; 12056 spec->autocfg.speaker_pins[0] = 0x14; 12057 spec->autocfg.speaker_pins[1] = 0x16; 12058 spec->automute = 1; 12059 spec->automute_mode = ALC_AUTOMUTE_AMP; 12060} 12061 12062static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { 12063 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12064 { 12065 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12066 .name = "Master Playback Switch", 12067 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, 12068 .info = snd_ctl_boolean_mono_info, 12069 .get = alc262_hp_master_sw_get, 12070 .put = alc262_hp_master_sw_put, 12071 }, 12072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 12073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 12074 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 12075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12077 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 12078 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 12079 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 12080 { } /* end */ 12081}; 12082 12083static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { 12084 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), 12085 ALC262_HIPPO_MASTER_SWITCH, 12086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 12087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 12088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 12089 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12090 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12091 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 12092 { } /* end */ 12093}; 12094 12095/* additional init verbs for Benq laptops */ 12096static const struct hda_verb alc262_EAPD_verbs[] = { 12097 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 12098 {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, 12099 {} 12100}; 12101 12102static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = { 12103 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12104 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12105 12106 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 12107 {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, 12108 {} 12109}; 12110 12111/* Samsung Q1 Ultra Vista model setup */ 12112static const struct snd_kcontrol_new alc262_ultra_mixer[] = { 12113 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 12114 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 12115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 12116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 12117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), 12118 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT), 12119 { } /* end */ 12120}; 12121 12122static const struct hda_verb alc262_ultra_verbs[] = { 12123 /* output mixer */ 12124 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12127 /* speaker */ 12128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 12129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12130 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12131 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 12132 /* HP */ 12133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 12135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12136 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12137 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12138 /* internal mic */ 12139 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 12140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12141 /* ADC, choose mic */ 12142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, 12152 {} 12153}; 12154 12155/* mute/unmute internal speaker according to the hp jack and mute state */ 12156static void alc262_ultra_automute(struct hda_codec *codec) 12157{ 12158 struct alc_spec *spec = codec->spec; 12159 unsigned int mute; 12160 12161 mute = 0; 12162 /* auto-mute only when HP is used as HP */ 12163 if (!spec->cur_mux[0]) { 12164 spec->jack_present = snd_hda_jack_detect(codec, 0x15); 12165 if (spec->jack_present) 12166 mute = HDA_AMP_MUTE; 12167 } 12168 /* mute/unmute internal speaker */ 12169 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, 12170 HDA_AMP_MUTE, mute); 12171 /* mute/unmute HP */ 12172 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 12173 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); 12174} 12175 12176/* unsolicited event for HP jack sensing */ 12177static void alc262_ultra_unsol_event(struct hda_codec *codec, 12178 unsigned int res) 12179{ 12180 if ((res >> 26) != ALC880_HP_EVENT) 12181 return; 12182 alc262_ultra_automute(codec); 12183} 12184 12185static const struct hda_input_mux alc262_ultra_capture_source = { 12186 .num_items = 2, 12187 .items = { 12188 { "Mic", 0x1 }, 12189 { "Headphone", 0x7 }, 12190 }, 12191}; 12192 12193static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, 12194 struct snd_ctl_elem_value *ucontrol) 12195{ 12196 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 12197 struct alc_spec *spec = codec->spec; 12198 int ret; 12199 12200 ret = alc_mux_enum_put(kcontrol, ucontrol); 12201 if (!ret) 12202 return 0; 12203 /* reprogram the HP pin as mic or HP according to the input source */ 12204 snd_hda_codec_write_cache(codec, 0x15, 0, 12205 AC_VERB_SET_PIN_WIDGET_CONTROL, 12206 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); 12207 alc262_ultra_automute(codec); /* mute/unmute HP */ 12208 return ret; 12209} 12210 12211static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { 12212 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 12213 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 12214 { 12215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12216 .name = "Capture Source", 12217 .info = alc_mux_enum_info, 12218 .get = alc_mux_enum_get, 12219 .put = alc262_ultra_mux_enum_put, 12220 }, 12221 { 12222 .iface = NID_MAPPING, 12223 .name = "Capture Source", 12224 .private_value = 0x15, 12225 }, 12226 { } /* end */ 12227}; 12228 12229/* We use two mixers depending on the output pin; 0x16 is a mono output 12230 * and thus it's bound with a different mixer. 12231 * This function returns which mixer amp should be used. 12232 */ 12233static int alc262_check_volbit(hda_nid_t nid) 12234{ 12235 if (!nid) 12236 return 0; 12237 else if (nid == 0x16) 12238 return 2; 12239 else 12240 return 1; 12241} 12242 12243static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid, 12244 const char *pfx, int *vbits, int idx) 12245{ 12246 unsigned long val; 12247 int vbit; 12248 12249 vbit = alc262_check_volbit(nid); 12250 if (!vbit) 12251 return 0; 12252 if (*vbits & vbit) /* a volume control for this mixer already there */ 12253 return 0; 12254 *vbits |= vbit; 12255 if (vbit == 2) 12256 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT); 12257 else 12258 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT); 12259 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val); 12260} 12261 12262static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid, 12263 const char *pfx, int idx) 12264{ 12265 unsigned long val; 12266 12267 if (!nid) 12268 return 0; 12269 if (nid == 0x16) 12270 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT); 12271 else 12272 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 12273 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val); 12274} 12275 12276/* add playback controls from the parsed DAC table */ 12277static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 12278 const struct auto_pin_cfg *cfg) 12279{ 12280 const char *pfx; 12281 int vbits; 12282 int i, err; 12283 12284 spec->multiout.num_dacs = 1; /* only use one dac */ 12285 spec->multiout.dac_nids = spec->private_dac_nids; 12286 spec->private_dac_nids[0] = 2; 12287 12288 pfx = alc_get_line_out_pfx(spec, true); 12289 if (!pfx) 12290 pfx = "Front"; 12291 for (i = 0; i < 2; i++) { 12292 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12293 if (err < 0) 12294 return err; 12295 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12296 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i], 12297 "Speaker", i); 12298 if (err < 0) 12299 return err; 12300 } 12301 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12302 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i], 12303 "Headphone", i); 12304 if (err < 0) 12305 return err; 12306 } 12307 } 12308 12309 vbits = alc262_check_volbit(cfg->line_out_pins[0]) | 12310 alc262_check_volbit(cfg->speaker_pins[0]) | 12311 alc262_check_volbit(cfg->hp_pins[0]); 12312 if (vbits == 1 || vbits == 2) 12313 pfx = "Master"; /* only one mixer is used */ 12314 vbits = 0; 12315 for (i = 0; i < 2; i++) { 12316 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx, 12317 &vbits, i); 12318 if (err < 0) 12319 return err; 12320 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 12321 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i], 12322 "Speaker", &vbits, i); 12323 if (err < 0) 12324 return err; 12325 } 12326 if (cfg->line_out_type != AUTO_PIN_HP_OUT) { 12327 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i], 12328 "Headphone", &vbits, i); 12329 if (err < 0) 12330 return err; 12331 } 12332 } 12333 return 0; 12334} 12335 12336#define alc262_auto_create_input_ctls \ 12337 alc882_auto_create_input_ctls 12338 12339/* 12340 * generic initialization of ADC, input mixers and output mixers 12341 */ 12342static const struct hda_verb alc262_volume_init_verbs[] = { 12343 /* 12344 * Unmute ADC0-2 and set the default input to mic-in 12345 */ 12346 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12348 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12349 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12350 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12351 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12352 12353 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12354 * mixer widget 12355 * Note: PASD motherboards uses the Line In 2 as the input for 12356 * front panel mic (mic 2) 12357 */ 12358 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12359 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12360 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12361 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12362 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12363 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12364 12365 /* 12366 * Set up output mixers (0x0c - 0x0f) 12367 */ 12368 /* set vol=0 to output mixers */ 12369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12372 12373 /* set up input amps for analog loopback */ 12374 /* Amp Indices: DAC = 0, mixer = 1 */ 12375 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12377 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12378 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12380 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12381 12382 /* FIXME: use matrix-type input source selection */ 12383 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12384 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12389 /* Input mixer2 */ 12390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12391 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12393 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12394 /* Input mixer3 */ 12395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12399 12400 { } 12401}; 12402 12403static const struct hda_verb alc262_HP_BPC_init_verbs[] = { 12404 /* 12405 * Unmute ADC0-2 and set the default input to mic-in 12406 */ 12407 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12409 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12411 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12412 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12413 12414 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12415 * mixer widget 12416 * Note: PASD motherboards uses the Line In 2 as the input for 12417 * front panel mic (mic 2) 12418 */ 12419 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12421 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12422 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12423 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12427 12428 /* 12429 * Set up output mixers (0x0c - 0x0e) 12430 */ 12431 /* set vol=0 to output mixers */ 12432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12433 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12434 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12435 12436 /* set up input amps for analog loopback */ 12437 /* Amp Indices: DAC = 0, mixer = 1 */ 12438 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12444 12445 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12447 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 12448 12449 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12451 12452 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12454 12455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12456 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12457 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 12458 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12459 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 12460 12461 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12462 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12464 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12465 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12466 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12467 12468 12469 /* FIXME: use matrix-type input source selection */ 12470 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ 12471 /* Input mixer1: only unmute Mic */ 12472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12474 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12475 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12476 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12477 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12478 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12479 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12480 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12481 /* Input mixer2 */ 12482 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12483 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12484 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12485 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12486 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12487 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12488 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12490 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12491 /* Input mixer3 */ 12492 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12493 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, 12494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, 12495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 12496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, 12497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, 12498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, 12499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, 12500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, 12501 12502 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12503 12504 { } 12505}; 12506 12507static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { 12508 /* 12509 * Unmute ADC0-2 and set the default input to mic-in 12510 */ 12511 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, 12512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12513 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 12514 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12515 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 12516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12517 12518 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback 12519 * mixer widget 12520 * Note: PASD motherboards uses the Line In 2 as the input for front 12521 * panel mic (mic 2) 12522 */ 12523 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 12524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 12525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 12526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 12527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 12528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 12529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 12530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 12531 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 12532 /* 12533 * Set up output mixers (0x0c - 0x0e) 12534 */ 12535 /* set vol=0 to output mixers */ 12536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 12539 12540 /* set up input amps for analog loopback */ 12541 /* Amp Indices: DAC = 0, mixer = 1 */ 12542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 12547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 12548 12549 12550 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ 12551 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ 12552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ 12553 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ 12554 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ 12556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ 12557 12558 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12560 12561 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 12562 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12563 12564 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ 12565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12566 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12567 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, 12568 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12569 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, 12570 12571 /* FIXME: use matrix-type input source selection */ 12572 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 12573 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 12574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ 12575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ 12576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ 12577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ 12578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ 12579 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12580 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ 12581 /* Input mixer2 */ 12582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12585 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12586 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12587 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12588 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12589 /* Input mixer3 */ 12590 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 12591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, 12592 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, 12593 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, 12594 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, 12595 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ 12596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, 12597 12598 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12599 12600 { } 12601}; 12602 12603static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { 12604 12605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ 12606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 12607 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, 12608 12609 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ 12610 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ 12611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, 12613 12614 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ 12615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 12616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 12617 {} 12618}; 12619 12620/* 12621 * Pin config fixes 12622 */ 12623enum { 12624 PINFIX_FSC_H270, 12625 PINFIX_HP_Z200, 12626}; 12627 12628static const struct alc_fixup alc262_fixups[] = { 12629 [PINFIX_FSC_H270] = { 12630 .type = ALC_FIXUP_PINS, 12631 .v.pins = (const struct alc_pincfg[]) { 12632 { 0x14, 0x99130110 }, /* speaker */ 12633 { 0x15, 0x0221142f }, /* front HP */ 12634 { 0x1b, 0x0121141f }, /* rear HP */ 12635 { } 12636 } 12637 }, 12638 [PINFIX_HP_Z200] = { 12639 .type = ALC_FIXUP_PINS, 12640 .v.pins = (const struct alc_pincfg[]) { 12641 { 0x16, 0x99130120 }, /* internal speaker */ 12642 { } 12643 } 12644 }, 12645}; 12646 12647static const struct snd_pci_quirk alc262_fixup_tbl[] = { 12648 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200), 12649 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), 12650 {} 12651}; 12652 12653 12654#ifdef CONFIG_SND_HDA_POWER_SAVE 12655#define alc262_loopbacks alc880_loopbacks 12656#endif 12657 12658/* pcm configuration: identical with ALC880 */ 12659#define alc262_pcm_analog_playback alc880_pcm_analog_playback 12660#define alc262_pcm_analog_capture alc880_pcm_analog_capture 12661#define alc262_pcm_digital_playback alc880_pcm_digital_playback 12662#define alc262_pcm_digital_capture alc880_pcm_digital_capture 12663 12664/* 12665 * BIOS auto configuration 12666 */ 12667static int alc262_parse_auto_config(struct hda_codec *codec) 12668{ 12669 struct alc_spec *spec = codec->spec; 12670 int err; 12671 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; 12672 12673 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 12674 alc262_ignore); 12675 if (err < 0) 12676 return err; 12677 if (!spec->autocfg.line_outs) { 12678 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 12679 spec->multiout.max_channels = 2; 12680 spec->no_analog = 1; 12681 goto dig_only; 12682 } 12683 return 0; /* can't find valid BIOS pin config */ 12684 } 12685 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 12686 if (err < 0) 12687 return err; 12688 err = alc262_auto_create_input_ctls(codec, &spec->autocfg); 12689 if (err < 0) 12690 return err; 12691 12692 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 12693 12694 dig_only: 12695 alc_auto_parse_digital(codec); 12696 12697 if (spec->kctls.list) 12698 add_mixer(spec, spec->kctls.list); 12699 12700 add_verb(spec, alc262_volume_init_verbs); 12701 spec->num_mux_defs = 1; 12702 spec->input_mux = &spec->private_imux[0]; 12703 12704 err = alc_auto_add_mic_boost(codec); 12705 if (err < 0) 12706 return err; 12707 12708 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 12709 12710 return 1; 12711} 12712 12713#define alc262_auto_init_multi_out alc882_auto_init_multi_out 12714#define alc262_auto_init_hp_out alc882_auto_init_hp_out 12715#define alc262_auto_init_analog_input alc882_auto_init_analog_input 12716#define alc262_auto_init_input_src alc882_auto_init_input_src 12717 12718 12719/* init callback for auto-configuration model -- overriding the default init */ 12720static void alc262_auto_init(struct hda_codec *codec) 12721{ 12722 struct alc_spec *spec = codec->spec; 12723 alc262_auto_init_multi_out(codec); 12724 alc262_auto_init_hp_out(codec); 12725 alc262_auto_init_analog_input(codec); 12726 alc262_auto_init_input_src(codec); 12727 alc_auto_init_digital(codec); 12728 if (spec->unsol_event) 12729 alc_inithook(codec); 12730} 12731 12732/* 12733 * configuration and preset 12734 */ 12735static const char * const alc262_models[ALC262_MODEL_LAST] = { 12736 [ALC262_BASIC] = "basic", 12737 [ALC262_HIPPO] = "hippo", 12738 [ALC262_HIPPO_1] = "hippo_1", 12739 [ALC262_FUJITSU] = "fujitsu", 12740 [ALC262_HP_BPC] = "hp-bpc", 12741 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 12742 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 12743 [ALC262_HP_RP5700] = "hp-rp5700", 12744 [ALC262_BENQ_ED8] = "benq", 12745 [ALC262_BENQ_T31] = "benq-t31", 12746 [ALC262_SONY_ASSAMD] = "sony-assamd", 12747 [ALC262_TOSHIBA_S06] = "toshiba-s06", 12748 [ALC262_TOSHIBA_RX1] = "toshiba-rx1", 12749 [ALC262_ULTRA] = "ultra", 12750 [ALC262_LENOVO_3000] = "lenovo-3000", 12751 [ALC262_NEC] = "nec", 12752 [ALC262_TYAN] = "tyan", 12753 [ALC262_AUTO] = "auto", 12754}; 12755 12756static const struct snd_pci_quirk alc262_cfg_tbl[] = { 12757 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), 12758 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), 12759 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", 12760 ALC262_HP_BPC), 12761 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12762 ALC262_HP_BPC), 12763 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", 12764 ALC262_HP_BPC), 12765 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", 12766 ALC262_AUTO), 12767 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12768 ALC262_HP_BPC), 12769 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12770 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), 12771 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), 12772 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), 12773 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), 12774 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), 12775 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), 12776 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), 12777 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), 12778 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), 12779 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 12780 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 12781 ALC262_HP_TC_T5735), 12782 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), 12783 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12784 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 12785 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 12786 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ 12787 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), 12788 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), 12789 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), 12790#if 0 /* disable the quirk since model=auto works better in recent versions */ 12791 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", 12792 ALC262_SONY_ASSAMD), 12793#endif 12794 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 12795 ALC262_TOSHIBA_RX1), 12796 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 12797 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), 12798 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), 12799 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), 12800 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", 12801 ALC262_ULTRA), 12802 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), 12803 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), 12804 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), 12805 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), 12806 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), 12807 {} 12808}; 12809 12810static const struct alc_config_preset alc262_presets[] = { 12811 [ALC262_BASIC] = { 12812 .mixers = { alc262_base_mixer }, 12813 .init_verbs = { alc262_init_verbs }, 12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12815 .dac_nids = alc262_dac_nids, 12816 .hp_nid = 0x03, 12817 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12818 .channel_mode = alc262_modes, 12819 .input_mux = &alc262_capture_source, 12820 }, 12821 [ALC262_HIPPO] = { 12822 .mixers = { alc262_hippo_mixer }, 12823 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, 12824 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12825 .dac_nids = alc262_dac_nids, 12826 .hp_nid = 0x03, 12827 .dig_out_nid = ALC262_DIGOUT_NID, 12828 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12829 .channel_mode = alc262_modes, 12830 .input_mux = &alc262_capture_source, 12831 .unsol_event = alc_sku_unsol_event, 12832 .setup = alc262_hippo_setup, 12833 .init_hook = alc_inithook, 12834 }, 12835 [ALC262_HIPPO_1] = { 12836 .mixers = { alc262_hippo1_mixer }, 12837 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, 12838 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12839 .dac_nids = alc262_dac_nids, 12840 .hp_nid = 0x02, 12841 .dig_out_nid = ALC262_DIGOUT_NID, 12842 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12843 .channel_mode = alc262_modes, 12844 .input_mux = &alc262_capture_source, 12845 .unsol_event = alc_sku_unsol_event, 12846 .setup = alc262_hippo1_setup, 12847 .init_hook = alc_inithook, 12848 }, 12849 [ALC262_FUJITSU] = { 12850 .mixers = { alc262_fujitsu_mixer }, 12851 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12852 alc262_fujitsu_unsol_verbs }, 12853 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12854 .dac_nids = alc262_dac_nids, 12855 .hp_nid = 0x03, 12856 .dig_out_nid = ALC262_DIGOUT_NID, 12857 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12858 .channel_mode = alc262_modes, 12859 .input_mux = &alc262_fujitsu_capture_source, 12860 .unsol_event = alc_sku_unsol_event, 12861 .setup = alc262_fujitsu_setup, 12862 .init_hook = alc_inithook, 12863 }, 12864 [ALC262_HP_BPC] = { 12865 .mixers = { alc262_HP_BPC_mixer }, 12866 .init_verbs = { alc262_HP_BPC_init_verbs }, 12867 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12868 .dac_nids = alc262_dac_nids, 12869 .hp_nid = 0x03, 12870 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12871 .channel_mode = alc262_modes, 12872 .input_mux = &alc262_HP_capture_source, 12873 .unsol_event = alc_sku_unsol_event, 12874 .setup = alc262_hp_bpc_setup, 12875 .init_hook = alc_inithook, 12876 }, 12877 [ALC262_HP_BPC_D7000_WF] = { 12878 .mixers = { alc262_HP_BPC_WildWest_mixer }, 12879 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12880 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12881 .dac_nids = alc262_dac_nids, 12882 .hp_nid = 0x03, 12883 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12884 .channel_mode = alc262_modes, 12885 .input_mux = &alc262_HP_D7000_capture_source, 12886 .unsol_event = alc_sku_unsol_event, 12887 .setup = alc262_hp_wildwest_setup, 12888 .init_hook = alc_inithook, 12889 }, 12890 [ALC262_HP_BPC_D7000_WL] = { 12891 .mixers = { alc262_HP_BPC_WildWest_mixer, 12892 alc262_HP_BPC_WildWest_option_mixer }, 12893 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, 12894 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12895 .dac_nids = alc262_dac_nids, 12896 .hp_nid = 0x03, 12897 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12898 .channel_mode = alc262_modes, 12899 .input_mux = &alc262_HP_D7000_capture_source, 12900 .unsol_event = alc_sku_unsol_event, 12901 .setup = alc262_hp_wildwest_setup, 12902 .init_hook = alc_inithook, 12903 }, 12904 [ALC262_HP_TC_T5735] = { 12905 .mixers = { alc262_hp_t5735_mixer }, 12906 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, 12907 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12908 .dac_nids = alc262_dac_nids, 12909 .hp_nid = 0x03, 12910 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12911 .channel_mode = alc262_modes, 12912 .input_mux = &alc262_capture_source, 12913 .unsol_event = alc_sku_unsol_event, 12914 .setup = alc262_hp_t5735_setup, 12915 .init_hook = alc_inithook, 12916 }, 12917 [ALC262_HP_RP5700] = { 12918 .mixers = { alc262_hp_rp5700_mixer }, 12919 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, 12920 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12921 .dac_nids = alc262_dac_nids, 12922 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12923 .channel_mode = alc262_modes, 12924 .input_mux = &alc262_hp_rp5700_capture_source, 12925 }, 12926 [ALC262_BENQ_ED8] = { 12927 .mixers = { alc262_base_mixer }, 12928 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 12929 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12930 .dac_nids = alc262_dac_nids, 12931 .hp_nid = 0x03, 12932 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12933 .channel_mode = alc262_modes, 12934 .input_mux = &alc262_capture_source, 12935 }, 12936 [ALC262_SONY_ASSAMD] = { 12937 .mixers = { alc262_sony_mixer }, 12938 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, 12939 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12940 .dac_nids = alc262_dac_nids, 12941 .hp_nid = 0x02, 12942 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12943 .channel_mode = alc262_modes, 12944 .input_mux = &alc262_capture_source, 12945 .unsol_event = alc_sku_unsol_event, 12946 .setup = alc262_hippo_setup, 12947 .init_hook = alc_inithook, 12948 }, 12949 [ALC262_BENQ_T31] = { 12950 .mixers = { alc262_benq_t31_mixer }, 12951 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, 12952 alc_hp15_unsol_verbs }, 12953 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12954 .dac_nids = alc262_dac_nids, 12955 .hp_nid = 0x03, 12956 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12957 .channel_mode = alc262_modes, 12958 .input_mux = &alc262_capture_source, 12959 .unsol_event = alc_sku_unsol_event, 12960 .setup = alc262_hippo_setup, 12961 .init_hook = alc_inithook, 12962 }, 12963 [ALC262_ULTRA] = { 12964 .mixers = { alc262_ultra_mixer }, 12965 .cap_mixer = alc262_ultra_capture_mixer, 12966 .init_verbs = { alc262_ultra_verbs }, 12967 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12968 .dac_nids = alc262_dac_nids, 12969 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12970 .channel_mode = alc262_modes, 12971 .input_mux = &alc262_ultra_capture_source, 12972 .adc_nids = alc262_adc_nids, /* ADC0 */ 12973 .capsrc_nids = alc262_capsrc_nids, 12974 .num_adc_nids = 1, /* single ADC */ 12975 .unsol_event = alc262_ultra_unsol_event, 12976 .init_hook = alc262_ultra_automute, 12977 }, 12978 [ALC262_LENOVO_3000] = { 12979 .mixers = { alc262_lenovo_3000_mixer }, 12980 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, 12981 alc262_lenovo_3000_unsol_verbs, 12982 alc262_lenovo_3000_init_verbs }, 12983 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12984 .dac_nids = alc262_dac_nids, 12985 .hp_nid = 0x03, 12986 .dig_out_nid = ALC262_DIGOUT_NID, 12987 .num_channel_mode = ARRAY_SIZE(alc262_modes), 12988 .channel_mode = alc262_modes, 12989 .input_mux = &alc262_fujitsu_capture_source, 12990 .unsol_event = alc_sku_unsol_event, 12991 .setup = alc262_lenovo_3000_setup, 12992 .init_hook = alc_inithook, 12993 }, 12994 [ALC262_NEC] = { 12995 .mixers = { alc262_nec_mixer }, 12996 .init_verbs = { alc262_nec_verbs }, 12997 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 12998 .dac_nids = alc262_dac_nids, 12999 .hp_nid = 0x03, 13000 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13001 .channel_mode = alc262_modes, 13002 .input_mux = &alc262_capture_source, 13003 }, 13004 [ALC262_TOSHIBA_S06] = { 13005 .mixers = { alc262_toshiba_s06_mixer }, 13006 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, 13007 alc262_eapd_verbs }, 13008 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 13009 .capsrc_nids = alc262_dmic_capsrc_nids, 13010 .dac_nids = alc262_dac_nids, 13011 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ 13012 .num_adc_nids = 1, /* single ADC */ 13013 .dig_out_nid = ALC262_DIGOUT_NID, 13014 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13015 .channel_mode = alc262_modes, 13016 .unsol_event = alc_sku_unsol_event, 13017 .setup = alc262_toshiba_s06_setup, 13018 .init_hook = alc_inithook, 13019 }, 13020 [ALC262_TOSHIBA_RX1] = { 13021 .mixers = { alc262_toshiba_rx1_mixer }, 13022 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, 13023 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 13024 .dac_nids = alc262_dac_nids, 13025 .hp_nid = 0x03, 13026 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13027 .channel_mode = alc262_modes, 13028 .input_mux = &alc262_capture_source, 13029 .unsol_event = alc_sku_unsol_event, 13030 .setup = alc262_hippo_setup, 13031 .init_hook = alc_inithook, 13032 }, 13033 [ALC262_TYAN] = { 13034 .mixers = { alc262_tyan_mixer }, 13035 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, 13036 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 13037 .dac_nids = alc262_dac_nids, 13038 .hp_nid = 0x02, 13039 .dig_out_nid = ALC262_DIGOUT_NID, 13040 .num_channel_mode = ARRAY_SIZE(alc262_modes), 13041 .channel_mode = alc262_modes, 13042 .input_mux = &alc262_capture_source, 13043 .unsol_event = alc_sku_unsol_event, 13044 .setup = alc262_tyan_setup, 13045 .init_hook = alc_hp_automute, 13046 }, 13047}; 13048 13049static int patch_alc262(struct hda_codec *codec) 13050{ 13051 struct alc_spec *spec; 13052 int board_config; 13053 int err; 13054 13055 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 13056 if (spec == NULL) 13057 return -ENOMEM; 13058 13059 codec->spec = spec; 13060#if 0 13061 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 13062 * under-run 13063 */ 13064 { 13065 int tmp; 13066 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 13067 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); 13068 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); 13069 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); 13070 } 13071#endif 13072 alc_auto_parse_customize_define(codec); 13073 13074 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 13075 13076 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 13077 alc262_models, 13078 alc262_cfg_tbl); 13079 13080 if (board_config < 0) { 13081 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 13082 codec->chip_name); 13083 board_config = ALC262_AUTO; 13084 } 13085 13086 if (board_config == ALC262_AUTO) { 13087 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 13088 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 13089 } 13090 13091 if (board_config == ALC262_AUTO) { 13092 /* automatic parse from the BIOS config */ 13093 err = alc262_parse_auto_config(codec); 13094 if (err < 0) { 13095 alc_free(codec); 13096 return err; 13097 } else if (!err) { 13098 printk(KERN_INFO 13099 "hda_codec: Cannot set up configuration " 13100 "from BIOS. Using base mode...\n"); 13101 board_config = ALC262_BASIC; 13102 } 13103 } 13104 13105 if (!spec->no_analog && has_cdefine_beep(codec)) { 13106 err = snd_hda_attach_beep_device(codec, 0x1); 13107 if (err < 0) { 13108 alc_free(codec); 13109 return err; 13110 } 13111 } 13112 13113 if (board_config != ALC262_AUTO) 13114 setup_preset(codec, &alc262_presets[board_config]); 13115 13116 spec->stream_analog_playback = &alc262_pcm_analog_playback; 13117 spec->stream_analog_capture = &alc262_pcm_analog_capture; 13118 13119 spec->stream_digital_playback = &alc262_pcm_digital_playback; 13120 spec->stream_digital_capture = &alc262_pcm_digital_capture; 13121 13122 if (!spec->adc_nids && spec->input_mux) { 13123 int i; 13124 /* check whether the digital-mic has to be supported */ 13125 for (i = 0; i < spec->input_mux->num_items; i++) { 13126 if (spec->input_mux->items[i].index >= 9) 13127 break; 13128 } 13129 if (i < spec->input_mux->num_items) { 13130 /* use only ADC0 */ 13131 spec->adc_nids = alc262_dmic_adc_nids; 13132 spec->num_adc_nids = 1; 13133 spec->capsrc_nids = alc262_dmic_capsrc_nids; 13134 } else { 13135 /* all analog inputs */ 13136 /* check whether NID 0x07 is valid */ 13137 unsigned int wcap = get_wcaps(codec, 0x07); 13138 13139 /* get type */ 13140 wcap = get_wcaps_type(wcap); 13141 if (wcap != AC_WID_AUD_IN) { 13142 spec->adc_nids = alc262_adc_nids_alt; 13143 spec->num_adc_nids = 13144 ARRAY_SIZE(alc262_adc_nids_alt); 13145 spec->capsrc_nids = alc262_capsrc_nids_alt; 13146 } else { 13147 spec->adc_nids = alc262_adc_nids; 13148 spec->num_adc_nids = 13149 ARRAY_SIZE(alc262_adc_nids); 13150 spec->capsrc_nids = alc262_capsrc_nids; 13151 } 13152 } 13153 } 13154 if (!spec->cap_mixer && !spec->no_analog) 13155 set_capture_mixer(codec); 13156 if (!spec->no_analog && has_cdefine_beep(codec)) 13157 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 13158 13159 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 13160 13161 spec->vmaster_nid = 0x0c; 13162 13163 codec->patch_ops = alc_patch_ops; 13164 if (board_config == ALC262_AUTO) 13165 spec->init_hook = alc262_auto_init; 13166 spec->shutup = alc_eapd_shutup; 13167 13168 alc_init_jacks(codec); 13169#ifdef CONFIG_SND_HDA_POWER_SAVE 13170 if (!spec->loopback.amplist) 13171 spec->loopback.amplist = alc262_loopbacks; 13172#endif 13173 13174 return 0; 13175} 13176 13177/* 13178 * ALC268 channel source setting (2 channel) 13179 */ 13180#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID 13181#define alc268_modes alc260_modes 13182 13183static const hda_nid_t alc268_dac_nids[2] = { 13184 /* front, hp */ 13185 0x02, 0x03 13186}; 13187 13188static const hda_nid_t alc268_adc_nids[2] = { 13189 /* ADC0-1 */ 13190 0x08, 0x07 13191}; 13192 13193static const hda_nid_t alc268_adc_nids_alt[1] = { 13194 /* ADC0 */ 13195 0x08 13196}; 13197 13198static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; 13199 13200static const struct snd_kcontrol_new alc268_base_mixer[] = { 13201 /* output mixer control */ 13202 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13203 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13206 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13207 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13208 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13209 { } 13210}; 13211 13212static const struct snd_kcontrol_new alc268_toshiba_mixer[] = { 13213 /* output mixer control */ 13214 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13216 ALC262_HIPPO_MASTER_SWITCH, 13217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13218 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 13219 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13220 { } 13221}; 13222 13223/* bind Beep switches of both NID 0x0f and 0x10 */ 13224static const struct hda_bind_ctls alc268_bind_beep_sw = { 13225 .ops = &snd_hda_bind_sw, 13226 .values = { 13227 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), 13228 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), 13229 0 13230 }, 13231}; 13232 13233static const struct snd_kcontrol_new alc268_beep_mixer[] = { 13234 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), 13235 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), 13236 { } 13237}; 13238 13239static const struct hda_verb alc268_eapd_verbs[] = { 13240 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13241 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13242 { } 13243}; 13244 13245/* Toshiba specific */ 13246static const struct hda_verb alc268_toshiba_verbs[] = { 13247 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13248 { } /* end */ 13249}; 13250 13251/* Acer specific */ 13252/* bind volumes of both NID 0x02 and 0x03 */ 13253static const struct hda_bind_ctls alc268_acer_bind_master_vol = { 13254 .ops = &snd_hda_bind_vol, 13255 .values = { 13256 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 13257 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 13258 0 13259 }, 13260}; 13261 13262static void alc268_acer_setup(struct hda_codec *codec) 13263{ 13264 struct alc_spec *spec = codec->spec; 13265 13266 spec->autocfg.hp_pins[0] = 0x14; 13267 spec->autocfg.speaker_pins[0] = 0x15; 13268 spec->automute = 1; 13269 spec->automute_mode = ALC_AUTOMUTE_AMP; 13270} 13271 13272#define alc268_acer_master_sw_get alc262_hp_master_sw_get 13273#define alc268_acer_master_sw_put alc262_hp_master_sw_put 13274 13275static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { 13276 /* output mixer control */ 13277 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13278 { 13279 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13280 .name = "Master Playback Switch", 13281 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15, 13282 .info = snd_ctl_boolean_mono_info, 13283 .get = alc268_acer_master_sw_get, 13284 .put = alc268_acer_master_sw_put, 13285 }, 13286 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), 13287 { } 13288}; 13289 13290static const struct snd_kcontrol_new alc268_acer_mixer[] = { 13291 /* output mixer control */ 13292 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13293 { 13294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13295 .name = "Master Playback Switch", 13296 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, 13297 .info = snd_ctl_boolean_mono_info, 13298 .get = alc268_acer_master_sw_get, 13299 .put = alc268_acer_master_sw_put, 13300 }, 13301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13302 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13303 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13304 { } 13305}; 13306 13307static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { 13308 /* output mixer control */ 13309 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 13310 { 13311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 13312 .name = "Master Playback Switch", 13313 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, 13314 .info = snd_ctl_boolean_mono_info, 13315 .get = alc268_acer_master_sw_get, 13316 .put = alc268_acer_master_sw_put, 13317 }, 13318 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13319 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), 13320 { } 13321}; 13322 13323static const struct hda_verb alc268_acer_aspire_one_verbs[] = { 13324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13326 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13327 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 13328 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, 13329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, 13330 { } 13331}; 13332 13333static const struct hda_verb alc268_acer_verbs[] = { 13334 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ 13335 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 13336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 13338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 13340 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13341 { } 13342}; 13343 13344/* unsolicited event for HP jack sensing */ 13345#define alc268_toshiba_setup alc262_hippo_setup 13346 13347static void alc268_acer_lc_setup(struct hda_codec *codec) 13348{ 13349 struct alc_spec *spec = codec->spec; 13350 spec->autocfg.hp_pins[0] = 0x15; 13351 spec->autocfg.speaker_pins[0] = 0x14; 13352 spec->automute = 1; 13353 spec->automute_mode = ALC_AUTOMUTE_AMP; 13354 spec->ext_mic.pin = 0x18; 13355 spec->ext_mic.mux_idx = 0; 13356 spec->int_mic.pin = 0x12; 13357 spec->int_mic.mux_idx = 6; 13358 spec->auto_mic = 1; 13359} 13360 13361static const struct snd_kcontrol_new alc268_dell_mixer[] = { 13362 /* output mixer control */ 13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13367 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13368 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13369 { } 13370}; 13371 13372static const struct hda_verb alc268_dell_verbs[] = { 13373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13374 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13377 { } 13378}; 13379 13380/* mute/unmute internal speaker according to the hp jack and mute state */ 13381static void alc268_dell_setup(struct hda_codec *codec) 13382{ 13383 struct alc_spec *spec = codec->spec; 13384 13385 spec->autocfg.hp_pins[0] = 0x15; 13386 spec->autocfg.speaker_pins[0] = 0x14; 13387 spec->ext_mic.pin = 0x18; 13388 spec->ext_mic.mux_idx = 0; 13389 spec->int_mic.pin = 0x19; 13390 spec->int_mic.mux_idx = 1; 13391 spec->auto_mic = 1; 13392 spec->automute = 1; 13393 spec->automute_mode = ALC_AUTOMUTE_PIN; 13394} 13395 13396static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 13397 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13398 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13401 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13402 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13403 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 13404 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 13405 { } 13406}; 13407 13408static const struct hda_verb alc267_quanta_il1_verbs[] = { 13409 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 13410 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 13411 { } 13412}; 13413 13414static void alc267_quanta_il1_setup(struct hda_codec *codec) 13415{ 13416 struct alc_spec *spec = codec->spec; 13417 spec->autocfg.hp_pins[0] = 0x15; 13418 spec->autocfg.speaker_pins[0] = 0x14; 13419 spec->ext_mic.pin = 0x18; 13420 spec->ext_mic.mux_idx = 0; 13421 spec->int_mic.pin = 0x19; 13422 spec->int_mic.mux_idx = 1; 13423 spec->auto_mic = 1; 13424 spec->automute = 1; 13425 spec->automute_mode = ALC_AUTOMUTE_PIN; 13426} 13427 13428/* 13429 * generic initialization of ADC, input mixers and output mixers 13430 */ 13431static const struct hda_verb alc268_base_init_verbs[] = { 13432 /* Unmute DAC0-1 and set vol = 0 */ 13433 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13434 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13435 13436 /* 13437 * Set up output mixers (0x0c - 0x0e) 13438 */ 13439 /* set vol=0 to output mixers */ 13440 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13441 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, 13442 13443 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13444 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13445 13446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 13448 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, 13449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13450 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13452 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13453 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13454 13455 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13458 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13459 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13460 13461 /* set PCBEEP vol = 0, mute connections */ 13462 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13463 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13464 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13465 13466 /* Unmute Selector 23h,24h and set the default input to mic-in */ 13467 13468 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 13469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13470 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, 13471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13472 13473 { } 13474}; 13475 13476/* 13477 * generic initialization of ADC, input mixers and output mixers 13478 */ 13479static const struct hda_verb alc268_volume_init_verbs[] = { 13480 /* set output DAC */ 13481 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13483 13484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13485 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, 13486 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13487 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13488 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, 13489 13490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13492 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13493 13494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13495 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 13496 13497 /* set PCBEEP vol = 0, mute connections */ 13498 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13499 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13500 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 13501 13502 { } 13503}; 13504 13505static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { 13506 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13507 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13508 { } /* end */ 13509}; 13510 13511static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 13512 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13513 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13514 _DEFINE_CAPSRC(1), 13515 { } /* end */ 13516}; 13517 13518static const struct snd_kcontrol_new alc268_capture_mixer[] = { 13519 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13520 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 13521 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 13522 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 13523 _DEFINE_CAPSRC(2), 13524 { } /* end */ 13525}; 13526 13527static const struct hda_input_mux alc268_capture_source = { 13528 .num_items = 4, 13529 .items = { 13530 { "Mic", 0x0 }, 13531 { "Front Mic", 0x1 }, 13532 { "Line", 0x2 }, 13533 { "CD", 0x3 }, 13534 }, 13535}; 13536 13537static const struct hda_input_mux alc268_acer_capture_source = { 13538 .num_items = 3, 13539 .items = { 13540 { "Mic", 0x0 }, 13541 { "Internal Mic", 0x1 }, 13542 { "Line", 0x2 }, 13543 }, 13544}; 13545 13546static const struct hda_input_mux alc268_acer_dmic_capture_source = { 13547 .num_items = 3, 13548 .items = { 13549 { "Mic", 0x0 }, 13550 { "Internal Mic", 0x6 }, 13551 { "Line", 0x2 }, 13552 }, 13553}; 13554 13555#ifdef CONFIG_SND_DEBUG 13556static const struct snd_kcontrol_new alc268_test_mixer[] = { 13557 /* Volume widgets */ 13558 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13559 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13560 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), 13561 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), 13562 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), 13563 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), 13564 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), 13565 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), 13566 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), 13567 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), 13568 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), 13569 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), 13570 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), 13571 /* The below appears problematic on some hardwares */ 13572 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ 13573 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13574 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), 13575 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), 13576 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), 13577 13578 /* Modes for retasking pin widgets */ 13579 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), 13580 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), 13581 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), 13582 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), 13583 13584 /* Controls for GPIO pins, assuming they are configured as outputs */ 13585 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), 13586 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), 13587 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), 13588 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), 13589 13590 /* Switches to allow the digital SPDIF output pin to be enabled. 13591 * The ALC268 does not have an SPDIF input. 13592 */ 13593 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), 13594 13595 /* A switch allowing EAPD to be enabled. Some laptops seem to use 13596 * this output to turn on an external amplifier. 13597 */ 13598 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), 13599 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), 13600 13601 { } /* end */ 13602}; 13603#endif 13604 13605/* create input playback/capture controls for the given pin */ 13606static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 13607 const char *ctlname, int idx) 13608{ 13609 hda_nid_t dac; 13610 int err; 13611 13612 switch (nid) { 13613 case 0x14: 13614 case 0x16: 13615 dac = 0x02; 13616 break; 13617 case 0x15: 13618 case 0x1a: /* ALC259/269 only */ 13619 case 0x1b: /* ALC259/269 only */ 13620 case 0x21: /* ALC269vb has this pin, too */ 13621 dac = 0x03; 13622 break; 13623 default: 13624 snd_printd(KERN_WARNING "hda_codec: " 13625 "ignoring pin 0x%x as unknown\n", nid); 13626 return 0; 13627 } 13628 if (spec->multiout.dac_nids[0] != dac && 13629 spec->multiout.dac_nids[1] != dac) { 13630 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 13631 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 13632 HDA_OUTPUT)); 13633 if (err < 0) 13634 return err; 13635 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 13636 } 13637 13638 if (nid != 0x16) 13639 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13640 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 13641 else /* mono */ 13642 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 13643 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT)); 13644 if (err < 0) 13645 return err; 13646 return 0; 13647} 13648 13649/* add playback controls from the parsed DAC table */ 13650static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, 13651 const struct auto_pin_cfg *cfg) 13652{ 13653 hda_nid_t nid; 13654 int err; 13655 13656 spec->multiout.dac_nids = spec->private_dac_nids; 13657 13658 nid = cfg->line_out_pins[0]; 13659 if (nid) { 13660 const char *name; 13661 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 13662 name = "Speaker"; 13663 else 13664 name = "Front"; 13665 err = alc268_new_analog_output(spec, nid, name, 0); 13666 if (err < 0) 13667 return err; 13668 } 13669 13670 nid = cfg->speaker_pins[0]; 13671 if (nid == 0x1d) { 13672 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker", 13673 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 13674 if (err < 0) 13675 return err; 13676 } else if (nid) { 13677 err = alc268_new_analog_output(spec, nid, "Speaker", 0); 13678 if (err < 0) 13679 return err; 13680 } 13681 nid = cfg->hp_pins[0]; 13682 if (nid) { 13683 err = alc268_new_analog_output(spec, nid, "Headphone", 0); 13684 if (err < 0) 13685 return err; 13686 } 13687 13688 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 13689 if (nid == 0x16) { 13690 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono", 13691 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); 13692 if (err < 0) 13693 return err; 13694 } 13695 return 0; 13696} 13697 13698/* create playback/capture controls for input pins */ 13699static int alc268_auto_create_input_ctls(struct hda_codec *codec, 13700 const struct auto_pin_cfg *cfg) 13701{ 13702 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24); 13703} 13704 13705static void alc268_auto_set_output_and_unmute(struct hda_codec *codec, 13706 hda_nid_t nid, int pin_type) 13707{ 13708 int idx; 13709 13710 alc_set_pin_output(codec, nid, pin_type); 13711 if (nid == 0x14 || nid == 0x16) 13712 idx = 0; 13713 else 13714 idx = 1; 13715 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); 13716} 13717 13718static void alc268_auto_init_multi_out(struct hda_codec *codec) 13719{ 13720 struct alc_spec *spec = codec->spec; 13721 int i; 13722 13723 for (i = 0; i < spec->autocfg.line_outs; i++) { 13724 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13725 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13726 alc268_auto_set_output_and_unmute(codec, nid, pin_type); 13727 } 13728} 13729 13730static void alc268_auto_init_hp_out(struct hda_codec *codec) 13731{ 13732 struct alc_spec *spec = codec->spec; 13733 hda_nid_t pin; 13734 int i; 13735 13736 for (i = 0; i < spec->autocfg.hp_outs; i++) { 13737 pin = spec->autocfg.hp_pins[i]; 13738 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP); 13739 } 13740 for (i = 0; i < spec->autocfg.speaker_outs; i++) { 13741 pin = spec->autocfg.speaker_pins[i]; 13742 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT); 13743 } 13744 if (spec->autocfg.mono_out_pin) 13745 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0, 13746 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13747} 13748 13749static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 13750{ 13751 struct alc_spec *spec = codec->spec; 13752 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; 13753 hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; 13754 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 13755 unsigned int dac_vol1, dac_vol2; 13756 13757 if (line_nid == 0x1d || speaker_nid == 0x1d) { 13758 snd_hda_codec_write(codec, speaker_nid, 0, 13759 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 13760 /* mute mixer inputs from 0x1d */ 13761 snd_hda_codec_write(codec, 0x0f, 0, 13762 AC_VERB_SET_AMP_GAIN_MUTE, 13763 AMP_IN_UNMUTE(1)); 13764 snd_hda_codec_write(codec, 0x10, 0, 13765 AC_VERB_SET_AMP_GAIN_MUTE, 13766 AMP_IN_UNMUTE(1)); 13767 } else { 13768 /* unmute mixer inputs from 0x1d */ 13769 snd_hda_codec_write(codec, 0x0f, 0, 13770 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13771 snd_hda_codec_write(codec, 0x10, 0, 13772 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 13773 } 13774 13775 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ 13776 if (line_nid == 0x14) 13777 dac_vol2 = AMP_OUT_ZERO; 13778 else if (line_nid == 0x15) 13779 dac_vol1 = AMP_OUT_ZERO; 13780 if (hp_nid == 0x14) 13781 dac_vol2 = AMP_OUT_ZERO; 13782 else if (hp_nid == 0x15) 13783 dac_vol1 = AMP_OUT_ZERO; 13784 if (line_nid != 0x16 || hp_nid != 0x16 || 13785 spec->autocfg.line_out_pins[1] != 0x16 || 13786 spec->autocfg.line_out_pins[2] != 0x16) 13787 dac_vol1 = dac_vol2 = AMP_OUT_ZERO; 13788 13789 snd_hda_codec_write(codec, 0x02, 0, 13790 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1); 13791 snd_hda_codec_write(codec, 0x03, 0, 13792 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 13793} 13794 13795/* pcm configuration: identical with ALC880 */ 13796#define alc268_pcm_analog_playback alc880_pcm_analog_playback 13797#define alc268_pcm_analog_capture alc880_pcm_analog_capture 13798#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 13799#define alc268_pcm_digital_playback alc880_pcm_digital_playback 13800 13801/* 13802 * BIOS auto configuration 13803 */ 13804static int alc268_parse_auto_config(struct hda_codec *codec) 13805{ 13806 struct alc_spec *spec = codec->spec; 13807 int err; 13808 static const hda_nid_t alc268_ignore[] = { 0 }; 13809 13810 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13811 alc268_ignore); 13812 if (err < 0) 13813 return err; 13814 if (!spec->autocfg.line_outs) { 13815 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 13816 spec->multiout.max_channels = 2; 13817 spec->no_analog = 1; 13818 goto dig_only; 13819 } 13820 return 0; /* can't find valid BIOS pin config */ 13821 } 13822 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 13823 if (err < 0) 13824 return err; 13825 err = alc268_auto_create_input_ctls(codec, &spec->autocfg); 13826 if (err < 0) 13827 return err; 13828 13829 spec->multiout.max_channels = 2; 13830 13831 dig_only: 13832 /* digital only support output */ 13833 alc_auto_parse_digital(codec); 13834 if (spec->kctls.list) 13835 add_mixer(spec, spec->kctls.list); 13836 13837 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) 13838 add_mixer(spec, alc268_beep_mixer); 13839 13840 add_verb(spec, alc268_volume_init_verbs); 13841 spec->num_mux_defs = 2; 13842 spec->input_mux = &spec->private_imux[0]; 13843 13844 err = alc_auto_add_mic_boost(codec); 13845 if (err < 0) 13846 return err; 13847 13848 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 13849 13850 return 1; 13851} 13852 13853#define alc268_auto_init_analog_input alc882_auto_init_analog_input 13854#define alc268_auto_init_input_src alc882_auto_init_input_src 13855 13856/* init callback for auto-configuration model -- overriding the default init */ 13857static void alc268_auto_init(struct hda_codec *codec) 13858{ 13859 struct alc_spec *spec = codec->spec; 13860 alc268_auto_init_multi_out(codec); 13861 alc268_auto_init_hp_out(codec); 13862 alc268_auto_init_mono_speaker_out(codec); 13863 alc268_auto_init_analog_input(codec); 13864 alc268_auto_init_input_src(codec); 13865 alc_auto_init_digital(codec); 13866 if (spec->unsol_event) 13867 alc_inithook(codec); 13868} 13869 13870/* 13871 * configuration and preset 13872 */ 13873static const char * const alc268_models[ALC268_MODEL_LAST] = { 13874 [ALC267_QUANTA_IL1] = "quanta-il1", 13875 [ALC268_3ST] = "3stack", 13876 [ALC268_TOSHIBA] = "toshiba", 13877 [ALC268_ACER] = "acer", 13878 [ALC268_ACER_DMIC] = "acer-dmic", 13879 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 13880 [ALC268_DELL] = "dell", 13881 [ALC268_ZEPTO] = "zepto", 13882#ifdef CONFIG_SND_DEBUG 13883 [ALC268_TEST] = "test", 13884#endif 13885 [ALC268_AUTO] = "auto", 13886}; 13887 13888static const struct snd_pci_quirk alc268_cfg_tbl[] = { 13889 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), 13890 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), 13891 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), 13892 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), 13893 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), 13894 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 13895 ALC268_ACER_ASPIRE_ONE), 13896 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 13897 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO), 13898 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, 13899 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), 13900 /* almost compatible with toshiba but with optional digital outs; 13901 * auto-probing seems working fine 13902 */ 13903 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 13904 ALC268_AUTO), 13905 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 13906 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 13907 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 13908 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), 13909 {} 13910}; 13911 13912/* Toshiba laptops have no unique PCI SSID but only codec SSID */ 13913static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { 13914 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), 13915 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), 13916 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", 13917 ALC268_TOSHIBA), 13918 {} 13919}; 13920 13921static const struct alc_config_preset alc268_presets[] = { 13922 [ALC267_QUANTA_IL1] = { 13923 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, 13924 alc268_capture_nosrc_mixer }, 13925 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13926 alc267_quanta_il1_verbs }, 13927 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13928 .dac_nids = alc268_dac_nids, 13929 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13930 .adc_nids = alc268_adc_nids_alt, 13931 .hp_nid = 0x03, 13932 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13933 .channel_mode = alc268_modes, 13934 .unsol_event = alc_sku_unsol_event, 13935 .setup = alc267_quanta_il1_setup, 13936 .init_hook = alc_inithook, 13937 }, 13938 [ALC268_3ST] = { 13939 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 13940 alc268_beep_mixer }, 13941 .init_verbs = { alc268_base_init_verbs }, 13942 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13943 .dac_nids = alc268_dac_nids, 13944 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13945 .adc_nids = alc268_adc_nids_alt, 13946 .capsrc_nids = alc268_capsrc_nids, 13947 .hp_nid = 0x03, 13948 .dig_out_nid = ALC268_DIGOUT_NID, 13949 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13950 .channel_mode = alc268_modes, 13951 .input_mux = &alc268_capture_source, 13952 }, 13953 [ALC268_TOSHIBA] = { 13954 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer, 13955 alc268_beep_mixer }, 13956 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13957 alc268_toshiba_verbs }, 13958 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13959 .dac_nids = alc268_dac_nids, 13960 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13961 .adc_nids = alc268_adc_nids_alt, 13962 .capsrc_nids = alc268_capsrc_nids, 13963 .hp_nid = 0x03, 13964 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13965 .channel_mode = alc268_modes, 13966 .input_mux = &alc268_capture_source, 13967 .unsol_event = alc_sku_unsol_event, 13968 .setup = alc268_toshiba_setup, 13969 .init_hook = alc_inithook, 13970 }, 13971 [ALC268_ACER] = { 13972 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 13973 alc268_beep_mixer }, 13974 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13975 alc268_acer_verbs }, 13976 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13977 .dac_nids = alc268_dac_nids, 13978 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13979 .adc_nids = alc268_adc_nids_alt, 13980 .capsrc_nids = alc268_capsrc_nids, 13981 .hp_nid = 0x02, 13982 .num_channel_mode = ARRAY_SIZE(alc268_modes), 13983 .channel_mode = alc268_modes, 13984 .input_mux = &alc268_acer_capture_source, 13985 .unsol_event = alc_sku_unsol_event, 13986 .setup = alc268_acer_setup, 13987 .init_hook = alc_inithook, 13988 }, 13989 [ALC268_ACER_DMIC] = { 13990 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, 13991 alc268_beep_mixer }, 13992 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 13993 alc268_acer_verbs }, 13994 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 13995 .dac_nids = alc268_dac_nids, 13996 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 13997 .adc_nids = alc268_adc_nids_alt, 13998 .capsrc_nids = alc268_capsrc_nids, 13999 .hp_nid = 0x02, 14000 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14001 .channel_mode = alc268_modes, 14002 .input_mux = &alc268_acer_dmic_capture_source, 14003 .unsol_event = alc_sku_unsol_event, 14004 .setup = alc268_acer_setup, 14005 .init_hook = alc_inithook, 14006 }, 14007 [ALC268_ACER_ASPIRE_ONE] = { 14008 .mixers = { alc268_acer_aspire_one_mixer, 14009 alc268_beep_mixer, 14010 alc268_capture_nosrc_mixer }, 14011 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 14012 alc268_acer_aspire_one_verbs }, 14013 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 14014 .dac_nids = alc268_dac_nids, 14015 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 14016 .adc_nids = alc268_adc_nids_alt, 14017 .capsrc_nids = alc268_capsrc_nids, 14018 .hp_nid = 0x03, 14019 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14020 .channel_mode = alc268_modes, 14021 .unsol_event = alc_sku_unsol_event, 14022 .setup = alc268_acer_lc_setup, 14023 .init_hook = alc_inithook, 14024 }, 14025 [ALC268_DELL] = { 14026 .mixers = { alc268_dell_mixer, alc268_beep_mixer, 14027 alc268_capture_nosrc_mixer }, 14028 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 14029 alc268_dell_verbs }, 14030 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 14031 .dac_nids = alc268_dac_nids, 14032 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 14033 .adc_nids = alc268_adc_nids_alt, 14034 .capsrc_nids = alc268_capsrc_nids, 14035 .hp_nid = 0x02, 14036 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14037 .channel_mode = alc268_modes, 14038 .unsol_event = alc_sku_unsol_event, 14039 .setup = alc268_dell_setup, 14040 .init_hook = alc_inithook, 14041 }, 14042 [ALC268_ZEPTO] = { 14043 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 14044 alc268_beep_mixer }, 14045 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 14046 alc268_toshiba_verbs }, 14047 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 14048 .dac_nids = alc268_dac_nids, 14049 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 14050 .adc_nids = alc268_adc_nids_alt, 14051 .capsrc_nids = alc268_capsrc_nids, 14052 .hp_nid = 0x03, 14053 .dig_out_nid = ALC268_DIGOUT_NID, 14054 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14055 .channel_mode = alc268_modes, 14056 .input_mux = &alc268_capture_source, 14057 .unsol_event = alc_sku_unsol_event, 14058 .setup = alc268_toshiba_setup, 14059 .init_hook = alc_inithook, 14060 }, 14061#ifdef CONFIG_SND_DEBUG 14062 [ALC268_TEST] = { 14063 .mixers = { alc268_test_mixer, alc268_capture_mixer }, 14064 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 14065 alc268_volume_init_verbs }, 14066 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 14067 .dac_nids = alc268_dac_nids, 14068 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), 14069 .adc_nids = alc268_adc_nids_alt, 14070 .capsrc_nids = alc268_capsrc_nids, 14071 .hp_nid = 0x03, 14072 .dig_out_nid = ALC268_DIGOUT_NID, 14073 .num_channel_mode = ARRAY_SIZE(alc268_modes), 14074 .channel_mode = alc268_modes, 14075 .input_mux = &alc268_capture_source, 14076 }, 14077#endif 14078}; 14079 14080static int patch_alc268(struct hda_codec *codec) 14081{ 14082 struct alc_spec *spec; 14083 int board_config; 14084 int i, has_beep, err; 14085 14086 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14087 if (spec == NULL) 14088 return -ENOMEM; 14089 14090 codec->spec = spec; 14091 14092 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 14093 alc268_models, 14094 alc268_cfg_tbl); 14095 14096 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 14097 board_config = snd_hda_check_board_codec_sid_config(codec, 14098 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 14099 14100 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 14101 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 14102 codec->chip_name); 14103 board_config = ALC268_AUTO; 14104 } 14105 14106 if (board_config == ALC268_AUTO) { 14107 /* automatic parse from the BIOS config */ 14108 err = alc268_parse_auto_config(codec); 14109 if (err < 0) { 14110 alc_free(codec); 14111 return err; 14112 } else if (!err) { 14113 printk(KERN_INFO 14114 "hda_codec: Cannot set up configuration " 14115 "from BIOS. Using base mode...\n"); 14116 board_config = ALC268_3ST; 14117 } 14118 } 14119 14120 if (board_config != ALC268_AUTO) 14121 setup_preset(codec, &alc268_presets[board_config]); 14122 14123 spec->stream_analog_playback = &alc268_pcm_analog_playback; 14124 spec->stream_analog_capture = &alc268_pcm_analog_capture; 14125 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture; 14126 14127 spec->stream_digital_playback = &alc268_pcm_digital_playback; 14128 14129 has_beep = 0; 14130 for (i = 0; i < spec->num_mixers; i++) { 14131 if (spec->mixers[i] == alc268_beep_mixer) { 14132 has_beep = 1; 14133 break; 14134 } 14135 } 14136 14137 if (has_beep) { 14138 err = snd_hda_attach_beep_device(codec, 0x1); 14139 if (err < 0) { 14140 alc_free(codec); 14141 return err; 14142 } 14143 if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) 14144 /* override the amp caps for beep generator */ 14145 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, 14146 (0x0c << AC_AMPCAP_OFFSET_SHIFT) | 14147 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | 14148 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | 14149 (0 << AC_AMPCAP_MUTE_SHIFT)); 14150 } 14151 14152 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 14153 /* check whether NID 0x07 is valid */ 14154 unsigned int wcap = get_wcaps(codec, 0x07); 14155 14156 spec->capsrc_nids = alc268_capsrc_nids; 14157 /* get type */ 14158 wcap = get_wcaps_type(wcap); 14159 if (spec->auto_mic || 14160 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 14161 spec->adc_nids = alc268_adc_nids_alt; 14162 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 14163 if (spec->auto_mic) 14164 fixup_automic_adc(codec); 14165 if (spec->auto_mic || spec->input_mux->num_items == 1) 14166 add_mixer(spec, alc268_capture_nosrc_mixer); 14167 else 14168 add_mixer(spec, alc268_capture_alt_mixer); 14169 } else { 14170 spec->adc_nids = alc268_adc_nids; 14171 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 14172 add_mixer(spec, alc268_capture_mixer); 14173 } 14174 } 14175 14176 spec->vmaster_nid = 0x02; 14177 14178 codec->patch_ops = alc_patch_ops; 14179 if (board_config == ALC268_AUTO) 14180 spec->init_hook = alc268_auto_init; 14181 spec->shutup = alc_eapd_shutup; 14182 14183 alc_init_jacks(codec); 14184 14185 return 0; 14186} 14187 14188/* 14189 * ALC269 channel source setting (2 channel) 14190 */ 14191#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID 14192 14193#define alc269_dac_nids alc260_dac_nids 14194 14195static const hda_nid_t alc269_adc_nids[1] = { 14196 /* ADC1 */ 14197 0x08, 14198}; 14199 14200static const hda_nid_t alc269_capsrc_nids[1] = { 14201 0x23, 14202}; 14203 14204static const hda_nid_t alc269vb_adc_nids[1] = { 14205 /* ADC1 */ 14206 0x09, 14207}; 14208 14209static const hda_nid_t alc269vb_capsrc_nids[1] = { 14210 0x22, 14211}; 14212 14213static const hda_nid_t alc269_adc_candidates[] = { 14214 0x08, 0x09, 0x07, 0x11, 14215}; 14216 14217#define alc269_modes alc260_modes 14218#define alc269_capture_source alc880_lg_lw_capture_source 14219 14220static const struct snd_kcontrol_new alc269_base_mixer[] = { 14221 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14222 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 14224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14227 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14230 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 14231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14232 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14233 { } /* end */ 14234}; 14235 14236static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 14237 /* output mixer control */ 14238 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14239 { 14240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14241 .name = "Master Playback Switch", 14242 .subdevice = HDA_SUBDEV_AMP_FLAG, 14243 .info = snd_hda_mixer_amp_switch_info, 14244 .get = snd_hda_mixer_amp_switch_get, 14245 .put = alc268_acer_master_sw_put, 14246 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14247 }, 14248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14249 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14250 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14251 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14252 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14253 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14254 { } 14255}; 14256 14257static const struct snd_kcontrol_new alc269_lifebook_mixer[] = { 14258 /* output mixer control */ 14259 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), 14260 { 14261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 14262 .name = "Master Playback Switch", 14263 .subdevice = HDA_SUBDEV_AMP_FLAG, 14264 .info = snd_hda_mixer_amp_switch_info, 14265 .get = snd_hda_mixer_amp_switch_get, 14266 .put = alc268_acer_master_sw_put, 14267 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 14268 }, 14269 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14270 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14272 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14273 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14275 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14276 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14277 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), 14278 { } 14279}; 14280 14281static const struct snd_kcontrol_new alc269_laptop_mixer[] = { 14282 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14283 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14285 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14286 { } /* end */ 14287}; 14288 14289static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = { 14290 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 14291 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 14293 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 14294 { } /* end */ 14295}; 14296 14297static const struct snd_kcontrol_new alc269_asus_mixer[] = { 14298 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 14299 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), 14300 { } /* end */ 14301}; 14302 14303/* capture mixer elements */ 14304static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14305 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14306 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14307 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14308 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14309 { } /* end */ 14310}; 14311 14312static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14313 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14314 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14315 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14316 { } /* end */ 14317}; 14318 14319static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14320 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14321 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14322 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14323 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 14324 { } /* end */ 14325}; 14326 14327static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14328 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14329 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14330 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 14331 { } /* end */ 14332}; 14333 14334/* FSC amilo */ 14335#define alc269_fujitsu_mixer alc269_laptop_mixer 14336 14337static const struct hda_verb alc269_quanta_fl1_verbs[] = { 14338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14339 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14343 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14344 { } 14345}; 14346 14347static const struct hda_verb alc269_lifebook_verbs[] = { 14348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14349 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, 14350 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14353 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14354 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14355 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 14356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14357 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14358 { } 14359}; 14360 14361/* toggle speaker-output according to the hp-jack state */ 14362static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 14363{ 14364 alc_hp_automute(codec); 14365 14366 snd_hda_codec_write(codec, 0x20, 0, 14367 AC_VERB_SET_COEF_INDEX, 0x0c); 14368 snd_hda_codec_write(codec, 0x20, 0, 14369 AC_VERB_SET_PROC_COEF, 0x680); 14370 14371 snd_hda_codec_write(codec, 0x20, 0, 14372 AC_VERB_SET_COEF_INDEX, 0x0c); 14373 snd_hda_codec_write(codec, 0x20, 0, 14374 AC_VERB_SET_PROC_COEF, 0x480); 14375} 14376 14377#define alc269_lifebook_speaker_automute \ 14378 alc269_quanta_fl1_speaker_automute 14379 14380static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 14381{ 14382 unsigned int present_laptop; 14383 unsigned int present_dock; 14384 14385 present_laptop = snd_hda_jack_detect(codec, 0x18); 14386 present_dock = snd_hda_jack_detect(codec, 0x1b); 14387 14388 /* Laptop mic port overrides dock mic port, design decision */ 14389 if (present_dock) 14390 snd_hda_codec_write(codec, 0x23, 0, 14391 AC_VERB_SET_CONNECT_SEL, 0x3); 14392 if (present_laptop) 14393 snd_hda_codec_write(codec, 0x23, 0, 14394 AC_VERB_SET_CONNECT_SEL, 0x0); 14395 if (!present_dock && !present_laptop) 14396 snd_hda_codec_write(codec, 0x23, 0, 14397 AC_VERB_SET_CONNECT_SEL, 0x1); 14398} 14399 14400static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 14401 unsigned int res) 14402{ 14403 switch (res >> 26) { 14404 case ALC880_HP_EVENT: 14405 alc269_quanta_fl1_speaker_automute(codec); 14406 break; 14407 case ALC880_MIC_EVENT: 14408 alc_mic_automute(codec); 14409 break; 14410 } 14411} 14412 14413static void alc269_lifebook_unsol_event(struct hda_codec *codec, 14414 unsigned int res) 14415{ 14416 if ((res >> 26) == ALC880_HP_EVENT) 14417 alc269_lifebook_speaker_automute(codec); 14418 if ((res >> 26) == ALC880_MIC_EVENT) 14419 alc269_lifebook_mic_autoswitch(codec); 14420} 14421 14422static void alc269_quanta_fl1_setup(struct hda_codec *codec) 14423{ 14424 struct alc_spec *spec = codec->spec; 14425 spec->autocfg.hp_pins[0] = 0x15; 14426 spec->autocfg.speaker_pins[0] = 0x14; 14427 spec->automute_mixer_nid[0] = 0x0c; 14428 spec->automute = 1; 14429 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14430 spec->ext_mic.pin = 0x18; 14431 spec->ext_mic.mux_idx = 0; 14432 spec->int_mic.pin = 0x19; 14433 spec->int_mic.mux_idx = 1; 14434 spec->auto_mic = 1; 14435} 14436 14437static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 14438{ 14439 alc269_quanta_fl1_speaker_automute(codec); 14440 alc_mic_automute(codec); 14441} 14442 14443static void alc269_lifebook_setup(struct hda_codec *codec) 14444{ 14445 struct alc_spec *spec = codec->spec; 14446 spec->autocfg.hp_pins[0] = 0x15; 14447 spec->autocfg.hp_pins[1] = 0x1a; 14448 spec->autocfg.speaker_pins[0] = 0x14; 14449 spec->automute_mixer_nid[0] = 0x0c; 14450 spec->automute = 1; 14451 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14452} 14453 14454static void alc269_lifebook_init_hook(struct hda_codec *codec) 14455{ 14456 alc269_lifebook_speaker_automute(codec); 14457 alc269_lifebook_mic_autoswitch(codec); 14458} 14459 14460static const struct hda_verb alc269_laptop_dmic_init_verbs[] = { 14461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14462 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 14463 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14465 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14467 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14468 {} 14469}; 14470 14471static const struct hda_verb alc269_laptop_amic_init_verbs[] = { 14472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 14473 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 14474 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14475 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, 14476 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14477 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14478 {} 14479}; 14480 14481static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { 14482 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14483 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, 14484 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14486 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14487 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14488 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14489 {} 14490}; 14491 14492static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = { 14493 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, 14494 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, 14495 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 14496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, 14497 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14498 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14499 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14500 {} 14501}; 14502 14503static const struct hda_verb alc271_acer_dmic_verbs[] = { 14504 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14505 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14508 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14509 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14510 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, 14511 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 14512 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 14513 {0x22, AC_VERB_SET_CONNECT_SEL, 6}, 14514 { } 14515}; 14516 14517static void alc269_laptop_amic_setup(struct hda_codec *codec) 14518{ 14519 struct alc_spec *spec = codec->spec; 14520 spec->autocfg.hp_pins[0] = 0x15; 14521 spec->autocfg.speaker_pins[0] = 0x14; 14522 spec->automute_mixer_nid[0] = 0x0c; 14523 spec->automute = 1; 14524 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14525 spec->ext_mic.pin = 0x18; 14526 spec->ext_mic.mux_idx = 0; 14527 spec->int_mic.pin = 0x19; 14528 spec->int_mic.mux_idx = 1; 14529 spec->auto_mic = 1; 14530} 14531 14532static void alc269_laptop_dmic_setup(struct hda_codec *codec) 14533{ 14534 struct alc_spec *spec = codec->spec; 14535 spec->autocfg.hp_pins[0] = 0x15; 14536 spec->autocfg.speaker_pins[0] = 0x14; 14537 spec->automute_mixer_nid[0] = 0x0c; 14538 spec->automute = 1; 14539 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14540 spec->ext_mic.pin = 0x18; 14541 spec->ext_mic.mux_idx = 0; 14542 spec->int_mic.pin = 0x12; 14543 spec->int_mic.mux_idx = 5; 14544 spec->auto_mic = 1; 14545} 14546 14547static void alc269vb_laptop_amic_setup(struct hda_codec *codec) 14548{ 14549 struct alc_spec *spec = codec->spec; 14550 spec->autocfg.hp_pins[0] = 0x21; 14551 spec->autocfg.speaker_pins[0] = 0x14; 14552 spec->automute_mixer_nid[0] = 0x0c; 14553 spec->automute = 1; 14554 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14555 spec->ext_mic.pin = 0x18; 14556 spec->ext_mic.mux_idx = 0; 14557 spec->int_mic.pin = 0x19; 14558 spec->int_mic.mux_idx = 1; 14559 spec->auto_mic = 1; 14560} 14561 14562static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 14563{ 14564 struct alc_spec *spec = codec->spec; 14565 spec->autocfg.hp_pins[0] = 0x21; 14566 spec->autocfg.speaker_pins[0] = 0x14; 14567 spec->automute_mixer_nid[0] = 0x0c; 14568 spec->automute = 1; 14569 spec->automute_mode = ALC_AUTOMUTE_MIXER; 14570 spec->ext_mic.pin = 0x18; 14571 spec->ext_mic.mux_idx = 0; 14572 spec->int_mic.pin = 0x12; 14573 spec->int_mic.mux_idx = 6; 14574 spec->auto_mic = 1; 14575} 14576 14577/* 14578 * generic initialization of ADC, input mixers and output mixers 14579 */ 14580static const struct hda_verb alc269_init_verbs[] = { 14581 /* 14582 * Unmute ADC0 and set the default input to mic-in 14583 */ 14584 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14585 14586 /* 14587 * Set up output mixers (0x02 - 0x03) 14588 */ 14589 /* set vol=0 to output mixers */ 14590 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14591 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14592 14593 /* set up input amps for analog loopback */ 14594 /* Amp Indices: DAC = 0, mixer = 1 */ 14595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14601 14602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14604 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14606 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14607 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14608 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14609 14610 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14612 14613 /* FIXME: use Mux-type input source selection */ 14614 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14615 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14616 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, 14617 14618 /* set EAPD */ 14619 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14620 { } 14621}; 14622 14623static const struct hda_verb alc269vb_init_verbs[] = { 14624 /* 14625 * Unmute ADC0 and set the default input to mic-in 14626 */ 14627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14628 14629 /* 14630 * Set up output mixers (0x02 - 0x03) 14631 */ 14632 /* set vol=0 to output mixers */ 14633 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14634 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 14635 14636 /* set up input amps for analog loopback */ 14637 /* Amp Indices: DAC = 0, mixer = 1 */ 14638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14643 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14644 14645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14646 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 14647 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 14648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14649 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 14650 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14651 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 14652 14653 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14654 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 14655 14656 /* FIXME: use Mux-type input source selection */ 14657 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 14658 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 14659 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, 14660 14661 /* set EAPD */ 14662 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 14663 { } 14664}; 14665 14666#define alc269_auto_create_multi_out_ctls \ 14667 alc268_auto_create_multi_out_ctls 14668#define alc269_auto_create_input_ctls \ 14669 alc268_auto_create_input_ctls 14670 14671#ifdef CONFIG_SND_HDA_POWER_SAVE 14672#define alc269_loopbacks alc880_loopbacks 14673#endif 14674 14675/* pcm configuration: identical with ALC880 */ 14676#define alc269_pcm_analog_playback alc880_pcm_analog_playback 14677#define alc269_pcm_analog_capture alc880_pcm_analog_capture 14678#define alc269_pcm_digital_playback alc880_pcm_digital_playback 14679#define alc269_pcm_digital_capture alc880_pcm_digital_capture 14680 14681static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 14682 .substreams = 1, 14683 .channels_min = 2, 14684 .channels_max = 8, 14685 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14686 /* NID is set in alc_build_pcms */ 14687 .ops = { 14688 .open = alc880_playback_pcm_open, 14689 .prepare = alc880_playback_pcm_prepare, 14690 .cleanup = alc880_playback_pcm_cleanup 14691 }, 14692}; 14693 14694static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { 14695 .substreams = 1, 14696 .channels_min = 2, 14697 .channels_max = 2, 14698 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 14699 /* NID is set in alc_build_pcms */ 14700}; 14701 14702#ifdef CONFIG_SND_HDA_POWER_SAVE 14703static int alc269_mic2_for_mute_led(struct hda_codec *codec) 14704{ 14705 switch (codec->subsystem_id) { 14706 case 0x103c1586: 14707 return 1; 14708 } 14709 return 0; 14710} 14711 14712static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) 14713{ 14714 /* update mute-LED according to the speaker mute state */ 14715 if (nid == 0x01 || nid == 0x14) { 14716 int pinval; 14717 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & 14718 HDA_AMP_MUTE) 14719 pinval = 0x24; 14720 else 14721 pinval = 0x20; 14722 /* mic2 vref pin is used for mute LED control */ 14723 snd_hda_codec_update_cache(codec, 0x19, 0, 14724 AC_VERB_SET_PIN_WIDGET_CONTROL, 14725 pinval); 14726 } 14727 return alc_check_power_status(codec, nid); 14728} 14729#endif /* CONFIG_SND_HDA_POWER_SAVE */ 14730 14731static int alc275_setup_dual_adc(struct hda_codec *codec) 14732{ 14733 struct alc_spec *spec = codec->spec; 14734 14735 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic) 14736 return 0; 14737 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) || 14738 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) { 14739 if (spec->ext_mic.pin <= 0x12) { 14740 spec->private_adc_nids[0] = 0x08; 14741 spec->private_adc_nids[1] = 0x11; 14742 spec->private_capsrc_nids[0] = 0x23; 14743 spec->private_capsrc_nids[1] = 0x22; 14744 } else { 14745 spec->private_adc_nids[0] = 0x11; 14746 spec->private_adc_nids[1] = 0x08; 14747 spec->private_capsrc_nids[0] = 0x22; 14748 spec->private_capsrc_nids[1] = 0x23; 14749 } 14750 spec->adc_nids = spec->private_adc_nids; 14751 spec->capsrc_nids = spec->private_capsrc_nids; 14752 spec->num_adc_nids = 2; 14753 spec->dual_adc_switch = 1; 14754 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n", 14755 spec->adc_nids[0], spec->adc_nids[1]); 14756 return 1; 14757 } 14758 return 0; 14759} 14760 14761/* different alc269-variants */ 14762enum { 14763 ALC269_TYPE_NORMAL, 14764 ALC269_TYPE_ALC258, 14765 ALC269_TYPE_ALC259, 14766 ALC269_TYPE_ALC269VB, 14767 ALC269_TYPE_ALC270, 14768 ALC269_TYPE_ALC271X, 14769}; 14770 14771/* 14772 * BIOS auto configuration 14773 */ 14774static int alc269_parse_auto_config(struct hda_codec *codec) 14775{ 14776 struct alc_spec *spec = codec->spec; 14777 int err; 14778 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 14779 14780 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 14781 alc269_ignore); 14782 if (err < 0) 14783 return err; 14784 14785 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 14786 if (err < 0) 14787 return err; 14788 if (spec->codec_variant == ALC269_TYPE_NORMAL) 14789 err = alc269_auto_create_input_ctls(codec, &spec->autocfg); 14790 else 14791 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0, 14792 0x22, 0); 14793 if (err < 0) 14794 return err; 14795 14796 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 14797 14798 alc_auto_parse_digital(codec); 14799 14800 if (spec->kctls.list) 14801 add_mixer(spec, spec->kctls.list); 14802 14803 if (spec->codec_variant != ALC269_TYPE_NORMAL) { 14804 add_verb(spec, alc269vb_init_verbs); 14805 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); 14806 } else { 14807 add_verb(spec, alc269_init_verbs); 14808 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 14809 } 14810 14811 spec->num_mux_defs = 1; 14812 spec->input_mux = &spec->private_imux[0]; 14813 14814 if (!alc275_setup_dual_adc(codec)) 14815 fillup_priv_adc_nids(codec, alc269_adc_candidates, 14816 sizeof(alc269_adc_candidates)); 14817 14818 err = alc_auto_add_mic_boost(codec); 14819 if (err < 0) 14820 return err; 14821 14822 if (!spec->cap_mixer && !spec->no_analog) 14823 set_capture_mixer(codec); 14824 14825 return 1; 14826} 14827 14828#define alc269_auto_init_multi_out alc268_auto_init_multi_out 14829#define alc269_auto_init_hp_out alc268_auto_init_hp_out 14830#define alc269_auto_init_analog_input alc882_auto_init_analog_input 14831#define alc269_auto_init_input_src alc882_auto_init_input_src 14832 14833 14834/* init callback for auto-configuration model -- overriding the default init */ 14835static void alc269_auto_init(struct hda_codec *codec) 14836{ 14837 struct alc_spec *spec = codec->spec; 14838 alc269_auto_init_multi_out(codec); 14839 alc269_auto_init_hp_out(codec); 14840 alc269_auto_init_analog_input(codec); 14841 if (!spec->dual_adc_switch) 14842 alc269_auto_init_input_src(codec); 14843 alc_auto_init_digital(codec); 14844 if (spec->unsol_event) 14845 alc_inithook(codec); 14846} 14847 14848static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 14849{ 14850 int val = alc_read_coef_idx(codec, 0x04); 14851 if (power_up) 14852 val |= 1 << 11; 14853 else 14854 val &= ~(1 << 11); 14855 alc_write_coef_idx(codec, 0x04, val); 14856} 14857 14858static void alc269_shutup(struct hda_codec *codec) 14859{ 14860 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) 14861 alc269_toggle_power_output(codec, 0); 14862 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14863 alc269_toggle_power_output(codec, 0); 14864 msleep(150); 14865 } 14866} 14867 14868#ifdef SND_HDA_NEEDS_RESUME 14869static int alc269_resume(struct hda_codec *codec) 14870{ 14871 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 14872 alc269_toggle_power_output(codec, 0); 14873 msleep(150); 14874 } 14875 14876 codec->patch_ops.init(codec); 14877 14878 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 14879 alc269_toggle_power_output(codec, 1); 14880 msleep(200); 14881 } 14882 14883 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) 14884 alc269_toggle_power_output(codec, 1); 14885 14886 snd_hda_codec_resume_amp(codec); 14887 snd_hda_codec_resume_cache(codec); 14888 hda_call_check_power_status(codec, 0x01); 14889 return 0; 14890} 14891#endif /* SND_HDA_NEEDS_RESUME */ 14892 14893static void alc269_fixup_hweq(struct hda_codec *codec, 14894 const struct alc_fixup *fix, int action) 14895{ 14896 int coef; 14897 14898 if (action != ALC_FIXUP_ACT_INIT) 14899 return; 14900 coef = alc_read_coef_idx(codec, 0x1e); 14901 alc_write_coef_idx(codec, 0x1e, coef | 0x80); 14902} 14903 14904static void alc271_fixup_dmic(struct hda_codec *codec, 14905 const struct alc_fixup *fix, int action) 14906{ 14907 static const struct hda_verb verbs[] = { 14908 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, 14909 {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, 14910 {} 14911 }; 14912 unsigned int cfg; 14913 14914 if (strcmp(codec->chip_name, "ALC271X")) 14915 return; 14916 cfg = snd_hda_codec_get_pincfg(codec, 0x12); 14917 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) 14918 snd_hda_sequence_write(codec, verbs); 14919} 14920 14921enum { 14922 ALC269_FIXUP_SONY_VAIO, 14923 ALC275_FIXUP_SONY_VAIO_GPIO2, 14924 ALC269_FIXUP_DELL_M101Z, 14925 ALC269_FIXUP_SKU_IGNORE, 14926 ALC269_FIXUP_ASUS_G73JW, 14927 ALC269_FIXUP_LENOVO_EAPD, 14928 ALC275_FIXUP_SONY_HWEQ, 14929 ALC271_FIXUP_DMIC, 14930}; 14931 14932static const struct alc_fixup alc269_fixups[] = { 14933 [ALC269_FIXUP_SONY_VAIO] = { 14934 .type = ALC_FIXUP_VERBS, 14935 .v.verbs = (const struct hda_verb[]) { 14936 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14937 {} 14938 } 14939 }, 14940 [ALC275_FIXUP_SONY_VAIO_GPIO2] = { 14941 .type = ALC_FIXUP_VERBS, 14942 .v.verbs = (const struct hda_verb[]) { 14943 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 14944 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 14945 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 14946 { } 14947 }, 14948 .chained = true, 14949 .chain_id = ALC269_FIXUP_SONY_VAIO 14950 }, 14951 [ALC269_FIXUP_DELL_M101Z] = { 14952 .type = ALC_FIXUP_VERBS, 14953 .v.verbs = (const struct hda_verb[]) { 14954 /* Enables internal speaker */ 14955 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14956 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14957 {} 14958 } 14959 }, 14960 [ALC269_FIXUP_SKU_IGNORE] = { 14961 .type = ALC_FIXUP_SKU, 14962 .v.sku = ALC_FIXUP_SKU_IGNORE, 14963 }, 14964 [ALC269_FIXUP_ASUS_G73JW] = { 14965 .type = ALC_FIXUP_PINS, 14966 .v.pins = (const struct alc_pincfg[]) { 14967 { 0x17, 0x99130111 }, /* subwoofer */ 14968 { } 14969 } 14970 }, 14971 [ALC269_FIXUP_LENOVO_EAPD] = { 14972 .type = ALC_FIXUP_VERBS, 14973 .v.verbs = (const struct hda_verb[]) { 14974 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 14975 {} 14976 } 14977 }, 14978 [ALC275_FIXUP_SONY_HWEQ] = { 14979 .type = ALC_FIXUP_FUNC, 14980 .v.func = alc269_fixup_hweq, 14981 .chained = true, 14982 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 14983 }, 14984 [ALC271_FIXUP_DMIC] = { 14985 .type = ALC_FIXUP_FUNC, 14986 .v.func = alc271_fixup_dmic, 14987 }, 14988}; 14989 14990static const struct snd_pci_quirk alc269_fixup_tbl[] = { 14991 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 14992 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14993 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 14994 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14995 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14996 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 14997 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 14998 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 14999 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 15000 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 15001 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 15002 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 15003 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 15004 {} 15005}; 15006 15007 15008/* 15009 * configuration and preset 15010 */ 15011static const char * const alc269_models[ALC269_MODEL_LAST] = { 15012 [ALC269_BASIC] = "basic", 15013 [ALC269_QUANTA_FL1] = "quanta", 15014 [ALC269_AMIC] = "laptop-amic", 15015 [ALC269_DMIC] = "laptop-dmic", 15016 [ALC269_FUJITSU] = "fujitsu", 15017 [ALC269_LIFEBOOK] = "lifebook", 15018 [ALC269_AUTO] = "auto", 15019}; 15020 15021static const struct snd_pci_quirk alc269_cfg_tbl[] = { 15022 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 15023 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), 15024 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 15025 ALC269_AMIC), 15026 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), 15027 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), 15028 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), 15029 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), 15030 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), 15031 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), 15032 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), 15033 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), 15034 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), 15035 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), 15036 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), 15037 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), 15038 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), 15039 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), 15040 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), 15041 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), 15042 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), 15043 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), 15044 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), 15045 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), 15046 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), 15047 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), 15048 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), 15049 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), 15050 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), 15051 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), 15052 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), 15053 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), 15054 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), 15055 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), 15056 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), 15057 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), 15058 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), 15059 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), 15060 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), 15061 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), 15062 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 15063 ALC269_DMIC), 15064 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 15065 ALC269_DMIC), 15066 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), 15067 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), 15068 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), 15069 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 15070 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), 15071 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 15072 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), 15073 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), 15074 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), 15075 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), 15076 {} 15077}; 15078 15079static const struct alc_config_preset alc269_presets[] = { 15080 [ALC269_BASIC] = { 15081 .mixers = { alc269_base_mixer }, 15082 .init_verbs = { alc269_init_verbs }, 15083 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15084 .dac_nids = alc269_dac_nids, 15085 .hp_nid = 0x03, 15086 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15087 .channel_mode = alc269_modes, 15088 .input_mux = &alc269_capture_source, 15089 }, 15090 [ALC269_QUANTA_FL1] = { 15091 .mixers = { alc269_quanta_fl1_mixer }, 15092 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, 15093 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15094 .dac_nids = alc269_dac_nids, 15095 .hp_nid = 0x03, 15096 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15097 .channel_mode = alc269_modes, 15098 .input_mux = &alc269_capture_source, 15099 .unsol_event = alc269_quanta_fl1_unsol_event, 15100 .setup = alc269_quanta_fl1_setup, 15101 .init_hook = alc269_quanta_fl1_init_hook, 15102 }, 15103 [ALC269_AMIC] = { 15104 .mixers = { alc269_laptop_mixer }, 15105 .cap_mixer = alc269_laptop_analog_capture_mixer, 15106 .init_verbs = { alc269_init_verbs, 15107 alc269_laptop_amic_init_verbs }, 15108 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15109 .dac_nids = alc269_dac_nids, 15110 .hp_nid = 0x03, 15111 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15112 .channel_mode = alc269_modes, 15113 .unsol_event = alc_sku_unsol_event, 15114 .setup = alc269_laptop_amic_setup, 15115 .init_hook = alc_inithook, 15116 }, 15117 [ALC269_DMIC] = { 15118 .mixers = { alc269_laptop_mixer }, 15119 .cap_mixer = alc269_laptop_digital_capture_mixer, 15120 .init_verbs = { alc269_init_verbs, 15121 alc269_laptop_dmic_init_verbs }, 15122 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15123 .dac_nids = alc269_dac_nids, 15124 .hp_nid = 0x03, 15125 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15126 .channel_mode = alc269_modes, 15127 .unsol_event = alc_sku_unsol_event, 15128 .setup = alc269_laptop_dmic_setup, 15129 .init_hook = alc_inithook, 15130 }, 15131 [ALC269VB_AMIC] = { 15132 .mixers = { alc269vb_laptop_mixer }, 15133 .cap_mixer = alc269vb_laptop_analog_capture_mixer, 15134 .init_verbs = { alc269vb_init_verbs, 15135 alc269vb_laptop_amic_init_verbs }, 15136 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15137 .dac_nids = alc269_dac_nids, 15138 .hp_nid = 0x03, 15139 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15140 .channel_mode = alc269_modes, 15141 .unsol_event = alc_sku_unsol_event, 15142 .setup = alc269vb_laptop_amic_setup, 15143 .init_hook = alc_inithook, 15144 }, 15145 [ALC269VB_DMIC] = { 15146 .mixers = { alc269vb_laptop_mixer }, 15147 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15148 .init_verbs = { alc269vb_init_verbs, 15149 alc269vb_laptop_dmic_init_verbs }, 15150 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15151 .dac_nids = alc269_dac_nids, 15152 .hp_nid = 0x03, 15153 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15154 .channel_mode = alc269_modes, 15155 .unsol_event = alc_sku_unsol_event, 15156 .setup = alc269vb_laptop_dmic_setup, 15157 .init_hook = alc_inithook, 15158 }, 15159 [ALC269_FUJITSU] = { 15160 .mixers = { alc269_fujitsu_mixer }, 15161 .cap_mixer = alc269_laptop_digital_capture_mixer, 15162 .init_verbs = { alc269_init_verbs, 15163 alc269_laptop_dmic_init_verbs }, 15164 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15165 .dac_nids = alc269_dac_nids, 15166 .hp_nid = 0x03, 15167 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15168 .channel_mode = alc269_modes, 15169 .unsol_event = alc_sku_unsol_event, 15170 .setup = alc269_laptop_dmic_setup, 15171 .init_hook = alc_inithook, 15172 }, 15173 [ALC269_LIFEBOOK] = { 15174 .mixers = { alc269_lifebook_mixer }, 15175 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, 15176 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15177 .dac_nids = alc269_dac_nids, 15178 .hp_nid = 0x03, 15179 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15180 .channel_mode = alc269_modes, 15181 .input_mux = &alc269_capture_source, 15182 .unsol_event = alc269_lifebook_unsol_event, 15183 .setup = alc269_lifebook_setup, 15184 .init_hook = alc269_lifebook_init_hook, 15185 }, 15186 [ALC271_ACER] = { 15187 .mixers = { alc269_asus_mixer }, 15188 .cap_mixer = alc269vb_laptop_digital_capture_mixer, 15189 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, 15190 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 15191 .dac_nids = alc269_dac_nids, 15192 .adc_nids = alc262_dmic_adc_nids, 15193 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), 15194 .capsrc_nids = alc262_dmic_capsrc_nids, 15195 .num_channel_mode = ARRAY_SIZE(alc269_modes), 15196 .channel_mode = alc269_modes, 15197 .input_mux = &alc269_capture_source, 15198 .dig_out_nid = ALC880_DIGOUT_NID, 15199 .unsol_event = alc_sku_unsol_event, 15200 .setup = alc269vb_laptop_dmic_setup, 15201 .init_hook = alc_inithook, 15202 }, 15203}; 15204 15205static int alc269_fill_coef(struct hda_codec *codec) 15206{ 15207 int val; 15208 15209 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { 15210 alc_write_coef_idx(codec, 0xf, 0x960b); 15211 alc_write_coef_idx(codec, 0xe, 0x8817); 15212 } 15213 15214 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { 15215 alc_write_coef_idx(codec, 0xf, 0x960b); 15216 alc_write_coef_idx(codec, 0xe, 0x8814); 15217 } 15218 15219 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { 15220 val = alc_read_coef_idx(codec, 0x04); 15221 /* Power up output pin */ 15222 alc_write_coef_idx(codec, 0x04, val | (1<<11)); 15223 } 15224 15225 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 15226 val = alc_read_coef_idx(codec, 0xd); 15227 if ((val & 0x0c00) >> 10 != 0x1) { 15228 /* Capless ramp up clock control */ 15229 alc_write_coef_idx(codec, 0xd, val | (1<<10)); 15230 } 15231 val = alc_read_coef_idx(codec, 0x17); 15232 if ((val & 0x01c0) >> 6 != 0x4) { 15233 /* Class D power on reset */ 15234 alc_write_coef_idx(codec, 0x17, val | (1<<7)); 15235 } 15236 } 15237 15238 val = alc_read_coef_idx(codec, 0xd); /* Class D */ 15239 alc_write_coef_idx(codec, 0xd, val | (1<<14)); 15240 15241 val = alc_read_coef_idx(codec, 0x4); /* HP */ 15242 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 15243 15244 return 0; 15245} 15246 15247static int patch_alc269(struct hda_codec *codec) 15248{ 15249 struct alc_spec *spec; 15250 int board_config, coef; 15251 int err; 15252 15253 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 15254 if (spec == NULL) 15255 return -ENOMEM; 15256 15257 codec->spec = spec; 15258 15259 alc_auto_parse_customize_define(codec); 15260 15261 if (codec->vendor_id == 0x10ec0269) { 15262 coef = alc_read_coef_idx(codec, 0); 15263 if ((coef & 0x00f0) == 0x0010) { 15264 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15265 spec->cdefine.platform_type == 1) { 15266 alc_codec_rename(codec, "ALC271X"); 15267 spec->codec_variant = ALC269_TYPE_ALC271X; 15268 } else if ((coef & 0xf000) == 0x1000) { 15269 spec->codec_variant = ALC269_TYPE_ALC270; 15270 } else if ((coef & 0xf000) == 0x2000) { 15271 alc_codec_rename(codec, "ALC259"); 15272 spec->codec_variant = ALC269_TYPE_ALC259; 15273 } else if ((coef & 0xf000) == 0x3000) { 15274 alc_codec_rename(codec, "ALC258"); 15275 spec->codec_variant = ALC269_TYPE_ALC258; 15276 } else { 15277 alc_codec_rename(codec, "ALC269VB"); 15278 spec->codec_variant = ALC269_TYPE_ALC269VB; 15279 } 15280 } else 15281 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15282 alc269_fill_coef(codec); 15283 } 15284 15285 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15286 alc269_models, 15287 alc269_cfg_tbl); 15288 15289 if (board_config < 0) { 15290 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 15291 codec->chip_name); 15292 board_config = ALC269_AUTO; 15293 } 15294 15295 if (board_config == ALC269_AUTO) { 15296 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 15297 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 15298 } 15299 15300 if (board_config == ALC269_AUTO) { 15301 /* automatic parse from the BIOS config */ 15302 err = alc269_parse_auto_config(codec); 15303 if (err < 0) { 15304 alc_free(codec); 15305 return err; 15306 } else if (!err) { 15307 printk(KERN_INFO 15308 "hda_codec: Cannot set up configuration " 15309 "from BIOS. Using base mode...\n"); 15310 board_config = ALC269_BASIC; 15311 } 15312 } 15313 15314 if (has_cdefine_beep(codec)) { 15315 err = snd_hda_attach_beep_device(codec, 0x1); 15316 if (err < 0) { 15317 alc_free(codec); 15318 return err; 15319 } 15320 } 15321 15322 if (board_config != ALC269_AUTO) 15323 setup_preset(codec, &alc269_presets[board_config]); 15324 15325 if (board_config == ALC269_QUANTA_FL1) { 15326 /* Due to a hardware problem on Lenovo Ideadpad, we need to 15327 * fix the sample rate of analog I/O to 44.1kHz 15328 */ 15329 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 15330 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 15331 } else if (spec->dual_adc_switch) { 15332 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15333 /* switch ADC dynamically */ 15334 spec->stream_analog_capture = &dualmic_pcm_analog_capture; 15335 } else { 15336 spec->stream_analog_playback = &alc269_pcm_analog_playback; 15337 spec->stream_analog_capture = &alc269_pcm_analog_capture; 15338 } 15339 spec->stream_digital_playback = &alc269_pcm_digital_playback; 15340 spec->stream_digital_capture = &alc269_pcm_digital_capture; 15341 15342 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 15343 if (spec->codec_variant == ALC269_TYPE_NORMAL) { 15344 spec->adc_nids = alc269_adc_nids; 15345 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 15346 spec->capsrc_nids = alc269_capsrc_nids; 15347 } else { 15348 spec->adc_nids = alc269vb_adc_nids; 15349 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); 15350 spec->capsrc_nids = alc269vb_capsrc_nids; 15351 } 15352 } 15353 15354 if (!spec->cap_mixer) 15355 set_capture_mixer(codec); 15356 if (has_cdefine_beep(codec)) 15357 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15358 15359 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 15360 15361 spec->vmaster_nid = 0x02; 15362 15363 codec->patch_ops = alc_patch_ops; 15364#ifdef SND_HDA_NEEDS_RESUME 15365 codec->patch_ops.resume = alc269_resume; 15366#endif 15367 if (board_config == ALC269_AUTO) 15368 spec->init_hook = alc269_auto_init; 15369 spec->shutup = alc269_shutup; 15370 15371 alc_init_jacks(codec); 15372#ifdef CONFIG_SND_HDA_POWER_SAVE 15373 if (!spec->loopback.amplist) 15374 spec->loopback.amplist = alc269_loopbacks; 15375 if (alc269_mic2_for_mute_led(codec)) 15376 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; 15377#endif 15378 15379 return 0; 15380} 15381 15382/* 15383 * ALC861 channel source setting (2/6 channel selection for 3-stack) 15384 */ 15385 15386/* 15387 * set the path ways for 2 channel output 15388 * need to set the codec line out and mic 1 pin widgets to inputs 15389 */ 15390static const struct hda_verb alc861_threestack_ch2_init[] = { 15391 /* set pin widget 1Ah (line in) for input */ 15392 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15393 /* set pin widget 18h (mic1/2) for input, for mic also enable 15394 * the vref 15395 */ 15396 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15397 15398 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15399#if 0 15400 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15401 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15402#endif 15403 { } /* end */ 15404}; 15405/* 15406 * 6ch mode 15407 * need to set the codec line out and mic 1 pin widgets to outputs 15408 */ 15409static const struct hda_verb alc861_threestack_ch6_init[] = { 15410 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15411 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15412 /* set pin widget 18h (mic1) for output (CLFE)*/ 15413 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15414 15415 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15416 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15417 15418 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15419#if 0 15420 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15421 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15422#endif 15423 { } /* end */ 15424}; 15425 15426static const struct hda_channel_mode alc861_threestack_modes[2] = { 15427 { 2, alc861_threestack_ch2_init }, 15428 { 6, alc861_threestack_ch6_init }, 15429}; 15430/* Set mic1 as input and unmute the mixer */ 15431static const struct hda_verb alc861_uniwill_m31_ch2_init[] = { 15432 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15433 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15434 { } /* end */ 15435}; 15436/* Set mic1 as output and mute mixer */ 15437static const struct hda_verb alc861_uniwill_m31_ch4_init[] = { 15438 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15439 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15440 { } /* end */ 15441}; 15442 15443static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = { 15444 { 2, alc861_uniwill_m31_ch2_init }, 15445 { 4, alc861_uniwill_m31_ch4_init }, 15446}; 15447 15448/* Set mic1 and line-in as input and unmute the mixer */ 15449static const struct hda_verb alc861_asus_ch2_init[] = { 15450 /* set pin widget 1Ah (line in) for input */ 15451 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15452 /* set pin widget 18h (mic1/2) for input, for mic also enable 15453 * the vref 15454 */ 15455 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15456 15457 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, 15458#if 0 15459 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ 15460 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ 15461#endif 15462 { } /* end */ 15463}; 15464/* Set mic1 nad line-in as output and mute mixer */ 15465static const struct hda_verb alc861_asus_ch6_init[] = { 15466 /* set pin widget 1Ah (line in) for output (Back Surround)*/ 15467 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15468 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15469 /* set pin widget 18h (mic1) for output (CLFE)*/ 15470 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15471 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ 15472 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15473 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15474 15475 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 15476#if 0 15477 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ 15478 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ 15479#endif 15480 { } /* end */ 15481}; 15482 15483static const struct hda_channel_mode alc861_asus_modes[2] = { 15484 { 2, alc861_asus_ch2_init }, 15485 { 6, alc861_asus_ch6_init }, 15486}; 15487 15488/* patch-ALC861 */ 15489 15490static const struct snd_kcontrol_new alc861_base_mixer[] = { 15491 /* output mixer control */ 15492 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15493 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15494 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15495 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15496 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15497 15498 /*Input mixer control */ 15499 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15500 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15501 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15502 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15503 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15504 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15506 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15507 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15509 15510 { } /* end */ 15511}; 15512 15513static const struct snd_kcontrol_new alc861_3ST_mixer[] = { 15514 /* output mixer control */ 15515 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15516 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15517 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15518 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15519 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15520 15521 /* Input mixer control */ 15522 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15523 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15524 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15525 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15526 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15527 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15529 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15530 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15531 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15532 15533 { 15534 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15535 .name = "Channel Mode", 15536 .info = alc_ch_mode_info, 15537 .get = alc_ch_mode_get, 15538 .put = alc_ch_mode_put, 15539 .private_value = ARRAY_SIZE(alc861_threestack_modes), 15540 }, 15541 { } /* end */ 15542}; 15543 15544static const struct snd_kcontrol_new alc861_toshiba_mixer[] = { 15545 /* output mixer control */ 15546 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15548 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15549 15550 { } /* end */ 15551}; 15552 15553static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 15554 /* output mixer control */ 15555 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15556 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15557 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15558 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15559 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ 15560 15561 /* Input mixer control */ 15562 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15563 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ 15564 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15565 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15566 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15567 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15568 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15569 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15570 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 15572 15573 { 15574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15575 .name = "Channel Mode", 15576 .info = alc_ch_mode_info, 15577 .get = alc_ch_mode_get, 15578 .put = alc_ch_mode_put, 15579 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), 15580 }, 15581 { } /* end */ 15582}; 15583 15584static const struct snd_kcontrol_new alc861_asus_mixer[] = { 15585 /* output mixer control */ 15586 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 15587 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), 15588 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), 15589 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), 15590 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), 15591 15592 /* Input mixer control */ 15593 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), 15594 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), 15595 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15596 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15597 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), 15598 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), 15599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 15600 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 15601 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 15602 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 15603 15604 { 15605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 15606 .name = "Channel Mode", 15607 .info = alc_ch_mode_info, 15608 .get = alc_ch_mode_get, 15609 .put = alc_ch_mode_put, 15610 .private_value = ARRAY_SIZE(alc861_asus_modes), 15611 }, 15612 { } 15613}; 15614 15615/* additional mixer */ 15616static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { 15617 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), 15618 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), 15619 { } 15620}; 15621 15622/* 15623 * generic initialization of ADC, input mixers and output mixers 15624 */ 15625static const struct hda_verb alc861_base_init_verbs[] = { 15626 /* 15627 * Unmute ADC0 and set the default input to mic-in 15628 */ 15629 /* port-A for surround (rear panel) */ 15630 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15631 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15632 /* port-B for mic-in (rear panel) with vref */ 15633 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15634 /* port-C for line-in (rear panel) */ 15635 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15636 /* port-D for Front */ 15637 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15638 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15639 /* port-E for HP out (front panel) */ 15640 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15641 /* route front PCM to HP */ 15642 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15643 /* port-F for mic-in (front panel) with vref */ 15644 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15645 /* port-G for CLFE (rear panel) */ 15646 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15647 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15648 /* port-H for side (rear panel) */ 15649 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15650 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15651 /* CD-in */ 15652 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15653 /* route front mic to ADC1*/ 15654 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15656 15657 /* Unmute DAC0~3 & spdif out*/ 15658 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15659 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15660 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15661 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15663 15664 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15665 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15666 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15667 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15668 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15669 15670 /* Unmute Stereo Mixer 15 */ 15671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15674 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15675 15676 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15679 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15681 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15682 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15684 /* hp used DAC 3 (Front) */ 15685 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15687 15688 { } 15689}; 15690 15691static const struct hda_verb alc861_threestack_init_verbs[] = { 15692 /* 15693 * Unmute ADC0 and set the default input to mic-in 15694 */ 15695 /* port-A for surround (rear panel) */ 15696 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15697 /* port-B for mic-in (rear panel) with vref */ 15698 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15699 /* port-C for line-in (rear panel) */ 15700 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15701 /* port-D for Front */ 15702 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15703 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15704 /* port-E for HP out (front panel) */ 15705 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 15706 /* route front PCM to HP */ 15707 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15708 /* port-F for mic-in (front panel) with vref */ 15709 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15710 /* port-G for CLFE (rear panel) */ 15711 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15712 /* port-H for side (rear panel) */ 15713 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15714 /* CD-in */ 15715 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15716 /* route front mic to ADC1*/ 15717 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15719 /* Unmute DAC0~3 & spdif out*/ 15720 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15721 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15722 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15723 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15724 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15725 15726 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15727 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15728 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15729 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15730 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15731 15732 /* Unmute Stereo Mixer 15 */ 15733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15737 15738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15740 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15741 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15744 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15746 /* hp used DAC 3 (Front) */ 15747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15748 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15749 { } 15750}; 15751 15752static const struct hda_verb alc861_uniwill_m31_init_verbs[] = { 15753 /* 15754 * Unmute ADC0 and set the default input to mic-in 15755 */ 15756 /* port-A for surround (rear panel) */ 15757 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15758 /* port-B for mic-in (rear panel) with vref */ 15759 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15760 /* port-C for line-in (rear panel) */ 15761 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15762 /* port-D for Front */ 15763 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15764 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15765 /* port-E for HP out (front panel) */ 15766 /* this has to be set to VREF80 */ 15767 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15768 /* route front PCM to HP */ 15769 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15770 /* port-F for mic-in (front panel) with vref */ 15771 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15772 /* port-G for CLFE (rear panel) */ 15773 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15774 /* port-H for side (rear panel) */ 15775 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 15776 /* CD-in */ 15777 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15778 /* route front mic to ADC1*/ 15779 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15781 /* Unmute DAC0~3 & spdif out*/ 15782 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15783 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15784 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15785 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15787 15788 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15789 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15790 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15791 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15792 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15793 15794 /* Unmute Stereo Mixer 15 */ 15795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15799 15800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15802 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15803 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15806 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15807 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15808 /* hp used DAC 3 (Front) */ 15809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15810 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15811 { } 15812}; 15813 15814static const struct hda_verb alc861_asus_init_verbs[] = { 15815 /* 15816 * Unmute ADC0 and set the default input to mic-in 15817 */ 15818 /* port-A for surround (rear panel) 15819 * according to codec#0 this is the HP jack 15820 */ 15821 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ 15822 /* route front PCM to HP */ 15823 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, 15824 /* port-B for mic-in (rear panel) with vref */ 15825 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15826 /* port-C for line-in (rear panel) */ 15827 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15828 /* port-D for Front */ 15829 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15830 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15831 /* port-E for HP out (front panel) */ 15832 /* this has to be set to VREF80 */ 15833 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15834 /* route front PCM to HP */ 15835 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, 15836 /* port-F for mic-in (front panel) with vref */ 15837 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 15838 /* port-G for CLFE (rear panel) */ 15839 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15840 /* port-H for side (rear panel) */ 15841 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 15842 /* CD-in */ 15843 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 15844 /* route front mic to ADC1*/ 15845 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 15846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15847 /* Unmute DAC0~3 & spdif out*/ 15848 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15849 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15850 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15851 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15852 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15853 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15854 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15855 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15856 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15857 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15858 15859 /* Unmute Stereo Mixer 15 */ 15860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15861 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15863 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ 15864 15865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15866 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15867 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15869 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15871 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15872 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15873 /* hp used DAC 3 (Front) */ 15874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 15875 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15876 { } 15877}; 15878 15879/* additional init verbs for ASUS laptops */ 15880static const struct hda_verb alc861_asus_laptop_init_verbs[] = { 15881 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ 15882 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ 15883 { } 15884}; 15885 15886/* 15887 * generic initialization of ADC, input mixers and output mixers 15888 */ 15889static const struct hda_verb alc861_auto_init_verbs[] = { 15890 /* 15891 * Unmute ADC0 and set the default input to mic-in 15892 */ 15893 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ 15894 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15895 15896 /* Unmute DAC0~3 & spdif out*/ 15897 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15898 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15899 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15900 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 15901 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 15902 15903 /* Unmute Mixer 14 (mic) 1c (Line in)*/ 15904 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15905 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15906 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15907 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15908 15909 /* Unmute Stereo Mixer 15 */ 15910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 15911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 15912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 15913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 15914 15915 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15916 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15917 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15918 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15919 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15920 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15921 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15922 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15923 15924 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15925 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15927 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15928 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 15929 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 15930 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 15931 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 15932 15933 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 15934 15935 { } 15936}; 15937 15938static const struct hda_verb alc861_toshiba_init_verbs[] = { 15939 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 15940 15941 { } 15942}; 15943 15944/* toggle speaker-output according to the hp-jack state */ 15945static void alc861_toshiba_automute(struct hda_codec *codec) 15946{ 15947 unsigned int present = snd_hda_jack_detect(codec, 0x0f); 15948 15949 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, 15950 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 15951 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, 15952 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); 15953} 15954 15955static void alc861_toshiba_unsol_event(struct hda_codec *codec, 15956 unsigned int res) 15957{ 15958 if ((res >> 26) == ALC880_HP_EVENT) 15959 alc861_toshiba_automute(codec); 15960} 15961 15962/* pcm configuration: identical with ALC880 */ 15963#define alc861_pcm_analog_playback alc880_pcm_analog_playback 15964#define alc861_pcm_analog_capture alc880_pcm_analog_capture 15965#define alc861_pcm_digital_playback alc880_pcm_digital_playback 15966#define alc861_pcm_digital_capture alc880_pcm_digital_capture 15967 15968 15969#define ALC861_DIGOUT_NID 0x07 15970 15971static const struct hda_channel_mode alc861_8ch_modes[1] = { 15972 { 8, NULL } 15973}; 15974 15975static const hda_nid_t alc861_dac_nids[4] = { 15976 /* front, surround, clfe, side */ 15977 0x03, 0x06, 0x05, 0x04 15978}; 15979 15980static const hda_nid_t alc660_dac_nids[3] = { 15981 /* front, clfe, surround */ 15982 0x03, 0x05, 0x06 15983}; 15984 15985static const hda_nid_t alc861_adc_nids[1] = { 15986 /* ADC0-2 */ 15987 0x08, 15988}; 15989 15990static const struct hda_input_mux alc861_capture_source = { 15991 .num_items = 5, 15992 .items = { 15993 { "Mic", 0x0 }, 15994 { "Front Mic", 0x3 }, 15995 { "Line", 0x1 }, 15996 { "CD", 0x4 }, 15997 { "Mixer", 0x5 }, 15998 }, 15999}; 16000 16001static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 16002{ 16003 struct alc_spec *spec = codec->spec; 16004 hda_nid_t mix, srcs[5]; 16005 int i, j, num; 16006 16007 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1) 16008 return 0; 16009 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 16010 if (num < 0) 16011 return 0; 16012 for (i = 0; i < num; i++) { 16013 unsigned int type; 16014 type = get_wcaps_type(get_wcaps(codec, srcs[i])); 16015 if (type != AC_WID_AUD_OUT) 16016 continue; 16017 for (j = 0; j < spec->multiout.num_dacs; j++) 16018 if (spec->multiout.dac_nids[j] == srcs[i]) 16019 break; 16020 if (j >= spec->multiout.num_dacs) 16021 return srcs[i]; 16022 } 16023 return 0; 16024} 16025 16026/* fill in the dac_nids table from the parsed pin configuration */ 16027static int alc861_auto_fill_dac_nids(struct hda_codec *codec, 16028 const struct auto_pin_cfg *cfg) 16029{ 16030 struct alc_spec *spec = codec->spec; 16031 int i; 16032 hda_nid_t nid, dac; 16033 16034 spec->multiout.dac_nids = spec->private_dac_nids; 16035 for (i = 0; i < cfg->line_outs; i++) { 16036 nid = cfg->line_out_pins[i]; 16037 dac = alc861_look_for_dac(codec, nid); 16038 if (!dac) 16039 continue; 16040 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 16041 } 16042 return 0; 16043} 16044 16045static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 16046 hda_nid_t nid, int idx, unsigned int chs) 16047{ 16048 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 16049 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 16050} 16051 16052#define alc861_create_out_sw(codec, pfx, nid, chs) \ 16053 __alc861_create_out_sw(codec, pfx, nid, 0, chs) 16054 16055/* add playback controls from the parsed DAC table */ 16056static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 16057 const struct auto_pin_cfg *cfg) 16058{ 16059 struct alc_spec *spec = codec->spec; 16060 static const char * const chname[4] = { 16061 "Front", "Surround", NULL /*CLFE*/, "Side" 16062 }; 16063 const char *pfx = alc_get_line_out_pfx(spec, true); 16064 hda_nid_t nid; 16065 int i, err, noutputs; 16066 16067 noutputs = cfg->line_outs; 16068 if (spec->multi_ios > 0) 16069 noutputs += spec->multi_ios; 16070 16071 for (i = 0; i < noutputs; i++) { 16072 nid = spec->multiout.dac_nids[i]; 16073 if (!nid) 16074 continue; 16075 if (!pfx && i == 2) { 16076 /* Center/LFE */ 16077 err = alc861_create_out_sw(codec, "Center", nid, 1); 16078 if (err < 0) 16079 return err; 16080 err = alc861_create_out_sw(codec, "LFE", nid, 2); 16081 if (err < 0) 16082 return err; 16083 } else { 16084 const char *name = pfx; 16085 int index = i; 16086 if (!name) { 16087 name = chname[i]; 16088 index = 0; 16089 } 16090 err = __alc861_create_out_sw(codec, name, nid, index, 3); 16091 if (err < 0) 16092 return err; 16093 } 16094 } 16095 return 0; 16096} 16097 16098static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) 16099{ 16100 struct alc_spec *spec = codec->spec; 16101 int err; 16102 hda_nid_t nid; 16103 16104 if (!pin) 16105 return 0; 16106 16107 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 16108 nid = alc861_look_for_dac(codec, pin); 16109 if (nid) { 16110 err = alc861_create_out_sw(codec, "Headphone", nid, 3); 16111 if (err < 0) 16112 return err; 16113 spec->multiout.hp_nid = nid; 16114 } 16115 } 16116 return 0; 16117} 16118 16119/* create playback/capture controls for input pins */ 16120static int alc861_auto_create_input_ctls(struct hda_codec *codec, 16121 const struct auto_pin_cfg *cfg) 16122{ 16123 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0); 16124} 16125 16126static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 16127 hda_nid_t nid, 16128 int pin_type, hda_nid_t dac) 16129{ 16130 hda_nid_t mix, srcs[5]; 16131 int i, num; 16132 16133 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 16134 pin_type); 16135 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16136 AMP_OUT_UNMUTE); 16137 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1) 16138 return; 16139 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs)); 16140 if (num < 0) 16141 return; 16142 for (i = 0; i < num; i++) { 16143 unsigned int mute; 16144 if (srcs[i] == dac || srcs[i] == 0x15) 16145 mute = AMP_IN_UNMUTE(i); 16146 else 16147 mute = AMP_IN_MUTE(i); 16148 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, 16149 mute); 16150 } 16151} 16152 16153static void alc861_auto_init_multi_out(struct hda_codec *codec) 16154{ 16155 struct alc_spec *spec = codec->spec; 16156 int i; 16157 16158 for (i = 0; i < spec->autocfg.line_outs; i++) { 16159 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16160 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16161 if (nid) 16162 alc861_auto_set_output_and_unmute(codec, nid, pin_type, 16163 spec->multiout.dac_nids[i]); 16164 } 16165} 16166 16167static void alc861_auto_init_hp_out(struct hda_codec *codec) 16168{ 16169 struct alc_spec *spec = codec->spec; 16170 16171 if (spec->autocfg.hp_outs) 16172 alc861_auto_set_output_and_unmute(codec, 16173 spec->autocfg.hp_pins[0], 16174 PIN_HP, 16175 spec->multiout.hp_nid); 16176 if (spec->autocfg.speaker_outs) 16177 alc861_auto_set_output_and_unmute(codec, 16178 spec->autocfg.speaker_pins[0], 16179 PIN_OUT, 16180 spec->multiout.dac_nids[0]); 16181} 16182 16183static void alc861_auto_init_analog_input(struct hda_codec *codec) 16184{ 16185 struct alc_spec *spec = codec->spec; 16186 struct auto_pin_cfg *cfg = &spec->autocfg; 16187 int i; 16188 16189 for (i = 0; i < cfg->num_inputs; i++) { 16190 hda_nid_t nid = cfg->inputs[i].pin; 16191 if (nid >= 0x0c && nid <= 0x11) 16192 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 16193 } 16194} 16195 16196/* parse the BIOS configuration and set up the alc_spec */ 16197/* return 1 if successful, 0 if the proper config is not found, 16198 * or a negative error code 16199 */ 16200static int alc861_parse_auto_config(struct hda_codec *codec) 16201{ 16202 struct alc_spec *spec = codec->spec; 16203 int err; 16204 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 16205 16206 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 16207 alc861_ignore); 16208 if (err < 0) 16209 return err; 16210 if (!spec->autocfg.line_outs) 16211 return 0; /* can't find valid BIOS pin config */ 16212 16213 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); 16214 if (err < 0) 16215 return err; 16216 err = alc_auto_add_multi_channel_mode(codec); 16217 if (err < 0) 16218 return err; 16219 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 16220 if (err < 0) 16221 return err; 16222 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 16223 if (err < 0) 16224 return err; 16225 err = alc861_auto_create_input_ctls(codec, &spec->autocfg); 16226 if (err < 0) 16227 return err; 16228 16229 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 16230 16231 alc_auto_parse_digital(codec); 16232 16233 if (spec->kctls.list) 16234 add_mixer(spec, spec->kctls.list); 16235 16236 add_verb(spec, alc861_auto_init_verbs); 16237 16238 spec->num_mux_defs = 1; 16239 spec->input_mux = &spec->private_imux[0]; 16240 16241 spec->adc_nids = alc861_adc_nids; 16242 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 16243 set_capture_mixer(codec); 16244 16245 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0); 16246 16247 return 1; 16248} 16249 16250/* additional initialization for auto-configuration model */ 16251static void alc861_auto_init(struct hda_codec *codec) 16252{ 16253 struct alc_spec *spec = codec->spec; 16254 alc861_auto_init_multi_out(codec); 16255 alc861_auto_init_hp_out(codec); 16256 alc861_auto_init_analog_input(codec); 16257 alc_auto_init_digital(codec); 16258 if (spec->unsol_event) 16259 alc_inithook(codec); 16260} 16261 16262#ifdef CONFIG_SND_HDA_POWER_SAVE 16263static const struct hda_amp_list alc861_loopbacks[] = { 16264 { 0x15, HDA_INPUT, 0 }, 16265 { 0x15, HDA_INPUT, 1 }, 16266 { 0x15, HDA_INPUT, 2 }, 16267 { 0x15, HDA_INPUT, 3 }, 16268 { } /* end */ 16269}; 16270#endif 16271 16272 16273/* 16274 * configuration and preset 16275 */ 16276static const char * const alc861_models[ALC861_MODEL_LAST] = { 16277 [ALC861_3ST] = "3stack", 16278 [ALC660_3ST] = "3stack-660", 16279 [ALC861_3ST_DIG] = "3stack-dig", 16280 [ALC861_6ST_DIG] = "6stack-dig", 16281 [ALC861_UNIWILL_M31] = "uniwill-m31", 16282 [ALC861_TOSHIBA] = "toshiba", 16283 [ALC861_ASUS] = "asus", 16284 [ALC861_ASUS_LAPTOP] = "asus-laptop", 16285 [ALC861_AUTO] = "auto", 16286}; 16287 16288static const struct snd_pci_quirk alc861_cfg_tbl[] = { 16289 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), 16290 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16291 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), 16292 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), 16293 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), 16294 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), 16295 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), 16296 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) 16297 * Any other models that need this preset? 16298 */ 16299 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ 16300 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), 16301 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), 16302 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), 16303 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), 16304 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), 16305 /* FIXME: the below seems conflict */ 16306 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ 16307 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), 16308 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), 16309 {} 16310}; 16311 16312static const struct alc_config_preset alc861_presets[] = { 16313 [ALC861_3ST] = { 16314 .mixers = { alc861_3ST_mixer }, 16315 .init_verbs = { alc861_threestack_init_verbs }, 16316 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16317 .dac_nids = alc861_dac_nids, 16318 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16319 .channel_mode = alc861_threestack_modes, 16320 .need_dac_fix = 1, 16321 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16322 .adc_nids = alc861_adc_nids, 16323 .input_mux = &alc861_capture_source, 16324 }, 16325 [ALC861_3ST_DIG] = { 16326 .mixers = { alc861_base_mixer }, 16327 .init_verbs = { alc861_threestack_init_verbs }, 16328 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16329 .dac_nids = alc861_dac_nids, 16330 .dig_out_nid = ALC861_DIGOUT_NID, 16331 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16332 .channel_mode = alc861_threestack_modes, 16333 .need_dac_fix = 1, 16334 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16335 .adc_nids = alc861_adc_nids, 16336 .input_mux = &alc861_capture_source, 16337 }, 16338 [ALC861_6ST_DIG] = { 16339 .mixers = { alc861_base_mixer }, 16340 .init_verbs = { alc861_base_init_verbs }, 16341 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16342 .dac_nids = alc861_dac_nids, 16343 .dig_out_nid = ALC861_DIGOUT_NID, 16344 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), 16345 .channel_mode = alc861_8ch_modes, 16346 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16347 .adc_nids = alc861_adc_nids, 16348 .input_mux = &alc861_capture_source, 16349 }, 16350 [ALC660_3ST] = { 16351 .mixers = { alc861_3ST_mixer }, 16352 .init_verbs = { alc861_threestack_init_verbs }, 16353 .num_dacs = ARRAY_SIZE(alc660_dac_nids), 16354 .dac_nids = alc660_dac_nids, 16355 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), 16356 .channel_mode = alc861_threestack_modes, 16357 .need_dac_fix = 1, 16358 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16359 .adc_nids = alc861_adc_nids, 16360 .input_mux = &alc861_capture_source, 16361 }, 16362 [ALC861_UNIWILL_M31] = { 16363 .mixers = { alc861_uniwill_m31_mixer }, 16364 .init_verbs = { alc861_uniwill_m31_init_verbs }, 16365 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16366 .dac_nids = alc861_dac_nids, 16367 .dig_out_nid = ALC861_DIGOUT_NID, 16368 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), 16369 .channel_mode = alc861_uniwill_m31_modes, 16370 .need_dac_fix = 1, 16371 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16372 .adc_nids = alc861_adc_nids, 16373 .input_mux = &alc861_capture_source, 16374 }, 16375 [ALC861_TOSHIBA] = { 16376 .mixers = { alc861_toshiba_mixer }, 16377 .init_verbs = { alc861_base_init_verbs, 16378 alc861_toshiba_init_verbs }, 16379 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16380 .dac_nids = alc861_dac_nids, 16381 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16382 .channel_mode = alc883_3ST_2ch_modes, 16383 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16384 .adc_nids = alc861_adc_nids, 16385 .input_mux = &alc861_capture_source, 16386 .unsol_event = alc861_toshiba_unsol_event, 16387 .init_hook = alc861_toshiba_automute, 16388 }, 16389 [ALC861_ASUS] = { 16390 .mixers = { alc861_asus_mixer }, 16391 .init_verbs = { alc861_asus_init_verbs }, 16392 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16393 .dac_nids = alc861_dac_nids, 16394 .dig_out_nid = ALC861_DIGOUT_NID, 16395 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), 16396 .channel_mode = alc861_asus_modes, 16397 .need_dac_fix = 1, 16398 .hp_nid = 0x06, 16399 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16400 .adc_nids = alc861_adc_nids, 16401 .input_mux = &alc861_capture_source, 16402 }, 16403 [ALC861_ASUS_LAPTOP] = { 16404 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, 16405 .init_verbs = { alc861_asus_init_verbs, 16406 alc861_asus_laptop_init_verbs }, 16407 .num_dacs = ARRAY_SIZE(alc861_dac_nids), 16408 .dac_nids = alc861_dac_nids, 16409 .dig_out_nid = ALC861_DIGOUT_NID, 16410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 16411 .channel_mode = alc883_3ST_2ch_modes, 16412 .need_dac_fix = 1, 16413 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), 16414 .adc_nids = alc861_adc_nids, 16415 .input_mux = &alc861_capture_source, 16416 }, 16417}; 16418 16419/* Pin config fixes */ 16420enum { 16421 PINFIX_FSC_AMILO_PI1505, 16422 PINFIX_ASUS_A6RP, 16423}; 16424 16425static const struct alc_fixup alc861_fixups[] = { 16426 [PINFIX_FSC_AMILO_PI1505] = { 16427 .type = ALC_FIXUP_PINS, 16428 .v.pins = (const struct alc_pincfg[]) { 16429 { 0x0b, 0x0221101f }, /* HP */ 16430 { 0x0f, 0x90170310 }, /* speaker */ 16431 { } 16432 } 16433 }, 16434 [PINFIX_ASUS_A6RP] = { 16435 .type = ALC_FIXUP_VERBS, 16436 .v.verbs = (const struct hda_verb[]) { 16437 /* node 0x0f VREF seems controlling the master output */ 16438 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 16439 { } 16440 }, 16441 }, 16442}; 16443 16444static const struct snd_pci_quirk alc861_fixup_tbl[] = { 16445 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), 16446 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 16447 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 16448 {} 16449}; 16450 16451static int patch_alc861(struct hda_codec *codec) 16452{ 16453 struct alc_spec *spec; 16454 int board_config; 16455 int err; 16456 16457 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 16458 if (spec == NULL) 16459 return -ENOMEM; 16460 16461 codec->spec = spec; 16462 16463 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 16464 alc861_models, 16465 alc861_cfg_tbl); 16466 16467 if (board_config < 0) { 16468 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 16469 codec->chip_name); 16470 board_config = ALC861_AUTO; 16471 } 16472 16473 if (board_config == ALC861_AUTO) { 16474 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 16475 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 16476 } 16477 16478 if (board_config == ALC861_AUTO) { 16479 /* automatic parse from the BIOS config */ 16480 err = alc861_parse_auto_config(codec); 16481 if (err < 0) { 16482 alc_free(codec); 16483 return err; 16484 } else if (!err) { 16485 printk(KERN_INFO 16486 "hda_codec: Cannot set up configuration " 16487 "from BIOS. Using base mode...\n"); 16488 board_config = ALC861_3ST_DIG; 16489 } 16490 } 16491 16492 err = snd_hda_attach_beep_device(codec, 0x23); 16493 if (err < 0) { 16494 alc_free(codec); 16495 return err; 16496 } 16497 16498 if (board_config != ALC861_AUTO) 16499 setup_preset(codec, &alc861_presets[board_config]); 16500 16501 spec->stream_analog_playback = &alc861_pcm_analog_playback; 16502 spec->stream_analog_capture = &alc861_pcm_analog_capture; 16503 16504 spec->stream_digital_playback = &alc861_pcm_digital_playback; 16505 spec->stream_digital_capture = &alc861_pcm_digital_capture; 16506 16507 if (!spec->cap_mixer) 16508 set_capture_mixer(codec); 16509 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 16510 16511 spec->vmaster_nid = 0x03; 16512 16513 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 16514 16515 codec->patch_ops = alc_patch_ops; 16516 if (board_config == ALC861_AUTO) { 16517 spec->init_hook = alc861_auto_init; 16518#ifdef CONFIG_SND_HDA_POWER_SAVE 16519 spec->power_hook = alc_power_eapd; 16520#endif 16521 } 16522#ifdef CONFIG_SND_HDA_POWER_SAVE 16523 if (!spec->loopback.amplist) 16524 spec->loopback.amplist = alc861_loopbacks; 16525#endif 16526 16527 return 0; 16528} 16529 16530/* 16531 * ALC861-VD support 16532 * 16533 * Based on ALC882 16534 * 16535 * In addition, an independent DAC 16536 */ 16537#define ALC861VD_DIGOUT_NID 0x06 16538 16539static const hda_nid_t alc861vd_dac_nids[4] = { 16540 /* front, surr, clfe, side surr */ 16541 0x02, 0x03, 0x04, 0x05 16542}; 16543 16544/* dac_nids for ALC660vd are in a different order - according to 16545 * Realtek's driver. 16546 * This should probably result in a different mixer for 6stack models 16547 * of ALC660vd codecs, but for now there is only 3stack mixer 16548 * - and it is the same as in 861vd. 16549 * adc_nids in ALC660vd are (is) the same as in 861vd 16550 */ 16551static const hda_nid_t alc660vd_dac_nids[3] = { 16552 /* front, rear, clfe, rear_surr */ 16553 0x02, 0x04, 0x03 16554}; 16555 16556static const hda_nid_t alc861vd_adc_nids[1] = { 16557 /* ADC0 */ 16558 0x09, 16559}; 16560 16561static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; 16562 16563/* input MUX */ 16564/* FIXME: should be a matrix-type input source selection */ 16565static const struct hda_input_mux alc861vd_capture_source = { 16566 .num_items = 4, 16567 .items = { 16568 { "Mic", 0x0 }, 16569 { "Front Mic", 0x1 }, 16570 { "Line", 0x2 }, 16571 { "CD", 0x4 }, 16572 }, 16573}; 16574 16575static const struct hda_input_mux alc861vd_dallas_capture_source = { 16576 .num_items = 2, 16577 .items = { 16578 { "Mic", 0x0 }, 16579 { "Internal Mic", 0x1 }, 16580 }, 16581}; 16582 16583static const struct hda_input_mux alc861vd_hp_capture_source = { 16584 .num_items = 2, 16585 .items = { 16586 { "Front Mic", 0x0 }, 16587 { "ATAPI Mic", 0x1 }, 16588 }, 16589}; 16590 16591/* 16592 * 2ch mode 16593 */ 16594static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { 16595 { 2, NULL } 16596}; 16597 16598/* 16599 * 6ch mode 16600 */ 16601static const struct hda_verb alc861vd_6stack_ch6_init[] = { 16602 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 16603 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16604 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16605 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16606 { } /* end */ 16607}; 16608 16609/* 16610 * 8ch mode 16611 */ 16612static const struct hda_verb alc861vd_6stack_ch8_init[] = { 16613 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16614 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16615 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16616 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 16617 { } /* end */ 16618}; 16619 16620static const struct hda_channel_mode alc861vd_6stack_modes[2] = { 16621 { 6, alc861vd_6stack_ch6_init }, 16622 { 8, alc861vd_6stack_ch8_init }, 16623}; 16624 16625static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = { 16626 { 16627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 16628 .name = "Channel Mode", 16629 .info = alc_ch_mode_info, 16630 .get = alc_ch_mode_get, 16631 .put = alc_ch_mode_put, 16632 }, 16633 { } /* end */ 16634}; 16635 16636/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 16637 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 16638 */ 16639static const struct snd_kcontrol_new alc861vd_6st_mixer[] = { 16640 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16641 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16642 16643 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16644 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), 16645 16646 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, 16647 HDA_OUTPUT), 16648 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, 16649 HDA_OUTPUT), 16650 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), 16651 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 16652 16653 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), 16654 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 16655 16656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16657 16658 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16661 16662 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16663 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16665 16666 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16667 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16668 16669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16670 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16671 16672 { } /* end */ 16673}; 16674 16675static const struct snd_kcontrol_new alc861vd_3st_mixer[] = { 16676 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16677 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16678 16679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16680 16681 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16684 16685 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16686 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16688 16689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 16690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 16691 16692 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16693 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16694 16695 { } /* end */ 16696}; 16697 16698static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { 16699 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16700 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ 16701 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 16702 16703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16704 16705 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16708 16709 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), 16710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16711 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16712 16713 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 16714 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 16715 16716 { } /* end */ 16717}; 16718 16719/* Pin assignment: Speaker=0x14, HP = 0x15, 16720 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16721 */ 16722static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16724 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16726 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16727 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 16728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16730 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 16731 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16732 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16733 { } /* end */ 16734}; 16735 16736/* Pin assignment: Speaker=0x14, Line-out = 0x15, 16737 * Front Mic=0x18, ATAPI Mic = 0x19, 16738 */ 16739static const struct snd_kcontrol_new alc861vd_hp_mixer[] = { 16740 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 16742 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16743 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16744 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16745 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16746 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16747 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16748 16749 { } /* end */ 16750}; 16751 16752/* 16753 * generic initialization of ADC, input mixers and output mixers 16754 */ 16755static const struct hda_verb alc861vd_volume_init_verbs[] = { 16756 /* 16757 * Unmute ADC0 and set the default input to mic-in 16758 */ 16759 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16760 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16761 16762 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of 16763 * the analog-loopback mixer widget 16764 */ 16765 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ 16766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16771 16772 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ 16773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 16776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, 16777 16778 /* 16779 * Set up output mixers (0x02 - 0x05) 16780 */ 16781 /* set vol=0 to output mixers */ 16782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16783 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16784 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16786 16787 /* set up input amps for analog loopback */ 16788 /* Amp Indices: DAC = 0, mixer = 1 */ 16789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16791 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16792 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16793 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16794 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16795 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16797 16798 { } 16799}; 16800 16801/* 16802 * 3-stack pin configuration: 16803 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b 16804 */ 16805static const struct hda_verb alc861vd_3stack_init_verbs[] = { 16806 /* 16807 * Set pin mode and muting 16808 */ 16809 /* set front pin widgets 0x14 for output */ 16810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16811 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16812 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16813 16814 /* Mic (rear) pin: input vref at 80% */ 16815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16817 /* Front Mic pin: input vref at 80% */ 16818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16820 /* Line In pin: input */ 16821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16823 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16827 /* CD pin widget for input */ 16828 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16829 16830 { } 16831}; 16832 16833/* 16834 * 6-stack pin configuration: 16835 */ 16836static const struct hda_verb alc861vd_6stack_init_verbs[] = { 16837 /* 16838 * Set pin mode and muting 16839 */ 16840 /* set front pin widgets 0x14 for output */ 16841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16843 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 16844 16845 /* Rear Pin: output 1 (0x0d) */ 16846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16848 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 16849 /* CLFE Pin: output 2 (0x0e) */ 16850 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16851 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16852 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, 16853 /* Side Pin: output 3 (0x0f) */ 16854 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16856 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, 16857 16858 /* Mic (rear) pin: input vref at 80% */ 16859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16860 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16861 /* Front Mic pin: input vref at 80% */ 16862 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 16863 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16864 /* Line In pin: input */ 16865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16867 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 16868 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 16869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16870 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 16871 /* CD pin widget for input */ 16872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16873 16874 { } 16875}; 16876 16877static const struct hda_verb alc861vd_eapd_verbs[] = { 16878 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16879 { } 16880}; 16881 16882static const struct hda_verb alc660vd_eapd_verbs[] = { 16883 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16884 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 16885 { } 16886}; 16887 16888static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = { 16889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 16892 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16893 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 16894 {} 16895}; 16896 16897static void alc861vd_lenovo_setup(struct hda_codec *codec) 16898{ 16899 struct alc_spec *spec = codec->spec; 16900 spec->autocfg.hp_pins[0] = 0x1b; 16901 spec->autocfg.speaker_pins[0] = 0x14; 16902 spec->automute = 1; 16903 spec->automute_mode = ALC_AUTOMUTE_AMP; 16904} 16905 16906static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16907{ 16908 alc_hp_automute(codec); 16909 alc88x_simple_mic_automute(codec); 16910} 16911 16912static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16913 unsigned int res) 16914{ 16915 switch (res >> 26) { 16916 case ALC880_MIC_EVENT: 16917 alc88x_simple_mic_automute(codec); 16918 break; 16919 default: 16920 alc_sku_unsol_event(codec, res); 16921 break; 16922 } 16923} 16924 16925static const struct hda_verb alc861vd_dallas_verbs[] = { 16926 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16927 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16928 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16929 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 16930 16931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 16939 16940 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16941 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16943 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16944 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16945 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16946 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 16947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 16948 16949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16950 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16951 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 16952 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 16953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16955 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16956 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16957 16958 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 16960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 16961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 16962 16963 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16964 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16965 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 16966 16967 { } /* end */ 16968}; 16969 16970/* toggle speaker-output according to the hp-jack state */ 16971static void alc861vd_dallas_setup(struct hda_codec *codec) 16972{ 16973 struct alc_spec *spec = codec->spec; 16974 16975 spec->autocfg.hp_pins[0] = 0x15; 16976 spec->autocfg.speaker_pins[0] = 0x14; 16977 spec->automute = 1; 16978 spec->automute_mode = ALC_AUTOMUTE_AMP; 16979} 16980 16981#ifdef CONFIG_SND_HDA_POWER_SAVE 16982#define alc861vd_loopbacks alc880_loopbacks 16983#endif 16984 16985/* pcm configuration: identical with ALC880 */ 16986#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback 16987#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture 16988#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback 16989#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture 16990 16991/* 16992 * configuration and preset 16993 */ 16994static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { 16995 [ALC660VD_3ST] = "3stack-660", 16996 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16997 [ALC660VD_ASUS_V1S] = "asus-v1s", 16998 [ALC861VD_3ST] = "3stack", 16999 [ALC861VD_3ST_DIG] = "3stack-digout", 17000 [ALC861VD_6ST_DIG] = "6stack-digout", 17001 [ALC861VD_LENOVO] = "lenovo", 17002 [ALC861VD_DALLAS] = "dallas", 17003 [ALC861VD_HP] = "hp", 17004 [ALC861VD_AUTO] = "auto", 17005}; 17006 17007static const struct snd_pci_quirk alc861vd_cfg_tbl[] = { 17008 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 17009 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 17010 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 17011 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ 17012 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 17013 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 17014 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 17015 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 17016 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ 17017 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), 17018 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), 17019 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), 17020 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), 17021 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), 17022 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), 17023 {} 17024}; 17025 17026static const struct alc_config_preset alc861vd_presets[] = { 17027 [ALC660VD_3ST] = { 17028 .mixers = { alc861vd_3st_mixer }, 17029 .init_verbs = { alc861vd_volume_init_verbs, 17030 alc861vd_3stack_init_verbs }, 17031 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17032 .dac_nids = alc660vd_dac_nids, 17033 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17034 .channel_mode = alc861vd_3stack_2ch_modes, 17035 .input_mux = &alc861vd_capture_source, 17036 }, 17037 [ALC660VD_3ST_DIG] = { 17038 .mixers = { alc861vd_3st_mixer }, 17039 .init_verbs = { alc861vd_volume_init_verbs, 17040 alc861vd_3stack_init_verbs }, 17041 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17042 .dac_nids = alc660vd_dac_nids, 17043 .dig_out_nid = ALC861VD_DIGOUT_NID, 17044 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17045 .channel_mode = alc861vd_3stack_2ch_modes, 17046 .input_mux = &alc861vd_capture_source, 17047 }, 17048 [ALC861VD_3ST] = { 17049 .mixers = { alc861vd_3st_mixer }, 17050 .init_verbs = { alc861vd_volume_init_verbs, 17051 alc861vd_3stack_init_verbs }, 17052 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17053 .dac_nids = alc861vd_dac_nids, 17054 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17055 .channel_mode = alc861vd_3stack_2ch_modes, 17056 .input_mux = &alc861vd_capture_source, 17057 }, 17058 [ALC861VD_3ST_DIG] = { 17059 .mixers = { alc861vd_3st_mixer }, 17060 .init_verbs = { alc861vd_volume_init_verbs, 17061 alc861vd_3stack_init_verbs }, 17062 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17063 .dac_nids = alc861vd_dac_nids, 17064 .dig_out_nid = ALC861VD_DIGOUT_NID, 17065 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17066 .channel_mode = alc861vd_3stack_2ch_modes, 17067 .input_mux = &alc861vd_capture_source, 17068 }, 17069 [ALC861VD_6ST_DIG] = { 17070 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, 17071 .init_verbs = { alc861vd_volume_init_verbs, 17072 alc861vd_6stack_init_verbs }, 17073 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17074 .dac_nids = alc861vd_dac_nids, 17075 .dig_out_nid = ALC861VD_DIGOUT_NID, 17076 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), 17077 .channel_mode = alc861vd_6stack_modes, 17078 .input_mux = &alc861vd_capture_source, 17079 }, 17080 [ALC861VD_LENOVO] = { 17081 .mixers = { alc861vd_lenovo_mixer }, 17082 .init_verbs = { alc861vd_volume_init_verbs, 17083 alc861vd_3stack_init_verbs, 17084 alc861vd_eapd_verbs, 17085 alc861vd_lenovo_unsol_verbs }, 17086 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17087 .dac_nids = alc660vd_dac_nids, 17088 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17089 .channel_mode = alc861vd_3stack_2ch_modes, 17090 .input_mux = &alc861vd_capture_source, 17091 .unsol_event = alc861vd_lenovo_unsol_event, 17092 .setup = alc861vd_lenovo_setup, 17093 .init_hook = alc861vd_lenovo_init_hook, 17094 }, 17095 [ALC861VD_DALLAS] = { 17096 .mixers = { alc861vd_dallas_mixer }, 17097 .init_verbs = { alc861vd_dallas_verbs }, 17098 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17099 .dac_nids = alc861vd_dac_nids, 17100 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17101 .channel_mode = alc861vd_3stack_2ch_modes, 17102 .input_mux = &alc861vd_dallas_capture_source, 17103 .unsol_event = alc_sku_unsol_event, 17104 .setup = alc861vd_dallas_setup, 17105 .init_hook = alc_hp_automute, 17106 }, 17107 [ALC861VD_HP] = { 17108 .mixers = { alc861vd_hp_mixer }, 17109 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, 17110 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), 17111 .dac_nids = alc861vd_dac_nids, 17112 .dig_out_nid = ALC861VD_DIGOUT_NID, 17113 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17114 .channel_mode = alc861vd_3stack_2ch_modes, 17115 .input_mux = &alc861vd_hp_capture_source, 17116 .unsol_event = alc_sku_unsol_event, 17117 .setup = alc861vd_dallas_setup, 17118 .init_hook = alc_hp_automute, 17119 }, 17120 [ALC660VD_ASUS_V1S] = { 17121 .mixers = { alc861vd_lenovo_mixer }, 17122 .init_verbs = { alc861vd_volume_init_verbs, 17123 alc861vd_3stack_init_verbs, 17124 alc861vd_eapd_verbs, 17125 alc861vd_lenovo_unsol_verbs }, 17126 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), 17127 .dac_nids = alc660vd_dac_nids, 17128 .dig_out_nid = ALC861VD_DIGOUT_NID, 17129 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), 17130 .channel_mode = alc861vd_3stack_2ch_modes, 17131 .input_mux = &alc861vd_capture_source, 17132 .unsol_event = alc861vd_lenovo_unsol_event, 17133 .setup = alc861vd_lenovo_setup, 17134 .init_hook = alc861vd_lenovo_init_hook, 17135 }, 17136}; 17137 17138/* 17139 * BIOS auto configuration 17140 */ 17141static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 17142 const struct auto_pin_cfg *cfg) 17143{ 17144 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0); 17145} 17146 17147 17148static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 17149 hda_nid_t nid, int pin_type, int dac_idx) 17150{ 17151 alc_set_pin_output(codec, nid, pin_type); 17152} 17153 17154static void alc861vd_auto_init_multi_out(struct hda_codec *codec) 17155{ 17156 struct alc_spec *spec = codec->spec; 17157 int i; 17158 17159 for (i = 0; i <= HDA_SIDE; i++) { 17160 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17161 int pin_type = get_pin_type(spec->autocfg.line_out_type); 17162 if (nid) 17163 alc861vd_auto_set_output_and_unmute(codec, nid, 17164 pin_type, i); 17165 } 17166} 17167 17168 17169static void alc861vd_auto_init_hp_out(struct hda_codec *codec) 17170{ 17171 struct alc_spec *spec = codec->spec; 17172 hda_nid_t pin; 17173 17174 pin = spec->autocfg.hp_pins[0]; 17175 if (pin) /* connect to front and use dac 0 */ 17176 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 17177 pin = spec->autocfg.speaker_pins[0]; 17178 if (pin) 17179 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 17180} 17181 17182#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 17183 17184static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 17185{ 17186 struct alc_spec *spec = codec->spec; 17187 struct auto_pin_cfg *cfg = &spec->autocfg; 17188 int i; 17189 17190 for (i = 0; i < cfg->num_inputs; i++) { 17191 hda_nid_t nid = cfg->inputs[i].pin; 17192 if (alc_is_input_pin(codec, nid)) { 17193 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 17194 if (nid != ALC861VD_PIN_CD_NID && 17195 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 17196 snd_hda_codec_write(codec, nid, 0, 17197 AC_VERB_SET_AMP_GAIN_MUTE, 17198 AMP_OUT_MUTE); 17199 } 17200 } 17201} 17202 17203#define alc861vd_auto_init_input_src alc882_auto_init_input_src 17204 17205#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 17206#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 17207 17208/* add playback controls from the parsed DAC table */ 17209/* Based on ALC880 version. But ALC861VD has separate, 17210 * different NIDs for mute/unmute switch and volume control */ 17211static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17212 const struct auto_pin_cfg *cfg) 17213{ 17214 static const char * const chname[4] = { 17215 "Front", "Surround", "CLFE", "Side" 17216 }; 17217 const char *pfx = alc_get_line_out_pfx(spec, true); 17218 hda_nid_t nid_v, nid_s; 17219 int i, err, noutputs; 17220 17221 noutputs = cfg->line_outs; 17222 if (spec->multi_ios > 0) 17223 noutputs += spec->multi_ios; 17224 17225 for (i = 0; i < noutputs; i++) { 17226 if (!spec->multiout.dac_nids[i]) 17227 continue; 17228 nid_v = alc861vd_idx_to_mixer_vol( 17229 alc880_dac_to_idx( 17230 spec->multiout.dac_nids[i])); 17231 nid_s = alc861vd_idx_to_mixer_switch( 17232 alc880_dac_to_idx( 17233 spec->multiout.dac_nids[i])); 17234 17235 if (!pfx && i == 2) { 17236 /* Center/LFE */ 17237 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17238 "Center", 17239 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, 17240 HDA_OUTPUT)); 17241 if (err < 0) 17242 return err; 17243 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17244 "LFE", 17245 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, 17246 HDA_OUTPUT)); 17247 if (err < 0) 17248 return err; 17249 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17250 "Center", 17251 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, 17252 HDA_INPUT)); 17253 if (err < 0) 17254 return err; 17255 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17256 "LFE", 17257 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, 17258 HDA_INPUT)); 17259 if (err < 0) 17260 return err; 17261 } else { 17262 const char *name = pfx; 17263 int index = i; 17264 if (!name) { 17265 name = chname[i]; 17266 index = 0; 17267 } 17268 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17269 name, index, 17270 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17271 HDA_OUTPUT)); 17272 if (err < 0) 17273 return err; 17274 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, 17275 name, index, 17276 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17277 HDA_INPUT)); 17278 if (err < 0) 17279 return err; 17280 } 17281 } 17282 return 0; 17283} 17284 17285/* add playback controls for speaker and HP outputs */ 17286/* Based on ALC880 version. But ALC861VD has separate, 17287 * different NIDs for mute/unmute switch and volume control */ 17288static int alc861vd_auto_create_extra_out(struct alc_spec *spec, 17289 hda_nid_t pin, const char *pfx) 17290{ 17291 hda_nid_t nid_v, nid_s; 17292 int err; 17293 17294 if (!pin) 17295 return 0; 17296 17297 if (alc880_is_fixed_pin(pin)) { 17298 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17299 /* specify the DAC as the extra output */ 17300 if (!spec->multiout.hp_nid) 17301 spec->multiout.hp_nid = nid_v; 17302 else 17303 spec->multiout.extra_out_nid[0] = nid_v; 17304 /* control HP volume/switch on the output mixer amp */ 17305 nid_v = alc861vd_idx_to_mixer_vol( 17306 alc880_fixed_pin_idx(pin)); 17307 nid_s = alc861vd_idx_to_mixer_switch( 17308 alc880_fixed_pin_idx(pin)); 17309 17310 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 17311 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 17312 if (err < 0) 17313 return err; 17314 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 17315 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 17316 if (err < 0) 17317 return err; 17318 } else if (alc880_is_multi_pin(pin)) { 17319 /* set manual connection */ 17320 /* we have only a switch on HP-out PIN */ 17321 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 17322 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 17323 if (err < 0) 17324 return err; 17325 } 17326 return 0; 17327} 17328 17329/* parse the BIOS configuration and set up the alc_spec 17330 * return 1 if successful, 0 if the proper config is not found, 17331 * or a negative error code 17332 * Based on ALC880 version - had to change it to override 17333 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */ 17334static int alc861vd_parse_auto_config(struct hda_codec *codec) 17335{ 17336 struct alc_spec *spec = codec->spec; 17337 int err; 17338 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 17339 17340 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 17341 alc861vd_ignore); 17342 if (err < 0) 17343 return err; 17344 if (!spec->autocfg.line_outs) 17345 return 0; /* can't find valid BIOS pin config */ 17346 17347 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17348 if (err < 0) 17349 return err; 17350 err = alc_auto_add_multi_channel_mode(codec); 17351 if (err < 0) 17352 return err; 17353 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); 17354 if (err < 0) 17355 return err; 17356 err = alc861vd_auto_create_extra_out(spec, 17357 spec->autocfg.speaker_pins[0], 17358 "Speaker"); 17359 if (err < 0) 17360 return err; 17361 err = alc861vd_auto_create_extra_out(spec, 17362 spec->autocfg.hp_pins[0], 17363 "Headphone"); 17364 if (err < 0) 17365 return err; 17366 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg); 17367 if (err < 0) 17368 return err; 17369 17370 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 17371 17372 alc_auto_parse_digital(codec); 17373 17374 if (spec->kctls.list) 17375 add_mixer(spec, spec->kctls.list); 17376 17377 add_verb(spec, alc861vd_volume_init_verbs); 17378 17379 spec->num_mux_defs = 1; 17380 spec->input_mux = &spec->private_imux[0]; 17381 17382 err = alc_auto_add_mic_boost(codec); 17383 if (err < 0) 17384 return err; 17385 17386 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 17387 17388 return 1; 17389} 17390 17391/* additional initialization for auto-configuration model */ 17392static void alc861vd_auto_init(struct hda_codec *codec) 17393{ 17394 struct alc_spec *spec = codec->spec; 17395 alc861vd_auto_init_multi_out(codec); 17396 alc861vd_auto_init_hp_out(codec); 17397 alc861vd_auto_init_analog_input(codec); 17398 alc861vd_auto_init_input_src(codec); 17399 alc_auto_init_digital(codec); 17400 if (spec->unsol_event) 17401 alc_inithook(codec); 17402} 17403 17404enum { 17405 ALC660VD_FIX_ASUS_GPIO1 17406}; 17407 17408/* reset GPIO1 */ 17409static const struct alc_fixup alc861vd_fixups[] = { 17410 [ALC660VD_FIX_ASUS_GPIO1] = { 17411 .type = ALC_FIXUP_VERBS, 17412 .v.verbs = (const struct hda_verb[]) { 17413 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 17414 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 17415 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 17416 { } 17417 } 17418 }, 17419}; 17420 17421static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { 17422 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), 17423 {} 17424}; 17425 17426static int patch_alc861vd(struct hda_codec *codec) 17427{ 17428 struct alc_spec *spec; 17429 int err, board_config; 17430 17431 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 17432 if (spec == NULL) 17433 return -ENOMEM; 17434 17435 codec->spec = spec; 17436 17437 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 17438 alc861vd_models, 17439 alc861vd_cfg_tbl); 17440 17441 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 17442 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 17443 codec->chip_name); 17444 board_config = ALC861VD_AUTO; 17445 } 17446 17447 if (board_config == ALC861VD_AUTO) { 17448 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 17449 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 17450 } 17451 17452 if (board_config == ALC861VD_AUTO) { 17453 /* automatic parse from the BIOS config */ 17454 err = alc861vd_parse_auto_config(codec); 17455 if (err < 0) { 17456 alc_free(codec); 17457 return err; 17458 } else if (!err) { 17459 printk(KERN_INFO 17460 "hda_codec: Cannot set up configuration " 17461 "from BIOS. Using base mode...\n"); 17462 board_config = ALC861VD_3ST; 17463 } 17464 } 17465 17466 err = snd_hda_attach_beep_device(codec, 0x23); 17467 if (err < 0) { 17468 alc_free(codec); 17469 return err; 17470 } 17471 17472 if (board_config != ALC861VD_AUTO) 17473 setup_preset(codec, &alc861vd_presets[board_config]); 17474 17475 if (codec->vendor_id == 0x10ec0660) { 17476 /* always turn on EAPD */ 17477 add_verb(spec, alc660vd_eapd_verbs); 17478 } 17479 17480 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 17481 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 17482 17483 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 17484 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 17485 17486 if (!spec->adc_nids) { 17487 spec->adc_nids = alc861vd_adc_nids; 17488 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 17489 } 17490 if (!spec->capsrc_nids) 17491 spec->capsrc_nids = alc861vd_capsrc_nids; 17492 17493 set_capture_mixer(codec); 17494 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17495 17496 spec->vmaster_nid = 0x02; 17497 17498 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 17499 17500 codec->patch_ops = alc_patch_ops; 17501 17502 if (board_config == ALC861VD_AUTO) 17503 spec->init_hook = alc861vd_auto_init; 17504 spec->shutup = alc_eapd_shutup; 17505#ifdef CONFIG_SND_HDA_POWER_SAVE 17506 if (!spec->loopback.amplist) 17507 spec->loopback.amplist = alc861vd_loopbacks; 17508#endif 17509 17510 return 0; 17511} 17512 17513/* 17514 * ALC662 support 17515 * 17516 * ALC662 is almost identical with ALC880 but has cleaner and more flexible 17517 * configuration. Each pin widget can choose any input DACs and a mixer. 17518 * Each ADC is connected from a mixer of all inputs. This makes possible 17519 * 6-channel independent captures. 17520 * 17521 * In addition, an independent DAC for the multi-playback (not used in this 17522 * driver yet). 17523 */ 17524#define ALC662_DIGOUT_NID 0x06 17525#define ALC662_DIGIN_NID 0x0a 17526 17527static const hda_nid_t alc662_dac_nids[3] = { 17528 /* front, rear, clfe */ 17529 0x02, 0x03, 0x04 17530}; 17531 17532static const hda_nid_t alc272_dac_nids[2] = { 17533 0x02, 0x03 17534}; 17535 17536static const hda_nid_t alc662_adc_nids[2] = { 17537 /* ADC1-2 */ 17538 0x09, 0x08 17539}; 17540 17541static const hda_nid_t alc272_adc_nids[1] = { 17542 /* ADC1-2 */ 17543 0x08, 17544}; 17545 17546static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; 17547static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 17548 17549 17550/* input MUX */ 17551/* FIXME: should be a matrix-type input source selection */ 17552static const struct hda_input_mux alc662_capture_source = { 17553 .num_items = 4, 17554 .items = { 17555 { "Mic", 0x0 }, 17556 { "Front Mic", 0x1 }, 17557 { "Line", 0x2 }, 17558 { "CD", 0x4 }, 17559 }, 17560}; 17561 17562static const struct hda_input_mux alc662_lenovo_101e_capture_source = { 17563 .num_items = 2, 17564 .items = { 17565 { "Mic", 0x1 }, 17566 { "Line", 0x2 }, 17567 }, 17568}; 17569 17570static const struct hda_input_mux alc663_capture_source = { 17571 .num_items = 3, 17572 .items = { 17573 { "Mic", 0x0 }, 17574 { "Front Mic", 0x1 }, 17575 { "Line", 0x2 }, 17576 }, 17577}; 17578 17579#if 0 /* set to 1 for testing other input sources below */ 17580static const struct hda_input_mux alc272_nc10_capture_source = { 17581 .num_items = 16, 17582 .items = { 17583 { "Autoselect Mic", 0x0 }, 17584 { "Internal Mic", 0x1 }, 17585 { "In-0x02", 0x2 }, 17586 { "In-0x03", 0x3 }, 17587 { "In-0x04", 0x4 }, 17588 { "In-0x05", 0x5 }, 17589 { "In-0x06", 0x6 }, 17590 { "In-0x07", 0x7 }, 17591 { "In-0x08", 0x8 }, 17592 { "In-0x09", 0x9 }, 17593 { "In-0x0a", 0x0a }, 17594 { "In-0x0b", 0x0b }, 17595 { "In-0x0c", 0x0c }, 17596 { "In-0x0d", 0x0d }, 17597 { "In-0x0e", 0x0e }, 17598 { "In-0x0f", 0x0f }, 17599 }, 17600}; 17601#endif 17602 17603/* 17604 * 2ch mode 17605 */ 17606static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = { 17607 { 2, NULL } 17608}; 17609 17610/* 17611 * 2ch mode 17612 */ 17613static const struct hda_verb alc662_3ST_ch2_init[] = { 17614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 17615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17616 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 17617 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 17618 { } /* end */ 17619}; 17620 17621/* 17622 * 6ch mode 17623 */ 17624static const struct hda_verb alc662_3ST_ch6_init[] = { 17625 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17626 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17627 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, 17628 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17629 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 17630 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 17631 { } /* end */ 17632}; 17633 17634static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = { 17635 { 2, alc662_3ST_ch2_init }, 17636 { 6, alc662_3ST_ch6_init }, 17637}; 17638 17639/* 17640 * 2ch mode 17641 */ 17642static const struct hda_verb alc662_sixstack_ch6_init[] = { 17643 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17644 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, 17645 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17646 { } /* end */ 17647}; 17648 17649/* 17650 * 6ch mode 17651 */ 17652static const struct hda_verb alc662_sixstack_ch8_init[] = { 17653 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17654 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17655 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 17656 { } /* end */ 17657}; 17658 17659static const struct hda_channel_mode alc662_5stack_modes[2] = { 17660 { 2, alc662_sixstack_ch6_init }, 17661 { 6, alc662_sixstack_ch8_init }, 17662}; 17663 17664/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 17665 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 17666 */ 17667 17668static const struct snd_kcontrol_new alc662_base_mixer[] = { 17669 /* output mixer control */ 17670 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 17671 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17672 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), 17673 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17674 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17675 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17676 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17677 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17678 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17679 17680 /*Input mixer control */ 17681 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), 17682 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), 17683 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), 17684 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), 17685 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), 17686 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), 17687 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), 17688 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), 17689 { } /* end */ 17690}; 17691 17692static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { 17693 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17694 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17695 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17696 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17697 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17698 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17699 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17702 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17703 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17704 { } /* end */ 17705}; 17706 17707static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { 17708 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17709 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), 17710 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17711 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), 17712 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17713 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17714 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), 17715 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), 17716 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 17718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 17719 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17720 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17723 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17725 { } /* end */ 17726}; 17727 17728static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { 17729 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17730 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), 17731 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17732 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), 17733 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17737 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17738 { } /* end */ 17739}; 17740 17741static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { 17742 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17743 ALC262_HIPPO_MASTER_SWITCH, 17744 17745 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 17746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17748 17749 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 17750 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17751 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17752 { } /* end */ 17753}; 17754 17755static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { 17756 ALC262_HIPPO_MASTER_SWITCH, 17757 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17759 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), 17760 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), 17761 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), 17762 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17763 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17766 { } /* end */ 17767}; 17768 17769static const struct hda_bind_ctls alc663_asus_bind_master_vol = { 17770 .ops = &snd_hda_bind_vol, 17771 .values = { 17772 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17773 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), 17774 0 17775 }, 17776}; 17777 17778static const struct hda_bind_ctls alc663_asus_one_bind_switch = { 17779 .ops = &snd_hda_bind_sw, 17780 .values = { 17781 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17782 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17783 0 17784 }, 17785}; 17786 17787static const struct snd_kcontrol_new alc663_m51va_mixer[] = { 17788 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17789 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), 17790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17792 { } /* end */ 17793}; 17794 17795static const struct hda_bind_ctls alc663_asus_tree_bind_switch = { 17796 .ops = &snd_hda_bind_sw, 17797 .values = { 17798 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17799 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17800 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17801 0 17802 }, 17803}; 17804 17805static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { 17806 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17807 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), 17808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17810 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17811 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17812 17813 { } /* end */ 17814}; 17815 17816static const struct hda_bind_ctls alc663_asus_four_bind_switch = { 17817 .ops = &snd_hda_bind_sw, 17818 .values = { 17819 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17820 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17821 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17822 0 17823 }, 17824}; 17825 17826static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { 17827 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17828 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), 17829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17830 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17831 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17832 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17833 { } /* end */ 17834}; 17835 17836static const struct snd_kcontrol_new alc662_1bjd_mixer[] = { 17837 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17838 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17839 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17842 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17843 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17844 { } /* end */ 17845}; 17846 17847static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = { 17848 .ops = &snd_hda_bind_vol, 17849 .values = { 17850 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), 17851 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), 17852 0 17853 }, 17854}; 17855 17856static const struct hda_bind_ctls alc663_asus_two_bind_switch = { 17857 .ops = &snd_hda_bind_sw, 17858 .values = { 17859 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17860 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), 17861 0 17862 }, 17863}; 17864 17865static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { 17866 HDA_BIND_VOL("Master Playback Volume", 17867 &alc663_asus_two_bind_master_vol), 17868 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17869 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17873 { } /* end */ 17874}; 17875 17876static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { 17877 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), 17878 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), 17879 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17880 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17882 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17883 { } /* end */ 17884}; 17885 17886static const struct snd_kcontrol_new alc663_g71v_mixer[] = { 17887 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17888 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17889 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), 17890 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17891 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17892 17893 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17895 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17896 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17897 { } /* end */ 17898}; 17899 17900static const struct snd_kcontrol_new alc663_g50v_mixer[] = { 17901 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17902 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 17903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17904 17905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17907 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17908 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17911 { } /* end */ 17912}; 17913 17914static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { 17915 .ops = &snd_hda_bind_sw, 17916 .values = { 17917 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17918 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), 17919 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17920 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 17921 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 17922 0 17923 }, 17924}; 17925 17926static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { 17927 .ops = &snd_hda_bind_sw, 17928 .values = { 17929 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 17930 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), 17931 0 17932 }, 17933}; 17934 17935static const struct snd_kcontrol_new alc663_mode7_mixer[] = { 17936 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17937 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17938 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17939 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 17940 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17941 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17942 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17943 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17944 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17945 { } /* end */ 17946}; 17947 17948static const struct snd_kcontrol_new alc663_mode8_mixer[] = { 17949 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), 17950 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), 17951 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), 17952 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), 17953 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), 17954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17956 { } /* end */ 17957}; 17958 17959 17960static const struct snd_kcontrol_new alc662_chmode_mixer[] = { 17961 { 17962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 17963 .name = "Channel Mode", 17964 .info = alc_ch_mode_info, 17965 .get = alc_ch_mode_get, 17966 .put = alc_ch_mode_put, 17967 }, 17968 { } /* end */ 17969}; 17970 17971static const struct hda_verb alc662_init_verbs[] = { 17972 /* ADC: mute amp left and right */ 17973 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 17974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 17975 17976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17978 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17979 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17980 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 17981 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 17982 17983 /* Front Pin: output 0 (0x0c) */ 17984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17985 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17986 17987 /* Rear Pin: output 1 (0x0d) */ 17988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17990 17991 /* CLFE Pin: output 2 (0x0e) */ 17992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 17993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 17994 17995 /* Mic (rear) pin: input vref at 80% */ 17996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 17997 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 17998 /* Front Mic pin: input vref at 80% */ 17999 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 18000 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 18001 /* Line In pin: input */ 18002 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 18004 /* Line-2 In: Headphone output (output 0 - 0x0c) */ 18005 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18006 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18007 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 18008 /* CD pin widget for input */ 18009 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18010 18011 /* FIXME: use matrix-type input source selection */ 18012 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 18013 /* Input mixer */ 18014 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 18015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 18016 18017 { } 18018}; 18019 18020static const struct hda_verb alc662_eapd_init_verbs[] = { 18021 /* always trun on EAPD */ 18022 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 18023 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, 18024 { } 18025}; 18026 18027static const struct hda_verb alc662_sue_init_verbs[] = { 18028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 18029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 18030 {} 18031}; 18032 18033static const struct hda_verb alc662_eeepc_sue_init_verbs[] = { 18034 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18036 {} 18037}; 18038 18039/* Set Unsolicited Event*/ 18040static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { 18041 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18042 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18043 {} 18044}; 18045 18046static const struct hda_verb alc663_m51va_init_verbs[] = { 18047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18049 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18050 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18051 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18055 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18056 {} 18057}; 18058 18059static const struct hda_verb alc663_21jd_amic_init_verbs[] = { 18060 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18061 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18062 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18065 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18066 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18067 {} 18068}; 18069 18070static const struct hda_verb alc662_1bjd_amic_init_verbs[] = { 18071 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18072 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18073 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18074 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18077 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18078 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18079 {} 18080}; 18081 18082static const struct hda_verb alc663_15jd_amic_init_verbs[] = { 18083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18088 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18090 {} 18091}; 18092 18093static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { 18094 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18095 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18096 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18097 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18100 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ 18101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18103 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18105 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18106 {} 18107}; 18108 18109static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { 18110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18111 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18112 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18113 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18115 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 18119 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18120 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18121 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18122 {} 18123}; 18124 18125static const struct hda_verb alc663_g71v_init_verbs[] = { 18126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18127 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ 18128 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ 18129 18130 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18131 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18132 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18133 18134 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 18135 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT}, 18136 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 18137 {} 18138}; 18139 18140static const struct hda_verb alc663_g50v_init_verbs[] = { 18141 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18143 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ 18144 18145 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18146 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18147 {} 18148}; 18149 18150static const struct hda_verb alc662_ecs_init_verbs[] = { 18151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, 18152 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18153 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18154 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18155 {} 18156}; 18157 18158static const struct hda_verb alc272_dell_zm1_init_verbs[] = { 18159 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18160 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18161 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18163 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18164 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18165 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18168 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18169 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18170 {} 18171}; 18172 18173static const struct hda_verb alc272_dell_init_verbs[] = { 18174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18175 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18177 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18178 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18179 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18180 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18183 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18184 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18185 {} 18186}; 18187 18188static const struct hda_verb alc663_mode7_init_verbs[] = { 18189 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18190 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18191 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18192 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18195 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, 18196 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18197 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18198 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18199 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18201 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18202 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18203 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18204 {} 18205}; 18206 18207static const struct hda_verb alc663_mode8_init_verbs[] = { 18208 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 18212 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18213 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 18214 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 18216 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 18217 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 18218 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ 18219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 18220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, 18221 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18222 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 18223 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, 18224 {} 18225}; 18226 18227static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 18228 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 18229 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 18230 { } /* end */ 18231}; 18232 18233static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = { 18234 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 18235 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 18236 { } /* end */ 18237}; 18238 18239static void alc662_lenovo_101e_setup(struct hda_codec *codec) 18240{ 18241 struct alc_spec *spec = codec->spec; 18242 18243 spec->autocfg.hp_pins[0] = 0x1b; 18244 spec->autocfg.line_out_pins[0] = 0x14; 18245 spec->autocfg.speaker_pins[0] = 0x15; 18246 spec->automute = 1; 18247 spec->detect_line = 1; 18248 spec->automute_lines = 1; 18249 spec->automute_mode = ALC_AUTOMUTE_AMP; 18250} 18251 18252static void alc662_eeepc_setup(struct hda_codec *codec) 18253{ 18254 struct alc_spec *spec = codec->spec; 18255 18256 alc262_hippo1_setup(codec); 18257 spec->ext_mic.pin = 0x18; 18258 spec->ext_mic.mux_idx = 0; 18259 spec->int_mic.pin = 0x19; 18260 spec->int_mic.mux_idx = 1; 18261 spec->auto_mic = 1; 18262} 18263 18264static void alc662_eeepc_ep20_setup(struct hda_codec *codec) 18265{ 18266 struct alc_spec *spec = codec->spec; 18267 18268 spec->autocfg.hp_pins[0] = 0x14; 18269 spec->autocfg.speaker_pins[0] = 0x1b; 18270 spec->automute = 1; 18271 spec->automute_mode = ALC_AUTOMUTE_AMP; 18272} 18273 18274static void alc663_m51va_setup(struct hda_codec *codec) 18275{ 18276 struct alc_spec *spec = codec->spec; 18277 spec->autocfg.hp_pins[0] = 0x21; 18278 spec->autocfg.speaker_pins[0] = 0x14; 18279 spec->automute_mixer_nid[0] = 0x0c; 18280 spec->automute = 1; 18281 spec->automute_mode = ALC_AUTOMUTE_MIXER; 18282 spec->ext_mic.pin = 0x18; 18283 spec->ext_mic.mux_idx = 0; 18284 spec->int_mic.pin = 0x12; 18285 spec->int_mic.mux_idx = 9; 18286 spec->auto_mic = 1; 18287} 18288 18289/* ***************** Mode1 ******************************/ 18290static void alc663_mode1_setup(struct hda_codec *codec) 18291{ 18292 struct alc_spec *spec = codec->spec; 18293 spec->autocfg.hp_pins[0] = 0x21; 18294 spec->autocfg.speaker_pins[0] = 0x14; 18295 spec->automute_mixer_nid[0] = 0x0c; 18296 spec->automute = 1; 18297 spec->automute_mode = ALC_AUTOMUTE_MIXER; 18298 spec->ext_mic.pin = 0x18; 18299 spec->ext_mic.mux_idx = 0; 18300 spec->int_mic.pin = 0x19; 18301 spec->int_mic.mux_idx = 1; 18302 spec->auto_mic = 1; 18303} 18304 18305/* ***************** Mode2 ******************************/ 18306static void alc662_mode2_setup(struct hda_codec *codec) 18307{ 18308 struct alc_spec *spec = codec->spec; 18309 spec->autocfg.hp_pins[0] = 0x1b; 18310 spec->autocfg.speaker_pins[0] = 0x14; 18311 spec->automute = 1; 18312 spec->automute_mode = ALC_AUTOMUTE_PIN; 18313 spec->ext_mic.pin = 0x18; 18314 spec->ext_mic.mux_idx = 0; 18315 spec->int_mic.pin = 0x19; 18316 spec->int_mic.mux_idx = 1; 18317 spec->auto_mic = 1; 18318} 18319 18320/* ***************** Mode3 ******************************/ 18321static void alc663_mode3_setup(struct hda_codec *codec) 18322{ 18323 struct alc_spec *spec = codec->spec; 18324 spec->autocfg.hp_pins[0] = 0x21; 18325 spec->autocfg.hp_pins[0] = 0x15; 18326 spec->autocfg.speaker_pins[0] = 0x14; 18327 spec->automute = 1; 18328 spec->automute_mode = ALC_AUTOMUTE_PIN; 18329 spec->ext_mic.pin = 0x18; 18330 spec->ext_mic.mux_idx = 0; 18331 spec->int_mic.pin = 0x19; 18332 spec->int_mic.mux_idx = 1; 18333 spec->auto_mic = 1; 18334} 18335 18336/* ***************** Mode4 ******************************/ 18337static void alc663_mode4_setup(struct hda_codec *codec) 18338{ 18339 struct alc_spec *spec = codec->spec; 18340 spec->autocfg.hp_pins[0] = 0x21; 18341 spec->autocfg.speaker_pins[0] = 0x14; 18342 spec->autocfg.speaker_pins[1] = 0x16; 18343 spec->automute_mixer_nid[0] = 0x0c; 18344 spec->automute_mixer_nid[1] = 0x0e; 18345 spec->automute = 1; 18346 spec->automute_mode = ALC_AUTOMUTE_MIXER; 18347 spec->ext_mic.pin = 0x18; 18348 spec->ext_mic.mux_idx = 0; 18349 spec->int_mic.pin = 0x19; 18350 spec->int_mic.mux_idx = 1; 18351 spec->auto_mic = 1; 18352} 18353 18354/* ***************** Mode5 ******************************/ 18355static void alc663_mode5_setup(struct hda_codec *codec) 18356{ 18357 struct alc_spec *spec = codec->spec; 18358 spec->autocfg.hp_pins[0] = 0x15; 18359 spec->autocfg.speaker_pins[0] = 0x14; 18360 spec->autocfg.speaker_pins[1] = 0x16; 18361 spec->automute_mixer_nid[0] = 0x0c; 18362 spec->automute_mixer_nid[1] = 0x0e; 18363 spec->automute = 1; 18364 spec->automute_mode = ALC_AUTOMUTE_MIXER; 18365 spec->ext_mic.pin = 0x18; 18366 spec->ext_mic.mux_idx = 0; 18367 spec->int_mic.pin = 0x19; 18368 spec->int_mic.mux_idx = 1; 18369 spec->auto_mic = 1; 18370} 18371 18372/* ***************** Mode6 ******************************/ 18373static void alc663_mode6_setup(struct hda_codec *codec) 18374{ 18375 struct alc_spec *spec = codec->spec; 18376 spec->autocfg.hp_pins[0] = 0x1b; 18377 spec->autocfg.hp_pins[0] = 0x15; 18378 spec->autocfg.speaker_pins[0] = 0x14; 18379 spec->automute_mixer_nid[0] = 0x0c; 18380 spec->automute = 1; 18381 spec->automute_mode = ALC_AUTOMUTE_MIXER; 18382 spec->ext_mic.pin = 0x18; 18383 spec->ext_mic.mux_idx = 0; 18384 spec->int_mic.pin = 0x19; 18385 spec->int_mic.mux_idx = 1; 18386 spec->auto_mic = 1; 18387} 18388 18389/* ***************** Mode7 ******************************/ 18390static void alc663_mode7_setup(struct hda_codec *codec) 18391{ 18392 struct alc_spec *spec = codec->spec; 18393 spec->autocfg.hp_pins[0] = 0x1b; 18394 spec->autocfg.hp_pins[0] = 0x21; 18395 spec->autocfg.speaker_pins[0] = 0x14; 18396 spec->autocfg.speaker_pins[0] = 0x17; 18397 spec->automute = 1; 18398 spec->automute_mode = ALC_AUTOMUTE_PIN; 18399 spec->ext_mic.pin = 0x18; 18400 spec->ext_mic.mux_idx = 0; 18401 spec->int_mic.pin = 0x19; 18402 spec->int_mic.mux_idx = 1; 18403 spec->auto_mic = 1; 18404} 18405 18406/* ***************** Mode8 ******************************/ 18407static void alc663_mode8_setup(struct hda_codec *codec) 18408{ 18409 struct alc_spec *spec = codec->spec; 18410 spec->autocfg.hp_pins[0] = 0x21; 18411 spec->autocfg.hp_pins[1] = 0x15; 18412 spec->autocfg.speaker_pins[0] = 0x14; 18413 spec->autocfg.speaker_pins[0] = 0x17; 18414 spec->automute = 1; 18415 spec->automute_mode = ALC_AUTOMUTE_PIN; 18416 spec->ext_mic.pin = 0x18; 18417 spec->ext_mic.mux_idx = 0; 18418 spec->int_mic.pin = 0x12; 18419 spec->int_mic.mux_idx = 9; 18420 spec->auto_mic = 1; 18421} 18422 18423static void alc663_g71v_setup(struct hda_codec *codec) 18424{ 18425 struct alc_spec *spec = codec->spec; 18426 spec->autocfg.hp_pins[0] = 0x21; 18427 spec->autocfg.line_out_pins[0] = 0x15; 18428 spec->autocfg.speaker_pins[0] = 0x14; 18429 spec->automute = 1; 18430 spec->automute_mode = ALC_AUTOMUTE_AMP; 18431 spec->detect_line = 1; 18432 spec->automute_lines = 1; 18433 spec->ext_mic.pin = 0x18; 18434 spec->ext_mic.mux_idx = 0; 18435 spec->int_mic.pin = 0x12; 18436 spec->int_mic.mux_idx = 9; 18437 spec->auto_mic = 1; 18438} 18439 18440#define alc663_g50v_setup alc663_m51va_setup 18441 18442static const struct snd_kcontrol_new alc662_ecs_mixer[] = { 18443 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18444 ALC262_HIPPO_MASTER_SWITCH, 18445 18446 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT), 18447 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18448 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18449 18450 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18451 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18452 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18453 { } /* end */ 18454}; 18455 18456static const struct snd_kcontrol_new alc272_nc10_mixer[] = { 18457 /* Master Playback automatically created from Speaker and Headphone */ 18458 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18459 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 18460 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18462 18463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18465 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 18466 18467 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18468 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18469 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), 18470 { } /* end */ 18471}; 18472 18473#ifdef CONFIG_SND_HDA_POWER_SAVE 18474#define alc662_loopbacks alc880_loopbacks 18475#endif 18476 18477 18478/* pcm configuration: identical with ALC880 */ 18479#define alc662_pcm_analog_playback alc880_pcm_analog_playback 18480#define alc662_pcm_analog_capture alc880_pcm_analog_capture 18481#define alc662_pcm_digital_playback alc880_pcm_digital_playback 18482#define alc662_pcm_digital_capture alc880_pcm_digital_capture 18483 18484/* 18485 * configuration and preset 18486 */ 18487static const char * const alc662_models[ALC662_MODEL_LAST] = { 18488 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18489 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18490 [ALC662_3ST_6ch] = "3stack-6ch", 18491 [ALC662_5ST_DIG] = "5stack-dig", 18492 [ALC662_LENOVO_101E] = "lenovo-101e", 18493 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 18494 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", 18495 [ALC662_ECS] = "ecs", 18496 [ALC663_ASUS_M51VA] = "m51va", 18497 [ALC663_ASUS_G71V] = "g71v", 18498 [ALC663_ASUS_H13] = "h13", 18499 [ALC663_ASUS_G50V] = "g50v", 18500 [ALC663_ASUS_MODE1] = "asus-mode1", 18501 [ALC662_ASUS_MODE2] = "asus-mode2", 18502 [ALC663_ASUS_MODE3] = "asus-mode3", 18503 [ALC663_ASUS_MODE4] = "asus-mode4", 18504 [ALC663_ASUS_MODE5] = "asus-mode5", 18505 [ALC663_ASUS_MODE6] = "asus-mode6", 18506 [ALC663_ASUS_MODE7] = "asus-mode7", 18507 [ALC663_ASUS_MODE8] = "asus-mode8", 18508 [ALC272_DELL] = "dell", 18509 [ALC272_DELL_ZM1] = "dell-zm1", 18510 [ALC272_SAMSUNG_NC10] = "samsung-nc10", 18511 [ALC662_AUTO] = "auto", 18512}; 18513 18514static const struct snd_pci_quirk alc662_cfg_tbl[] = { 18515 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), 18516 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), 18517 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 18518 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 18519 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 18520 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), 18521 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 18522 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 18523 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 18524 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), 18525 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), 18526 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), 18527 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), 18528 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), 18529 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), 18530 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), 18531 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), 18532 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), 18533 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), 18534 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), 18535 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), 18536 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), 18537 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), 18538 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), 18539 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), 18540 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), 18541 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), 18542 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), 18543 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), 18544 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), 18545 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), 18546 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), 18547 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), 18548 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), 18549 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), 18550 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), 18551 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), 18552 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ 18553 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 18554 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 18555 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 18556 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), 18557 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 18558 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 18559 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 18560 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), 18561 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), 18562 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), 18563 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), 18564 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), 18565 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), 18566 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), 18567 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), 18568 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ 18569 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), 18570 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), 18571 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), 18572 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), 18573 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), 18574 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), 18575 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 18576 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), 18577 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 18578 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 18579 ALC662_3ST_6ch_DIG), 18580 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), 18581 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 18582 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 18583 ALC662_3ST_6ch_DIG), 18584 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), 18585 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 18586 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 18587 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 18588 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", 18589 ALC662_3ST_6ch_DIG), 18590 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", 18591 ALC663_ASUS_H13), 18592 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E), 18593 {} 18594}; 18595 18596static const struct alc_config_preset alc662_presets[] = { 18597 [ALC662_3ST_2ch_DIG] = { 18598 .mixers = { alc662_3ST_2ch_mixer }, 18599 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18600 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18601 .dac_nids = alc662_dac_nids, 18602 .dig_out_nid = ALC662_DIGOUT_NID, 18603 .dig_in_nid = ALC662_DIGIN_NID, 18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18605 .channel_mode = alc662_3ST_2ch_modes, 18606 .input_mux = &alc662_capture_source, 18607 }, 18608 [ALC662_3ST_6ch_DIG] = { 18609 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18610 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18611 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18612 .dac_nids = alc662_dac_nids, 18613 .dig_out_nid = ALC662_DIGOUT_NID, 18614 .dig_in_nid = ALC662_DIGIN_NID, 18615 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18616 .channel_mode = alc662_3ST_6ch_modes, 18617 .need_dac_fix = 1, 18618 .input_mux = &alc662_capture_source, 18619 }, 18620 [ALC662_3ST_6ch] = { 18621 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, 18622 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18623 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18624 .dac_nids = alc662_dac_nids, 18625 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18626 .channel_mode = alc662_3ST_6ch_modes, 18627 .need_dac_fix = 1, 18628 .input_mux = &alc662_capture_source, 18629 }, 18630 [ALC662_5ST_DIG] = { 18631 .mixers = { alc662_base_mixer, alc662_chmode_mixer }, 18632 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, 18633 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18634 .dac_nids = alc662_dac_nids, 18635 .dig_out_nid = ALC662_DIGOUT_NID, 18636 .dig_in_nid = ALC662_DIGIN_NID, 18637 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), 18638 .channel_mode = alc662_5stack_modes, 18639 .input_mux = &alc662_capture_source, 18640 }, 18641 [ALC662_LENOVO_101E] = { 18642 .mixers = { alc662_lenovo_101e_mixer }, 18643 .init_verbs = { alc662_init_verbs, 18644 alc662_eapd_init_verbs, 18645 alc662_sue_init_verbs }, 18646 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18647 .dac_nids = alc662_dac_nids, 18648 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18649 .channel_mode = alc662_3ST_2ch_modes, 18650 .input_mux = &alc662_lenovo_101e_capture_source, 18651 .unsol_event = alc_sku_unsol_event, 18652 .setup = alc662_lenovo_101e_setup, 18653 .init_hook = alc_inithook, 18654 }, 18655 [ALC662_ASUS_EEEPC_P701] = { 18656 .mixers = { alc662_eeepc_p701_mixer }, 18657 .init_verbs = { alc662_init_verbs, 18658 alc662_eapd_init_verbs, 18659 alc662_eeepc_sue_init_verbs }, 18660 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18661 .dac_nids = alc662_dac_nids, 18662 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18663 .channel_mode = alc662_3ST_2ch_modes, 18664 .unsol_event = alc_sku_unsol_event, 18665 .setup = alc662_eeepc_setup, 18666 .init_hook = alc_inithook, 18667 }, 18668 [ALC662_ASUS_EEEPC_EP20] = { 18669 .mixers = { alc662_eeepc_ep20_mixer, 18670 alc662_chmode_mixer }, 18671 .init_verbs = { alc662_init_verbs, 18672 alc662_eapd_init_verbs, 18673 alc662_eeepc_ep20_sue_init_verbs }, 18674 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18675 .dac_nids = alc662_dac_nids, 18676 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18677 .channel_mode = alc662_3ST_6ch_modes, 18678 .input_mux = &alc662_lenovo_101e_capture_source, 18679 .unsol_event = alc_sku_unsol_event, 18680 .setup = alc662_eeepc_ep20_setup, 18681 .init_hook = alc_inithook, 18682 }, 18683 [ALC662_ECS] = { 18684 .mixers = { alc662_ecs_mixer }, 18685 .init_verbs = { alc662_init_verbs, 18686 alc662_eapd_init_verbs, 18687 alc662_ecs_init_verbs }, 18688 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18689 .dac_nids = alc662_dac_nids, 18690 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18691 .channel_mode = alc662_3ST_2ch_modes, 18692 .unsol_event = alc_sku_unsol_event, 18693 .setup = alc662_eeepc_setup, 18694 .init_hook = alc_inithook, 18695 }, 18696 [ALC663_ASUS_M51VA] = { 18697 .mixers = { alc663_m51va_mixer }, 18698 .init_verbs = { alc662_init_verbs, 18699 alc662_eapd_init_verbs, 18700 alc663_m51va_init_verbs }, 18701 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18702 .dac_nids = alc662_dac_nids, 18703 .dig_out_nid = ALC662_DIGOUT_NID, 18704 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18705 .channel_mode = alc662_3ST_2ch_modes, 18706 .unsol_event = alc_sku_unsol_event, 18707 .setup = alc663_m51va_setup, 18708 .init_hook = alc_inithook, 18709 }, 18710 [ALC663_ASUS_G71V] = { 18711 .mixers = { alc663_g71v_mixer }, 18712 .init_verbs = { alc662_init_verbs, 18713 alc662_eapd_init_verbs, 18714 alc663_g71v_init_verbs }, 18715 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18716 .dac_nids = alc662_dac_nids, 18717 .dig_out_nid = ALC662_DIGOUT_NID, 18718 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18719 .channel_mode = alc662_3ST_2ch_modes, 18720 .unsol_event = alc_sku_unsol_event, 18721 .setup = alc663_g71v_setup, 18722 .init_hook = alc_inithook, 18723 }, 18724 [ALC663_ASUS_H13] = { 18725 .mixers = { alc663_m51va_mixer }, 18726 .init_verbs = { alc662_init_verbs, 18727 alc662_eapd_init_verbs, 18728 alc663_m51va_init_verbs }, 18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18730 .dac_nids = alc662_dac_nids, 18731 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18732 .channel_mode = alc662_3ST_2ch_modes, 18733 .setup = alc663_m51va_setup, 18734 .unsol_event = alc_sku_unsol_event, 18735 .init_hook = alc_inithook, 18736 }, 18737 [ALC663_ASUS_G50V] = { 18738 .mixers = { alc663_g50v_mixer }, 18739 .init_verbs = { alc662_init_verbs, 18740 alc662_eapd_init_verbs, 18741 alc663_g50v_init_verbs }, 18742 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18743 .dac_nids = alc662_dac_nids, 18744 .dig_out_nid = ALC662_DIGOUT_NID, 18745 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), 18746 .channel_mode = alc662_3ST_6ch_modes, 18747 .input_mux = &alc663_capture_source, 18748 .unsol_event = alc_sku_unsol_event, 18749 .setup = alc663_g50v_setup, 18750 .init_hook = alc_inithook, 18751 }, 18752 [ALC663_ASUS_MODE1] = { 18753 .mixers = { alc663_m51va_mixer }, 18754 .cap_mixer = alc662_auto_capture_mixer, 18755 .init_verbs = { alc662_init_verbs, 18756 alc662_eapd_init_verbs, 18757 alc663_21jd_amic_init_verbs }, 18758 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18759 .hp_nid = 0x03, 18760 .dac_nids = alc662_dac_nids, 18761 .dig_out_nid = ALC662_DIGOUT_NID, 18762 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18763 .channel_mode = alc662_3ST_2ch_modes, 18764 .unsol_event = alc_sku_unsol_event, 18765 .setup = alc663_mode1_setup, 18766 .init_hook = alc_inithook, 18767 }, 18768 [ALC662_ASUS_MODE2] = { 18769 .mixers = { alc662_1bjd_mixer }, 18770 .cap_mixer = alc662_auto_capture_mixer, 18771 .init_verbs = { alc662_init_verbs, 18772 alc662_eapd_init_verbs, 18773 alc662_1bjd_amic_init_verbs }, 18774 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18775 .dac_nids = alc662_dac_nids, 18776 .dig_out_nid = ALC662_DIGOUT_NID, 18777 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18778 .channel_mode = alc662_3ST_2ch_modes, 18779 .unsol_event = alc_sku_unsol_event, 18780 .setup = alc662_mode2_setup, 18781 .init_hook = alc_inithook, 18782 }, 18783 [ALC663_ASUS_MODE3] = { 18784 .mixers = { alc663_two_hp_m1_mixer }, 18785 .cap_mixer = alc662_auto_capture_mixer, 18786 .init_verbs = { alc662_init_verbs, 18787 alc662_eapd_init_verbs, 18788 alc663_two_hp_amic_m1_init_verbs }, 18789 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18790 .hp_nid = 0x03, 18791 .dac_nids = alc662_dac_nids, 18792 .dig_out_nid = ALC662_DIGOUT_NID, 18793 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18794 .channel_mode = alc662_3ST_2ch_modes, 18795 .unsol_event = alc_sku_unsol_event, 18796 .setup = alc663_mode3_setup, 18797 .init_hook = alc_inithook, 18798 }, 18799 [ALC663_ASUS_MODE4] = { 18800 .mixers = { alc663_asus_21jd_clfe_mixer }, 18801 .cap_mixer = alc662_auto_capture_mixer, 18802 .init_verbs = { alc662_init_verbs, 18803 alc662_eapd_init_verbs, 18804 alc663_21jd_amic_init_verbs}, 18805 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18806 .hp_nid = 0x03, 18807 .dac_nids = alc662_dac_nids, 18808 .dig_out_nid = ALC662_DIGOUT_NID, 18809 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18810 .channel_mode = alc662_3ST_2ch_modes, 18811 .unsol_event = alc_sku_unsol_event, 18812 .setup = alc663_mode4_setup, 18813 .init_hook = alc_inithook, 18814 }, 18815 [ALC663_ASUS_MODE5] = { 18816 .mixers = { alc663_asus_15jd_clfe_mixer }, 18817 .cap_mixer = alc662_auto_capture_mixer, 18818 .init_verbs = { alc662_init_verbs, 18819 alc662_eapd_init_verbs, 18820 alc663_15jd_amic_init_verbs }, 18821 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18822 .hp_nid = 0x03, 18823 .dac_nids = alc662_dac_nids, 18824 .dig_out_nid = ALC662_DIGOUT_NID, 18825 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18826 .channel_mode = alc662_3ST_2ch_modes, 18827 .unsol_event = alc_sku_unsol_event, 18828 .setup = alc663_mode5_setup, 18829 .init_hook = alc_inithook, 18830 }, 18831 [ALC663_ASUS_MODE6] = { 18832 .mixers = { alc663_two_hp_m2_mixer }, 18833 .cap_mixer = alc662_auto_capture_mixer, 18834 .init_verbs = { alc662_init_verbs, 18835 alc662_eapd_init_verbs, 18836 alc663_two_hp_amic_m2_init_verbs }, 18837 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18838 .hp_nid = 0x03, 18839 .dac_nids = alc662_dac_nids, 18840 .dig_out_nid = ALC662_DIGOUT_NID, 18841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18842 .channel_mode = alc662_3ST_2ch_modes, 18843 .unsol_event = alc_sku_unsol_event, 18844 .setup = alc663_mode6_setup, 18845 .init_hook = alc_inithook, 18846 }, 18847 [ALC663_ASUS_MODE7] = { 18848 .mixers = { alc663_mode7_mixer }, 18849 .cap_mixer = alc662_auto_capture_mixer, 18850 .init_verbs = { alc662_init_verbs, 18851 alc662_eapd_init_verbs, 18852 alc663_mode7_init_verbs }, 18853 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18854 .hp_nid = 0x03, 18855 .dac_nids = alc662_dac_nids, 18856 .dig_out_nid = ALC662_DIGOUT_NID, 18857 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18858 .channel_mode = alc662_3ST_2ch_modes, 18859 .unsol_event = alc_sku_unsol_event, 18860 .setup = alc663_mode7_setup, 18861 .init_hook = alc_inithook, 18862 }, 18863 [ALC663_ASUS_MODE8] = { 18864 .mixers = { alc663_mode8_mixer }, 18865 .cap_mixer = alc662_auto_capture_mixer, 18866 .init_verbs = { alc662_init_verbs, 18867 alc662_eapd_init_verbs, 18868 alc663_mode8_init_verbs }, 18869 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 18870 .hp_nid = 0x03, 18871 .dac_nids = alc662_dac_nids, 18872 .dig_out_nid = ALC662_DIGOUT_NID, 18873 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18874 .channel_mode = alc662_3ST_2ch_modes, 18875 .unsol_event = alc_sku_unsol_event, 18876 .setup = alc663_mode8_setup, 18877 .init_hook = alc_inithook, 18878 }, 18879 [ALC272_DELL] = { 18880 .mixers = { alc663_m51va_mixer }, 18881 .cap_mixer = alc272_auto_capture_mixer, 18882 .init_verbs = { alc662_init_verbs, 18883 alc662_eapd_init_verbs, 18884 alc272_dell_init_verbs }, 18885 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18886 .dac_nids = alc272_dac_nids, 18887 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18888 .adc_nids = alc272_adc_nids, 18889 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 18890 .capsrc_nids = alc272_capsrc_nids, 18891 .channel_mode = alc662_3ST_2ch_modes, 18892 .unsol_event = alc_sku_unsol_event, 18893 .setup = alc663_m51va_setup, 18894 .init_hook = alc_inithook, 18895 }, 18896 [ALC272_DELL_ZM1] = { 18897 .mixers = { alc663_m51va_mixer }, 18898 .cap_mixer = alc662_auto_capture_mixer, 18899 .init_verbs = { alc662_init_verbs, 18900 alc662_eapd_init_verbs, 18901 alc272_dell_zm1_init_verbs }, 18902 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18903 .dac_nids = alc272_dac_nids, 18904 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18905 .adc_nids = alc662_adc_nids, 18906 .num_adc_nids = 1, 18907 .capsrc_nids = alc662_capsrc_nids, 18908 .channel_mode = alc662_3ST_2ch_modes, 18909 .unsol_event = alc_sku_unsol_event, 18910 .setup = alc663_m51va_setup, 18911 .init_hook = alc_inithook, 18912 }, 18913 [ALC272_SAMSUNG_NC10] = { 18914 .mixers = { alc272_nc10_mixer }, 18915 .init_verbs = { alc662_init_verbs, 18916 alc662_eapd_init_verbs, 18917 alc663_21jd_amic_init_verbs }, 18918 .num_dacs = ARRAY_SIZE(alc272_dac_nids), 18919 .dac_nids = alc272_dac_nids, 18920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 18921 .channel_mode = alc662_3ST_2ch_modes, 18922 /*.input_mux = &alc272_nc10_capture_source,*/ 18923 .unsol_event = alc_sku_unsol_event, 18924 .setup = alc663_mode4_setup, 18925 .init_hook = alc_inithook, 18926 }, 18927}; 18928 18929 18930/* 18931 * BIOS auto configuration 18932 */ 18933 18934/* convert from MIX nid to DAC */ 18935static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) 18936{ 18937 hda_nid_t list[5]; 18938 int i, num; 18939 18940 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); 18941 for (i = 0; i < num; i++) { 18942 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) 18943 return list[i]; 18944 } 18945 return 0; 18946} 18947 18948/* go down to the selector widget before the mixer */ 18949static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) 18950{ 18951 hda_nid_t srcs[5]; 18952 int num = snd_hda_get_connections(codec, pin, srcs, 18953 ARRAY_SIZE(srcs)); 18954 if (num != 1 || 18955 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) 18956 return pin; 18957 return srcs[0]; 18958} 18959 18960/* get MIX nid connected to the given pin targeted to DAC */ 18961static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, 18962 hda_nid_t dac) 18963{ 18964 hda_nid_t mix[5]; 18965 int i, num; 18966 18967 pin = alc_go_down_to_selector(codec, pin); 18968 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18969 for (i = 0; i < num; i++) { 18970 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) 18971 return mix[i]; 18972 } 18973 return 0; 18974} 18975 18976/* select the connection from pin to DAC if needed */ 18977static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, 18978 hda_nid_t dac) 18979{ 18980 hda_nid_t mix[5]; 18981 int i, num; 18982 18983 pin = alc_go_down_to_selector(codec, pin); 18984 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); 18985 if (num < 2) 18986 return 0; 18987 for (i = 0; i < num; i++) { 18988 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { 18989 snd_hda_codec_update_cache(codec, pin, 0, 18990 AC_VERB_SET_CONNECT_SEL, i); 18991 return 0; 18992 } 18993 } 18994 return 0; 18995} 18996 18997/* look for an empty DAC slot */ 18998static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 18999{ 19000 struct alc_spec *spec = codec->spec; 19001 hda_nid_t srcs[5]; 19002 int i, j, num; 19003 19004 pin = alc_go_down_to_selector(codec, pin); 19005 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 19006 for (i = 0; i < num; i++) { 19007 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); 19008 if (!nid) 19009 continue; 19010 for (j = 0; j < spec->multiout.num_dacs; j++) 19011 if (spec->multiout.dac_nids[j] == nid) 19012 break; 19013 if (j >= spec->multiout.num_dacs) 19014 return nid; 19015 } 19016 return 0; 19017} 19018 19019/* fill in the dac_nids table from the parsed pin configuration */ 19020static int alc662_auto_fill_dac_nids(struct hda_codec *codec, 19021 const struct auto_pin_cfg *cfg) 19022{ 19023 struct alc_spec *spec = codec->spec; 19024 int i; 19025 hda_nid_t dac; 19026 19027 spec->multiout.dac_nids = spec->private_dac_nids; 19028 for (i = 0; i < cfg->line_outs; i++) { 19029 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]); 19030 if (!dac) 19031 continue; 19032 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 19033 } 19034 return 0; 19035} 19036 19037static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19038 hda_nid_t nid, int idx, unsigned int chs) 19039{ 19040 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, 19041 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19042} 19043 19044static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19045 hda_nid_t nid, int idx, unsigned int chs) 19046{ 19047 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, 19048 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19049} 19050 19051#define alc662_add_vol_ctl(spec, pfx, nid, chs) \ 19052 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs) 19053#define alc662_add_sw_ctl(spec, pfx, nid, chs) \ 19054 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs) 19055#define alc662_add_stereo_vol(spec, pfx, nid) \ 19056 alc662_add_vol_ctl(spec, pfx, nid, 3) 19057#define alc662_add_stereo_sw(spec, pfx, nid) \ 19058 alc662_add_sw_ctl(spec, pfx, nid, 3) 19059 19060/* add playback controls from the parsed DAC table */ 19061static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, 19062 const struct auto_pin_cfg *cfg) 19063{ 19064 struct alc_spec *spec = codec->spec; 19065 static const char * const chname[4] = { 19066 "Front", "Surround", NULL /*CLFE*/, "Side" 19067 }; 19068 const char *pfx = alc_get_line_out_pfx(spec, true); 19069 hda_nid_t nid, mix, pin; 19070 int i, err, noutputs; 19071 19072 noutputs = cfg->line_outs; 19073 if (spec->multi_ios > 0) 19074 noutputs += spec->multi_ios; 19075 19076 for (i = 0; i < noutputs; i++) { 19077 nid = spec->multiout.dac_nids[i]; 19078 if (!nid) 19079 continue; 19080 if (i >= cfg->line_outs) 19081 pin = spec->multi_io[i - 1].pin; 19082 else 19083 pin = cfg->line_out_pins[i]; 19084 mix = alc_auto_dac_to_mix(codec, pin, nid); 19085 if (!mix) 19086 continue; 19087 if (!pfx && i == 2) { 19088 /* Center/LFE */ 19089 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19090 if (err < 0) 19091 return err; 19092 err = alc662_add_vol_ctl(spec, "LFE", nid, 2); 19093 if (err < 0) 19094 return err; 19095 err = alc662_add_sw_ctl(spec, "Center", mix, 1); 19096 if (err < 0) 19097 return err; 19098 err = alc662_add_sw_ctl(spec, "LFE", mix, 2); 19099 if (err < 0) 19100 return err; 19101 } else { 19102 const char *name = pfx; 19103 int index = i; 19104 if (!name) { 19105 name = chname[i]; 19106 index = 0; 19107 } 19108 err = __alc662_add_vol_ctl(spec, name, nid, index, 3); 19109 if (err < 0) 19110 return err; 19111 err = __alc662_add_sw_ctl(spec, name, mix, index, 3); 19112 if (err < 0) 19113 return err; 19114 } 19115 } 19116 return 0; 19117} 19118 19119/* add playback controls for speaker and HP outputs */ 19120/* return DAC nid if any new DAC is assigned */ 19121static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 19122 const char *pfx) 19123{ 19124 struct alc_spec *spec = codec->spec; 19125 hda_nid_t nid, mix; 19126 int err; 19127 19128 if (!pin) 19129 return 0; 19130 nid = alc_auto_look_for_dac(codec, pin); 19131 if (!nid) { 19132 /* the corresponding DAC is already occupied */ 19133 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) 19134 return 0; /* no way */ 19135 /* create a switch only */ 19136 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19137 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 19138 } 19139 19140 mix = alc_auto_dac_to_mix(codec, pin, nid); 19141 if (!mix) 19142 return 0; 19143 err = alc662_add_vol_ctl(spec, pfx, nid, 3); 19144 if (err < 0) 19145 return err; 19146 err = alc662_add_sw_ctl(spec, pfx, mix, 3); 19147 if (err < 0) 19148 return err; 19149 return nid; 19150} 19151 19152/* create playback/capture controls for input pins */ 19153#define alc662_auto_create_input_ctls \ 19154 alc882_auto_create_input_ctls 19155 19156static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 19157 hda_nid_t nid, int pin_type, 19158 hda_nid_t dac) 19159{ 19160 int i, num; 19161 hda_nid_t srcs[HDA_MAX_CONNECTIONS]; 19162 19163 alc_set_pin_output(codec, nid, pin_type); 19164 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); 19165 for (i = 0; i < num; i++) { 19166 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) 19167 continue; 19168 /* need the manual connection? */ 19169 if (num > 1) 19170 snd_hda_codec_write(codec, nid, 0, 19171 AC_VERB_SET_CONNECT_SEL, i); 19172 /* unmute mixer widget inputs */ 19173 snd_hda_codec_write(codec, srcs[i], 0, 19174 AC_VERB_SET_AMP_GAIN_MUTE, 19175 AMP_IN_UNMUTE(0)); 19176 snd_hda_codec_write(codec, srcs[i], 0, 19177 AC_VERB_SET_AMP_GAIN_MUTE, 19178 AMP_IN_UNMUTE(1)); 19179 return; 19180 } 19181} 19182 19183static void alc662_auto_init_multi_out(struct hda_codec *codec) 19184{ 19185 struct alc_spec *spec = codec->spec; 19186 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19187 int i; 19188 19189 for (i = 0; i <= HDA_SIDE; i++) { 19190 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 19191 if (nid) 19192 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 19193 spec->multiout.dac_nids[i]); 19194 } 19195} 19196 19197static void alc662_auto_init_hp_out(struct hda_codec *codec) 19198{ 19199 struct alc_spec *spec = codec->spec; 19200 hda_nid_t pin; 19201 19202 pin = spec->autocfg.hp_pins[0]; 19203 if (pin) 19204 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 19205 spec->multiout.hp_nid); 19206 pin = spec->autocfg.speaker_pins[0]; 19207 if (pin) 19208 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 19209 spec->multiout.extra_out_nid[0]); 19210} 19211 19212#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 19213 19214static void alc662_auto_init_analog_input(struct hda_codec *codec) 19215{ 19216 struct alc_spec *spec = codec->spec; 19217 struct auto_pin_cfg *cfg = &spec->autocfg; 19218 int i; 19219 19220 for (i = 0; i < cfg->num_inputs; i++) { 19221 hda_nid_t nid = cfg->inputs[i].pin; 19222 if (alc_is_input_pin(codec, nid)) { 19223 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 19224 if (nid != ALC662_PIN_CD_NID && 19225 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 19226 snd_hda_codec_write(codec, nid, 0, 19227 AC_VERB_SET_AMP_GAIN_MUTE, 19228 AMP_OUT_MUTE); 19229 } 19230 } 19231} 19232 19233#define alc662_auto_init_input_src alc882_auto_init_input_src 19234 19235/* 19236 * multi-io helper 19237 */ 19238static int alc_auto_fill_multi_ios(struct hda_codec *codec, 19239 unsigned int location) 19240{ 19241 struct alc_spec *spec = codec->spec; 19242 struct auto_pin_cfg *cfg = &spec->autocfg; 19243 int type, i, num_pins = 0; 19244 19245 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { 19246 for (i = 0; i < cfg->num_inputs; i++) { 19247 hda_nid_t nid = cfg->inputs[i].pin; 19248 hda_nid_t dac; 19249 unsigned int defcfg, caps; 19250 if (cfg->inputs[i].type != type) 19251 continue; 19252 defcfg = snd_hda_codec_get_pincfg(codec, nid); 19253 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) 19254 continue; 19255 if (location && get_defcfg_location(defcfg) != location) 19256 continue; 19257 caps = snd_hda_query_pin_caps(codec, nid); 19258 if (!(caps & AC_PINCAP_OUT)) 19259 continue; 19260 dac = alc_auto_look_for_dac(codec, nid); 19261 if (!dac) 19262 continue; 19263 spec->multi_io[num_pins].pin = nid; 19264 spec->multi_io[num_pins].dac = dac; 19265 num_pins++; 19266 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 19267 } 19268 } 19269 spec->multiout.num_dacs = 1; 19270 if (num_pins < 2) 19271 return 0; 19272 return num_pins; 19273} 19274 19275static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, 19276 struct snd_ctl_elem_info *uinfo) 19277{ 19278 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 19279 struct alc_spec *spec = codec->spec; 19280 19281 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 19282 uinfo->count = 1; 19283 uinfo->value.enumerated.items = spec->multi_ios + 1; 19284 if (uinfo->value.enumerated.item > spec->multi_ios) 19285 uinfo->value.enumerated.item = spec->multi_ios; 19286 sprintf(uinfo->value.enumerated.name, "%dch", 19287 (uinfo->value.enumerated.item + 1) * 2); 19288 return 0; 19289} 19290 19291static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, 19292 struct snd_ctl_elem_value *ucontrol) 19293{ 19294 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 19295 struct alc_spec *spec = codec->spec; 19296 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; 19297 return 0; 19298} 19299 19300static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) 19301{ 19302 struct alc_spec *spec = codec->spec; 19303 hda_nid_t nid = spec->multi_io[idx].pin; 19304 19305 if (!spec->multi_io[idx].ctl_in) 19306 spec->multi_io[idx].ctl_in = 19307 snd_hda_codec_read(codec, nid, 0, 19308 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 19309 if (output) { 19310 snd_hda_codec_update_cache(codec, nid, 0, 19311 AC_VERB_SET_PIN_WIDGET_CONTROL, 19312 PIN_OUT); 19313 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 19314 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 19315 HDA_AMP_MUTE, 0); 19316 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); 19317 } else { 19318 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) 19319 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 19320 HDA_AMP_MUTE, HDA_AMP_MUTE); 19321 snd_hda_codec_update_cache(codec, nid, 0, 19322 AC_VERB_SET_PIN_WIDGET_CONTROL, 19323 spec->multi_io[idx].ctl_in); 19324 } 19325 return 0; 19326} 19327 19328static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, 19329 struct snd_ctl_elem_value *ucontrol) 19330{ 19331 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 19332 struct alc_spec *spec = codec->spec; 19333 int i, ch; 19334 19335 ch = ucontrol->value.enumerated.item[0]; 19336 if (ch < 0 || ch > spec->multi_ios) 19337 return -EINVAL; 19338 if (ch == (spec->ext_channel_count - 1) / 2) 19339 return 0; 19340 spec->ext_channel_count = (ch + 1) * 2; 19341 for (i = 0; i < spec->multi_ios; i++) 19342 alc_set_multi_io(codec, i, i < ch); 19343 spec->multiout.max_channels = spec->ext_channel_count; 19344 return 1; 19345} 19346 19347static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { 19348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 19349 .name = "Channel Mode", 19350 .info = alc_auto_ch_mode_info, 19351 .get = alc_auto_ch_mode_get, 19352 .put = alc_auto_ch_mode_put, 19353}; 19354 19355static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) 19356{ 19357 struct alc_spec *spec = codec->spec; 19358 struct auto_pin_cfg *cfg = &spec->autocfg; 19359 unsigned int location, defcfg; 19360 int num_pins; 19361 19362 if (cfg->line_outs != 1 || 19363 cfg->line_out_type != AUTO_PIN_LINE_OUT) 19364 return 0; 19365 19366 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); 19367 location = get_defcfg_location(defcfg); 19368 19369 num_pins = alc_auto_fill_multi_ios(codec, location); 19370 if (num_pins > 0) { 19371 struct snd_kcontrol_new *knew; 19372 19373 knew = alc_kcontrol_new(spec); 19374 if (!knew) 19375 return -ENOMEM; 19376 *knew = alc_auto_channel_mode_enum; 19377 knew->name = kstrdup("Channel Mode", GFP_KERNEL); 19378 if (!knew->name) 19379 return -ENOMEM; 19380 19381 spec->multi_ios = num_pins; 19382 spec->ext_channel_count = 2; 19383 spec->multiout.num_dacs = num_pins + 1; 19384 } 19385 return 0; 19386} 19387 19388static int alc662_parse_auto_config(struct hda_codec *codec) 19389{ 19390 struct alc_spec *spec = codec->spec; 19391 int err; 19392 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 19393 19394 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19395 alc662_ignore); 19396 if (err < 0) 19397 return err; 19398 if (!spec->autocfg.line_outs) 19399 return 0; /* can't find valid BIOS pin config */ 19400 19401 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); 19402 if (err < 0) 19403 return err; 19404 err = alc_auto_add_multi_channel_mode(codec); 19405 if (err < 0) 19406 return err; 19407 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); 19408 if (err < 0) 19409 return err; 19410 err = alc662_auto_create_extra_out(codec, 19411 spec->autocfg.speaker_pins[0], 19412 "Speaker"); 19413 if (err < 0) 19414 return err; 19415 if (err) 19416 spec->multiout.extra_out_nid[0] = err; 19417 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], 19418 "Headphone"); 19419 if (err < 0) 19420 return err; 19421 if (err) 19422 spec->multiout.hp_nid = err; 19423 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 19424 if (err < 0) 19425 return err; 19426 19427 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 19428 19429 alc_auto_parse_digital(codec); 19430 19431 if (spec->kctls.list) 19432 add_mixer(spec, spec->kctls.list); 19433 19434 spec->num_mux_defs = 1; 19435 spec->input_mux = &spec->private_imux[0]; 19436 19437 err = alc_auto_add_mic_boost(codec); 19438 if (err < 0) 19439 return err; 19440 19441 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 19442 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 19443 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 19444 else 19445 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 19446 19447 return 1; 19448} 19449 19450/* additional initialization for auto-configuration model */ 19451static void alc662_auto_init(struct hda_codec *codec) 19452{ 19453 struct alc_spec *spec = codec->spec; 19454 alc662_auto_init_multi_out(codec); 19455 alc662_auto_init_hp_out(codec); 19456 alc662_auto_init_analog_input(codec); 19457 alc662_auto_init_input_src(codec); 19458 alc_auto_init_digital(codec); 19459 if (spec->unsol_event) 19460 alc_inithook(codec); 19461} 19462 19463static void alc272_fixup_mario(struct hda_codec *codec, 19464 const struct alc_fixup *fix, int action) 19465{ 19466 if (action != ALC_FIXUP_ACT_PROBE) 19467 return; 19468 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, 19469 (0x3b << AC_AMPCAP_OFFSET_SHIFT) | 19470 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | 19471 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | 19472 (0 << AC_AMPCAP_MUTE_SHIFT))) 19473 printk(KERN_WARNING 19474 "hda_codec: failed to override amp caps for NID 0x2\n"); 19475} 19476 19477enum { 19478 ALC662_FIXUP_ASPIRE, 19479 ALC662_FIXUP_IDEAPAD, 19480 ALC272_FIXUP_MARIO, 19481 ALC662_FIXUP_CZC_P10T, 19482 ALC662_FIXUP_SKU_IGNORE, 19483}; 19484 19485static const struct alc_fixup alc662_fixups[] = { 19486 [ALC662_FIXUP_ASPIRE] = { 19487 .type = ALC_FIXUP_PINS, 19488 .v.pins = (const struct alc_pincfg[]) { 19489 { 0x15, 0x99130112 }, /* subwoofer */ 19490 { } 19491 } 19492 }, 19493 [ALC662_FIXUP_IDEAPAD] = { 19494 .type = ALC_FIXUP_PINS, 19495 .v.pins = (const struct alc_pincfg[]) { 19496 { 0x17, 0x99130112 }, /* subwoofer */ 19497 { } 19498 } 19499 }, 19500 [ALC272_FIXUP_MARIO] = { 19501 .type = ALC_FIXUP_FUNC, 19502 .v.func = alc272_fixup_mario, 19503 }, 19504 [ALC662_FIXUP_CZC_P10T] = { 19505 .type = ALC_FIXUP_VERBS, 19506 .v.verbs = (const struct hda_verb[]) { 19507 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, 19508 {} 19509 } 19510 }, 19511 [ALC662_FIXUP_SKU_IGNORE] = { 19512 .type = ALC_FIXUP_SKU, 19513 .v.sku = ALC_FIXUP_SKU_IGNORE, 19514 }, 19515}; 19516 19517static const struct snd_pci_quirk alc662_fixup_tbl[] = { 19518 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 19519 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 19520 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 19521 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 19522 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 19523 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 19524 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), 19525 {} 19526}; 19527 19528static const struct alc_model_fixup alc662_fixup_models[] = { 19529 {.id = ALC272_FIXUP_MARIO, .name = "mario"}, 19530 {} 19531}; 19532 19533 19534static int patch_alc662(struct hda_codec *codec) 19535{ 19536 struct alc_spec *spec; 19537 int err, board_config; 19538 int coef; 19539 19540 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 19541 if (!spec) 19542 return -ENOMEM; 19543 19544 codec->spec = spec; 19545 19546 alc_auto_parse_customize_define(codec); 19547 19548 alc_fix_pll_init(codec, 0x20, 0x04, 15); 19549 19550 coef = alc_read_coef_idx(codec, 0); 19551 if (coef == 0x8020 || coef == 0x8011) 19552 alc_codec_rename(codec, "ALC661"); 19553 else if (coef & (1 << 14) && 19554 codec->bus->pci->subsystem_vendor == 0x1025 && 19555 spec->cdefine.platform_type == 1) 19556 alc_codec_rename(codec, "ALC272X"); 19557 else if (coef == 0x4011) 19558 alc_codec_rename(codec, "ALC656"); 19559 19560 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 19561 alc662_models, 19562 alc662_cfg_tbl); 19563 if (board_config < 0) { 19564 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 19565 codec->chip_name); 19566 board_config = ALC662_AUTO; 19567 } 19568 19569 if (board_config == ALC662_AUTO) { 19570 alc_pick_fixup(codec, alc662_fixup_models, 19571 alc662_fixup_tbl, alc662_fixups); 19572 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 19573 /* automatic parse from the BIOS config */ 19574 err = alc662_parse_auto_config(codec); 19575 if (err < 0) { 19576 alc_free(codec); 19577 return err; 19578 } else if (!err) { 19579 printk(KERN_INFO 19580 "hda_codec: Cannot set up configuration " 19581 "from BIOS. Using base mode...\n"); 19582 board_config = ALC662_3ST_2ch_DIG; 19583 } 19584 } 19585 19586 if (has_cdefine_beep(codec)) { 19587 err = snd_hda_attach_beep_device(codec, 0x1); 19588 if (err < 0) { 19589 alc_free(codec); 19590 return err; 19591 } 19592 } 19593 19594 if (board_config != ALC662_AUTO) 19595 setup_preset(codec, &alc662_presets[board_config]); 19596 19597 spec->stream_analog_playback = &alc662_pcm_analog_playback; 19598 spec->stream_analog_capture = &alc662_pcm_analog_capture; 19599 19600 spec->stream_digital_playback = &alc662_pcm_digital_playback; 19601 spec->stream_digital_capture = &alc662_pcm_digital_capture; 19602 19603 if (!spec->adc_nids) { 19604 spec->adc_nids = alc662_adc_nids; 19605 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 19606 } 19607 if (!spec->capsrc_nids) 19608 spec->capsrc_nids = alc662_capsrc_nids; 19609 19610 if (!spec->cap_mixer) 19611 set_capture_mixer(codec); 19612 19613 if (has_cdefine_beep(codec)) { 19614 switch (codec->vendor_id) { 19615 case 0x10ec0662: 19616 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 19617 break; 19618 case 0x10ec0272: 19619 case 0x10ec0663: 19620 case 0x10ec0665: 19621 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 19622 break; 19623 case 0x10ec0273: 19624 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); 19625 break; 19626 } 19627 } 19628 spec->vmaster_nid = 0x02; 19629 19630 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 19631 19632 codec->patch_ops = alc_patch_ops; 19633 if (board_config == ALC662_AUTO) 19634 spec->init_hook = alc662_auto_init; 19635 spec->shutup = alc_eapd_shutup; 19636 19637 alc_init_jacks(codec); 19638 19639#ifdef CONFIG_SND_HDA_POWER_SAVE 19640 if (!spec->loopback.amplist) 19641 spec->loopback.amplist = alc662_loopbacks; 19642#endif 19643 19644 return 0; 19645} 19646 19647static int patch_alc888(struct hda_codec *codec) 19648{ 19649 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ 19650 kfree(codec->chip_name); 19651 if (codec->vendor_id == 0x10ec0887) 19652 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); 19653 else 19654 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); 19655 if (!codec->chip_name) { 19656 alc_free(codec); 19657 return -ENOMEM; 19658 } 19659 return patch_alc662(codec); 19660 } 19661 return patch_alc882(codec); 19662} 19663 19664static int patch_alc899(struct hda_codec *codec) 19665{ 19666 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) { 19667 kfree(codec->chip_name); 19668 codec->chip_name = kstrdup("ALC898", GFP_KERNEL); 19669 } 19670 return patch_alc882(codec); 19671} 19672 19673/* 19674 * ALC680 support 19675 */ 19676#define ALC680_DIGIN_NID ALC880_DIGIN_NID 19677#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID 19678#define alc680_modes alc260_modes 19679 19680static const hda_nid_t alc680_dac_nids[3] = { 19681 /* Lout1, Lout2, hp */ 19682 0x02, 0x03, 0x04 19683}; 19684 19685static const hda_nid_t alc680_adc_nids[3] = { 19686 /* ADC0-2 */ 19687 /* DMIC, MIC, Line-in*/ 19688 0x07, 0x08, 0x09 19689}; 19690 19691/* 19692 * Analog capture ADC cgange 19693 */ 19694static void alc680_rec_autoswitch(struct hda_codec *codec) 19695{ 19696 struct alc_spec *spec = codec->spec; 19697 struct auto_pin_cfg *cfg = &spec->autocfg; 19698 int pin_found = 0; 19699 int type_found = AUTO_PIN_LAST; 19700 hda_nid_t nid; 19701 int i; 19702 19703 for (i = 0; i < cfg->num_inputs; i++) { 19704 nid = cfg->inputs[i].pin; 19705 if (!is_jack_detectable(codec, nid)) 19706 continue; 19707 if (snd_hda_jack_detect(codec, nid)) { 19708 if (cfg->inputs[i].type < type_found) { 19709 type_found = cfg->inputs[i].type; 19710 pin_found = nid; 19711 } 19712 } 19713 } 19714 19715 nid = 0x07; 19716 if (pin_found) 19717 snd_hda_get_connections(codec, pin_found, &nid, 1); 19718 19719 if (nid != spec->cur_adc) 19720 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 19721 spec->cur_adc = nid; 19722 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0, 19723 spec->cur_adc_format); 19724} 19725 19726static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 19727 struct hda_codec *codec, 19728 unsigned int stream_tag, 19729 unsigned int format, 19730 struct snd_pcm_substream *substream) 19731{ 19732 struct alc_spec *spec = codec->spec; 19733 19734 spec->cur_adc = 0x07; 19735 spec->cur_adc_stream_tag = stream_tag; 19736 spec->cur_adc_format = format; 19737 19738 alc680_rec_autoswitch(codec); 19739 return 0; 19740} 19741 19742static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 19743 struct hda_codec *codec, 19744 struct snd_pcm_substream *substream) 19745{ 19746 snd_hda_codec_cleanup_stream(codec, 0x07); 19747 snd_hda_codec_cleanup_stream(codec, 0x08); 19748 snd_hda_codec_cleanup_stream(codec, 0x09); 19749 return 0; 19750} 19751 19752static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = { 19753 .substreams = 1, /* can be overridden */ 19754 .channels_min = 2, 19755 .channels_max = 2, 19756 /* NID is set in alc_build_pcms */ 19757 .ops = { 19758 .prepare = alc680_capture_pcm_prepare, 19759 .cleanup = alc680_capture_pcm_cleanup 19760 }, 19761}; 19762 19763static const struct snd_kcontrol_new alc680_base_mixer[] = { 19764 /* output mixer control */ 19765 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 19766 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19769 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT), 19770 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), 19771 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT), 19772 { } 19773}; 19774 19775static const struct hda_bind_ctls alc680_bind_cap_vol = { 19776 .ops = &snd_hda_bind_vol, 19777 .values = { 19778 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19779 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19780 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19781 0 19782 }, 19783}; 19784 19785static const struct hda_bind_ctls alc680_bind_cap_switch = { 19786 .ops = &snd_hda_bind_sw, 19787 .values = { 19788 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), 19789 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), 19790 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), 19791 0 19792 }, 19793}; 19794 19795static const struct snd_kcontrol_new alc680_master_capture_mixer[] = { 19796 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), 19797 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), 19798 { } /* end */ 19799}; 19800 19801/* 19802 * generic initialization of ADC, input mixers and output mixers 19803 */ 19804static const struct hda_verb alc680_init_verbs[] = { 19805 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19806 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19807 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 19808 19809 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 19812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 19813 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 19814 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 19815 19816 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19817 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19819 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19820 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 19821 19822 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 19823 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19824 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, 19825 19826 { } 19827}; 19828 19829/* toggle speaker-output according to the hp-jack state */ 19830static void alc680_base_setup(struct hda_codec *codec) 19831{ 19832 struct alc_spec *spec = codec->spec; 19833 19834 spec->autocfg.hp_pins[0] = 0x16; 19835 spec->autocfg.speaker_pins[0] = 0x14; 19836 spec->autocfg.speaker_pins[1] = 0x15; 19837 spec->autocfg.num_inputs = 2; 19838 spec->autocfg.inputs[0].pin = 0x18; 19839 spec->autocfg.inputs[0].type = AUTO_PIN_MIC; 19840 spec->autocfg.inputs[1].pin = 0x19; 19841 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; 19842 spec->automute = 1; 19843 spec->automute_mode = ALC_AUTOMUTE_AMP; 19844} 19845 19846static void alc680_unsol_event(struct hda_codec *codec, 19847 unsigned int res) 19848{ 19849 if ((res >> 26) == ALC880_HP_EVENT) 19850 alc_hp_automute(codec); 19851 if ((res >> 26) == ALC880_MIC_EVENT) 19852 alc680_rec_autoswitch(codec); 19853} 19854 19855static void alc680_inithook(struct hda_codec *codec) 19856{ 19857 alc_hp_automute(codec); 19858 alc680_rec_autoswitch(codec); 19859} 19860 19861/* create input playback/capture controls for the given pin */ 19862static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 19863 const char *ctlname, int idx) 19864{ 19865 hda_nid_t dac; 19866 int err; 19867 19868 switch (nid) { 19869 case 0x14: 19870 dac = 0x02; 19871 break; 19872 case 0x15: 19873 dac = 0x03; 19874 break; 19875 case 0x16: 19876 dac = 0x04; 19877 break; 19878 default: 19879 return 0; 19880 } 19881 if (spec->multiout.dac_nids[0] != dac && 19882 spec->multiout.dac_nids[1] != dac) { 19883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, 19884 HDA_COMPOSE_AMP_VAL(dac, 3, idx, 19885 HDA_OUTPUT)); 19886 if (err < 0) 19887 return err; 19888 19889 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, 19890 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 19891 19892 if (err < 0) 19893 return err; 19894 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 19895 } 19896 19897 return 0; 19898} 19899 19900/* add playback controls from the parsed DAC table */ 19901static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec, 19902 const struct auto_pin_cfg *cfg) 19903{ 19904 hda_nid_t nid; 19905 int err; 19906 19907 spec->multiout.dac_nids = spec->private_dac_nids; 19908 19909 nid = cfg->line_out_pins[0]; 19910 if (nid) { 19911 const char *name; 19912 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 19913 name = "Speaker"; 19914 else 19915 name = "Front"; 19916 err = alc680_new_analog_output(spec, nid, name, 0); 19917 if (err < 0) 19918 return err; 19919 } 19920 19921 nid = cfg->speaker_pins[0]; 19922 if (nid) { 19923 err = alc680_new_analog_output(spec, nid, "Speaker", 0); 19924 if (err < 0) 19925 return err; 19926 } 19927 nid = cfg->hp_pins[0]; 19928 if (nid) { 19929 err = alc680_new_analog_output(spec, nid, "Headphone", 0); 19930 if (err < 0) 19931 return err; 19932 } 19933 19934 return 0; 19935} 19936 19937static void alc680_auto_set_output_and_unmute(struct hda_codec *codec, 19938 hda_nid_t nid, int pin_type) 19939{ 19940 alc_set_pin_output(codec, nid, pin_type); 19941} 19942 19943static void alc680_auto_init_multi_out(struct hda_codec *codec) 19944{ 19945 struct alc_spec *spec = codec->spec; 19946 hda_nid_t nid = spec->autocfg.line_out_pins[0]; 19947 if (nid) { 19948 int pin_type = get_pin_type(spec->autocfg.line_out_type); 19949 alc680_auto_set_output_and_unmute(codec, nid, pin_type); 19950 } 19951} 19952 19953static void alc680_auto_init_hp_out(struct hda_codec *codec) 19954{ 19955 struct alc_spec *spec = codec->spec; 19956 hda_nid_t pin; 19957 19958 pin = spec->autocfg.hp_pins[0]; 19959 if (pin) 19960 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP); 19961 pin = spec->autocfg.speaker_pins[0]; 19962 if (pin) 19963 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT); 19964} 19965 19966/* pcm configuration: identical with ALC880 */ 19967#define alc680_pcm_analog_playback alc880_pcm_analog_playback 19968#define alc680_pcm_analog_capture alc880_pcm_analog_capture 19969#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 19970#define alc680_pcm_digital_playback alc880_pcm_digital_playback 19971#define alc680_pcm_digital_capture alc880_pcm_digital_capture 19972 19973/* 19974 * BIOS auto configuration 19975 */ 19976static int alc680_parse_auto_config(struct hda_codec *codec) 19977{ 19978 struct alc_spec *spec = codec->spec; 19979 int err; 19980 static const hda_nid_t alc680_ignore[] = { 0 }; 19981 19982 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 19983 alc680_ignore); 19984 if (err < 0) 19985 return err; 19986 19987 if (!spec->autocfg.line_outs) { 19988 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { 19989 spec->multiout.max_channels = 2; 19990 spec->no_analog = 1; 19991 goto dig_only; 19992 } 19993 return 0; /* can't find valid BIOS pin config */ 19994 } 19995 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg); 19996 if (err < 0) 19997 return err; 19998 19999 spec->multiout.max_channels = 2; 20000 20001 dig_only: 20002 /* digital only support output */ 20003 alc_auto_parse_digital(codec); 20004 if (spec->kctls.list) 20005 add_mixer(spec, spec->kctls.list); 20006 20007 add_verb(spec, alc680_init_verbs); 20008 20009 err = alc_auto_add_mic_boost(codec); 20010 if (err < 0) 20011 return err; 20012 20013 return 1; 20014} 20015 20016#define alc680_auto_init_analog_input alc882_auto_init_analog_input 20017 20018/* init callback for auto-configuration model -- overriding the default init */ 20019static void alc680_auto_init(struct hda_codec *codec) 20020{ 20021 struct alc_spec *spec = codec->spec; 20022 alc680_auto_init_multi_out(codec); 20023 alc680_auto_init_hp_out(codec); 20024 alc680_auto_init_analog_input(codec); 20025 alc_auto_init_digital(codec); 20026 if (spec->unsol_event) 20027 alc_inithook(codec); 20028} 20029 20030/* 20031 * configuration and preset 20032 */ 20033static const char * const alc680_models[ALC680_MODEL_LAST] = { 20034 [ALC680_BASE] = "base", 20035 [ALC680_AUTO] = "auto", 20036}; 20037 20038static const struct snd_pci_quirk alc680_cfg_tbl[] = { 20039 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), 20040 {} 20041}; 20042 20043static const struct alc_config_preset alc680_presets[] = { 20044 [ALC680_BASE] = { 20045 .mixers = { alc680_base_mixer }, 20046 .cap_mixer = alc680_master_capture_mixer, 20047 .init_verbs = { alc680_init_verbs }, 20048 .num_dacs = ARRAY_SIZE(alc680_dac_nids), 20049 .dac_nids = alc680_dac_nids, 20050 .dig_out_nid = ALC680_DIGOUT_NID, 20051 .num_channel_mode = ARRAY_SIZE(alc680_modes), 20052 .channel_mode = alc680_modes, 20053 .unsol_event = alc680_unsol_event, 20054 .setup = alc680_base_setup, 20055 .init_hook = alc680_inithook, 20056 20057 }, 20058}; 20059 20060static int patch_alc680(struct hda_codec *codec) 20061{ 20062 struct alc_spec *spec; 20063 int board_config; 20064 int err; 20065 20066 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 20067 if (spec == NULL) 20068 return -ENOMEM; 20069 20070 codec->spec = spec; 20071 20072 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 20073 alc680_models, 20074 alc680_cfg_tbl); 20075 20076 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 20077 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 20078 codec->chip_name); 20079 board_config = ALC680_AUTO; 20080 } 20081 20082 if (board_config == ALC680_AUTO) { 20083 /* automatic parse from the BIOS config */ 20084 err = alc680_parse_auto_config(codec); 20085 if (err < 0) { 20086 alc_free(codec); 20087 return err; 20088 } else if (!err) { 20089 printk(KERN_INFO 20090 "hda_codec: Cannot set up configuration " 20091 "from BIOS. Using base mode...\n"); 20092 board_config = ALC680_BASE; 20093 } 20094 } 20095 20096 if (board_config != ALC680_AUTO) 20097 setup_preset(codec, &alc680_presets[board_config]); 20098 20099 spec->stream_analog_playback = &alc680_pcm_analog_playback; 20100 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 20101 spec->stream_digital_playback = &alc680_pcm_digital_playback; 20102 spec->stream_digital_capture = &alc680_pcm_digital_capture; 20103 20104 if (!spec->adc_nids) { 20105 spec->adc_nids = alc680_adc_nids; 20106 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids); 20107 } 20108 20109 if (!spec->cap_mixer) 20110 set_capture_mixer(codec); 20111 20112 spec->vmaster_nid = 0x02; 20113 20114 codec->patch_ops = alc_patch_ops; 20115 if (board_config == ALC680_AUTO) 20116 spec->init_hook = alc680_auto_init; 20117 20118 return 0; 20119} 20120 20121/* 20122 * patch entries 20123 */ 20124static const struct hda_codec_preset snd_hda_preset_realtek[] = { 20125 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, 20126 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 20127 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 20128 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 20129 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, 20130 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, 20131 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, 20132 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, 20133 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 20134 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 20135 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 20136 .patch = patch_alc861 }, 20137 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 20138 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 20139 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 20140 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 20141 .patch = patch_alc882 }, 20142 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 20143 .patch = patch_alc662 }, 20144 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", 20145 .patch = patch_alc662 }, 20146 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 20147 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 20148 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 20149 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, 20150 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 20151 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 20152 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 20153 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 20154 .patch = patch_alc882 }, 20155 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 20156 .patch = patch_alc882 }, 20157 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 20158 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, 20159 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 20160 .patch = patch_alc882 }, 20161 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, 20162 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, 20163 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, 20164 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 }, 20165 {} /* terminator */ 20166}; 20167 20168MODULE_ALIAS("snd-hda-codec-id:10ec*"); 20169 20170MODULE_LICENSE("GPL"); 20171MODULE_DESCRIPTION("Realtek HD-audio codec"); 20172 20173static struct hda_codec_preset_list realtek_list = { 20174 .preset = snd_hda_preset_realtek, 20175 .owner = THIS_MODULE, 20176}; 20177 20178static int __init patch_realtek_init(void) 20179{ 20180 return snd_hda_add_codec_preset(&realtek_list); 20181} 20182 20183static void __exit patch_realtek_exit(void) 20184{ 20185 snd_hda_delete_codec_preset(&realtek_list); 20186} 20187 20188module_init(patch_realtek_init) 20189module_exit(patch_realtek_exit) 20190